From da06bc595252c4ea0f528b74d068f8c97c34c7e7 Mon Sep 17 00:00:00 2001 From: link1107 <66795347+link1107@users.noreply.github.com> Date: Sat, 22 Jan 2022 20:02:36 +0100 Subject: [PATCH] Initial commit --- .gitignore | 113 ++++ pom.xml | 92 +++ .../DonationAlerts/DonationAlerts.java | 103 ++++ .../igorlink/command/AbstractCommand.java | 30 + .../igorlink/command/DonateSubCommand.java | 43 ++ .../command/DonationExecutorCommand.java | 68 +++ .../igorlink/command/FilterSubCommand.java | 26 + .../igorlink/command/ReloadSubCommand.java | 16 + .../donationexecutor/DonationExecutor.java | 64 ++ .../donationexecutor/EventListener.java | 44 ++ .../igorlink/donationexecutor/Executor.java | 315 ++++++++++ .../executionsstaff/Donation.java | 53 ++ .../executionsstaff/GiantMobManager.java | 577 ++++++++++++++++++ .../ListOfStreamerPlayers.java | 79 +++ .../executionsstaff/StreamerPlayer.java | 109 ++++ .../java/igorlink/service/MainConfig.java | 118 ++++ src/main/java/igorlink/service/Utils.java | 248 ++++++++ src/main/resources/config.yml | 96 +++ src/main/resources/plugin.yml | 15 + 19 files changed, 2209 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/igorlink/DonationAlerts/DonationAlerts.java create mode 100644 src/main/java/igorlink/command/AbstractCommand.java create mode 100644 src/main/java/igorlink/command/DonateSubCommand.java create mode 100644 src/main/java/igorlink/command/DonationExecutorCommand.java create mode 100644 src/main/java/igorlink/command/FilterSubCommand.java create mode 100644 src/main/java/igorlink/command/ReloadSubCommand.java create mode 100644 src/main/java/igorlink/donationexecutor/DonationExecutor.java create mode 100644 src/main/java/igorlink/donationexecutor/EventListener.java create mode 100644 src/main/java/igorlink/donationexecutor/Executor.java create mode 100644 src/main/java/igorlink/donationexecutor/executionsstaff/Donation.java create mode 100644 src/main/java/igorlink/donationexecutor/executionsstaff/GiantMobManager.java create mode 100644 src/main/java/igorlink/donationexecutor/executionsstaff/ListOfStreamerPlayers.java create mode 100644 src/main/java/igorlink/donationexecutor/executionsstaff/StreamerPlayer.java create mode 100644 src/main/java/igorlink/service/MainConfig.java create mode 100644 src/main/java/igorlink/service/Utils.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..7e5181b --- /dev/null +++ b/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + IgorLink + DonationExecutor + 1.0-SNAPSHOT + jar + + DonationExecutor + + Executes donations + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + mvnrepo-repo + https://papermc.io/repo/repository/maven-public/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + + + + io.papermc.paper + paper-api + 1.18.1-R0.1-SNAPSHOT + provided + + + io.socket + engine.io-client + 0.8.3 + + + io.socket + socket.io-client + 0.8.3 + + + org.json + json + 20190722 + + + + + diff --git a/src/main/java/igorlink/DonationAlerts/DonationAlerts.java b/src/main/java/igorlink/DonationAlerts/DonationAlerts.java new file mode 100644 index 0000000..c4ca073 --- /dev/null +++ b/src/main/java/igorlink/DonationAlerts/DonationAlerts.java @@ -0,0 +1,103 @@ +package igorlink.DonationAlerts; + +import igorlink.donationexecutor.DonationExecutor; +import igorlink.donationexecutor.executionsstaff.Donation; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitRunnable; +import io.socket.emitter.Emitter.Listener; +import io.socket.client.IO; +import io.socket.client.Socket; +import org.json.JSONException; +import org.json.JSONObject; +import java.net.URI; +import java.net.URISyntaxException; +import static igorlink.service.Utils.logToConsole; + + +public class DonationAlerts { + private Listener connectListener; + private Listener disconectListener; + private Listener donationListener; + private Listener errorListener; + + private URI url; + private Socket socket; + + + public DonationAlerts(String server) throws URISyntaxException { + + url = new URI(server); + socket = IO.socket(url); + + connectListener = new Listener() { + @Override + public void call(Object... arg0) { + logToConsole("Произведено успешное подключение!"); + } + }; + + disconectListener = new Listener() { + @Override + public void call(Object... arg0) { + logToConsole("Соединение разорвано!"); + } + }; + + donationListener = new Listener() { + @Override + public void call(Object... arg0) { + + JSONObject json = new JSONObject((String) arg0[0]); + json.toString(); + new BukkitRunnable() { + @Override + public void run() { + + if ( (json.isNull("username")) || (json.isNull("amount_formatted"))) { + return; + } + + if ((json.getString("amount_formatted")).length() <= 1) { + return; + } + + DonationExecutor.getInstance().listOfStreamerPlayers + .addToDonationsQueue(new Donation(Bukkit.getConsoleSender(), + json.getString("username"), + json.getString("amount_formatted"), + json.getString("message"))); + + } + }.runTask(Bukkit.getPluginManager().getPlugin("DonationExecutor")); + + } + }; + + errorListener = new Listener() { + @Override + public void call(Object... arg0) { + logToConsole("Произошла ошибка подключения к Donation Alerts!"); + } + }; + + socket.on(Socket.EVENT_CONNECT, connectListener) + .on(Socket.EVENT_DISCONNECT, disconectListener) + .on(Socket.EVENT_ERROR, errorListener) + .on("donation", donationListener); + } + + public void Connect (String token) throws JSONException { + socket.connect(); + socket.emit("add-user", new JSONObject() + .put("token", token) + .put("type", "minor")); + } + + public void Disconnect() throws JSONException { + socket.disconnect(); + } + + public boolean getConnected() { + return socket.connected(); + } +} \ No newline at end of file diff --git a/src/main/java/igorlink/command/AbstractCommand.java b/src/main/java/igorlink/command/AbstractCommand.java new file mode 100644 index 0000000..d62bf86 --- /dev/null +++ b/src/main/java/igorlink/command/AbstractCommand.java @@ -0,0 +1,30 @@ +package igorlink.command; + +import igorlink.donationexecutor.DonationExecutor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; +import org.jetbrains.annotations.NotNull; + +public abstract class AbstractCommand implements CommandExecutor { + + public AbstractCommand(String command) { + PluginCommand pluginCommand = DonationExecutor.getInstance().getCommand(command); + if (pluginCommand != null) { + pluginCommand.setExecutor(this); + } + } + + public abstract Boolean execute(CommandSender sender, String label, String[] args); + + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (execute(sender, label, args)) { + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/igorlink/command/DonateSubCommand.java b/src/main/java/igorlink/command/DonateSubCommand.java new file mode 100644 index 0000000..3e4c1b3 --- /dev/null +++ b/src/main/java/igorlink/command/DonateSubCommand.java @@ -0,0 +1,43 @@ +package igorlink.command; + +import igorlink.donationexecutor.DonationExecutor; +import igorlink.donationexecutor.executionsstaff.Donation; +import org.bukkit.command.CommandSender; + +public class DonateSubCommand { + public static void onDonateCommand(CommandSender sender, String[] args) { + int i; + + //Getting donation's amount + String donationAmount = new String(); + String donationUsername = new String(); + String donationMessage = new String(); + + //Getting donation's amount + donationAmount = args[0]; + + //Получаем имя донатера + for (i = 1; i <= args.length - 1; i++) { + if (args[i].equals("##")) { + break; + } + else { + if (i==1) { + donationUsername = donationUsername + args[i]; + } + else { + donationUsername = ' ' + donationUsername + args[i]; + } + } + } + + //Все, что после символов ## - это сообщение + for (i = i+1; i <= args.length - 1; i++) + { + donationMessage = donationMessage + args[i] + ' '; + } + + //Отправляем донат на исполнение + DonationExecutor.getInstance().listOfStreamerPlayers.addToDonationsQueue(new Donation(sender, donationUsername, donationAmount+".00", donationMessage)); + } +} diff --git a/src/main/java/igorlink/command/DonationExecutorCommand.java b/src/main/java/igorlink/command/DonationExecutorCommand.java new file mode 100644 index 0000000..fae90d7 --- /dev/null +++ b/src/main/java/igorlink/command/DonationExecutorCommand.java @@ -0,0 +1,68 @@ +package igorlink.command; + +import org.bukkit.command.CommandSender; +import static igorlink.service.Utils.logToConsole; + + +public class DonationExecutorCommand extends AbstractCommand { + + public DonationExecutorCommand() { + super("donationexecutor"); + } + + @Override + public Boolean execute(CommandSender sender, String label, String[] args) { + String[] newArgs; + + if (args.length == 0) { + return false; + } + + try { + + //Если команда - это reload, где не должно быть доп аргументов, то вызываем функцию релоуда конфига + if (args[0].equals("reload")) { + if (args.length == 1) { + ReloadSubCommand.onReloadCommand(sender); + return true; + } + } else if (args[0].equals("donate")) { + //Инициализируем список аргментов для новой сабфункции + //Если команда - donate, где нужен минимум 1 доп аргумент, создаем новый массив аргументов со смещением 1, и вызываем функцию обработки доната + if (args.length >= 2) { + //Инициализируем список новых аргументов для субкоманды + newArgs = new String[args.length - 1]; + //Создаем новый список аргументов, копируя старый со смещением 1 + System.arraycopy(args, 1, newArgs, 0, args.length - 1); + //Вызываем обработку доната + DonateSubCommand.onDonateCommand(sender, newArgs); + //Возвращаем true, к все прошло успешно + return true; + } + } else if (args[0].equals("filter")) { + if ((args.length == 2) && (args[1].equals("on")) || (args[1].equals("off"))) { + //Инициализируем список новых аргументов для субкоманды + newArgs = new String[args.length - 1]; + //Создаем новый список аргументов, копируя старый со смещением 1 + System.arraycopy(args, 1, newArgs, 0, args.length - 1); + //Вызываем обработку доната + FilterSubCommand.onFilterCommand(sender, newArgs); + //Возвращаем true, к все прошло успешно + return true; + } + } + + } catch (Exception e) { + + //Если получили exception, сообщаем о нем и выдаем сообщение об ошибке в консоль + e.printStackTrace(); + logToConsole("Произошла неизвестная ошибка при выполнении команды!"); + return false; + + } + + //Если ничего не выполнилось - в команде была ошибка + return false; + } + +} diff --git a/src/main/java/igorlink/command/FilterSubCommand.java b/src/main/java/igorlink/command/FilterSubCommand.java new file mode 100644 index 0000000..b6c8402 --- /dev/null +++ b/src/main/java/igorlink/command/FilterSubCommand.java @@ -0,0 +1,26 @@ +package igorlink.command; + +import igorlink.service.MainConfig; +import igorlink.service.Utils; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + + +public class FilterSubCommand { + public static void onFilterCommand(CommandSender sender, String[] args) { + if (args[0].toLowerCase().equals("on")) { + MainConfig.turnFilterOn(); + Utils.logToConsole("Фильтр никнеймов донатеров §bВКЛЮЧЕН"); + if (sender instanceof Player) { + Utils.sendSysMsgToPlayer((Player) sender, "Фильтр никнеймов донатеров §bВКЛЮЧЕН"); + } + } else { + MainConfig.turnFilterOff(); + Utils.logToConsole("Фильтр никнеймов донатеров §bВЫКЛЮЧЕН"); + if (sender instanceof Player) { + Utils.sendSysMsgToPlayer((Player) sender,"Фильтр никнеймов донатеров §bВЫКЛЮЧЕН"); + } + } + + } +} diff --git a/src/main/java/igorlink/command/ReloadSubCommand.java b/src/main/java/igorlink/command/ReloadSubCommand.java new file mode 100644 index 0000000..5c59c0c --- /dev/null +++ b/src/main/java/igorlink/command/ReloadSubCommand.java @@ -0,0 +1,16 @@ +package igorlink.command; + +import igorlink.service.MainConfig; +import igorlink.service.Utils; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ReloadSubCommand { + public static void onReloadCommand(CommandSender sender){ + MainConfig.loadMainConfig(true); + Utils.logToConsole("Настройки успешно обновлены!"); + if (sender instanceof Player) { + Utils.sendSysMsgToPlayer(((Player) sender).getPlayer(), "Настройки успешно обновлены!"); + } + } +} diff --git a/src/main/java/igorlink/donationexecutor/DonationExecutor.java b/src/main/java/igorlink/donationexecutor/DonationExecutor.java new file mode 100644 index 0000000..ddca55b --- /dev/null +++ b/src/main/java/igorlink/donationexecutor/DonationExecutor.java @@ -0,0 +1,64 @@ +package igorlink.donationexecutor; + +import igorlink.command.DonationExecutorCommand; +import igorlink.donationexecutor.executionsstaff.GiantMobManager; +import igorlink.donationexecutor.executionsstaff.ListOfStreamerPlayers; +import igorlink.service.MainConfig; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; +import igorlink.DonationAlerts.*; +import java.net.URISyntaxException; +import static igorlink.service.Utils.*; + + +public final class DonationExecutor extends JavaPlugin { + + public static final String DASERVER = "https://socket.donationalerts.ru:443"; + private static DonationExecutor instance; + public static DonationAlerts da; + public static GiantMobManager giantMobManager; + public static Boolean isRunning = true; + public ListOfStreamerPlayers listOfStreamerPlayers; + + + @Override + public void onEnable() { + instance = this; + listOfStreamerPlayers = new ListOfStreamerPlayers(); + MainConfig.loadMainConfig(); + giantMobManager = new GiantMobManager(this); + + if (CheckNameAndToken()) { + try { + da = new DonationAlerts(DASERVER); + da.Connect(MainConfig.token); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + new DonationExecutorCommand(); + } + + + Bukkit.getPluginManager().registerEvents(new EventListener(),this); + + } + + @Override + public void onDisable() { + try { + isRunning = false; + da.Disconnect(); + Thread.sleep(1000); + da = null; + } catch (Exception e) { + logToConsole("Какая-то ебаная ошибка, похуй на нее вообще"); + } + } + + + public static DonationExecutor getInstance() { + return instance; + } + + +} diff --git a/src/main/java/igorlink/donationexecutor/EventListener.java b/src/main/java/igorlink/donationexecutor/EventListener.java new file mode 100644 index 0000000..cf0748c --- /dev/null +++ b/src/main/java/igorlink/donationexecutor/EventListener.java @@ -0,0 +1,44 @@ +package igorlink.donationexecutor; + +import igorlink.service.Utils; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.*; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.scheduler.BukkitTask; +import java.util.HashMap; +import java.util.Map; +import static igorlink.service.Utils.*; + +public class EventListener implements Listener { + + private Map projectiles = new HashMap(); + + //Отмена горения НКВДшников + @EventHandler + public void onComburst(EntityCombustEvent e){ + if ((e.getEntity().getName().equals("§cСотрудник НКВД")) || (e.getEntity().getName().equals("§cИосиф Сталин"))) { + e.setCancelled(true); + } + } + + //Закачка ресурспака и оповещение о том, что плагин не активен, если он не активен + @EventHandler + public void onJoin(PlayerJoinEvent e) { + e.getPlayer().setResourcePack("https://download.mc-packs.net/pack/4923efe27212858f64c3ba65ff4bd35a42dadfb0.zip", Utils.decodeUsingBigInteger("4923efe27212858f64c3ba65ff4bd35a42dadfb0")); + if (!isPluginActive) { + sendSysMsgToPlayer(e.getPlayer(), " плагин не активен. Укажите токен и свой никнейм в файле конфигурации плагина и перезапустите сервер."); + } + } + + + //Отмена дропа у НКВДшников + @EventHandler + public void onEntityDeath(EntityDeathEvent e){ + if (e.getEntity().getName().equals("§cСотрудник НКВД")) { + e.getDrops().clear(); + } + } + +} + diff --git a/src/main/java/igorlink/donationexecutor/Executor.java b/src/main/java/igorlink/donationexecutor/Executor.java new file mode 100644 index 0000000..4ff2e9c --- /dev/null +++ b/src/main/java/igorlink/donationexecutor/Executor.java @@ -0,0 +1,315 @@ +package igorlink.donationexecutor; +import igorlink.service.MainConfig; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.*; +import org.bukkit.attribute.Attribute; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.*; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import java.util.*; + +import static igorlink.service.Utils.*; +import static java.lang.Math.*; +import static org.bukkit.Bukkit.getPlayer; + +public class Executor { + public static String nameOfStreamerPlayer; + public static String nameOfSecondStreamerPlayer; + public static List executionsList = new ArrayList<>(Arrays.asList("ShitToInventory", "Lesch", "DropActiveItem", + "PowerKick", "ClearLastDeathDrop", "SpawnCreeper", "GiveDiamonds", "GiveStackOfDiamonds", "GiveBread", + "CallNKVD", "CallStalin", "RandomChange", "TamedBecomesEnemies", "HalfHeart", "BigBoom")); + + + public static void DoExecute(CommandSender sender, String streamerName, String donationUsername, String fullDonationAmount, String donationMessage, String executionName) { + + //Если имя донатера не указано - устанавливаем в качестве имени "Кто-то" + String _donationUsername; + if (donationUsername.equals("")) { + _donationUsername = "Кто-то"; + } else { + _donationUsername = donationUsername; + } + + Boolean canContinue = true; + //Определяем игрока (если он оффлайн - не выполняем донат и пишем об этом в консоль), а также определяем мир, местоположение и направление игрока + Player streamerPlayer = getPlayer(streamerName); + if (streamerPlayer == null) { + canContinue = false; + } else if (streamerPlayer.isDead()) { + canContinue = false; + } + + if (!canContinue) { + logToConsole("Донат от §b" + donationUsername + " §f в размере §b" + fullDonationAmount + "§f выполнен из-за того, что целевой стример был недоступен."); + return; + } + + Location streamerPlayerLocation = streamerPlayer.getLocation(); + World world = streamerPlayer.getWorld(); + Vector direction = streamerPlayerLocation.getDirection(); + + //streamerPlayer.sendActionBar(donationMessage); + + switch (executionName) { + case "ShitToInventory": + shitToInventory(streamerPlayer, donationUsername); + break; + case "Lesch": + lesch(streamerPlayer, donationUsername); + break; + case "DropActiveItem": + dropActiveItem(streamerPlayer, donationUsername); + break; + case "PowerKick": + powerKick(streamerPlayer, donationUsername); + break; + case "ClearLastDeathDrop": + clearLastDeathDrop(streamerPlayer, donationUsername); + break; + case "SpawnCreeper": + spawnCreeper(streamerPlayer, donationUsername); + break; + case "GiveDiamonds": + giveDiamonds(streamerPlayer, donationUsername); + break; + case "GiveStackOfDiamonds": + giveStackOfDiamonds(streamerPlayer, donationUsername); + break; + case "GiveBread": + giveBread(streamerPlayer, donationUsername); + break; + case "CallNKVD": + callNKVD(streamerPlayer, donationUsername); + break; + case "CallStalin": + callStalin(streamerPlayer, donationUsername); + break; + case "RandomChange": + randomChange(streamerPlayer, donationUsername); + break; + case "TamedBecomesEnemies": + tamedBecomesEnemies(streamerPlayer, donationUsername); + break; + case "HalfHeart": + halfHeart(streamerPlayer, donationUsername); + break; + case "BigBoom": + bigBoom(streamerPlayer, donationUsername); + break; + } + + } + + + + + public static void shitToInventory (Player player, String donationUsername) { + announce(donationUsername, "насрал тебе в инвентарь", "насрал в инвентарь", player, true); + Material itemType = Material.DIRT; + ItemStack itemStack = new ItemStack(itemType, 64); + ItemMeta meta = itemStack.getItemMeta(); + meta.setDisplayName("§cГОВНО ОТ §f" + donationUsername.toUpperCase()); + meta.setLore(Arrays.asList("§7Это говно ужасно вонюче и занимает много места")); + itemStack.setItemMeta(meta); + + for (int i = 0; i < MainConfig.dirtAmount; i++) { + player.getInventory().addItem(itemStack); + } + } + + public static void dropActiveItem (Player player, String donationUsername) { + if (player.getEquipment().getItemInMainHand().getType() == Material.AIR) { + announce(donationUsername, "безуспешно пытался выбить у тебя предмет из рук", "безуспешно пытался выбить предмет из рук", player, true); + } else { + announce(donationUsername, "выбил у тебя предмет из рук", "выбил предмет из рук", player, true); + ((HumanEntity) player).dropItem(true); + player.updateInventory(); + } + } + + public static void lesch (Player player, String donationUsername) { + announce(donationUsername, "дал тебе леща", "дал леща", player, true); + Vector direction = player.getLocation().getDirection(); + direction.setY(0); + direction.normalize(); + direction.setY(0.3); + player.setVelocity(direction.multiply(0.8)); + if (player.getHealth()>2.0D) { + player.setHealth(player.getHealth()-2); + } else { + player.setHealth(0); + } + ((org.bukkit.entity.Player) player).playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 1, 1); + } + + public static void powerKick (Player player, String donationUsername) { + announce(donationUsername, "дал тебе смачного пинка под зад", "дал смачного пинка под зад", player, true); + Vector direction = player.getLocation().getDirection(); + direction.setY(0); + direction.normalize(); + direction.setY(0.5); + player.setVelocity(direction.multiply(1.66)); + if (player.getHealth()>3.0D) { + player.setHealth(player.getHealth()-3); + } else { + player.setHealth(0); + } + ((org.bukkit.entity.Player) player).playSound(player.getLocation(), Sound.ENTITY_PLAYER_HURT, 1, 1); + } + + public static void clearLastDeathDrop (Player player, String donationUsername) { + //Remove Last Death Dropped Items + if (DonationExecutor.getInstance().listOfStreamerPlayers.getStreamerPlayer(player.getName()).removeDeathDrop()) { + announce(donationUsername, "уничтожил твой посмертный дроп...", "уничтожил посмертный дроп", player, true); + } else { + announce(donationUsername, "безуспешно пытался уничтожить твой посмертный дроп...", "безуспешно пытался уничтожить посмертный дроп", player, true); + } + } + + public static void spawnCreeper (Player player, String donationUsername) { + //Spawn Creepers + Vector direction = player.getLocation().getDirection(); + announce(donationUsername, "прислал тебе в подарок крипера...", "прислал крипера в подарок", player, true); + direction.setY(0); + direction.normalize(); + player.getWorld().spawnEntity(player.getLocation().clone().subtract(direction.multiply(1)), EntityType.CREEPER); + + } + + public static void giveDiamonds (Player player, String donationUsername) { + //Give some diamonds to the player + announce(donationUsername, "насыпал тебе алмазов!", "насыпал алмазов", player, true); + Material itemType = Material.DIAMOND; + ItemStack itemStack = new ItemStack(itemType, MainConfig.diamondsAmount); + ItemMeta meta = itemStack.getItemMeta(); + meta.setDisplayName("§bАлмаз"); + meta.setLore(Arrays.asList("§7Эти алмазы подарил §f" + donationUsername)); + itemStack.setItemMeta(meta); + Item diamonds = player.getWorld().dropItemNaturally(player.getLocation(), itemStack); + } + + public static void giveStackOfDiamonds (Player player, String donationUsername) { + announce(donationUsername, "насыпал тебе алмазов!", "насыпал алмазов", player, true); + Material itemType = Material.DIAMOND; + ItemStack itemStack = new ItemStack(itemType, 64); + ItemMeta meta = itemStack.getItemMeta(); + meta.setDisplayName("§bАлмаз"); + meta.setLore(Arrays.asList("§7Эти алмазы подарил §f" + donationUsername)); + itemStack.setItemMeta(meta); + Item diamonds = player.getWorld().dropItemNaturally(player.getLocation(), itemStack); + } + + public static void giveBread (Player player, String donationUsername) { + announce(donationUsername, "дал тебе хлеба!", "дал хлеба", player, true); + Material itemType = Material.BREAD; + ItemStack itemStack = new ItemStack(itemType, 4); + ItemMeta meta = itemStack.getItemMeta(); + meta.setDisplayName("§bХлеб"); + meta.setLore(Arrays.asList("§7Этот хлеб подарил §f" + donationUsername)); + itemStack.setItemMeta(meta); + Item bread = player.getWorld().dropItemNaturally(player.getLocation(), itemStack); + } + + public static void callNKVD (Player player, String donationUsername) { + Vector direction = player.getLocation().getDirection(); + LivingEntity nkvdMob; + announce(donationUsername, "хочет отправить тебя в ГУЛАГ!", "хочет отправить в ГУЛАГ", player, true); + direction.setY(0); + direction.normalize(); + for (int i = 1; i <= 3; i++) { + Location newloc = player.getLocation().clone(); + Vector newdir = direction.clone(); + newdir = newdir.rotateAroundY(1.5708 * i).multiply(2); + newloc.add(newdir); + nkvdMob = (LivingEntity) player.getWorld().spawnEntity(newloc, EntityType.ZOMBIE); + nkvdMob.setCustomName("§cСотрудник НКВД"); + nkvdMob.getEquipment().setItem(EquipmentSlot.HAND, new ItemStack(Material.IRON_SWORD)); + nkvdMob.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.3); + } + + } + + public static void callStalin (Player player, String donationUsername) { + announce(donationUsername, "призвал Сталина разобраться с тобой!", "призвал Сталина разобраться с", player, true); + DonationExecutor.giantMobManager.addMob(player.getLocation(), "§cИосиф Сталин"); + } + + public static void randomChange (Player player, String donationUsername) { + announce(donationUsername, "подменил тебе кое-что на камни...", "призвал Сталина разобраться с", player, true); + int[] randoms = new int[5]; + for (int i = 0; i <= 4; i++) { + + int temp = 0; + Boolean isUnique = false; + while (!isUnique) { + temp = (int) (round(random() * 35)); + isUnique = true; + int n; + for (n = 0; n < i; n++) { + if (randoms[n] == temp) { + isUnique = false; + break; + } + } + } + randoms[i] = temp; + + } + + String replacedItems = new String(""); + int replacedCounter = 0; + for (int i = 0; i <= 4; i++) { + if (!(player.getInventory().getItem(randoms[i]) == null)) { + replacedCounter++; + if (replacedCounter > 1) { + replacedItems = replacedItems + "§f, "; + } + replacedItems = replacedItems + "§b" + player.getInventory().getItem(randoms[i]).getAmount() + " §f" + player.getInventory().getItem(randoms[i]).getI18NDisplayName().toString(); + } + player.getInventory().setItem(randoms[i], new ItemStack(Material.STONE, 1)); + } + + if (replacedCounter == 0) { + sendSysMsgToPlayer(player,"§cТебе повезло: все камни попали в пустые слоты!"); + } else { + sendSysMsgToPlayer(player,"§cБыли заменены следующие предметусы: §f" + replacedItems); + } + } + + public static void halfHeart (Player player, String donationUsername) { + player.setHealth(1); + announce(donationUsername, "оставил тебе лишь полсердечка...", "оставил лишь полсердечка", player, true); + } + + public static void tamedBecomesEnemies (Player player, String donationUsername) { + announce(donationUsername, "настроил твоих питомцев против тебя!", "настроил прирученных питомцев против", player, true); + for (Entity e : player.getWorld().getEntitiesByClasses(Wolf.class, Cat.class)) { + if (((Tameable) e).isTamed() && ((Tameable) e).getOwner().getName().equals(player.getName())) { + if (e instanceof Cat) { + ((Tameable) e).setOwner(null); + ((Cat) e).setSitting(false); + ((Cat) e).setTarget(player); + player.sendMessage("+"); + } else { + ((Wolf) e).setSitting(false); + ((Tameable) e).setOwner(null); + ((Wolf) e).setTarget(player); + } + } + } + } + + public static void bigBoom (Player player, String donationUsername) { + announce(donationUsername, "сейчас тебя РАЗНЕСЕТ В КЛОЧЬЯ!!!", "сейчас РАЗНЕСЕТ В КЛОЧЬЯ", player, true); + player.getWorld().createExplosion(player.getLocation(), MainConfig.bigBoomRadius, true); + + } + + +} diff --git a/src/main/java/igorlink/donationexecutor/executionsstaff/Donation.java b/src/main/java/igorlink/donationexecutor/executionsstaff/Donation.java new file mode 100644 index 0000000..6a33bda --- /dev/null +++ b/src/main/java/igorlink/donationexecutor/executionsstaff/Donation.java @@ -0,0 +1,53 @@ +package igorlink.donationexecutor.executionsstaff; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +public class Donation { + private CommandSender sender; + private String username; + private String amount; + private String message; + private String executionName = null; + + public Donation(String _username, String _amount, String _message) { + new Donation(Bukkit.getConsoleSender(), _username, _amount, _message); + } + + public Donation(CommandSender _sender, String _username, String _amount, String _message) { + sender = _sender; + if (_username.equals("")) { + username = "Аноним"; + } else { + username = _username; + } + amount = _amount; + message = _message; + } + + public CommandSender getSender() { + return sender; + } + + public String getName() { + return username; + } + + public String getAmount() { + return amount; + } + + public String getMessage() { + return message; + } + + public String getexecutionName() { + return executionName; + } + + public void setexecutionName(String _executionName) { + executionName = _executionName; + } + + +} diff --git a/src/main/java/igorlink/donationexecutor/executionsstaff/GiantMobManager.java b/src/main/java/igorlink/donationexecutor/executionsstaff/GiantMobManager.java new file mode 100644 index 0000000..082ee21 --- /dev/null +++ b/src/main/java/igorlink/donationexecutor/executionsstaff/GiantMobManager.java @@ -0,0 +1,577 @@ +package igorlink.donationexecutor.executionsstaff; +import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent; +import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent; +import igorlink.donationexecutor.DonationExecutor; +import io.papermc.paper.event.entity.EntityMoveEvent; +import org.bukkit.*; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +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.BukkitRunnable; +import org.bukkit.util.RayTraceResult; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import java.util.*; + +import static igorlink.service.Utils.*; +import static java.lang.Math.sqrt; +import static org.bukkit.Bukkit.getPlayer; + +import org.bukkit.event.Listener; + +public class GiantMobManager { + private HashMap listOfMobLists = new HashMap(); + private HashMap listOfGiantMob = new HashMap(); + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Конструктор класса. Регистрируем в нем слушателя событий GiantEventListener + + public GiantMobManager(Plugin thisPlugin) { + Bukkit.getPluginManager().registerEvents(new GiantMobEventListener(this), thisPlugin); + for (Player p : Bukkit.getOnlinePlayers()) { + for (Entity ent : p.getWorld().getEntities()) { + if (ent instanceof Giant) { + this.addMob((LivingEntity) ent); + } + } + } + } + + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Добавление и удаление моба + //Добавляем нового моба, которого нужно заспавнить + public void addMob(@NotNull Location playerLocation, @NotNull String mobName) { + addMobToList(new GiantMob(playerLocation, mobName)); + } + + //Добавляем нового моба, который уже был заспавнен + public void addMob(@NotNull LivingEntity giantMob) { + addMobToList(new GiantMob(giantMob)); + } + + //Удаляем моба + public void removeMob(@NotNull LivingEntity giantMob) { + removeMobFromList(giantMob); + } + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Добавление и удаления из списка мобов + + //Добавляем моба в оответствующий его типу список + private void addMobToList(@NotNull GiantMob newGiantMob) { + if (listOfMobLists.containsKey(newGiantMob.getName())) { + listOfMobLists.get(newGiantMob.getName()).put(newGiantMob.getUUID(), newGiantMob); + } else { + listOfMobLists.put(newGiantMob.getName(), new HashMap()); + listOfMobLists.get(newGiantMob.getName()).put(newGiantMob.getUUID(), newGiantMob); + } + + } + + //Удаляем моба из соответствующего ему списка + private void removeMobFromList(@NotNull LivingEntity giantMob) { + listOfMobLists.get(giantMob.getName()).remove(giantMob.getUniqueId()); + } + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Класс гигантского моба + private class GiantMob { + private int timesThisGiantMobIsOnOnePlace = 0; + private String thisGiantMobPlayerCurrentTargetName = null; + private int stepsAfterHiding = 0; + private LivingEntity giantMobLivingEntity = null; + private UUID thisGiantMobUUID = null; + + final private int howManySnowballsMobLaunches = 4; + final private Boolean SnowballsFollowingTarget = false; + final private int giantMobTrackingRange = 40; + final private static int timeBeforeThisGiantMobForgetHisTarget = 5; + final private static int ticksBetweenSnowballsShots = 7; + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Конструктор гигантского моба + + //Создаем моба, заспавнив его и указав Имя-тип + public GiantMob(@NotNull Location playerLocation, String mobName) { + + //Определяем направление игрока и спавним моба перед ним, повернутым к игроку лицом + Vector playerDirection = playerLocation.getDirection(); + playerDirection.setY(0); + playerDirection.normalize(); + this.giantMobLivingEntity = (LivingEntity) playerLocation.getWorld().spawnEntity(playerLocation.clone().add(playerDirection.clone().multiply(5)).setDirection(playerDirection.multiply(-1)), EntityType.GIANT); + if (!(mobName == null)) { + this.giantMobLivingEntity.setCustomName(mobName); + } + this.giantMobLivingEntity.setGravity(true); + this.giantMobLivingEntity.setRemoveWhenFarAway(false); + this.thisGiantMobUUID = giantMobLivingEntity.getUniqueId(); + this.giantMobLivingEntity.getEquipment().setItem(EquipmentSlot.HAND, new ItemStack(Material.IRON_SWORD)); + + //Заставляем бегать и стрелять + this.makeGiantMobAttackWithFireballs(); + this.forceGiantMobToMove(); + this.makeGiantMobAttackWithSnowballs(); + } + + //Добавляем существующего + public GiantMob(@NotNull LivingEntity _stalinMob) { + this.giantMobLivingEntity = _stalinMob; + + //Заставляем бегать и стрелять + this.turnOnGiantMobAi(); + } + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Геттеры + + //Отдает имя моба + public String getName() { + return this.giantMobLivingEntity.getName(); + } + + //Отдает UUID моба + public UUID getUUID() { + return this.thisGiantMobUUID; + } + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Поиск ближайшей цели + private LivingEntity findGiantMobTarget() { + //получаем список ближайших врагов dв радиусе sralinShootingRadius + Double sralinShootingRadius = (double) giantMobTrackingRange; + List listOfNearbyEntities = giantMobLivingEntity.getNearbyEntities(sralinShootingRadius, sralinShootingRadius, sralinShootingRadius); + List listOfNearbyPlayers = new ArrayList<>(); + List listOfNearbyLivingEntities = new ArrayList<>(); + + //Пробегаемся и ищем игроков + for (Entity e : listOfNearbyEntities) { + RayTraceResult rtRes1 = null; + RayTraceResult rtRes2 = null; + RayTraceResult rtRes3 = null; + RayTraceResult rtRes4 = null; + RayTraceResult rtRes5 = null; + RayTraceResult rtRes6 = null; + RayTraceResult rtRes7 = null; + RayTraceResult rtRes8 = null; + + if (e instanceof LivingEntity) { + //Позиции псевдоглаз вокруг головы с каждой стороны + Location rtGiantMobPseudoEyesPos1 = giantMobLivingEntity.getLocation().clone().add(2, 11, 0); + Location rtGiantMobPseudoEyesPos2 = giantMobLivingEntity.getLocation().clone().add(-2, 11, 0); + Location rtGiantMobPseudoEyesPos3 = giantMobLivingEntity.getLocation().clone().add(0, 11, 2); + Location rtGiantMobPseudoEyesPos4 = giantMobLivingEntity.getLocation().clone().add(0, 11, -2); + + //Пускаем лучи из каждой точки псевдоглаз до верха и низа каждой сущности + rtRes1 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos1, genVec(rtGiantMobPseudoEyesPos1, ((LivingEntity) e).getEyeLocation()), rtGiantMobPseudoEyesPos1.distance(((LivingEntity) e).getEyeLocation()), FluidCollisionMode.NEVER, true); + rtRes2 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos2, genVec(rtGiantMobPseudoEyesPos2, ((LivingEntity) e).getEyeLocation()), rtGiantMobPseudoEyesPos2.distance(((LivingEntity) e).getEyeLocation()), FluidCollisionMode.NEVER, true); + rtRes3 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos3, genVec(rtGiantMobPseudoEyesPos3, ((LivingEntity) e).getEyeLocation()), rtGiantMobPseudoEyesPos3.distance(((LivingEntity) e).getEyeLocation()), FluidCollisionMode.NEVER, true); + rtRes4 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos4, genVec(rtGiantMobPseudoEyesPos4, ((LivingEntity) e).getEyeLocation()), rtGiantMobPseudoEyesPos4.distance(((LivingEntity) e).getEyeLocation()), FluidCollisionMode.NEVER, true); + rtRes5 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos1, genVec(rtGiantMobPseudoEyesPos1, ((LivingEntity) e).getLocation()), rtGiantMobPseudoEyesPos1.distance(((LivingEntity) e).getLocation()), FluidCollisionMode.NEVER, true); + rtRes6 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos2, genVec(rtGiantMobPseudoEyesPos2, ((LivingEntity) e).getLocation()), rtGiantMobPseudoEyesPos2.distance(((LivingEntity) e).getLocation()), FluidCollisionMode.NEVER, true); + rtRes7 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos3, genVec(rtGiantMobPseudoEyesPos3, ((LivingEntity) e).getLocation()), rtGiantMobPseudoEyesPos3.distance(((LivingEntity) e).getLocation()), FluidCollisionMode.NEVER, true); + rtRes8 = giantMobLivingEntity.getWorld().rayTraceBlocks(rtGiantMobPseudoEyesPos4, genVec(rtGiantMobPseudoEyesPos4, ((LivingEntity) e).getLocation()), rtGiantMobPseudoEyesPos4.distance(((LivingEntity) e).getLocation()), FluidCollisionMode.NEVER, true); + + //Если Сталин может из любой позиции поврота голвоы увидеть верх или низ цели, то эта цель вносится в список кандидатов + if ((rtRes1 == null) || (rtRes2 == null) || (rtRes3 == null) || (rtRes4 == null) || (rtRes5 == null) || (rtRes6 == null) || (rtRes7 == null) || (rtRes8 == null)) { + if ((e instanceof Player) && (!(((Player) e).getGameMode() == GameMode.SPECTATOR)) && (!(((Player) e).getGameMode() == GameMode.CREATIVE))) { + listOfNearbyPlayers.add((LivingEntity) e); + } else if (!(e instanceof Player)) { + listOfNearbyLivingEntities.add((LivingEntity) e); + } + } + } + + } + + //Создаем переменную будущей цели + LivingEntity target = null; + Double minDistance = null; + + if (!(listOfNearbyPlayers.isEmpty())) { + + //Если есть игроки - ищем среди них ближайшего + for (LivingEntity e : listOfNearbyPlayers) { + if (target == null) { + target = e; + minDistance = giantMobLivingEntity.getLocation().distance(e.getLocation()); + } else if (minDistance > giantMobLivingEntity.getLocation().distance(e.getLocation())) { + target = e; + minDistance = giantMobLivingEntity.getLocation().distance(e.getLocation()); + } + } + + //Если новая цель - сбрасываем счетчик забвения после скрытия из области видимости моба, и назначаем цель текущей целью моба + if (!(target.getName().equals(thisGiantMobPlayerCurrentTargetName))) { + stepsAfterHiding = 0; + thisGiantMobPlayerCurrentTargetName = target.getName(); + } + + } else if (!(listOfNearbyLivingEntities.isEmpty())) { + //Если игроков рядом не было, проверяем все живые сущности + for (LivingEntity e : listOfNearbyLivingEntities) { + if (target == null) { + target = e; + minDistance = this.giantMobLivingEntity.getLocation().distance(e.getLocation()); + } else if (minDistance > this.giantMobLivingEntity.getLocation().distance(e.getLocation())) { + target = e; + minDistance = this.giantMobLivingEntity.getLocation().distance(e.getLocation()); + } + } + + } + + if ( (!(target instanceof Player)) && (!(thisGiantMobPlayerCurrentTargetName == null)) ) { + //Если прошлая цель-игрок существует, и он не мертв и находится в том же мире, что и наш моб + if ( (!(getPlayer(thisGiantMobPlayerCurrentTargetName).isDead())) && (getPlayer(thisGiantMobPlayerCurrentTargetName).getWorld() == giantMobLivingEntity.getWorld()) ) { + + //Если не подошло время забыть о нем и он не стал спектэйтором, фокусим моба на него + if ((stepsAfterHiding <= timeBeforeThisGiantMobForgetHisTarget * 2) && (!(getPlayer(thisGiantMobPlayerCurrentTargetName).getGameMode()==GameMode.SPECTATOR)) && (!(getPlayer(thisGiantMobPlayerCurrentTargetName).getGameMode()==GameMode.CREATIVE))){ + target = getPlayer(thisGiantMobPlayerCurrentTargetName); + stepsAfterHiding++; + } else { + //если подошло время забыть про него - забываем + stepsAfterHiding = 0; + thisGiantMobPlayerCurrentTargetName = null; + } + + } + } + + //Возвращаем ближайшее ентити (игрок в приоритете) + return target; + } + + private void turnOnGiantMobAi() { + this.forceGiantMobToMove(); + this.makeGiantMobAttackWithFireballs(); + this.makeGiantMobAttackWithSnowballs(); + } + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Заставляем нашего моба двигаться + private void forceGiantMobToMove() { + final GiantMob thisGiantMob = this; + new BukkitRunnable() { + @Override + public void run() { + LivingEntity thisGiantMobLivingEntity = thisGiantMob.giantMobLivingEntity; + + if ( (thisGiantMobLivingEntity.isDead()) || (!(DonationExecutor.isRunning)) ) { + //Если Сталин уже помер, отрубаем задание + this.cancel(); + return; + } else { + //Если не помер, находим ближайшую цель (игроки в приоритете) + LivingEntity target; + target = thisGiantMob.findGiantMobTarget(); + + //Если цели нет... + if (target == null) { + //Если моб не в воде, то прижимаем его к Земле, чтобы не улетел в небо на прыжке + if (!(thisGiantMobLivingEntity.getEyeLocation().clone().add(0,2,0).getBlock().getType()==Material.WATER)) { + thisGiantMobLivingEntity.setVelocity(thisGiantMobLivingEntity.getLocation().getDirection().clone().normalize().setY(-4.5)); + } else { + //сли над мобом вода - всплываем + thisGiantMobLivingEntity.setVelocity(thisGiantMobLivingEntity.getLocation().getDirection().clone().normalize().setY(3)); + } + return; + } + + //Поворачиваем в плоскости XZ + float newYaw = (float) Math.toDegrees( + Math.atan2( + target.getLocation().getZ() - thisGiantMobLivingEntity.getLocation().getZ(), + target.getLocation().getX() - thisGiantMobLivingEntity.getLocation().getX())) + - 90; + + //Поворачиваем по вертикальной оси Y (не работает из-за зачатков AI, которые сами крутят моба) + double xDiff = target.getEyeLocation().getX() - thisGiantMobLivingEntity.getEyeLocation().getX(); + double yDiff = target.getEyeLocation().getY() - thisGiantMobLivingEntity.getEyeLocation().getY(); + double zDiff = target.getEyeLocation().getZ() - thisGiantMobLivingEntity.getEyeLocation().getZ(); + + double distanceXZ = sqrt(xDiff * xDiff + zDiff * zDiff); + double distanceY = 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; + } + + thisGiantMobLivingEntity.setRotation(newYaw, (float) pitch); + + + //Готовимся к совершению движения + Location thisGiantMobLoc = thisGiantMobLivingEntity.getLocation().clone(); + Location thisGiantMobLocXZ = thisGiantMobLivingEntity.getLocation().clone(); + thisGiantMobLocXZ.setY(0); + double thisGiantMobLocY = thisGiantMobLoc.clone().getY(); + + Location targetLoc = target.getLocation().clone(); + Location targetLocXZ = target.getLocation().clone(); + targetLocXZ.setY(0); + double targetY = targetLoc.clone().getY(); + + + //Совершаем движение, если мы далеко от цели, либо если мы сильно под ней + if ((thisGiantMobLocXZ.distance(targetLocXZ) > 1) || (((targetY - thisGiantMobLocY) > 20) && (thisGiantMobLocY < targetY))) { + double oldX = thisGiantMobLoc.getX(); + double oldZ = thisGiantMobLoc.getZ(); + //sendSysMsgToPlayer(Bukkit.getPlayer("Evropejets"), "ДВИЖЕНИЕ! До цели " + (int) (Math.round(thisGiantMobLoc.distance(target.getLocation()))) + "\nЦЕЛЬ: " + target.getName()); + //Стандартное движение к цели, если она за радиусом досягаемости + if (!(thisGiantMobLivingEntity.getEyeLocation().clone().add(0,1,0).getBlock().getType()==Material.WATER)) { + thisGiantMobLivingEntity.setRemainingAir(thisGiantMobLivingEntity.getMaximumAir()); + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().setY(-4.5)); + } else { + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().setY(1.4)); + return; + } + + new BukkitRunnable() { + @Override + public void run() { + + if ( (thisGiantMobLivingEntity.isDead()) || (!(DonationExecutor.isRunning)) ) { + this.cancel(); + return; + } + + //Если моб не сдвинулся за счет стандартного движения (разница между новыми и старыми кордами<2), и при этом он находится ниже цели по Y, но дальше по XZ, чем на 2.5 блока от нее (то есть ему есть куда стремиться до цели)... + if ((Math.abs(thisGiantMobLivingEntity.getLocation().getX() - oldX) < 1) && (Math.abs(thisGiantMobLivingEntity.getLocation().getZ() - oldZ) < 1) && ((thisGiantMobLocY < targetY) || (thisGiantMobLocXZ.distance(targetLocXZ) > 2.5))) { + thisGiantMob.timesThisGiantMobIsOnOnePlace++; + if (thisGiantMob.timesThisGiantMobIsOnOnePlace > 2) { + if (timesThisGiantMobIsOnOnePlace == 3) { + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().multiply(1).setY(4)); + } else if (timesThisGiantMobIsOnOnePlace == 6) { + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().rotateAroundY(0.9).multiply(2).setY(5)); + } else if (timesThisGiantMobIsOnOnePlace == 9) { + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().rotateAroundY(-0.9).multiply(2).setY(5)); + } else if (timesThisGiantMobIsOnOnePlace == 10) { + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().rotateAroundY(-0.9).multiply(2).setY(5)); + } else if (timesThisGiantMobIsOnOnePlace == 13) { + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().rotateAroundY(0.9).multiply(2).setY(5)); + thisGiantMob.timesThisGiantMobIsOnOnePlace = 0; + } + + } else { + //обычный прыжок + thisGiantMobLivingEntity.setVelocity(thisGiantMobLoc.getDirection().clone().normalize().multiply(1).setY(1)); + // sendSysMsgToPlayer(Bukkit.getPlayer("Evropejets"), "HIGH"); + } + + } else { + //если он сдвинулся, обнуляем счетчик нахождения на одном месте по XZ + thisGiantMob.timesThisGiantMobIsOnOnePlace = 0; + } + + } + }.runTaskLater(DonationExecutor.getInstance(), 7); + } + } + } + }.runTaskTimer(DonationExecutor.getInstance(), 0, 10); + } + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Заставляем моба стрелять файерболами + private void makeGiantMobAttackWithFireballs() { + final GiantMob thisGiantMob = this; + new BukkitRunnable() { + @Override + public void run() { + + + LivingEntity thisGiantMobLivingEntity = thisGiantMob.giantMobLivingEntity; + + //Если моб уже не существует, отменяем стрельбу + if ((thisGiantMobLivingEntity.isDead()) || (!(DonationExecutor.isRunning)) ) { + this.cancel(); + return; + } + + //Находим ближайшее ентити (игроки в приоритете), чтобы сделать из него цель для моба + LivingEntity target; + target = thisGiantMob.findGiantMobTarget(); + if (target == null) { + return; + } + + //Спавним файер болл на 2 блока ниже глаз (район между рук) + Fireball stalinBall; + stalinBall = (Fireball) thisGiantMobLivingEntity.getWorld().spawnEntity(thisGiantMobLivingEntity.getEyeLocation().clone() + .add(genVec(thisGiantMobLivingEntity.getEyeLocation().clone(), target.getLocation()).clone().multiply(3.5)).clone() + .add(0, -2, 0), + EntityType.FIREBALL); + stalinBall.setDirection(genVec(stalinBall.getLocation(), target.getLocation()).clone().multiply(2)); + + } + + }.runTaskTimer(DonationExecutor.getInstance(), 0, 45); + } + + private void makeGiantMobAttackWithSnowballs() { + final GiantMob thisGiantMob = this; + new BukkitRunnable() { + @Override + public void run() { + LivingEntity thisGiantMobLivingEntity = thisGiantMob.giantMobLivingEntity; + + //Если моб уже не существует, отменяем стрельбу + if ( (thisGiantMobLivingEntity.isDead()) || (!(DonationExecutor.isRunning)) ) { + this.cancel(); + return; + } + + //Находим ближайшее ентити (игроки в приоритете), чтобы сделать из него цель для моба + LivingEntity target; + target = thisGiantMob.findGiantMobTarget(); + if (target == null) { + return; + } + + //Запускаем снежки в количестве howManySnowballsMobLaunches + for (int i = 0; i <= howManySnowballsMobLaunches; i++) { + final int finali = i; + final LivingEntity finalTarget = target; + new BukkitRunnable() { + @Override + public void run() { + if ( (thisGiantMob.giantMobLivingEntity.isDead()) || (!(DonationExecutor.isRunning)) ) { + this.cancel(); + return; + } + Snowball snowball; + Location handHeightPoint; + handHeightPoint = thisGiantMobLivingEntity.getLocation().clone().add(0, 7, 0); + snowball = (Snowball) thisGiantMobLivingEntity.getWorld().spawnEntity(handHeightPoint.clone() + .add(handHeightPoint.getDirection().rotateAroundY(0.7).multiply(3.5)), + EntityType.SNOWBALL); + ItemStack itemStack = new ItemStack(Material.SNOWBALL, 1); + ItemMeta meta = snowball.getItem().getItemMeta(); + meta.setLore(Arrays.asList("Stalinball")); + itemStack.setItemMeta(meta); + snowball.setItem(itemStack); + snowball.setVelocity(genVec(snowball.getLocation(), finalTarget.getEyeLocation()).multiply(2.2)); + snowball.getWorld().playSound(snowball.getLocation(), Sound.ENTITY_DRAGON_FIREBALL_EXPLODE, 3, 2); + + //Каждый тик направляем снежок в игрока + if (SnowballsFollowingTarget) { + new BukkitRunnable() { + @Override + public void run() { + if ( (snowball.isDead()) || finalTarget.isDead() || (!(finalTarget.getWorld() == snowball.getWorld())) || (!(DonationExecutor.isRunning)) ) { + this.cancel(); + return; + } else { + snowball.setVelocity(genVec(snowball.getLocation(), finalTarget.getEyeLocation())); + } + } + }.runTaskTimer(DonationExecutor.getInstance(), finali * ticksBetweenSnowballsShots, 1); + } + + } + }.runTaskLater(DonationExecutor.getInstance(), i * ticksBetweenSnowballsShots); + } + + + } + }.runTaskTimer(DonationExecutor.getInstance(), 0, 150); + } + } + + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //Проверка всех добавлений и удалений из мира, чтобы ловить и упаковывать подходящих гигантов или удалять их из списка + private class GiantMobEventListener implements Listener{ + + GiantMobManager thisInstanceOfGiantMobManager; + private GiantMobEventListener(GiantMobManager _thisInstanceOfGiantMobManager) { + thisInstanceOfGiantMobManager = _thisInstanceOfGiantMobManager; + } + + @EventHandler + private void onGiantMobAddTOWorld(EntityAddToWorldEvent e) { + if (e.getEntity() instanceof Giant) { + thisInstanceOfGiantMobManager.addMob((LivingEntity) e.getEntity()); + } + } + + @EventHandler + private void onGiantMobRemoveFromWorld(EntityRemoveFromWorldEvent e) { + if (thisInstanceOfGiantMobManager.listOfMobLists.containsKey(e.getEntity().getName())) { + thisInstanceOfGiantMobManager.removeMob((LivingEntity) e.getEntity()); + } + } + + @EventHandler + public void onGiantMobDamage(EntityDamageEvent e){ + //Нашему мобу отменяем дамаг от падения + if ( (e.getEntity() instanceof Giant) && ((e.getCause() == EntityDamageEvent.DamageCause.FALL) || (e.getCause() == EntityDamageEvent.DamageCause.BLOCK_EXPLOSION) || (e.getCause() == EntityDamageEvent.DamageCause.FIRE) || (e.getCause() == EntityDamageEvent.DamageCause.FIRE_TICK))) { + e.setCancelled(true); + // sendSysMsgToPlayer(getPlayer(Executor.nameOfStreamerPlayer), "Cancelled DMG from: " + e.getCause().toString()); + } else if (e.getEntity() instanceof Giant) { + // sendSysMsgToPlayer(getPlayer(Executor.nameOfStreamerPlayer), "Passed DMG from: " + e.getCause().toString()); + } + } + + @EventHandler + public void onProjectileHit(ProjectileHitEvent e) { + if (e.getEntity() instanceof Snowball) { + + if ((e.getHitEntity()) instanceof LivingEntity) { + + if (((LivingEntity) e.getHitEntity()).getHealth()>1) { + ((LivingEntity) e.getHitEntity()).setHealth(((LivingEntity) e.getHitEntity()).getHealth()-1); + } else { + ((LivingEntity) e.getHitEntity()).setHealth(0); + } + } + + + } else if (e.getEntity() instanceof Fireball) { + + if (!(e.getHitEntity() instanceof Giant)) { + e.getEntity().getWorld().createExplosion(e.getEntity().getLocation(), 2.0F, true); + e.getEntity().remove(); + e.setCancelled(true); + } + } + } + + + @EventHandler + public void onComeTooClose(EntityMoveEvent e){ + //дать пинка, если слишком близок к Сталину + if (e.getEntity() instanceof Giant) { + for (Entity ent : e.getEntity().getNearbyEntities(1.9, 4, 1.9)) { + if (ent instanceof LivingEntity) { + Vector launchDirection = e.getEntity().getLocation().getDirection().clone().setY(0).normalize().multiply(0.8); + launchDirection.setY(0.4); + ent.setVelocity(launchDirection); + } + } + } + } + + } + + +} diff --git a/src/main/java/igorlink/donationexecutor/executionsstaff/ListOfStreamerPlayers.java b/src/main/java/igorlink/donationexecutor/executionsstaff/ListOfStreamerPlayers.java new file mode 100644 index 0000000..f6d44aa --- /dev/null +++ b/src/main/java/igorlink/donationexecutor/executionsstaff/ListOfStreamerPlayers.java @@ -0,0 +1,79 @@ +package igorlink.donationexecutor.executionsstaff; + +import igorlink.donationexecutor.DonationExecutor; +import igorlink.donationexecutor.Executor; +import igorlink.service.Utils; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + +public class ListOfStreamerPlayers { + private List listOfStreamerPlayers = new ArrayList(); + + //Таймер будет выполнять донаты из очередей игроков каждые 2 сек, если они живы и онлайн - выполняем донат и убираем его из очереди + public ListOfStreamerPlayers() { + new BukkitRunnable() { + @Override + public void run() { + if (!DonationExecutor.isRunning) { + this.cancel(); + return; + } + + for (StreamerPlayer sp : listOfStreamerPlayers) { + if ( !(Bukkit.getPlayer(sp.getName()) == null) ) { + if (!(Bukkit.getPlayer(sp.getName()).isDead())) { + Donation donation = sp.takeDonationFromQueue(); + if (donation==null) { + continue; + } + Utils.logToConsole("Отправлен на выполнение донат §b" + donation.getexecutionName() + "§f для стримера §b" + sp.getName() + "§f от донатера §b" + donation.getName()); + Executor.DoExecute(donation.getSender(), sp.getName(), donation.getName(), donation.getAmount(), donation.getMessage(), donation.getexecutionName()); + } + } + + } + } + }.runTaskTimer(DonationExecutor.getInstance(), 0, 40); + } + + public int getNumberOfStreamers() { + return listOfStreamerPlayers.size(); + } + + //Добавляем стримера в список + public void addStreamerPlayer(@NotNull String streamerPlayerName) { + listOfStreamerPlayers.add(new StreamerPlayer(streamerPlayerName)); + } + + public StreamerPlayer getStreamerPlayer(@NotNull String name) { + for (StreamerPlayer p : listOfStreamerPlayers) { + if (p.getName().equals(name)) { + return p; + } + } + return null; + } + + //Очищаем список стримеров + public void clear() { + listOfStreamerPlayers.clear(); + } + + //Добавление доната в очередь + public void addToDonationsQueue(Donation donation) { + String execution; + for (StreamerPlayer sp : listOfStreamerPlayers) { + execution = sp.checkExecution(Utils.cutOffKopeykis(donation.getAmount())); + if (!(execution == null)) { + donation.setexecutionName(execution); + sp.putDonationToQueue(donation); + Utils.logToConsole("Донат от §b" + donation.getName() + "§f в размере §b" + donation.getAmount() + " руб.§f был обработан и отправлен в очередь на выполнение."); + return; + } + } + } + +} diff --git a/src/main/java/igorlink/donationexecutor/executionsstaff/StreamerPlayer.java b/src/main/java/igorlink/donationexecutor/executionsstaff/StreamerPlayer.java new file mode 100644 index 0000000..2d89de3 --- /dev/null +++ b/src/main/java/igorlink/donationexecutor/executionsstaff/StreamerPlayer.java @@ -0,0 +1,109 @@ +package igorlink.donationexecutor.executionsstaff; + +import igorlink.donationexecutor.DonationExecutor; +import igorlink.donationexecutor.Executor; +import igorlink.service.MainConfig; +import igorlink.service.Utils; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class StreamerPlayer { + private String streamerPlayerName; + private List listOfDeathDropItems = new ArrayList(); + private Queue listOfQueuedDonations = new LinkedList(); + private HashMap listOfAmounts = new HashMap(); + + + //Инициализация нового объекта стримера-игрока + public StreamerPlayer(@NotNull String _streamerPlayerName) { + FileConfiguration config = MainConfig.getConfig(); + streamerPlayerName = _streamerPlayerName; + Bukkit.getPluginManager().registerEvents(new PlayerDeathListener(this), DonationExecutor.getInstance()); + + + //Заполняем список сумм для донатов + String amount; + for (String execName : Executor.executionsList) { + amount = config.getString("DonationAmounts." + streamerPlayerName + "." + execName); + if (!(amount==null)) { + listOfAmounts.put(amount, execName); + } else { + Utils.logToConsole("Сумма доната, необходимая для " + execName + " для стримера " + streamerPlayerName + " не найдена. Проверьте правильность заполнения файла конфигурации DonationExecutor.yml в папке с именем плагина."); + } + } + } + + public String checkExecution(@NotNull String amount) { + return listOfAmounts.get(amount); + } + + public String getName(){ + return streamerPlayerName; + } + + //Работа со списком выпавших при смерти вещей + public void setDeathDrop(List listOfItems) { + listOfDeathDropItems.clear(); + listOfDeathDropItems.addAll(listOfItems); + } + + + //Работа с очередью донатов + //Поставить донат в очередь на выполнение донатов для этого игрока + public void putDonationToQueue(@NotNull Donation donation) { + listOfQueuedDonations.add(donation); + } + + //Взять донат из очереди и убрать его из нее + public Donation takeDonationFromQueue() { + return listOfQueuedDonations.poll(); + } + + + //Удалить дроп игрока после смерти + public Boolean removeDeathDrop() { + Boolean wasAnythingDeleted = false; + for (Item i : listOfDeathDropItems) { + if (i.isDead()) { + continue; + } + i.remove(); + wasAnythingDeleted = true; + } + return wasAnythingDeleted; + } + + //Замена дездропа при смерти игрока (через Listener) + private class PlayerDeathListener implements Listener{ + StreamerPlayer thisStreamerPlayer; + + //Передача родительского объекта в слушателя + private PlayerDeathListener(StreamerPlayer _thisStreamerPlayer) { + thisStreamerPlayer = _thisStreamerPlayer; + } + + //Если данный игрок умер - запоминаем его посмертный дроп + @EventHandler + private void onPlayerDeath(PlayerDeathEvent event) { + List deathDrop = new ArrayList<>(); + if (event.getPlayer().getName().equals(thisStreamerPlayer.getName())) { + for (ItemStack i : event.getDrops()) { + deathDrop.add(event.getPlayer().getWorld().dropItemNaturally(event.getPlayer().getLocation(), i)); + } + } + event.getDrops().clear(); + thisStreamerPlayer.setDeathDrop(deathDrop); + } + } + + + +} diff --git a/src/main/java/igorlink/service/MainConfig.java b/src/main/java/igorlink/service/MainConfig.java new file mode 100644 index 0000000..cc81967 --- /dev/null +++ b/src/main/java/igorlink/service/MainConfig.java @@ -0,0 +1,118 @@ +package igorlink.service; + +import igorlink.donationexecutor.DonationExecutor; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import static igorlink.service.Utils.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class MainConfig { + private static HashMap> donationAmountsHashMap = new HashMap>(); + private static FileConfiguration config = DonationExecutor.getInstance().getConfig(); + public static int dirtAmount = 0; + public static int diamondsAmount = 0; + public static int breadAmount = 0; + public static int bigBoomRadius = 0; + public static String token; + public static List listOfBlackListedSubstrings = new ArrayList<>(); + public static List listOfWhiteListedSubstrings = new ArrayList<>(); + private static Boolean twitchFilter; + + public MainConfig() { + + } + + //Геттер конфига + public static FileConfiguration getConfig(){ + return config; + } + + //Обновить данные из конфига + public static void reloadMainConfig() { + loadMainConfig(true); + } + + //Загрузить данные из конфига без указания параметра перезагрузки + public static void loadMainConfig() { + loadMainConfig(false); + } + + //Загрузка данных из конфигфайла с указанным параметром перезагрузки + public static void loadMainConfig(Boolean isReload) { + DonationExecutor.getInstance().saveDefaultConfig(); + + //Если это перезагрузка, обновляем данные, очищаем список игроков + if (isReload) { + DonationExecutor.getInstance().reloadConfig(); + DonationExecutor.getInstance().listOfStreamerPlayers.clear(); + } + + config = DonationExecutor.getInstance().getConfig(); + + String stringWithPlayersNames = config.getString("StreamersNamesList"); + List streamerPlayersNamesList = new ArrayList(Arrays.asList(stringWithPlayersNames.split(","))); + for (String playerName : streamerPlayersNamesList) { + DonationExecutor.getInstance().listOfStreamerPlayers.addStreamerPlayer(playerName); + } + + logToConsole("При чтении файла конфигурации было добавлено §b" + DonationExecutor.getInstance().listOfStreamerPlayers.getNumberOfStreamers() + "§f стримеров."); + + dirtAmount = Integer.valueOf(config.getString("DirtAmount")); + diamondsAmount = Integer.valueOf(config.getString("DiamondsAmount")); + breadAmount = Integer.valueOf(config.getString("BreadAmount")); + bigBoomRadius = Integer.valueOf(config.getString("BigBoomRadius")); + + token = config.getString("DonationAlertsToken"); + listOfBlackListedSubstrings = Arrays.asList(config.getString("BlacklistedSubstrings").split(",")); + listOfWhiteListedSubstrings = Arrays.asList(config.getString("WhitelistedSubstrings").split(",")); + + if (config.getString("TwitchFilter") == "true") { + twitchFilter = true; + } else if (config.getString("TwitchFilter") == "false") { + twitchFilter = false; + } + else { + logToConsole("Ошибка при чтении значение TwitchFilter"); + } + + + } + + + + public static void turnFilterOn() { + twitchFilter = true; + config.set("TwitchFilter", "true"); + } + + public static void turnFilterOff() { + twitchFilter = false; + config.set("TwitchFilter", "false"); + } + + public static Boolean getFilterStatus() { + return twitchFilter; + } + + public static HashMap getNameAndExecution (@NotNull String donationAmount) { + String thisDonateForStreamerName = null; + String nameOfExecution = null; + for (String p : donationAmountsHashMap.keySet()) { + if (donationAmountsHashMap.get(p).containsKey(donationAmount)) { + HashMap temp = new HashMap(); + thisDonateForStreamerName = p; + nameOfExecution = donationAmountsHashMap.get(p).get(donationAmount); + temp.put("name", p); + temp.put("execution", nameOfExecution); + return temp; + } + } + + return null; + } + + +} diff --git a/src/main/java/igorlink/service/Utils.java b/src/main/java/igorlink/service/Utils.java new file mode 100644 index 0000000..debc62b --- /dev/null +++ b/src/main/java/igorlink/service/Utils.java @@ -0,0 +1,248 @@ +package igorlink.service; + +import com.destroystokyo.paper.Title; +import igorlink.donationexecutor.DonationExecutor; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Utils { + public static Boolean isPluginActive; + + //Вывод сообщения в консоль + public static void logToConsole(String text){ + Bukkit.getConsoleSender().sendMessage("§c[DonationExecutor] §f" + text); + } + + //Отправка сообщения игроку со стороны плагина + public static void sendSysMsgToPlayer(Player player, String text){ + player.sendMessage("§c[DE] §f" + text); + } + + public static byte[] decodeUsingBigInteger(String hexString) { + byte[] byteArray = new BigInteger(hexString, 16).toByteArray(); + if (byteArray[0] == 0) { + byte[] output = new byte[byteArray.length - 1]; + System.arraycopy(byteArray, 1, output,0, output.length); + return output; + } + return byteArray; + } + + public static Boolean CheckNameAndToken() { + isPluginActive = true; + if ((DonationExecutor.getInstance().getConfig().getString("DonationAlertsToken") == "") || (DonationExecutor.getInstance().getConfig().getString("DonationAlertsToken") == null)) { + logToConsole("Вы не указали свой токен DonationAlerts в файле конфигурации плагина, поэтому сейчас плагин не работает."); + isPluginActive = false; + } else if ((DonationExecutor.getInstance().getConfig().getString("Nickname") == "") || (DonationExecutor.getInstance().getConfig().getString("Nickname") == "")) { + logToConsole("Вы не указали свой игровой никнейм в файле конфигурации плагина, поэтому сейчас плагин не работает."); + isPluginActive = false; + } + return isPluginActive; + } + + public static void announce(String donaterName, String subText, String alterSubtext, Player player, Boolean bigAnnounce) { + String _donaterName = donaterName; + + if (bigAnnounce) { + if (donaterName.equals("")) { + _donaterName = "Кто-то"; + } + Title title = new Title("§c" + _donaterName, "§f" + subText); + player.sendTitle(title); + player.sendMessage("§c[DE] §fДонатер §c" + _donaterName, "§f" + subText); + } + + if (_donaterName == "") { + _donaterName = "Кто-то"; + } + for (Player p : Bukkit.getOnlinePlayers()) { + if (!(p.getName() == player.getName())) { + p.sendMessage("§c[DE] §fДонатер §c" + _donaterName + " §f" + alterSubtext + " §b" + player.getName()); + } + } + + + } + + public static Vector genVec(Location a, Location b, Boolean isNormalized) { + Vector vec = locToVec(b).clone().subtract(locToVec(a)); + if (isNormalized) { + return vec.normalize(); + } else { + return vec; + } + } + + public static Vector genVec(Location a, Location b) { + Vector vec = locToVec(b).clone().subtract(locToVec(a)); + return vec.normalize(); + } + + public static Vector locToVec(Location loc) { + Vector vec = new Vector(loc.getX(), loc.getY(), loc.getZ()); + return vec; + } + + public static String cutOffKopeykis(String donationAmountWithKopeykis) { + String amountWithoutKopeykis = ""; + for (int i = 0; i <= donationAmountWithKopeykis.length() - 1; i++) { + if (donationAmountWithKopeykis.charAt(i) == '.') { + break; + } else if (donationAmountWithKopeykis.charAt(i) == ' ') { + continue; + } else { + amountWithoutKopeykis = amountWithoutKopeykis + donationAmountWithKopeykis.charAt(i); + } + } + + return amountWithoutKopeykis; + } + + public static Boolean isBlackListed(String text) { + HashMap> mapOfSynonimousChars = new HashMap>(); + + mapOfSynonimousChars.put('h', (Arrays.asList('x', 'х', 'н', 'n'))); //eng + mapOfSynonimousChars.put('n', (Arrays.asList('н', 'й', 'и'))); //eng + mapOfSynonimousChars.put('н', (Arrays.asList('h', 'n', 'й', 'и'))); //rus + mapOfSynonimousChars.put('e', (Arrays.asList('е', '3', 'з'))); //eng + mapOfSynonimousChars.put('е', (Arrays.asList('e', '3', 'з'))); //rus + mapOfSynonimousChars.put('г', (Arrays.asList('r', 'я', 'g', '7'))); //rus + mapOfSynonimousChars.put('r', (Arrays.asList('г', 'я', 'g', '7'))); //eng + mapOfSynonimousChars.put('g', (Arrays.asList('г', 'r', '7'))); //eng + mapOfSynonimousChars.put('p', (Arrays.asList('п', 'р', 'n', 'я', 'r'))); //eng + mapOfSynonimousChars.put('р', (Arrays.asList('p', 'r', 'я'))); //rus + mapOfSynonimousChars.put('п', (Arrays.asList('p', 'n', 'и', 'р'))); //rus + mapOfSynonimousChars.put('o', (Arrays.asList('о', '0'))); //eng + mapOfSynonimousChars.put('о', (Arrays.asList('o', '0'))); //rus + mapOfSynonimousChars.put('a', (Arrays.asList('а'))); //eng + mapOfSynonimousChars.put('а', (Arrays.asList('a'))); //rus + mapOfSynonimousChars.put('и', (Arrays.asList('i', 'n', 'e', 'е', '|', 'l', '!', '1', '3', 'й'))); //rus + mapOfSynonimousChars.put('i', (Arrays.asList('1', 'и', 'e', 'е', '|', 'l', '!', 'й'))); //eng + mapOfSynonimousChars.put('с', (Arrays.asList('c', 's', '$', '5'))); //rus + mapOfSynonimousChars.put('s', (Arrays.asList('c', 'с', '$', '5'))); //eng + mapOfSynonimousChars.put('c', (Arrays.asList('s', 'с', '$', '5'))); //eng + mapOfSynonimousChars.put('л', (Arrays.asList('l', '1', '|'))); //rus + mapOfSynonimousChars.put('l', (Arrays.asList('л', '1', '|', '!'))); //eng + mapOfSynonimousChars.put('1', (Arrays.asList('л', 'i', 'l', '|'))); //eng + mapOfSynonimousChars.put('d', (Arrays.asList('д', 'л'))); //eng + mapOfSynonimousChars.put('д', (Arrays.asList('d', 'л', '9'))); //rus + mapOfSynonimousChars.put('y', (Arrays.asList('у', 'u', 'ы'))); //eng + mapOfSynonimousChars.put('у', (Arrays.asList('y', 'u', 'ы'))); //rus + mapOfSynonimousChars.put('x', (Arrays.asList('х', 'h'))); //eng + mapOfSynonimousChars.put('х', (Arrays.asList('x', 'h'))); //rus + mapOfSynonimousChars.put('ы', (Arrays.asList('у', 'u', 'y'))); //rus + mapOfSynonimousChars.put('ы', (Arrays.asList('у', 'u', 'y'))); //rus + mapOfSynonimousChars.put('ч', (Arrays.asList('4')));//rus + mapOfSynonimousChars.put('k', (Arrays.asList('к')));//eng + mapOfSynonimousChars.put('к', (Arrays.asList('k')));//rus + mapOfSynonimousChars.put('0', (Arrays.asList('o', 'о'))); //num + mapOfSynonimousChars.put('1', (Arrays.asList('i', 'l'))); //num + mapOfSynonimousChars.put('3', (Arrays.asList('e', 'е','з'))); + mapOfSynonimousChars.put('4', (Arrays.asList('ч'))); + mapOfSynonimousChars.put('5', (Arrays.asList('с', 'c', 's'))); + mapOfSynonimousChars.put('9', (Arrays.asList('r', 'я'))); + + + String validationText = text.toLowerCase(); + + Pattern pattern = Pattern.compile("[l1i]*[\\-]*[l1i]*"); + Matcher matcher = pattern.matcher(validationText); + if ( (matcher.find()) && (matcher.group().length()>0) ) { + validationText = validationText.replace(matcher.group(), "н"); + } + + validationText = validationText.replace(" ", ""); + validationText = validationText.replace(",", ""); + validationText = validationText.replace(".", ""); + validationText = validationText.replace("-", ""); + validationText = validationText.replace("%", ""); + validationText = validationText.replace("*", ""); + validationText = validationText.replace("?", ""); + + if (validationText.length() == 0) { + return false; + } + +// for (String ss : MainConfig.listOfWhiteListedSubstrings) { +// if (validationText.contains(ss)) { +// validationText = validationText.replace(ss, ""); +// } +// } + + + if (!(validationText.matches("[a-zа-я0-9$!ё]*"))) { + return true; + } + + + for (String ss : MainConfig.listOfBlackListedSubstrings) { + for (int i = 0; i <= validationText.length() - ss.length(); i++) { + int tempi = i; + for (int j = 0; j <= ss.length(); j++) { + + if (j == ss.length()) { + return true; + } + + if (validationText.charAt(tempi + j) == ss.charAt(j)) { + continue; + } else if ((mapOfSynonimousChars.containsKey(ss.charAt(j)))) { + if ((mapOfSynonimousChars.get(ss.charAt(j)).contains(validationText.charAt(tempi + j)))) { + continue; + } + } + + Boolean repeated = true; + Boolean finishCycle = false; + while ((repeated) && (!finishCycle)) { + if (j==0) { + break; + } + if (!(validationText.charAt(tempi + j) == validationText.charAt(tempi + j - 1))) { + if (!(mapOfSynonimousChars.containsKey(validationText.charAt(tempi + j)))) { + repeated = false; + break; + } else if (!(mapOfSynonimousChars.get(validationText.charAt(tempi + j)).contains(validationText.charAt(tempi + j - 1)))) { + repeated = false; + break; + } + } + tempi++; + if ((validationText.length()-tempi-j) < (ss.length()-j)) { + finishCycle=true; + break; + } + } + + if (finishCycle) { + break; + } + + if (validationText.charAt(tempi + j) == ss.charAt(j)) { + continue; + } else if ((mapOfSynonimousChars.containsKey(ss.charAt(j)))) { + if ((mapOfSynonimousChars.get(ss.charAt(j)).contains(validationText.charAt(tempi + j)))) { + continue; + } + } + + break; + + } + } + } + + return false; + } + + +} + diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..f24a9d8 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,96 @@ +# Секретный токен Donation Alerts. +# Находится на Donation Alerts на странице "Настройки" -> "Основные настройки". +DonationAlertsToken: + +# Никнеймы стримеров в игре ЧЕРЕЗ ЗАПЯТУЮ БЕЗ ПРОБЕЛОВ! +# Не забудьте про цветовые коды, если используете их +StreamersNamesList: Evropejets,mdenz3 + +# Точные суммы донатов для событий +DonationAmounts: + # Имя первого стримера (ДОЛЖЕН СОВПАДАТЬ С ПЕРВЫМ ЗНАЧЕНИЕМ, УКАЗАННЫМ В StreamersNamesList) + Evropejets: + # Насрать стримеру в инвентарь подписанными стаками говна + ShitToInventory: 62 + # Выбить предмет из рук + DropActiveItem: 65 + # Дать леща - толчок вперед, который отнимет 1 сердечко + Lesch: 67 + # Дать хлеб в количестве N кусков + GiveBread: 82 + # Выдать определенное количество алмазов (настраивается дальше) + GiveDiamonds: 132 + # Заспавнятся несколько сотрудников НКВД, которые заходят увести вас в ГУЛАГ + CallNKVD: 142 + # Дать очень смачный пинок под зад, который отнимет 1.5 сердечка + PowerKick: 152 + # В вашем инвентаре будет случайным образом заменено N слотов (по умолчанию -5) + # на некие предметы (по умолчанию - камни) + RandomChange: 197 + # Заспавнить крипера за спиной + SpawnCreeper: 202 + # Уничтожить вещи, выпавшие после последней смерти + ClearLastDeathDrop: 214 + # Все прирученные игроком кошки снова станут дикими, а прирученные волки, + # помимо этого, еще и нападут на игрока, который был их хозяином + TamedBecomesEnemies: 252 + # Заспавнить исполинского Иосифа Сталина, испепеляющий все вокруг + CallStalin: 352 + # Оставить игроку лишь полсердечка + HalfHeart: 602 + # Через N секунд (по умолчанию - 3) произойдет взрыв с радиусом M + # (по умолчанию - 20) вокруг игрока + BigBoom: 2002 + # Выдать целый стак алмазов + GiveStackOfDiamonds: 2012 + # Имя второго стримера (ДОЛЖЕН СОВПАДАТЬ СО ВТОРЫМ ЗНАЧЕНИЕМ, УКАЗАННЫМ В StreamersNamesList) + mdenz3: + # Насрать стримеру в инвентарь подписанными стаками говна + ShitToInventory: 61 + # Выбить предмет из рук + DropActiveItem: 64 + # Дать леща - толчок вперед, который отнимет 1 сердечко + Lesch: 66 + # Дать хлеб в количестве N кусков + GiveBread: 81 + # Выдать определенное количество алмазов (настраивается дальше) + GiveDiamonds: 131 + # Заспавнятся несколько сотрудников НКВД, которые заходят увести вас в ГУЛАГ + CallNKVD: 141 + # Дать очень смачный пинок под зад, который отнимет 1.5 сердечка + PowerKick: 151 + # В вашем инвентаре будет случайным образом заменено N слотов (по умолчанию -5) + # на некие предметы (по умолчанию - камни) + RandomChange: 196 + # Заспавнить крипера за спиной + SpawnCreeper: 201 + # Уничтожить вещи, выпавшие после последней смерти + ClearLastDeathDrop: 213 + # Все прирученные игроком кошки снова станут дикими, а прирученные волки, + # помимо этого, еще и нападут на игрока, который был их хозяином + TamedBecomesEnemies: 251 + # Заспавнить исполинского Иосифа Сталина, испепеляющий все вокруг + CallStalin: 351 + # Оставить игроку лишь полсердечка + HalfHeart: 601 + # Через N секунд (по умолчанию - 3) произойдет взрыв с радиусом M + # (по умолчанию - 20) вокруг игрока + BigBoom: 2001 + # Выдать целый стак алмазов + GiveStackOfDiamonds: 2011 + +# Сколько блоков говна игроки будут получать в инвентарь от ShitToInventory +DirtAmount: 10 +# Сколько алмазов игроки будут получать в инвентарь от GiveDiamonds +DiamondsAmount: 4 +# Сколько хлеба игроки будут получать в инвентарь от GiveBread +BreadAmount: 4 +# Радиус взрыва от BigBoom +BigBoomRadius: 20 + +TwitchFilter: true +BlacklistedSubstrings: негр,пидо,пида,niga,нигр,ниге,додик,петух,петуч,куколд,симп,kukold,cuckold,fag,хуе,хуй,даун,кады,кадь,kadb,4e4e,4e4n,cheche,chechn,4echn,che4n,4eche,4eche +WhitelistedSubstrings: книг,нигерия + + + diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..d0af3eb --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,15 @@ +name: DonationExecutor +version: 0.2 Beta +main: igorlink.donationexecutor.DonationExecutor +api-version: 1.18 +authors: [Igor Link] +description: Executes donations +commands: + donationexecutor: { + aliases: [d], + description: "Позволяет имитировать донаты для тестов или для воспроизведения события вручную", + usage: "§c[DonationExecutor] §fДоступные команды: \n + §c/d §7donate §b<СУММА> <ИМЯ> §7## §b<СООБЩЕНИЕ>§f - сымитировать донат\n + §c/d §7reload§f - перезагрузить настройки из конфига + " + }