LogoyStore

API

A API fornece uma interface pública para desenvolvedores integrarem seus plugins ao sistema de VIPs do yVips, permitindo consultar dados de usuários VIPs, gerenciar chaves VIP e acessar informações de associações VIP de forma assíncrona.

Obtendo a instância da API

A API é exposta através de um BukkitService assim como feito comumente no Vault.

Exemplo:

VipAPIHolder vipAPI;

try {
  RegisteredServiceProvider<VipAPIHolder> rsp = Bukkit.getServer().getServicesManager().getRegistration(VipAPIHolder.class);
  return rsp == null ? null : (VipAPIHolder)rsp.getProvider();
} catch (Throwable t) {
  return null;
}

Métodos disponíveis

hasUser(String name)

Verifica se um usuário existe no banco de dados.

CompletableFuture<Boolean> future = vipAPI.hasUser("Player1");
future.thenAccept(exists -> {
    if (exists) {
        System.out.println("Usuário existe!");
    }
});

Parâmetros:

  • name - Nome do jogador (convertido automaticamente para minúsculas)

Retorno:

  • CompletableFuture<Boolean> - Operação assíncrona que retorna true se o usuário existe

Observações:

  • Nome é automaticamente convertido para minúsculas
  • Executa em thread assíncrona
  • Use .thenAccept() ou .join() para obter o resultado

getUser(String name)

Obtém os dados completos de um usuário.

CompletableFuture<UserHolder> future = vipAPI.getUser("Player1");
future.thenAccept(user -> {
    if (user != null) {
        System.out.println("Usuário encontrado!");
    }
});

Parâmetros:

  • name - Nome do jogador

Retorno:

  • CompletableFuture<UserHolder> - Operação assíncrona contendo dados do usuário ou null

Observações:

  • Nome é automaticamente convertido para minúsculas
  • Retorna null se o usuário não existir
  • Executa em thread assíncrona

getVip(String name)

Obtém os dados de um VIP pelo nome.

CompletableFuture<VipHolder> future = vipAPI.getVip("VIP_Gold");
future.thenAccept(vip -> {
    if (vip != null) {
        System.out.println("VIP encontrado: " + vip.getId());
    }
});

Parâmetros:

  • name - Nome ou identificador do VIP

Retorno:

  • CompletableFuture<VipHolder> - Operação assíncrona contendo dados do VIP ou null

Observações:

  • Busca pelo nome exato do VIP
  • Retorna null se o VIP não existir
  • Executa em thread assíncrona

getVipById(String name)

Obtém um VIP pelo seu ID único.

CompletableFuture<VipHolder> future = vipAPI.getVipById("gold_001");
future.thenAccept(vip -> {
    if (vip != null) {
        System.out.println("VIP encontrado por ID!");
    }
});

Parâmetros:

  • name - ID único do VIP

Retorno:

  • CompletableFuture<VipHolder> - Operação assíncrona contendo o VIP ou null

Observações:

  • Busca é case-insensitive
  • Carrega todos os VIPs e filtra por ID
  • Mais pesado que getVip() - use com cuidado em operações frequentes
  • Executa em thread assíncrona

hasKey(String name)

Verifica se uma chave VIP existe.

CompletableFuture<Boolean> future = vipAPI.hasKey("CHAVE123ABC");
future.thenAccept(exists -> {
    if (exists) {
        System.out.println("Chave existe!");
    }
});

Parâmetros:

  • name - Código da chave (convertido automaticamente para minúsculas)

Retorno:

  • CompletableFuture<Boolean> - Operação assíncrona que retorna true se a chave existe

Observações:

  • Código é automaticamente convertido para minúsculas
  • Executa em thread assíncrona

getKey(String name)

Obtém os dados de uma chave VIP.

CompletableFuture<VipKeyHolder> future = vipAPI.getKey("CHAVE123ABC");
future.thenAccept(key -> {
    if (key != null) {
        System.out.println("Chave encontrada!");
    }
});

Parâmetros:

  • name - Código da chave

Retorno:

  • CompletableFuture<VipKeyHolder> - Operação assíncrona contendo dados da chave ou null

Observações:

  • Código é automaticamente convertido para minúsculas
  • Retorna null se a chave não existir
  • Executa em thread assíncrona

hasUserKey(String name)

Verifica se um usuário possui uma chave VIP associada.

CompletableFuture<Boolean> future = vipAPI.hasUserKey("Player1");
future.thenAccept(hasKey -> {
    if (hasKey) {
        System.out.println("Usuário possui chave!");
    }
});

Parâmetros:

  • name - Nome do jogador (convertido automaticamente para minúsculas)

