commit 0d337e7b7f964e979b86ea8893bb79dd22eb3d53 Author: Max Nullov Date: Tue Mar 4 19:57:46 2025 +0300 first commit 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/LICENSE b/LICENSE new file mode 100644 index 0000000..a5508d2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Denis Shurygin + +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/media/banner.png b/media/banner.png new file mode 100644 index 0000000..a64897c Binary files /dev/null and b/media/banner.png differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a916c97 --- /dev/null +++ b/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + top.dixxe + bombezhka + 1.0.0 + jar + + bombezhka + + + 21 + UTF-8 + + + + clean package + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.3 + + + package + + shade + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + + + + org.spigotmc + spigot-api + 1.20.1-R0.1-SNAPSHOT + provided + + + com.google.code.gson + gson + 2.10.1 + + + diff --git a/src/main/java/top/dixxe/bombezhka/Plugin.java b/src/main/java/top/dixxe/bombezhka/Plugin.java new file mode 100644 index 0000000..101c1f0 --- /dev/null +++ b/src/main/java/top/dixxe/bombezhka/Plugin.java @@ -0,0 +1,32 @@ +package top.dixxe.bombezhka; + +import org.bukkit.plugin.java.JavaPlugin; + +import top.dixxe.bombezhka.events.TelegramMessageEvent; +import top.dixxe.bombezhka.listeners.RocketWarningListener; +import top.dixxe.bombezhka.listeners.TelegramMessageListener; + +public class Plugin extends JavaPlugin { + @Override + public void onEnable() { + saveDefaultConfig(); + String botToken = getConfig().getString("telegram.bot-token"); + long chatId = getConfig().getLong("telegram.chat-id"); + getLogger().info("Bombezhka mod has been baked by @zelenichai "); + + TelegramMessageListener telegramListener = new TelegramMessageListener(this, botToken, chatId); + getServer().getPluginManager().registerEvents(telegramListener, this); + telegramListener.startPolling(); + + // Register event handler for your custom event + RocketWarningListener rwListener = new RocketWarningListener(this); + getServer().getPluginManager().registerEvents(rwListener, this); + } + + @Override + public void onDisable() { + // Save any necessary data + saveConfig(); + } +} + diff --git a/src/main/java/top/dixxe/bombezhka/assets/TntSpawner.java b/src/main/java/top/dixxe/bombezhka/assets/TntSpawner.java new file mode 100644 index 0000000..e6cc91c --- /dev/null +++ b/src/main/java/top/dixxe/bombezhka/assets/TntSpawner.java @@ -0,0 +1,47 @@ +package top.dixxe.bombezhka.assets; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.util.Vector; +import java.util.Random; + +public class TntSpawner { + private static final int CHUNK_RADIUS = 6; // 6 chunks = 96 blocks + + public static String spawnTntNearPlayer(Player player) { + World world = player.getWorld(); + Location playerLoc = player.getLocation(); + Random random = new Random(); + + // Generate random offset within 6 chunks (96 blocks) + int offsetX = (random.nextInt(CHUNK_RADIUS * 2 + 1) - CHUNK_RADIUS) * 16; + int offsetZ = (random.nextInt(CHUNK_RADIUS * 2 + 1) - CHUNK_RADIUS) * 16; + + // Find the highest safe Y coordinate at target location + Location tntLocation = new Location( + world, + playerLoc.getX() + offsetX, + 0, + playerLoc.getZ() + offsetZ + ); + + tntLocation.setY(world.getHighestBlockYAt(tntLocation)); + + // Center TNT in the block + tntLocation.add(0.5, 1, 0.5); + + // Spawn primed TNT with 4-second fuse + TNTPrimed tnt = world.spawn(tntLocation, TNTPrimed.class); + tnt.setFuseTicks(80); // 80 ticks = 4 seconds + + // Broadcast coordinates + String coords = String.format("TNT spawned at [X: %d, Y: %d, Z: %d]", + tntLocation.getBlockX(), + tntLocation.getBlockY(), + tntLocation.getBlockZ() + ); + return coords; + } +} diff --git a/src/main/java/top/dixxe/bombezhka/commands/BombCommandExecutor.java b/src/main/java/top/dixxe/bombezhka/commands/BombCommandExecutor.java new file mode 100644 index 0000000..087421f --- /dev/null +++ b/src/main/java/top/dixxe/bombezhka/commands/BombCommandExecutor.java @@ -0,0 +1,38 @@ +package top.dixxe.bombezhka.commands; + +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 top.dixxe.bombezhka.Plugin; +import top.dixxe.bombezhka.assets.TntSpawner; + +public class BombCommandExecutor implements CommandExecutor { + private final Plugin plugin; + + public BombCommandExecutor(Plugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("This command can only be used by players!"); + return true; + } + + Player player = (Player) sender; + + if (!player.isOp()) { + player.sendMessage(ChatColor.RED + "You don't have permission to use this command!"); + return true; + } + + TntSpawner.spawnTntNearPlayer(player); + + // Command logic here + player.sendMessage(ChatColor.GREEN + "Command executed successfully!"); + return true; + } +} diff --git a/src/main/java/top/dixxe/bombezhka/events/TelegramMessageEvent.java b/src/main/java/top/dixxe/bombezhka/events/TelegramMessageEvent.java new file mode 100644 index 0000000..b1113e2 --- /dev/null +++ b/src/main/java/top/dixxe/bombezhka/events/TelegramMessageEvent.java @@ -0,0 +1,26 @@ +package top.dixxe.bombezhka.events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class TelegramMessageEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + private final String message; + + public TelegramMessageEvent(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/top/dixxe/bombezhka/listeners/RocketWarningListener.java b/src/main/java/top/dixxe/bombezhka/listeners/RocketWarningListener.java new file mode 100644 index 0000000..e3c0315 --- /dev/null +++ b/src/main/java/top/dixxe/bombezhka/listeners/RocketWarningListener.java @@ -0,0 +1,50 @@ +package top.dixxe.bombezhka.listeners; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import top.dixxe.bombezhka.Plugin; +import top.dixxe.bombezhka.assets.TntSpawner; +import top.dixxe.bombezhka.events.TelegramMessageEvent; + +import java.util.Random; +import java.util.concurrent.TimeUnit; + +public class RocketWarningListener implements Listener { + private Plugin _plugin; + + public RocketWarningListener(Plugin plugin) + { + _plugin = plugin; + } + @EventHandler + public void onTelegramMessage(TelegramMessageEvent event) { + // Random generator + Random rand = new Random(); + + //_plugin.getServer().broadcastMessage("[Telegram] " + event.getMessage()); + _plugin.getLogger().info("ROKETNAYA TREVOGA OBNARUZHENA!!"); + _plugin.getServer().broadcastMessage("§4 РАКЕТНАЯ ОПАСНОСТЬ ВСЕМ СРОЧНО НАПРАВИТСЯ В БОМБОУБЕЖИЩЕ!!!"); + new Thread(() -> { + + try + { + TimeUnit.SECONDS.sleep(rand.nextInt(10,20)); + } + catch(InterruptedException ex) + { + Thread.currentThread().interrupt(); + } + + for (Player player : _plugin.getServer().getOnlinePlayers()) { + for (int i = 0; i < rand.nextInt(1,4) ; i++) + { + String coords = TntSpawner.spawnTntNearPlayer(player); + _plugin.getServer().broadcastMessage("§4 [РАКЕТНАЯ ОПАСНОСТЬ] Прилет в " + coords); + } + } + + }).run(); + + } +} diff --git a/src/main/java/top/dixxe/bombezhka/listeners/TelegramMessageListener.java b/src/main/java/top/dixxe/bombezhka/listeners/TelegramMessageListener.java new file mode 100644 index 0000000..a3b7de0 --- /dev/null +++ b/src/main/java/top/dixxe/bombezhka/listeners/TelegramMessageListener.java @@ -0,0 +1,87 @@ +package top.dixxe.bombezhka.listeners; + +import org.bukkit.Bukkit; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; +import top.dixxe.bombezhka.events.TelegramMessageEvent; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +public class TelegramMessageListener implements Listener { + private final JavaPlugin plugin; + private final HttpClient httpClient; + private final String botToken; + private final long chatId; + private int lastUpdateId = 0; + + public TelegramMessageListener(JavaPlugin plugin, String botToken, long chatId) { + this.plugin = plugin; + this.botToken = botToken; + this.chatId = chatId; + this.httpClient = HttpClient.newHttpClient(); + } + + public void startPolling() { + // Poll every 20 seconds (adjust as needed) + plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this::pollTelegram, 0L, 20 * 20L); + } + + private void pollTelegram() { + try { + String url = String.format("https://api.telegram.org/bot%s/getUpdates?offset=%d&timeout=30", botToken, lastUpdateId + 1); + HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() == 200) { + parseUpdates(response.body()); + } else { + if (response.statusCode() == 409) { return; } + plugin.getLogger().warning("Telegram API error: " + response.statusCode()); + } + } catch (Exception e) { + plugin.getLogger().warning("Polling error: " + e.getMessage()); + } + } + + private void parseUpdates(String json) { + try { + com.google.gson.JsonObject root = com.google.gson.JsonParser.parseString(json).getAsJsonObject(); + if (root.get("ok").getAsBoolean()) { + com.google.gson.JsonArray updates = root.getAsJsonArray("result"); + for (com.google.gson.JsonElement element : updates) { + com.google.gson.JsonObject update = element.getAsJsonObject(); + int updateId = update.get("update_id").getAsInt(); + lastUpdateId = updateId; + + // Changed: Check for "message" instead of "channel_post" + if (update.has("message")) { + com.google.gson.JsonObject message = update.getAsJsonObject("message"); + com.google.gson.JsonObject chat = message.getAsJsonObject("chat"); + + // Get chat type and ID + String chatType = chat.get("type").getAsString(); + long messageChatId = chat.get("id").getAsLong(); + + // Check if it's a group/supergroup and matches configured chat ID + if ((chatType.equals("group") || chatType.equals("supergroup")) && + messageChatId == chatId && + message.has("text")) { + + String text = message.get("text").getAsString(); + + plugin.getServer().getScheduler().runTask(plugin, () -> { + Bukkit.getPluginManager().callEvent(new TelegramMessageEvent(text)); + }); + } + } + } + } + } catch (Exception e) { + plugin.getLogger().warning("JSON parsing error: " + e.getMessage()); + } + } + +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..8f2616d --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,3 @@ +telegram: + bot-token: "YOUR_BOT_TOKEN" + chat-id: "YOUR_CHANNEL_CHAT_ID" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..00525fb --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,8 @@ +name: bombezhka +version: '1.0.0' +main: top.dixxe.bombezhka.Plugin +api-version: '1.20' +prefix: Bombezhka +authors: [ zelenichai ] +description: A plugin that syncs rocket warnings with minecraft +website: dixxe.top