Следуйте инструкциям в видео ниже, чтобы узнать, как установить наш сайт как веб-приложение на главный экран вашего устройства.
Примечание: Эта функция может быть недоступна в некоторых браузерах.
Наверное имелся в виду WG?
В WG события связанные со входом/выходом в регион отсутствуют. Поэтому по сути их нужно самому реализовывать (ну или, если не создавать сами события, то по крайней мере проверять вошёл игрок в новый регион или нет).
Собственно вот пример из ReActions, метод определяющий по двум координатам (он у меня вызывается из PlayerMoveEvent) входит ли игрок в новый регион и если да - то вызывает событие (это событие "собственного" производства - вместо вызова события можно выполнять свой код).
Спасибо. Вот только один вопрос: Не будет постоянное прослушивание PlayerMoveEvent давать большую нагрузку при больших онлайнах?Есть плагин WG Events, загугли сам.
Да и самому не так уж и сложно проверять. Кстати, сверху @fromgate привёл отличный пример реализации.
)Спасибо за полный и ясный ответ. Буду знать теперь)Shockwave, Вам же в PlayerMoveEvent не нужно выполнять что-то безумно большое. Вы просто проверяете принадлежность одной/двух координат регионам. Не думаю, что у Вас количество игроков и регионов будет таким, чтобы Вы испытали проблемы по этому поводу.
Начинайте беспокоиться, когда Вы начнёте выполнять в PlayerMoveEvent что-то конкретное (ну предположим, менять алмазы на уголь на расстоянии 500 блоков вокруг игрока)
Если задача трудоемкая, то тогда выносите её в отдельную задачу (несинхронизированную) и запускайте из из обработчика события.
Ну и если есть сомнения, не поленитесь, сделайте собственный профайлер. Это самый надежный способ их снять. Я для себя вопрос закрыл — в ReActions есть механизма подсчитывающий сколько и чего ReActions выполняет с разбивкой по тикам — т.е. можно оценить сколько процентов от тика приходится на выполнение методов ReActions (эта процедура, правда в сам плагин не встроена, — подключается и компилируется по мере необходимости). Когда были подозрения, что какие-то действия выполняются слишком долго, то снималась информация с живого сервера, активно использующего ReActions (в т.ч. активаторы связанные с регионами) — и мы даже близко не подошли к тому, чтобы у меня возникла необходимость что-то менять. В процессе, помню что-то оптимизировал, но это был необязательно, по большому счету.
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());
}
}
for(; !Thread.interrupted(); Thread.sleep(granularity))
for(Player player : movedPlayers.getMovedPlayersAsync())
if(regionListProvider.IsRegionListChanged(player))
{ /* Сделать что-то ваше */ }
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);
}
}
