LogoyStore

API

API do yStaffLogin para gerenciamento de autenticação e verificação de staff

Visão Geral

A API do yStaffLogin fornece métodos para verificar o status de autenticação da staff e recuperar informações dos membros da equipe. Este é um sistema de autenticação assíncrono projetado para verificar membros da equipe através de códigos de segurança.

Obtendo a Instância da API

import br.com.ystoreplugins.product.ystafflogin.StaffLoginAPIHolder;
import com.ystoreplugins.ystafflogin.api.StaffLoginAPI;

// Método 1: Instanciação direta
StaffLoginAPI api = new StaffLoginAPI();

// Método 2: Através do provedor de serviços (recomendado)
RegisteredServiceProvider<StaffLoginAPIHolder> provider = 
    Bukkit.getServicesManager().getRegistration(StaffLoginAPIHolder.class);
    
if (provider != null) {
    StaffLoginAPIHolder api = provider.getProvider();
    // Usar API
}

Métodos Disponíveis

isCached(String player)

Verifica se um membro da equipe existe em cache e se ele não está logado no momento.

Parâmetros:

  • player (String) - O nome do membro da equipe a verificar

Retorna:

  • boolean - true se o jogador está em cache E não está logado, false caso contrário

Observações Importantes:

  • Este método verifica tanto a existência em cache QUANTO o status de login
  • Um jogador em cache que está logado retornará false
  • O nome do método é contra-intuitivo: retorna true quando o jogador precisa de autenticação
  • Use isto antes de tentar processos de autenticação

Exemplo de Uso:

StaffLoginAPI api = new StaffLoginAPI();

if (api.isCached("Steve")) {
    // Jogador está em cache mas ainda não foi logado
    System.out.println("Jogador precisa de autenticação");
} else {
    // Jogador não está em cache ou já está logado
    System.out.println("Jogador não está disponível ou já foi autenticado");
}

getPlayer(String player)

Recupera informações do membro da equipe do cache.

Parâmetros:

  • player (String) - O nome do membro da equipe

Retorna:

  • StaffHolder - O objeto de dados do membro da equipe, ou null se não encontrado

Observações Importantes:

  • Retorna dados de staff em cache
  • Retorna null se o jogador não está no cache
  • Use isto para acessar as propriedades e estado de autenticação do membro da equipe
  • Sempre verifique se há null antes de usar o objeto retornado

Exemplo de Uso:

StaffLoginAPI api = new StaffLoginAPI();

StaffHolder staff = api.getPlayer("Steve");
if (staff != null) {
    System.out.println("Membro da equipe encontrado: " + staff.getNome());
    System.out.println("Logado: " + staff.logado);
} else {
    System.out.println("Membro da equipe não encontrado em cache");
}

Estruturas de Dados

StaffHolder

Contém informações sobre um membro da equipe.

Propriedades Principais:

  • logado (boolean) - Se o membro da equipe está autenticado no momento
  • nome (String) - O nome/identificador do membro da equipe

Operações Comuns:

StaffHolder staff = api.getPlayer("Steve");

// Verificar status de autenticação
if (staff.logado) {
    System.out.println("Staff está autenticado");
}

// Obter nome do staff
String staffName = staff.nome;

Eventos

AsyncStaffSentCodeEvent

Disparado quando um membro da equipe recebe um código de autenticação.

Acesso:

import br.com.ystoreplugins.product.ystafflogin.event.AsyncStaffSentCodeEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class StaffLoginListener implements Listener {
    @EventHandler
    public void onCodeSent(AsyncStaffSentCodeEvent event) {
        // Lidar com código enviado
    }
}

Métodos Disponíveis:

  • getPlayer() - Retorna o Jogador que recebeu o código
  • getCode() - Retorna o código de autenticação enviado ao jogador

Observações Importantes:

  • Este é um evento assíncrono (dispara em thread assíncrona)
  • Cuidado com operações síncronas como teleporte ou mudanças de inventário
  • O código é gerado e enviado (provavelmente via Discord/Email)
  • Múltiplos códigos podem ser gerados para o mesmo jogador

Exemplo de Uso:

@EventHandler
public void onCodeSent(AsyncStaffSentCodeEvent event) {
    Player player = event.getPlayer();
    String code = event.getCode();
    
    // Registrar a solicitação de autenticação
    System.out.println("Código enviado para staff: " + player.getName());
    System.out.println("Código: " + code);
    
    // Você pode armazenar isto para fins de auditoria
    logAuthenticationAttempt(player.getUniqueId(), code);
}

StaffSuccessAuthEvent

Disparado quando um membro da equipe se autentica com sucesso.

Acesso:

import br.com.ystoreplugins.product.ystafflogin.event.StaffSuccessAuthEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class StaffAuthListener implements Listener {
    @EventHandler
    public void onAuthSuccess(StaffSuccessAuthEvent event) {
        // Lidar com autenticação bem-sucedida
    }
}

