Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import org.bukkit.entity.Player;
- import org.bukkit.plugin.Plugin;
- import org.bukkit.scheduler.BukkitScheduler;
- import org.bukkit.scheduler.BukkitTask;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- import java.util.Map;
- import java.util.Objects;
- import java.util.Optional;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- public class RequestContextService {
- private static final long PERIOD_IN_TICKS = 100L;
- private final Plugin plugin;
- public RequestContextService(Plugin plugin) {
- this.plugin = plugin;
- }
- private final Map<Player, Collection<RequestContext>> contexts = new ConcurrentHashMap<>();
- /**
- * По команде отправки запроса.
- */
- public void addRequest(RequestContext newRequest) {
- // Сохраняем ссылки на контекст обоим игрокам
- Player source = newRequest.getSource();
- Player target = newRequest.getTarget();
- getPlayerContextStorage(source).add(newRequest);
- getPlayerContextStorage(target).add(newRequest);
- // Запускаем уведомления игрокам.
- BukkitScheduler scheduler = plugin.getServer().getScheduler();
- Optional.ofNullable(newRequest.getSourceNotification())
- .ifPresent(r -> scheduler.runTaskTimer(plugin, r, 0L, PERIOD_IN_TICKS));
- Optional.ofNullable(newRequest.getTargetNotification())
- .ifPresent(r -> scheduler.runTaskTimer(plugin, r, 0L, PERIOD_IN_TICKS));
- plugin.getLogger().info(String.format("Registered request from player %s to player %s.",
- source.getName(), target.getName()));
- }
- /**
- * Найти список контекстов, отправленных игроком (например, для отмены по его команде).
- */
- public Stream<RequestContext> findBySource(Player source) {
- return getPlayerContextStorage(source)
- .stream()
- .filter(c -> c.getSource().equals(source));
- }
- /**
- * Найти список контекстов, полученных игроком (например, для принятия/отказа).
- */
- public Stream<RequestContext> findByTarget(Player target) {
- return getPlayerContextStorage(target)
- .stream()
- .filter(c -> c.getTarget().equals(target));
- }
- /**
- * Если исходный игрок отменил запрос, или целевой принял или отказал по нему.
- */
- public void removeContext(RequestContext context) {
- // Отмена уведомлений
- Stream.of(context.getSourceTask(), context.getTargetTask())
- .filter(Objects::nonNull)
- .forEach(BukkitTask::cancel);
- // Удаление ссылок
- Player source = context.getSource();
- Player target = context.getTarget();
- getPlayerContextStorage(source).remove(context);
- getPlayerContextStorage(target).remove(context);
- plugin.getLogger().info(String.format("Request from player %s to player %s has been removed.",
- source.getName(), target.getName()));
- }
- /**
- * Если нужно окончательно забыть игрока (вышел из игры, например).
- */
- public void forgotPlayer(Player player) {
- // Находим все контексты, где участвует указанных игрок.
- List<RequestContext> playerContexts = Stream.concat(findBySource(player), findByTarget(player))
- .distinct()
- .collect(Collectors.toList());
- // Удаляем их.
- playerContexts.forEach(this::removeContext);
- // Теряем его персональное хранилище ссылок.
- contexts.remove(player);
- }
- private Collection<RequestContext> getPlayerContextStorage(Player player) {
- return contexts.computeIfAbsent(player, p -> new ArrayList<>(32));
- }
- public static class PackagePrivateRequestContext {
- private BukkitTask sourceTask;
- private BukkitTask targetTask;
- BukkitTask getSourceTask() {
- return this.sourceTask;
- }
- BukkitTask getTargetTask() {
- return this.targetTask;
- }
- }
- /**
- * Во внешнем коде можно наследоваться от этого класса для хранения фактических контекстов.
- */
- public static class RequestContext extends PackagePrivateRequestContext {
- private Player source;
- private Player target;
- private Runnable sourceNotification;
- private Runnable targetNotification;
- public Player getSource() {
- return this.source;
- }
- public Player getTarget() {
- return this.target;
- }
- public Runnable getSourceNotification() {
- return this.sourceNotification;
- }
- public Runnable getTargetNotification() {
- return this.getTargetNotification();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement