diff --git a/src/main/java/popa/popa.java b/src/main/java/popa/popa.java index 1e96113..568bbf9 100644 --- a/src/main/java/popa/popa.java +++ b/src/main/java/popa/popa.java @@ -29,6 +29,10 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.Material; import com.google.gson.Gson; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.attribute.Attribute; +import org.bukkit.event.player.PlayerExpChangeEvent; public final class popa extends JavaPlugin implements Listener { @@ -40,6 +44,7 @@ public final class popa extends JavaPlugin implements Listener { private String commandsUrl; private String inventoryRequestsUrl; private String marketplaceUrl; + private String bonusesUrl; private final Map playerLoginTimes = new HashMap<>(); private final Map playerNames = new HashMap<>(); private ScheduledExecutorService scheduler; @@ -83,6 +88,9 @@ public final class popa extends JavaPlugin implements Listener { marketplaceUrl = getConfig().getString("api-base", "http://localhost:8000") + "/api/marketplace"; scheduler.scheduleAtFixedRate(this::checkMarketplaceOperations, 3, 3, TimeUnit.SECONDS); + bonusesUrl = getConfig().getString("api-base", "http://localhost:8000") + "/api/bonuses/effects"; + scheduler.scheduleAtFixedRate(this::checkPlayerBonuses, 10, 10, TimeUnit.SECONDS); + getLogger().info("PopaPlugin has been enabled!"); getLogger().info("API URL: " + apiUrl); getLogger().info("Commands URL: " + commandsUrl); @@ -170,6 +178,9 @@ public final class popa extends JavaPlugin implements Listener { playerLoginTimes.remove(playerId); playerNames.remove(playerId); sendOnlinePlayersUpdate(); + + // Восстанавливаем базовые атрибуты + player.getAttribute(Attribute.MAX_HEALTH).setBaseValue(20.0); } private void sendOnlinePlayersUpdate() { @@ -882,4 +893,171 @@ public final class popa extends JavaPlugin implements Listener { return null; } + + /** + * Проверяет активные бонусы для всех онлайн игроков и применяет их + */ + private void checkPlayerBonuses() { + if (!getServer().isPrimaryThread()) { + Bukkit.getScheduler().runTask(this, this::checkPlayerBonuses); + return; + } + + for (Player player : Bukkit.getOnlinePlayers()) { + applyPlayerBonuses(player); + } + } + + /** + * Получает и применяет бонусы для конкретного игрока + */ + private void applyPlayerBonuses(Player player) { + String playerName = player.getName(); + + try { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(bonusesUrl + "?username=" + playerName)) + .version(HttpClient.Version.HTTP_1_1) + .GET() + .build(); + + httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()) + .thenAccept(response -> { + if (response.statusCode() == 200) { + try { + JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject(); + if (json.has("effects") && json.get("effects").isJsonArray()) { + // Обрабатываем в основном потоке сервера + Bukkit.getScheduler().runTask(this, () -> { + processPlayerEffects(player, json.getAsJsonArray("effects")); + }); + } + } catch (Exception e) { + getLogger().warning("Ошибка при обработке бонусов: " + e.getMessage()); + } + } + }); + } catch (Exception e) { + getLogger().warning("Ошибка при запросе бонусов для игрока " + playerName + ": " + e.getMessage()); + } + } + + /** + * Обрабатывает и применяет эффекты к игроку + */ + private void processPlayerEffects(Player player, JsonArray effects) { + // Очищаем предыдущие временные эффекты от нашего плагина + for (PotionEffect effect : player.getActivePotionEffects()) { + // Проверяем, что это наш эффект (можно использовать метаданные) + // player.removePotionEffect(effect.getType()); + } + + for (JsonElement effectElement : effects) { + JsonObject effect = effectElement.getAsJsonObject(); + String type = effect.get("effect_type").getAsString(); + float value = effect.get("effect_value").getAsFloat(); + + // Применяем различные типы эффектов + switch (type) { + case "experience": + // Увеличиваем опыт при получении + // Этот бонус будет применяться при событии получения опыта + break; + + case "strength": + // Применяем усиление атаки + player.addPotionEffect(new PotionEffect( + PotionEffectType.STRENGTH, + 220, // длительность эффекта (11 секунд) + (int)(value * 10) - 1, // уровень эффекта (0.1 -> уровень 0) + false, // ambient + false, // показывать частицы + true // показывать значок + )); + break; + + case "speed": + // Увеличиваем скорость + player.addPotionEffect(new PotionEffect( + PotionEffectType.SPEED, + 220, // длительность эффекта (11 секунд) + (int)(value * 10) - 1, // уровень эффекта + false, + false, + true + )); + break; + + case "jump": + // Увеличиваем высоту прыжка + player.addPotionEffect(new PotionEffect( + PotionEffectType.JUMP_BOOST, + 220, + (int)(value * 10) - 1, + false, + false, + true + )); + break; + + case "health": + // Увеличиваем максимальное здоровье + double baseHealth = 20.0; // Стандартное здоровье + double bonusHealth = baseHealth * value; + + // Устанавливаем временный атрибут + player.getAttribute(Attribute.MAX_HEALTH).setBaseValue(baseHealth + bonusHealth); + break; + } + } + } + + // Добавляем обработчик события получения опыта для применения бонуса к опыту + @EventHandler + public void onPlayerExpGain(PlayerExpChangeEvent event) { + Player player = event.getPlayer(); + String playerName = player.getName(); + + // Проверяем, есть ли у игрока активный бонус к опыту + // В реальной реализации лучше кэшировать эти данные, а не запрашивать каждый раз + try { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(bonusesUrl + "?username=" + playerName)) + .version(HttpClient.Version.HTTP_1_1) + .GET() + .build(); + + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + + if (response.statusCode() == 200) { + JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject(); + if (json.has("effects") && json.get("effects").isJsonArray()) { + JsonArray effects = json.getAsJsonArray("effects"); + + for (JsonElement effectElement : effects) { + JsonObject effect = effectElement.getAsJsonObject(); + String type = effect.get("effect_type").getAsString(); + + if ("experience".equals(type)) { + float value = effect.get("effect_value").getAsFloat(); + int originalExp = event.getAmount(); + int bonusExp = Math.round(originalExp * value); + + // Устанавливаем новое количество опыта с бонусом + event.setAmount(originalExp + bonusExp); + + // Отправляем сообщение игроку (опционально) + if (bonusExp > 0) { + player.sendMessage("§a+" + bonusExp + " бонусного опыта!"); + } + + break; // Применяем только один бонус к опыту + } + } + } + } + } catch (Exception e) { + getLogger().warning("Ошибка при применении бонуса опыта: " + e.getMessage()); + } + } }