Métodos Disponíveis:

  • getPlayer() - Retorna o Jogador que se autenticou
  • getCode() - Retorna o código que foi usado para autenticação

Observações Importantes:

  • Disparado quando a autenticação é concluída com sucesso
  • Neste ponto, o status logado do jogador se torna true
  • O código usado ainda está disponível (útil para logging)
  • Use isto para disparar ações pós-autenticação

Exemplo de Uso:

@EventHandler
public void onAuthSuccess(StaffSuccessAuthEvent event) {
    Player player = event.getPlayer();
    String usedCode = event.getCode();
    
    // Conceder permissões especiais
    player.addAttachment(plugin, "staff.authenticated", true);
    
    // Notificar outros admins
    Bukkit.broadcastMessage("§6Membro da equipe " + player.getName() + " autenticado");
    
    // Registrar autenticação bem-sucedida
    logSuccessfulAuth(player.getUniqueId(), usedCode);
}

Melhores Práticas

  1. Verificar Disponibilidade da API - Sempre verifique se o plugin está carregado antes de usar a API através do registro do provedor de serviços.

  2. Lidar com Retornos Nulos - O método getPlayer() pode retornar null, sempre verifique antes de acessar propriedades.

  3. Tratamento de Eventos Assíncronos - AsyncStaffSentCodeEvent é executado em thread assíncrona, evite operações síncronas sem agendamento de tarefas apropriado.

  4. Compreensão do Cache - A API funciona com dados em cache; membros da equipe recém-adicionados podem não aparecer imediatamente.

  5. Verificação de Código - Armazene códigos de autenticação para fins de auditoria e para evitar ataques de força bruta.

  6. Verificação de Status - Use isCached() para verificar se um jogador precisa de autenticação antes de tentar fluxos de autenticação.

  7. Escuta de Eventos - Ouça ambos os eventos para ter visibilidade completa do ciclo de vida da autenticação.

Exemplos de Código

Exemplo 1: Verificar Status de Autenticação do Staff

public void checkStaffStatus(String playerName) {
    StaffLoginAPI api = new StaffLoginAPI();
    StaffHolder staff = api.getPlayer(playerName);
    
    if (staff == null) {
        System.out.println("Não é um membro da equipe");
        return;
    }
    
    if (staff.logado) {
        System.out.println("Staff autenticado");
    } else {
        System.out.println("Staff não autenticado");
    }
}

Exemplo 2: Ouvinte de Auditoria de Autenticação

public class StaffAuthAuditListener implements Listener {
    private final Map<UUID, Long> lastAttempt = new HashMap<>();
    
    @EventHandler
    public void onCodeSent(AsyncStaffSentCodeEvent event) {
        UUID uuid = event.getPlayer().getUniqueId();
        long now = System.currentTimeMillis();
        
        // Registrar tentativa
        System.out.println("[AUTH] Código enviado para " + event.getPlayer().getName());
        
        lastAttempt.put(uuid, now);
    }
    
    @EventHandler
    public void onAuthSuccess(StaffSuccessAuthEvent event) {
        UUID uuid = event.getPlayer().getUniqueId();
        Long lastAttemptTime = lastAttempt.get(uuid);
        
        long timeTaken = System.currentTimeMillis() - lastAttemptTime;
        System.out.println("[AUTH] " + event.getPlayer().getName() + 
                          " autenticado em " + timeTaken + "ms");
    }
}

Exemplo 3: Conceder Permissões na Autenticação

public class StaffPermissionManager implements Listener {
    private final Plugin plugin;
    
    public StaffPermissionManager(Plugin plugin) {
        this.plugin = plugin;
    }
    
    @EventHandler
    public void onAuthSuccess(StaffSuccessAuthEvent event) {
        Player player = event.getPlayer();
        
        // Adicionar permissões de staff
        PermissionAttachment attachment = player.addAttachment(plugin);
        attachment.setPermission("staff.access", true);
        attachment.setPermission("staff.commands.warn", true);
        attachment.setPermission("staff.commands.kick", true);
        attachment.setPermission("staff.commands.ban", true);
        
        // Notificar jogador
        player.sendMessage("§6Você foi autenticado como staff");
    }
}

Exemplo 4: Prevenir Acesso Não Autorizado

public void verifyStaffAccess(Player player) throws UnauthorizedAccessException {
    StaffLoginAPI api = new StaffLoginAPI();
    StaffHolder staff = api.getPlayer(player.getName());
    
    if (staff == null) {
        throw new UnauthorizedAccessException("Não é um membro da equipe");
    }
    
    if (!staff.logado) {
        throw new UnauthorizedAccessException("Staff não autenticado");
    }
    
    // Acesso concedido
    System.out.println("Acesso concedido a " + player.getName());
}

private static class UnauthorizedAccessException extends Exception {
    UnauthorizedAccessException(String message) {
        super(message);
    }
}

