Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
20 kB
0
Indexable
Never
package ovout.timetracker;


import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.CommandExecutor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;

import java.io.File;
import java.io.IOException;

public class TimeTracker extends JavaPlugin implements CommandExecutor, Listener {

    private Map<String, List<Session>> projectSessions = new HashMap<>();
    private Map<UUID, Session> activeSessions = new HashMap<>();
    private SessionManager sessionManager;

    @Override
    public void onEnable() {
        // Registra los comandos y eventos
        getCommand("startsession").setExecutor(this);
        getCommand("createsession").setExecutor(this);
        getCommand("selectworld").setExecutor(this);
        getCommand("sessions").setExecutor(this);
        getCommand("sessioninfo").setExecutor(this);

        getServer().getPluginManager().registerEvents(this, this);

        sessionManager = new SessionManager(this);
        // Programar la tarea periódica para actualizar las sesiones cada 1200 ticks (60 segundos)
        int ticksInterval = 100;
        scheduleTask(ticksInterval);
    }
    private void scheduleTask(int ticks) {
        BukkitScheduler scheduler = getServer().getScheduler();
        scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
            @Override
            public void run() {
                updateSessions();
            }
        }, 0, ticks);
    }
    private void updateSessions() {
        long currentTime = System.currentTimeMillis();

        for (Session session : activeSessions.values()) {
            // Si la sesión está en línea, actualiza el tiempo de trabajo
            if (session.getPlayer() != null && session.getPlayer().isOnline()) {
                if (!session.isAfk()) {
                    long sessionTime = currentTime - session.getStartTime();
                    session.setTotalWorkTime(session.getTotalWorkTime() + sessionTime);
                }
            }

            // Guarda la sesión actualizada en el archivo
            saveSession(session);
        }
    }

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("createsession")) {
            if (sender.hasPermission("timetracker.admin")) {
                if (args.length == 1) {
                    String sessionName = args[0];
                    createSession(sender, sessionName); // Pasamos sender y sessionName como parámetros
                } else {
                    sender.sendMessage(ChatColor.RED + "Uso incorrecto. /createsession <nombre>");
                }
            } else {
                sender.sendMessage(ChatColor.RED + "No tienes permiso para usar este comando.");
            }
            return true;
        }

        if (cmd.getName().equalsIgnoreCase("startsession")) {
            if (sender instanceof Player) {
                Player player = (Player) sender;
                if (args.length == 1) {
                    String sessionName = args[0];
                    startSession(player, sessionName); // Pasamos player y sessionName como parámetros
                } else {
                    sender.sendMessage(ChatColor.RED + "Uso incorrecto. /startsession <nombre_sesion>");
                }
            } else {
                sender.sendMessage(ChatColor.RED + "Este comando solo puede ser usado por jugadores.");
            }
            return true;
        }

        if (cmd.getName().equalsIgnoreCase("selectworld")) {
            if (sender.hasPermission("timetracker.admin")) {
                if (args.length == 2) {
                    String sessionName = args[0];
                    String worldName = args[1];
                    Session session = getSessionByName(sessionName);
                    if (session != null) {
                        selectWorld(session, worldName); // Establecer el nombre del mundo en la sesión
                        sender.sendMessage(ChatColor.GREEN + "La sesión \"" + sessionName + "\" ha sido vinculada al mundo \"" + worldName + "\".");
                    } else {
                        sender.sendMessage(ChatColor.RED + "No se encontró una sesión con ese nombre.");
                    }
                } else {
                    sender.sendMessage(ChatColor.RED + "Uso incorrecto. /selectworld <nombre_sesion> <nombre_mundo>");
                }
            } else {
                sender.sendMessage(ChatColor.RED + "No tienes permiso para usar este comando.");
            }
            return true;
        }

        if (cmd.getName().equalsIgnoreCase("sessions")) {
            List<String> sessionList = new ArrayList<>();
            for (Session session : activeSessions.values()) {
                long totalWorkTime = calculateUpdatedWorkTime(session); // Calcula el tiempo trabajado actualizado
                String formattedTime = formatTime(totalWorkTime);
                sessionList.add(session.getName() + " - " + session.getPlayer().getName() + " - " + formattedTime);
            }
            sender.sendMessage(ChatColor.GOLD + "---- Sesiones Activas ----");
            sender.sendMessage(sessionList.toArray(new String[0]));
            return true;
        }

        if (cmd.getName().equalsIgnoreCase("sessioninfo")) {
            if (args.length == 1) {
                String sessionName = args[0];
                Session session = getSessionByName(sessionName); // Debes obtener la sesión por su nombre
                if (session != null) {
                    long totalWorkTime = calculateUpdatedWorkTime(session); // Calcula el tiempo trabajado actualizado
                    sender.sendMessage(ChatColor.GOLD + "---- Información de la Sesión \"" + sessionName + "\" ----");
                    sender.sendMessage(ChatColor.GREEN + "Jugador: " + session.getPlayer().getName());
                    sender.sendMessage(ChatColor.GREEN + "Mundo Vinculado: " + session.getWorld());
                    sender.sendMessage(ChatColor.GREEN + "Tiempo Trabajado: " + formatTime(totalWorkTime));
                } else {
                    sender.sendMessage(ChatColor.RED + "No se encontró una sesión con ese nombre.");
                }
            } else {
                sender.sendMessage(ChatColor.RED + "Uso incorrecto. /sessioninfo <nombre_sesion>");
            }
            return true;
        }

        return false;
    }

    @EventHandler
    public void onPlayerMove(PlayerMoveEvent event) {
        Player player = event.getPlayer();
        UUID uuid = player.getUniqueId();

        if (activeSessions.containsKey(uuid)) {
            Session session = activeSessions.get(uuid);
            if (session.getWorld() != null && !session.getWorld().equals(player.getWorld().getName())) {
                session.stop();
                saveSession(session);
                activeSessions.remove(uuid);
                player.sendMessage(ChatColor.GREEN + "Tu sesión ha sido detenida automáticamente por cambiar de mundo.");
            } else if (session.isAfk()) {
                session.setAfk(false);
                player.sendMessage(ChatColor.GREEN + "¡Has vuelto al trabajo! La sesión se ha reanudado.");
            }

            // Guardar sesión al detener (si no se detuvo por cambio de mundo)
            saveSession(session);
        }
    }

    private void startSession(Player player, String sessionName) {
        // Verificar que el jugador tenga una sesión activa del proyecto correspondiente
        List<Session> projectSessionList = projectSessions.get(sessionName);
        if (projectSessionList == null) {
            player.sendMessage(ChatColor.RED + "No se encontró una sesión con ese nombre.");
            return;
        }

        // Buscar la sesión activa para el jugador
        Session activeSession = null;
        for (Session session : projectSessionList) {
            if (session.getPlayer() != null && session.getPlayer().getUniqueId().equals(player.getUniqueId())) {
                activeSession = session;
                break;
            }
        }

        if (activeSession != null) {
            player.sendMessage(ChatColor.RED + "Ya tienes una sesión activa. Deténla antes de iniciar una nueva.");
            return;
        }

        // Si el jugador no tiene una sesión activa, buscamos una disponible para él
        for (Session session : projectSessionList) {
            if (session.getPlayer() == null) {
                session.setPlayer(player);
                activeSessions.put(player.getUniqueId(), session); // Agregar la sesión activa al mapa
                player.sendMessage(ChatColor.GREEN + "Sesión \"" + sessionName + "\" iniciada. ¡Trabaja duro!");

                // Guardar sesión al iniciar
                saveSession(session);
                return;
            }
        }

        // Si no encontramos una sesión disponible para el jugador, significa que todas las sesiones están ocupadas.
        player.sendMessage(ChatColor.RED + "No hay sesiones disponibles para este proyecto en este momento.");
    }

    private void createSession(CommandSender sender, String sessionName) {
        // Implementa la creación de una nueva sesión.
        if (sessionName != null && !sessionName.trim().isEmpty()) {
            // Verificar que el nombre de sesión no esté vacío o sea nulo
            if (getSessionByName(sessionName) == null) {
                // Creamos la sesión sin jugador (solo con el nombre)
                Session session = new Session(sessionName);

                // Agregamos la sesión a las sesiones activas para este proyecto
                List<Session> projectSessionList = projectSessions.computeIfAbsent(sessionName, k -> new ArrayList<>());
                projectSessionList.add(session);

                sender.sendMessage(ChatColor.GREEN + "Sesión \"" + sessionName + "\" creada correctamente.");
            } else {
                sender.sendMessage(ChatColor.RED + "Ya existe una sesión con ese nombre.");
            }
        } else {
            sender.sendMessage(ChatColor.RED + "Por favor, proporciona un nombre válido para la sesión.");
        }
    }

    private void selectWorld(Session session, String worldName) {
        // Implementa la selección de mundo para una sesión.
        session.setWorld(worldName);
    }

    private void saveSession(Session session) {
        // Implementa el guardado de la sesión en tu sistema de persistencia (archivo, base de datos, etc.).
        sessionManager.saveSession(session);
    }

    private Session getSessionByName(String sessionName) {
        // Implementa la obtención de una sesión por su nombre.
        // Puedes usar un bucle para buscar entre las sesiones activas.
        for (Session session : activeSessions.values()) {
            if (session.getName().equalsIgnoreCase(sessionName)) {
                return session;
            }
        }
        return null;
    }

    private String formatTime(long milliseconds) {
        long seconds = milliseconds / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        return String.format("%02d:%02d:%02d", hours, minutes % 60, seconds % 60);
    }

    // Clase que representa una sesión de trabajo
    private static class Session {
        private final String name;
        private final UUID playerUUID; // Cambiamos el tipo de jugador a UUID
        private long startTime;
        private long totalWorkTime;
        private boolean afk;
        private String world;

        // Constructor para sesiones con jugador
        public Session(Player player, String name) {
            this.name = name;
            this.playerUUID = player.getUniqueId(); // Almacenamos el UUID del jugador
            this.startTime = System.currentTimeMillis();
            this.totalWorkTime = 0;
            this.afk = false;
            this.world = null;
        }
        // Constructor para sesiones sin jugador (cargadas desde archivo)
        public Session(String name, UUID playerUUID, long startTime, long totalWorkTime, boolean afk, String world) {
            this.name = name;
            this.playerUUID = playerUUID;
            this.startTime = startTime;
            this.totalWorkTime = totalWorkTime;
            this.afk = afk;
            this.world = world;
        }

        public void setPlayer(Player player) {
            // Opcionalmente, puedes agregar aquí una lógica para detener la sesión actual si ya había un jugador asociado
            this.startTime = System.currentTimeMillis();
        }
        public void setTotalWorkTime(long totalWorkTime) {
            this.totalWorkTime = totalWorkTime;
        }
        public void setStartTime(long startTime) {
            this.startTime = startTime;
        }
        public long getStartTime() {
            return startTime;
        }
        public void setWorld(String world) {
            this.world = world;
        }

        public void stop() {
            long currentTime = System.currentTimeMillis();
            totalWorkTime += (currentTime - startTime);
        }

        public boolean isAfk() {
            return afk;
        }

        public void setAfk(boolean afk) {
            this.afk = afk;
        }

        public String getWorld() {
            return world;
        }

        public String getName() {
            return name;
        }

        public Player getPlayer() {
            return player;
        }

        public long getTotalWorkTime() {
            if (afk) {
                long currentTime = System.currentTimeMillis();
                return totalWorkTime + (currentTime - startTime);
            } else {
                return totalWorkTime;
            }
        }
    }

    private long calculateUpdatedWorkTime(Session session) {
        long currentTime = System.currentTimeMillis();
        if (session.isAfk()) {
            return session.getTotalWorkTime() + (currentTime - session.getStartTime());
        } else {
            return session.getTotalWorkTime();
        }
    }
    public class SessionManager {

        private TimeTracker plugin; // Agregar esta variable para almacenar el plugin
        private FileConfiguration dataConfig;
        private File dataFile;

        public SessionManager(TimeTracker plugin) {
            this.plugin = plugin; // Asignar el plugin al campo 'plugin' de la clase
            // Crea el directorio TimeTracker si no existe
            File dataFolder = plugin.getDataFolder();
            if (!dataFolder.exists()) {
                dataFolder.mkdir();
            }

            // Crea el archivo de configuración si no existe
            dataFile = new File(plugin.getDataFolder(), "sessions.yml");
            if (!dataFile.exists()) {
                try {
                    dataFile.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            dataConfig = YamlConfiguration.loadConfiguration(dataFile);
        }

        public void saveSession(Session session) {
            UUID uuid = session.getPlayer().getUniqueId();
            ConfigurationSection sessionSection = dataConfig.createSection(uuid.toString());
            sessionSection.set("name", session.getName());
            sessionSection.set("startTime", session.getStartTime());
            sessionSection.set("totalWorkTime", session.getTotalWorkTime());
            sessionSection.set("afk", session.isAfk());
            sessionSection.set("world", session.getWorld());

            try {
                dataConfig.save(dataFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        public Session loadSession(String sessionName) {
            // Cargamos el archivo sessions.yml
            File dataFile = new File(plugin.getDataFolder(), "sessions.yml");
            FileConfiguration dataConfig = YamlConfiguration.loadConfiguration(dataFile);

            // Recorremos todas las secciones del archivo para buscar la sesión con el nombre proporcionado
            for (String uuidStr : dataConfig.getKeys(false)) {
                ConfigurationSection sessionSection = dataConfig.getConfigurationSection(uuidStr);
                if (sessionSection != null) {
                    String name = sessionSection.getString("name");

                    // Si encontramos una sesión con el nombre buscado, la cargamos y devolvemos
                    if (name != null && name.equalsIgnoreCase(sessionName)) {
                        UUID uuid = UUID.fromString(uuidStr);
                        Player player = Bukkit.getPlayer(uuid);

                        if (player != null) {
                            // Si el jugador está en línea, podemos cargar la sesión con el jugador
                            long startTime = sessionSection.getLong("startTime");
                            long totalWorkTime = sessionSection.getLong("totalWorkTime");
                            boolean afk = sessionSection.getBoolean("afk");
                            String world = sessionSection.getString("world");

                            Session session = new Session(player, name);
                            session.setStartTime(startTime);
                            session.setTotalWorkTime(totalWorkTime);
                            session.setAfk(afk);
                            session.setWorld(world);
                            return session;
                        } else {
                            // Si el jugador no está en línea, cargamos la sesión solo con el nombre
                            // Aquí, como no tenemos un objeto Player, usaremos el UUID almacenado en el archivo
                            UUID playerUUID = UUID.fromString(uuidStr);
                            long startTime = sessionSection.getLong("startTime");
                            long totalWorkTime = sessionSection.getLong("totalWorkTime");
                            boolean afk = sessionSection.getBoolean("afk");
                            String world = sessionSection.getString("world");

                            Session session = new Session(name, playerUUID, startTime, totalWorkTime, afk, world);
                            return session;
                        }
                    }
                }
                return null; // Si no se encontró la sesión con el nombre buscado, devolvemos null
        }
    }
    @Override
    public void onDisable() {
        // Guardar todas las sesiones activas en el archivo sessions.yml
        for (Session session : activeSessions.values()) {
            saveSession(session);
        }
    }
}