Retorno:

  • CompletableFuture<Boolean> - Operação assíncrona que retorna true se o usuário tem chave

Observações:

  • Nome é automaticamente convertido para minúsculas
  • Executa em thread assíncrona

getUserKey(String name)

Obtém a chave VIP associada a um usuário.

CompletableFuture<UserKeyHolder> future = vipAPI.getUserKey("Player1");
future.thenAccept(userKey -> {
    if (userKey != null) {
        System.out.println("Chave do usuário encontrada!");
    }
});

Parâmetros:

  • name - Nome do jogador

Retorno:

  • CompletableFuture<UserKeyHolder> - Operação assíncrona contendo dados da chave do usuário ou null

Observações:

  • Nome é automaticamente convertido para minúsculas
  • Retorna null se o usuário não tiver chave associada
  • Executa em thread assíncrona

Estrutura de dados

UserHolder

Representa um usuário do sistema VIP.

Principais propriedades:

  • Nome do jogador
  • UUID
  • Status VIP
  • Data de expiração (se aplicável)
  • Permissões associadas
  • Histórico de compras

VipHolder

Representa um tipo/nível de VIP disponível no servidor.

Principais propriedades:

  • ID único do VIP
  • Nome do VIP
  • Descrição
  • Duração (em dias)
  • Preço
  • Permissões incluídas
  • Bônus associados

VipKeyHolder

Representa uma chave/código VIP gerada para distribuição.

Principais propriedades:

  • Código da chave
  • Tipo de VIP associado
  • Data de geração
  • Status (usado/não usado)
  • Usuário que resgatou (se aplicável)

UserKeyHolder

Representa a associação de uma chave com um usuário.

Principais propriedades:

  • Chave resgatada
  • Usuário que resgatou
  • Data do resgate
  • VIP ativado

Melhores práticas

  1. Sempre use CompletableFuture - Todas as operações são assíncronas, não bloqueie a thread principal
  2. Trate exceções adequadamente - Use .exceptionally() ou .handle() para tratamento de erros
  3. Valide resultados null - Sempre verifique se o objeto retornado é null antes de usar
  4. Cache resultados quando apropriado - Para operações frequentes, considere cachear dados
  5. Use .thenAccept() para operações sem retorno - Mais eficiente que .join()
  6. Evite .join() na thread principal - Pode causar lag se a operação demorar
  7. Use .join() apenas em tarefas assíncronas - Nunca na thread principal do servidor
  8. Implemente timeouts - Use orTimeout() para evitar operações infinitas
  9. Log adequadamente - Registre erros e operações importantes
  10. Documente suas integrações - Mantenha registro das modificações realizadas pela sua API

Exemplos de uso

Verificar se jogador é VIP

vipAPI.hasUser("Player1").thenAccept(exists -> {
    if (exists) {
        System.out.println("Player1 é um usuário registrado!");
    } else {
        System.out.println("Player1 ainda não é registrado!");
    }
});

Obter dados de usuário VIP

vipAPI.getUser("Player1").thenAccept(user -> {
    if (user != null) {
        System.out.println("Usuário: " + user.getName());
        System.out.println("UUID: " + user.getUUID());
    } else {
        System.out.println("Usuário não encontrado!");
    }
}).exceptionally(error -> {
    System.err.println("Erro ao buscar usuário: " + error.getMessage());
    return null;
});

Verificar tipo de VIP do jogador

vipAPI.getVip("VIP_Gold").thenAccept(vip -> {
    if (vip != null) {
        System.out.println("VIP: " + vip.getId());
        System.out.println("Duração: " + vip.getDuration() + " dias");
    }
}).orTimeout(5, java.util.concurrent.TimeUnit.SECONDS);

Validar chave VIP

vipAPI.hasKey("CHAVE123ABC").thenAccept(exists -> {
    if (exists) {
        vipAPI.getKey("CHAVE123ABC").thenAccept(key -> {
            System.out.println("Chave válida!");
            System.out.println("Tipo de VIP: " + key.getVipType());
        });
    } else {
        System.out.println("Chave inválida!");
    }
});

Resgatar chave para jogador

public void resgatar(Player player, String codigoChave) {
    vipAPI.getKey(codigoChave).thenAccept(key -> {
        if (key != null && !key.isUsed()) {
            // Chave válida e não foi usada
            vipAPI.getUserKey(player.getName()).thenAccept(userKey -> {
                if (userKey == null) {
                    // Jogador ainda não resgatou nenhuma chave
                    player.sendMessage("§aChave resgatada com sucesso!");
                    // Lógica de resgate aqui
                } else {
                    player.sendMessage("§cVocê já resgatou uma chave!");
                }
            });
        } else {
            player.sendMessage("§cChave inválida ou já foi usada!");
        }
    });
}

