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 retornatruese 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 ounull
Observações:
- Nome é automaticamente convertido para minúsculas
- Retorna
nullse 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 ounull
Observações:
- Busca pelo nome exato do VIP
- Retorna
nullse 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 ounull
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 retornatruese 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 ounull
Observações:
- Código é automaticamente convertido para minúsculas
- Retorna
nullse 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 retornatruese 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 ounull
Observações:
- Nome é automaticamente convertido para minúsculas
- Retorna
nullse 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
- Sempre use CompletableFuture - Todas as operações são assíncronas, não bloqueie a thread principal
- Trate exceções adequadamente - Use
.exceptionally()ou.handle()para tratamento de erros - Valide resultados null - Sempre verifique se o objeto retornado é
nullantes de usar - Cache resultados quando apropriado - Para operações frequentes, considere cachear dados
- Use
.thenAccept()para operações sem retorno - Mais eficiente que.join() - Evite
.join()na thread principal - Pode causar lag se a operação demorar - Use
.join()apenas em tarefas assíncronas - Nunca na thread principal do servidor - Implemente timeouts - Use
orTimeout()para evitar operações infinitas - Log adequadamente - Registre erros e operações importantes
- 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!");
}
});
}