package tc.oc.commons.bukkit.ticket;
import java.util.Objects;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import tc.oc.api.bukkit.users.OnlinePlayers;
import tc.oc.api.docs.Server;
import tc.oc.api.docs.Ticket;
import tc.oc.api.games.TicketStore;
import tc.oc.api.minecraft.users.UserStore;
import tc.oc.api.model.ModelDispatcher;
import tc.oc.api.model.ModelListener;
import tc.oc.api.servers.ServerStore;
import tc.oc.commons.bukkit.teleport.PlayerServerChanger;
import tc.oc.commons.core.logging.Loggers;
import tc.oc.commons.core.plugin.PluginFacet;
/**
* Reacts to changing {@link Ticket}s and joining {@link Player}s, sending players
* to a different server, if their ticket implies they should be elsewhere.
*
* Currently, the dispatch is unconditional, and does not fire a PlayerServerChangeEvent.
* In the future, the event should be fired and cancellation respected.
*/
@Singleton
public class TicketListener implements PluginFacet, Listener, ModelListener {
private final Logger logger;
private final ServerStore servers;
private final TicketStore tickets;
private final UserStore userStore;
private final Server localServer;
private final OnlinePlayers onlinePlayers;
private final PlayerServerChanger serverChanger;
@Inject TicketListener(Loggers loggers, ServerStore servers, TicketStore tickets, UserStore userStore, Server localServer, OnlinePlayers onlinePlayers, PlayerServerChanger serverChanger, ModelDispatcher modelDispatcher) {
this.logger = loggers.get(getClass());
this.servers = servers;
this.tickets = tickets;
this.userStore = userStore;
this.localServer = localServer;
this.onlinePlayers = onlinePlayers;
this.serverChanger = serverChanger;
modelDispatcher.subscribe(this);
}
private void dispatch(@Nullable Player player, @Nullable Ticket ticket) {
if(player == null || ticket == null) return;
if(ticket.server_id() != null && !localServer._id().equals(ticket.server_id())) {
final Server server = servers.byId(ticket.server_id());
logger.info("Sending " + player.getName() + " to server " + server.bungee_name() + " to play a game");
serverChanger.sendPlayerToServer(player, server, true);
}
}
@HandleModel
private void onTicketUpdate(@Nullable Ticket before, @Nullable Ticket after, Ticket ticket) {
if(before == null || after == null || !Objects.equals(before.server_id(), after.server_id())) {
dispatch(onlinePlayers.find(ticket.user()), after);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(PlayerJoinEvent event) {
dispatch(event.getPlayer(), tickets.tryUser(userStore.playerId(event.getPlayer())));
}
}