Sincronizar dados de VIP em tempo real

public class VipSyncTask extends BukkitRunnable {
    private VipAPIHolder vipAPI;
    
    public VipSyncTask(VipAPIHolder vipAPI) {
        this.vipAPI = vipAPI;
    }
    
    @Override
    public void run() {
        for (Player player : Bukkit.getOnlinePlayers()) {
            vipAPI.getUser(player.getName())
                .thenAccept(user -> {
                    if (user != null) {
                        atualizarPermissoes(player, user);
                    }
                })
                .exceptionally(error -> {
                    Bukkit.getLogger().warning("Erro ao sincronizar VIP: " + error.getMessage());
                    return null;
                });
        }
    }
    
    private void atualizarPermissoes(Player player, UserHolder user) {
        // Atualizar permissões do jogador baseado no VIP
    }
}

// Executar a cada 10 minutos
new VipSyncTask(vipAPI).runTaskTimerAsynchronously(plugin, 0, 12000);

Gerar relatório de chaves VIP

public void gerarRelatório() {
    List<String> chaves = new ArrayList<>();
    
    // Este é um exemplo simplificado
    // Em produção, você precisaria de um método para listar todas as chaves
    
    Bukkit.getLogger().info("=== Relatório de Chaves VIP ===");
    Bukkit.getLogger().info("Total de chaves: " + chaves.size());
}

Integrar com comando de admin

@Command(name = "vpiadmin")
public void vipAdminCommand(CommandSender sender, String[] args) {
    if (args.length < 2) {
        sender.sendMessage("§cUso: /vpiadmin check <jogador>");
        return;
    }
    
    String player = args[1];
    
    vipAPI.getUser(player).thenAccept(user -> {
        if (user != null) {
            sender.sendMessage("§e=== Dados do VIP ===");
            sender.sendMessage("§eJogador: §f" + user.getName());
            sender.sendMessage("§eUUID: §f" + user.getUUID());
            sender.sendMessage("§eVIP Ativo: §f" + user.isVip());
            
            vipAPI.getUserKey(player).thenAccept(userKey -> {
                if (userKey != null) {
                    sender.sendMessage("§eChave: §f" + userKey.getKeyCode());
                }
            });
        } else {
            sender.sendMessage("§cJogador não encontrado!");
        }
    }).exceptionally(error -> {
        sender.sendMessage("§cErro ao buscar dados: " + error.getMessage());
        return null;
    });
}

Implementar listeners para eventos VIP

public class VipEventListener implements Listener {
    private VipAPIHolder vipAPI;
    
    public VipEventListener(VipAPIHolder vipAPI) {
        this.vipAPI = vipAPI;
    }
    
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        
        vipAPI.getUser(player.getName()).thenAccept(user -> {
            if (user != null && user.isVip()) {
                player.sendMessage("§e§lBem-vindo VIP!");
                
                // Dar bônus de login
                player.addPotionEffect(new PotionEffect(
                    PotionEffectType.SPEED, 
                    3600, 
                    1
                ));
            }
        });
    }
}

Validar acesso à API

public VipAPIHolder obterVipAPI() {
    try {
        RegisteredServiceProvider<VipAPIHolder> rsp = 
            Bukkit.getServer().getServicesManager()
                  .getRegistration(VipAPIHolder.class);
        
        if (rsp == null) {
            Bukkit.getLogger().warning("yVips não está instalado!");
            return null;
        }
        
        return rsp.getProvider();
    } catch (Throwable t) {
        Bukkit.getLogger().severe("Erro ao obter VipAPI: " + t.getMessage());
        return null;
    }
}

Tratamento robusto com CompletableFuture

public void buscarDadosVip(String jogador) {
    vipAPI.getUser(jogador)
        .orTimeout(5, java.util.concurrent.TimeUnit.SECONDS)
        .handle((user, error) -> {
            if (error != null) {
                System.err.println("Erro ou timeout: " + error.getMessage());
                return null;
            }
            
            if (user != null) {
                System.out.println("Usuário encontrado: " + user.getName());
                
                // Continuar com busca de chave
                return vipAPI.getUserKey(jogador)
                    .orTimeout(5, java.util.concurrent.TimeUnit.SECONDS);
            }
            
            return null;
        })
        .thenAccept(key -> {
            if (key != null) {
                System.out.println("Chave encontrada!");
            }
        });
}

Nesta página