Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Dismiss Notice

Помогите Отслеживание ивентов WG

Discussion in 'Разработка плагинов для новичков' started by Shockwave, Jun 2, 2014.

  1. Автор темы
    Shockwave

    Shockwave Старожил Пользователь

    Trophy Points:
    103
    Нужно ловить например ивент WG входа в регион и выполнять некий код. Прошу помочь(лучше всего кодом)
     
    Last edited: Jun 3, 2014
  2. Хостинг MineCraft
    <
  3. Gentalion

    Gentalion Активный участник Пользователь

    Trophy Points:
    93
    Имя в Minecraft:
    Gentalion
    Есть плагин WG Events, загугли сам.

    Да и самому не так уж и сложно проверять. Кстати, сверху @fromgate привёл отличный пример реализации.
     
  4. Автор темы
    Shockwave

    Shockwave Старожил Пользователь

    Trophy Points:
    103
    Спасибо. Вот только один вопрос: Не будет постоянное прослушивание PlayerMoveEvent давать большую нагрузку при больших онлайнах?
     
  5. Автор темы
    Shockwave

    Shockwave Старожил Пользователь

    Trophy Points:
    103
    Спасибо за полный и ясный ответ. Буду знать теперь)
     
  6. Reality_SC

    Reality_SC Старожил Пользователь

    Trophy Points:
    123
    Имя в Minecraft:
    Reality_SC
    Поделюсь своим опытом:

    Класс листенера, который отлавливает подвигавшихся игроков:
    Code:
    import java.util.HashSet;
    import org.bukkit.entity.Player;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerChangedWorldEvent;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.PlayerMoveEvent;
    import org.bukkit.event.player.PlayerTeleportEvent;
    
    public class MovingPlayersCatcher implements Listener
    {
        private final HashSet<Player> movedPlayers = new HashSet<>();
        public synchronized HashSet<Player> getMovedPlayersAsync()
        {
            HashSet<Player> result = new HashSet<>(movedPlayers);
            movedPlayers.clear();
            return result;
        }
        @org.bukkit.event.EventHandler
        protected synchronized void onPlayerJoin(PlayerJoinEvent event)
        {
            movedPlayers.add(event.getPlayer());
        }
        @org.bukkit.event.EventHandler
        protected synchronized void onPlayerMove(PlayerMoveEvent event)
        {
            movedPlayers.add(event.getPlayer());
        }
        @org.bukkit.event.EventHandler
        protected synchronized void onPlayerTeleport(PlayerTeleportEvent event)
        {
            movedPlayers.add(event.getPlayer());
        }
        @org.bukkit.event.EventHandler
        protected synchronized void onPlayerChangedWorld(PlayerChangedWorldEvent event)
        {
            movedPlayers.add(event.getPlayer());
        }
    }
    Где-то отдельно кусок тела параллельного потока:
    Code:
    for(; !Thread.interrupted(); Thread.sleep(granularity))
       for(Player player : movedPlayers.getMovedPlayersAsync())
          if(regionListProvider.IsRegionListChanged(player))
             { /* Сделать что-то ваше */ }
    Гранулярность позволяет задать периодичность обработки, для моих задач стоит 1 секунда, что вполне решает поставленные задачи.
    Ну и то, как я делаю поиск регионов:
    Code:
    import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
    import com.sk89q.worldguard.protection.ApplicableRegionSet;
    import com.sk89q.worldguard.protection.managers.RegionManager;
    import com.sk89q.worldguard.protection.regions.ProtectedRegion;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;
    import org.bukkit.Location;
    import org.bukkit.World;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.Plugin;
    
    public final class RegionListProviders
    {
        private final MainPluginClass plugin;
        private Plugin worldguard;
        private final Map<Player, Set<String>> regionsByPlayer = new HashMap<>();
        private final Map<Player, Integer> playerRegionHashes = new HashMap<>();
        private final Map<Player, World> playerLastWorld = new HashMap<>();
        public RegionListProviders(MainPluginClass rscp)
        {
            this.plugin = rscp;
        }
        public synchronized void integrate()
        {
            // WorldGuard
            if(plugin.settings.isUseWorldGuard())
            {
                final Plugin pluginWG = plugin.getServer().getPluginManager().getPlugin("WorldGuard");
                if((pluginWG != null) && (pluginWG instanceof WorldGuardPlugin))
                {
                    this.worldguard = pluginWG;
                    MainPluginClass.consoleLog.info("[rscp] WorldGuard was found and integrated.");
                } else {
                    this.worldguard = null;
                    MainPluginClass.consoleLog.info("[rscp] WorldGuard was not found.");
                }
            } else
                this.worldguard = null;
        }
        public synchronized void deintegrate()
        {
            this.worldguard = null;
            this.residence = null;
        }
        public synchronized boolean IsRegionListChanged(Player player)
        {
            final Location location = player.getLocation();
            final World world = location.getWorld();
            final Set<String> playerRegions = new HashSet<>();
            // WorldGuard
            if(worldguard != null && worldguard.isEnabled())
                try
                {
                    final WorldGuardPlugin pluginWG = (WorldGuardPlugin)worldguard;
                    final RegionManager rman = pluginWG.getRegionManager(world);
                    if(rman == null)
                        return false;
                    // Get list
                    final ApplicableRegionSet appregs = rman.getApplicableRegions(location);
                    for(ProtectedRegion region : appregs)
                        playerRegions.add(region.getId());
                } catch(RuntimeException ex) {
                }
            // Is it changed?
            int hashcode = playerRegions.hashCode();
            if(playerLastWorld.containsKey(player))
                if(playerLastWorld.get(player).equals(world))
                    if(hashcode == playerRegionHashes.get(player))
                        return false;
            // Update
            playerRegionHashes.put(player, hashcode);
            regionsByPlayer.put(player, playerRegions);
            playerLastWorld.put(player, world);
            return true;
        }
        public synchronized Set<String> GetRegionList(Player player)
        {
            Set<String> result = regionsByPlayer.get(player);
            return (result != null) ? result : Collections.<String>emptySet();
        }
        public synchronized void removePlayer(Player player)
        {
            playerRegionHashes.remove(player);
            regionsByPlayer.remove(player);
            playerLastWorld.remove(player);
        }
    }
    Тут на самом деле задача другая немного, просто выяснить, изменился и список регионов, в которых находится игрок, или нет. Но при желании вы сможете это довести до нужного вам состояния. Я кое что лишнее подрезал, так что не обещаю, что это 100% рабочий код :)
     

Share This Page