Exemplo 5: Monitorar Taxa de Autenticação

public class AuthenticationRateMonitor implements Listener {
    private final Map<UUID, List<Long>> authAttempts = new HashMap<>();
    private final int maxAttemptsPerMinute = 5;
    
    @EventHandler
    public void onCodeSent(AsyncStaffSentCodeEvent event) {
        UUID uuid = event.getPlayer().getUniqueId();
        long now = System.currentTimeMillis();
        
        authAttempts.computeIfAbsent(uuid, k -> new ArrayList<>()).add(now);
        
        // Limpar tentativas antigas
        authAttempts.get(uuid).removeIf(time -> now - time > 60000);
        
        int recentAttempts = authAttempts.get(uuid).size();
        if (recentAttempts > maxAttemptsPerMinute) {
            System.out.println("§cAviso de limite de taxa para " + event.getPlayer().getName());
        }
    }
}

Exemplo 6: Gerenciamento de Sessão

public class StaffSessionManager implements Listener {
    private final Map<UUID, Long> sessions = new HashMap<>();
    
    @EventHandler
    public void onAuthSuccess(StaffSuccessAuthEvent event) {
        sessions.put(event.getPlayer().getUniqueId(), System.currentTimeMillis());
        System.out.println("Sessão iniciada: " + event.getPlayer().getName());
    }
    
    public long getSessionDuration(UUID uuid) {
        Long startTime = sessions.get(uuid);
        if (startTime == null) return -1;
        return System.currentTimeMillis() - startTime;
    }
}

Exemplo 7: Manipulador de Callback de Autenticação

public class AuthenticationCallback {
    public void handleAuthenticationProcess(Player player) {
        StaffLoginAPI api = new StaffLoginAPI();
        
        // Verificar se o jogador precisa de autenticação
        if (api.isCached(player.getName())) {
            System.out.println("Iniciando autenticação para " + player.getName());
            // A autenticação será enviada, eventos serão disparados
        } else {
            StaffHolder staff = api.getPlayer(player.getName());
            if (staff != null && staff.logado) {
                System.out.println("Já autenticado: " + player.getName());
            } else {
                System.out.println("Não é um membro da equipe: " + player.getName());
            }
        }
    }
}

Exemplo 8: Painel de Status de Autenticação

public void displayAuthStatus() {
    StaffLoginAPI api = new StaffLoginAPI();
    List<String> staffMembers = getStaffList(); // Seu método
    
    System.out.println("=== Status de Autenticação da Staff ===");
    for (String staff : staffMembers) {
        StaffHolder holder = api.getPlayer(staff);
        
        if (holder == null) {
            System.out.println(staff + " - NÃO EM CACHE");
        } else if (holder.logado) {
            System.out.println(staff + " - AUTENTICADO");
        } else {
            System.out.println(staff + " - PRECISA DE AUTENTICAÇÃO");
        }
    }
}

Exemplo 9: Manipulador de Autenticação Assíncrona

public class AsyncAuthHandler implements Listener {
    private final Plugin plugin;
    
    public AsyncAuthHandler(Plugin plugin) {
        this.plugin = plugin;
    }
    
    @EventHandler
    public void onCodeSent(AsyncStaffSentCodeEvent event) {
        // Isto é assíncrono, agende uma tarefa síncrona se necessário
        Bukkit.getScheduler().runTask(plugin, () -> {
            Player player = event.getPlayer();
            if (player.isOnline()) {
                player.sendTitle("§6Autenticação", "§eVerifique seu DM do Discord");
            }
        });
    }
}

Exemplo 10: Exemplo de Integração Completa

public class StaffLoginIntegration implements Listener {
    private final Plugin plugin;
    private final StaffLoginAPI api;
    
    public StaffLoginIntegration(Plugin plugin) {
        this.plugin = plugin;
        this.api = new StaffLoginAPI();
    }
    
    public void onPlayerJoin(Player player) {
        // Verificar se o jogador é staff e precisa de autenticação
        if (api.isCached(player.getName())) {
            player.sendMessage("§6Por favor, autentique usando o código enviado para você");
            // O código será enviado pelo plugin
        }
    }
    
    @EventHandler
    public void onAuthSuccess(StaffSuccessAuthEvent event) {
        Player player = event.getPlayer();
        StaffHolder staff = api.getPlayer(player.getName());
        
        if (staff != null) {
            // Conceder modo staff
            player.setGameMode(GameMode.SPECTATOR);
            player.sendMessage("§6Você está agora no modo staff");
            
            // Registrar autenticação bem-sucedida
            System.out.println("[STAFF] " + player.getName() + 
                              " autenticado em " + new Date());
        }
    }
    
    @EventHandler
    public void onCodeSent(AsyncStaffSentCodeEvent event) {
        // Rastrear tentativas de autenticação para segurança
        System.out.println("[AUTH] Código enviado para " + event.getPlayer().getName());
    }
}

Nesta página