Advertisement
Guest User

RequestContextService.java

a guest
Jan 18th, 2019
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.34 KB | None | 0 0
  1. import org.bukkit.entity.Player;
  2. import org.bukkit.plugin.Plugin;
  3. import org.bukkit.scheduler.BukkitScheduler;
  4. import org.bukkit.scheduler.BukkitTask;
  5.  
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.Objects;
  11. import java.util.Optional;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. import java.util.stream.Collectors;
  14. import java.util.stream.Stream;
  15.  
  16. public class RequestContextService {
  17.  
  18.     private static final long PERIOD_IN_TICKS = 100L;
  19.  
  20.     private final Plugin plugin;
  21.  
  22.     public RequestContextService(Plugin plugin) {
  23.         this.plugin = plugin;
  24.     }
  25.  
  26.     private final Map<Player, Collection<RequestContext>> contexts = new ConcurrentHashMap<>();
  27.  
  28.     /**
  29.      * По команде отправки запроса.
  30.      */
  31.     public void addRequest(RequestContext newRequest) {
  32.         // Сохраняем ссылки на контекст обоим игрокам
  33.         Player source = newRequest.getSource();
  34.         Player target = newRequest.getTarget();
  35.         getPlayerContextStorage(source).add(newRequest);
  36.         getPlayerContextStorage(target).add(newRequest);
  37.  
  38.         // Запускаем уведомления игрокам.
  39.         BukkitScheduler scheduler = plugin.getServer().getScheduler();
  40.         Optional.ofNullable(newRequest.getSourceNotification())
  41.                 .ifPresent(r -> scheduler.runTaskTimer(plugin, r, 0L, PERIOD_IN_TICKS));
  42.         Optional.ofNullable(newRequest.getTargetNotification())
  43.                 .ifPresent(r -> scheduler.runTaskTimer(plugin, r, 0L, PERIOD_IN_TICKS));
  44.  
  45.         plugin.getLogger().info(String.format("Registered request from player %s to player %s.",
  46.                 source.getName(), target.getName()));
  47.     }
  48.  
  49.     /**
  50.      * Найти список контекстов, отправленных игроком (например, для отмены по его команде).
  51.      */
  52.     public Stream<RequestContext> findBySource(Player source) {
  53.         return getPlayerContextStorage(source)
  54.                 .stream()
  55.                 .filter(c -> c.getSource().equals(source));
  56.     }
  57.  
  58.     /**
  59.      * Найти список контекстов, полученных игроком (например, для принятия/отказа).
  60.      */
  61.     public Stream<RequestContext> findByTarget(Player target) {
  62.         return getPlayerContextStorage(target)
  63.                 .stream()
  64.                 .filter(c -> c.getTarget().equals(target));
  65.     }
  66.  
  67.     /**
  68.      * Если исходный игрок отменил запрос, или целевой принял или отказал по нему.
  69.      */
  70.     public void removeContext(RequestContext context) {
  71.         // Отмена уведомлений
  72.         Stream.of(context.getSourceTask(), context.getTargetTask())
  73.                 .filter(Objects::nonNull)
  74.                 .forEach(BukkitTask::cancel);
  75.  
  76.         // Удаление ссылок
  77.         Player source = context.getSource();
  78.         Player target = context.getTarget();
  79.         getPlayerContextStorage(source).remove(context);
  80.         getPlayerContextStorage(target).remove(context);
  81.  
  82.         plugin.getLogger().info(String.format("Request from player %s to player %s has been removed.",
  83.                 source.getName(), target.getName()));
  84.     }
  85.  
  86.     /**
  87.      * Если нужно окончательно забыть игрока (вышел из игры, например).
  88.      */
  89.     public void forgotPlayer(Player player) {
  90.         // Находим все контексты, где участвует указанных игрок.
  91.         List<RequestContext> playerContexts = Stream.concat(findBySource(player), findByTarget(player))
  92.                 .distinct()
  93.                 .collect(Collectors.toList());
  94.         // Удаляем их.
  95.         playerContexts.forEach(this::removeContext);
  96.         // Теряем его персональное хранилище ссылок.
  97.         contexts.remove(player);
  98.     }
  99.  
  100.     private Collection<RequestContext> getPlayerContextStorage(Player player) {
  101.         return contexts.computeIfAbsent(player, p -> new ArrayList<>(32));
  102.     }
  103.  
  104.     public static class PackagePrivateRequestContext {
  105.  
  106.         private BukkitTask sourceTask;
  107.  
  108.         private BukkitTask targetTask;
  109.  
  110.         BukkitTask getSourceTask() {
  111.             return this.sourceTask;
  112.         }
  113.  
  114.         BukkitTask getTargetTask() {
  115.             return this.targetTask;
  116.         }
  117.     }
  118.  
  119.     /**
  120.      * Во внешнем коде можно наследоваться от этого класса для хранения фактических контекстов.
  121.      */
  122.     public static class RequestContext extends PackagePrivateRequestContext {
  123.  
  124.         private Player source;
  125.  
  126.         private Player target;
  127.  
  128.         private Runnable sourceNotification;
  129.  
  130.         private Runnable targetNotification;
  131.  
  132.         public Player getSource() {
  133.             return this.source;
  134.         }
  135.  
  136.         public Player getTarget() {
  137.             return this.target;
  138.         }
  139.  
  140.         public Runnable getSourceNotification() {
  141.             return this.sourceNotification;
  142.         }
  143.  
  144.         public Runnable getTargetNotification() {
  145.             return this.getTargetNotification();
  146.         }
  147.     }
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement