🌐 eeDomainInfo API

ΠœΠΎΡ‰Π½Ρ‹ΠΉ API для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠΌ eeDomainInfo

Автор: tyulpan
Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π°: Velocity, BungeeCord, NullCordX


πŸš€ Быстрый старт

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ API

βŽ—
βœ“
1
2
3
4
5
6
7
8
DomainInfoAPI api = DomainInfoAPI.getInstance();

if (api == null || !api.isAvailable()) {
    System.out.println("eeDomainInfo ΠΏΠ»Π°Π³ΠΈΠ½ Π½Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½!");
    return;
}

System.out.println("API Π³ΠΎΡ‚ΠΎΠ² ΠΊ использованию!");

Основная информация

βŽ—
βœ“
1
2
3
String apiVersion = api.getAPIVesion();        
String pluginVersion = api.getPluginVersion();  
boolean available = api.isAvailable();          // true/false

🌐 Π Π°Π±ΠΎΡ‚Π° с Π΄ΠΎΠΌΠ΅Π½Π°ΠΌΠΈ (api.domains())

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²

βŽ—
βœ“
1
2
3
4
5
6
Map<String, Integer> domains = api.domains().getActiveDomains();
// Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: {"example.com": 5, "test.net": 2, "demo.org": 1}

domains.forEach((domain, online) -> {
    System.out.println(domain + ": " + online + " ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²");
});

Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ Π΄ΠΎΠΌΠ΅Π½Π΅

βŽ—
βœ“
Optional<DomainInfo> info = api.domains().getDomainInfo("example.com");

if (info.isPresent()) {
    DomainInfo domain = info.get();

    System.out.println("Π”ΠΎΠΌΠ΅Π½: " + domain.getDomain());              // "example.com"
    System.out.println("Онлайн: " + domain.getCurrentOnline());      // 5
    System.out.println("Π˜Π³Ρ€ΠΎΠΊΠΈ: " + domain.getOnlinePlayers());      // ["Player1", "Player2"]
    System.out.println("АктивСн: " + domain.isActive());             // true
    System.out.println("ΠΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ: " + domain.getLastActivity());   // 2025-01-01T12:00:00
}

Бтатистика Π΄ΠΎΠΌΠ΅Π½Π°

βŽ—
βœ“
// ВСкущая статистика
api.domains().getDomainStats("example.com").thenAccept(stats -> {
    System.out.println("Онлайн (сСрвис): " + stats.getCurrentOnline());    // 5
    System.out.println("Онлайн (Π‘Π”): " + stats.getDatabaseOnline());        // 5
    System.out.println("Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ: " + stats.isSynced());            // true
});

// Бтатистика Π·Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ (7 Π΄Π½Π΅ΠΉ)
api.domains().getDomainStats("example.com", 7).thenAccept(stats -> {
    System.out.println("ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π·Π° нСдСлю: " + stats.getTotalConnections()); // 150
    System.out.println("Π£Π½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²: " + stats.getUniquePlayers());       // 45
});

Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ для Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²

βŽ—
βœ“
// Бписок ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² Π½Π° Π΄ΠΎΠΌΠ΅Π½Π΅
List<String> players = api.domains().getPlayersOnDomain("example.com");

// ΠžΠ±Ρ‰ΠΈΠΉ ΠΎΠ½Π»Π°ΠΉΠ½
int totalOnline = api.domains().getTotalOnline();

// Онлайн ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Π΄ΠΎΠΌΠ΅Π½Π°
int domainOnline = api.domains().getDomainOnline("example.com");

// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования
boolean exists = api.domains().domainExists("example.com");

// Валидация Π΄ΠΎΠΌΠ΅Π½Π°
boolean valid = api.domains().isValidDomain("example.com");

πŸ‘€ Π Π°Π±ΠΎΡ‚Π° с ΠΈΠ³Ρ€ΠΎΠΊΠ°ΠΌΠΈ (api.players())

Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΎΠ± ΠΈΠ³Ρ€ΠΎΠΊΠ΅

βŽ—
βœ“
// Поиск ΠΏΠΎ Π½ΠΈΠΊΡƒ
api.players().getPlayerInfo("Player1").thenAccept(playerOpt -> {
    if (playerOpt.isPresent()) {
        PlayerInfo player = playerOpt.get();

        System.out.println("Ник: " + player.getPlayerName());         // "Player1"
        System.out.println("UUID: " + player.getPlayerUuid());        // UUID
        System.out.println("Π”ΠΎΠΌΠ΅Π½: " + player.getCurrentDomain());    // "example.com"
        System.out.println("IP: " + player.getLastKnownIP());         // "192.168.1.1"
        System.out.println("ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π²Ρ…ΠΎΠ΄: " + player.getFirstJoin());  // LocalDateTime
        System.out.println("ПослСдний Π²Ρ…ΠΎΠ΄: " + player.getLastJoin()); // LocalDateTime
        System.out.println("ВсСго Π²Ρ…ΠΎΠ΄ΠΎΠ²: " + player.getTotalJoins()); // 25
        System.out.println("Онлайн: " + player.isOnline());           // true
    }
});

// Поиск по UUID
UUID playerUUID = UUID.fromString("...");
api.players().getPlayerInfo(playerUUID).thenAccept(playerOpt -> {
    // Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ
});

Π£Ρ‚ΠΈΠ»ΠΈΡ‚Ρ‹ для ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²

βŽ—
βœ“
// Π”ΠΎΠΌΠ΅Π½ ΠΈΠ³Ρ€ΠΎΠΊΠ°
Optional<String> domain = api.players().getPlayerDomain("Player1");
if (domain.isPresent()) {
    System.out.println("Player1 ΠΈΠ³Ρ€Π°Π΅Ρ‚ Π½Π°: " + domain.get());
}

// ВсС ΠΎΠ½Π»Π°ΠΉΠ½ ΠΈΠ³Ρ€ΠΎΠΊΠΈ
List<String> allPlayers = api.players().getOnlinePlayers();

// ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΎΠ½Π»Π°ΠΉΠ½Π°
boolean online = api.players().isPlayerOnline("Player1");

πŸ“Š Бтатистика (api.stats())

Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Π°Ρ статистика

βŽ—
βœ“
api.stats().getGlobalStats().thenAccept(stats -> {
    System.out.println("ΠžΠ±Ρ‰ΠΈΠΉ ΠΎΠ½Π»Π°ΠΉΠ½: " + stats.getTotalOnline());           // 15
    System.out.println("ВсСго Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²: " + stats.getTotalDomains());         // 3
    System.out.println("Π˜Π³Ρ€ΠΎΠΊΠΎΠ² Π² Π‘Π”: " + stats.getTotalPlayersInDatabase()); // 1250
    System.out.println("ΠŸΠΎΠΏΡƒΠ»ΡΡ€Π½Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½: " + stats.getMostPopularDomain()); // "example.com"

    // РаспрСдСлСниС ΠΏΠΎ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌ
    Map<String, Integer> distribution = stats.getDomainDistribution();
    distribution.forEach((domain, count) -> {
        System.out.println(domain + ": " + count + " ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²");
    });
});

Π’ΠΎΠΏ Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²

βŽ—
βœ“
// Π’ΠΎΠΏ ΠΏΠΎ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ ΠΎΠ½Π»Π°ΠΉΠ½Ρƒ
api.stats().getTopDomainsByOnline(5).thenAccept(top -> {
    System.out.println("Π’ΠΎΠΏ 5 Π΄ΠΎΠΌΠ΅Π½ΠΎΠ² ΠΏΠΎ ΠΎΠ½Π»Π°ΠΉΠ½Ρƒ:");
    top.forEach((domain, online) -> {
        System.out.println(domain + ": " + online + " ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²");
    });
    // Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚: {"example.com": 10, "test.net": 5, "demo.org": 2}
});

// Π’ΠΎΠΏ ΠΏΠΎ ΠΎΠ±Ρ‰Π΅ΠΌΡƒ количСству ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ
api.stats().getTopDomainsByConnections(5).thenAccept(top -> {
    System.out.println("Π’ΠΎΠΏ 5 Π΄ΠΎΠΌΠ΅Π½ΠΎΠ² ΠΏΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌ:");
    top.forEach((domain, connections) -> {
        System.out.println(domain + ": " + connections + " ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ");
    });
});

Бинхронизация Π΄Π°Π½Π½Ρ‹Ρ…

βŽ—
βœ“
1
2
3
api.stats().syncData().thenRun(() -> {
    System.out.println("Π”Π°Π½Π½Ρ‹Π΅ сСрвиса ΠΈ Π‘Π” синхронизированы!");
});

🎯 Бобытия (api.events())

Бобытия Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²

βŽ—
βœ“
api.events().registerDomainListener(new DomainEventListener() {
    @Override
    public void onPlayerJoinDomain(DomainPlayerJoinEvent event) {
        String player = event.getPlayerName();        // "Player1"
        String domain = event.getDomain();            // "example.com"
        String ip = event.getPlayerIP();              // "192.168.1.1"
        LocalDateTime time = event.getTimestamp();    // 2025-01-01T12:00:00
        int newCount = event.getNewOnlineCount();     // 6

        System.out.println("🟒 " + player + " ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ ΠΊ " + domain);

        // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π² Discord
        sendDiscordWebhook("🟒 **" + player + "** ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ ΠΊ `" + domain + "`");
    }

    @Override
    public void onPlayerLeaveDomain(DomainPlayerLeaveEvent event) {
        System.out.println("πŸ”΄ " + event.getPlayerName() + " ΠΏΠΎΠΊΠΈΠ½ΡƒΠ» " + event.getDomain());

        // ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π² Discord
        sendDiscordWebhook("πŸ”΄ **" + event.getPlayerName() + "** ΠΏΠΎΠΊΠΈΠ½ΡƒΠ» `" + event.getDomain() + "`");
    }
});

Бобытия ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²

βŽ—
βœ“
api.events().registerPlayerListener(new PlayerEventListener() {
    @Override
    public void onPlayerConnect(PlayerConnectEvent event) {
        String player = event.getPlayerName();        // "Player1"
        UUID uuid = event.getPlayerUuid();           // UUID
        String domain = event.getDomain();            // "example.com"
        String ip = event.getPlayerIP();              // "192.168.1.1"
        LocalDateTime time = event.getTimestamp();    // 2025-01-01T12:00:00
        boolean firstJoin = event.isFirstJoin();      // false

        System.out.println("πŸ‘€ НовоС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅: " + player + " (" + uuid + ")");

        // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° VPN
        if (isVPN(ip)) {
            System.out.println("⚠️ Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ VPN: " + ip);
        }

        // Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
        logToFile("CONNECT", player, domain, ip);
    }

    @Override
    public void onPlayerDisconnect(PlayerDisconnectEvent event) {
        long sessionMs = event.getSessionDuration();  // врСмя сСссии Π² миллисСкундах
        long sessionMin = sessionMs / 1000 / 60;      // Π² ΠΌΠΈΠ½ΡƒΡ‚Π°Ρ…

        System.out.println("πŸ‘€ ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅: " + event.getPlayerName() + 
                          " (сСссия: " + sessionMin + " мин)");

        // ОбновлСниС вСб-панСли
        updateWebStats();
    }

    @Override
    public void onPlayerSwitchDomain(PlayerSwitchDomainEvent event) {
        String from = event.getFromDomain();          // "old.com"
        String to = event.getToDomain();              // "new.com"

        System.out.println("πŸ”„ " + event.getPlayerName() + 
                          " ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ: " + from + " β†’ " + to);
    }
});

ΠžΡ‚ΠΌΠ΅Π½Π° рСгистрации

βŽ—
βœ“
DomainEventListener domainListener = new DomainEventListener() { /* ... */ };
PlayerEventListener playerListener = new PlayerEventListener() { /* ... */ };

// РСгистрация
api.events().registerDomainListener(domainListener);
api.events().registerPlayerListener(playerListener);

// ΠžΡ‚ΠΌΠ΅Π½Π° рСгистрации
api.events().unregisterDomainListener(domainListener);
api.events().unregisterPlayerListener(playerListener);

πŸ’‘ ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования

πŸ€– Discord Π±ΠΎΡ‚ с увСдомлСниями

βŽ—
βœ“
public class DiscordIntegration {
    private final String webhookUrl = "https://discord.com/api/webhooks/...";

    public void setupBot() {
        DomainInfoAPI api = DomainInfoAPI.getInstance();

        api.events().registerDomainListener(new DomainEventListener() {
            @Override
            public void onPlayerJoinDomain(DomainPlayerJoinEvent event) {
                // ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΡƒΡŽ статистику
                api.domains().getDomainInfo(event.getDomain()).ifPresent(info -> {
                    String embed = createDiscordEmbed(
                        "НовоС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅",
                        "**Π˜Π³Ρ€ΠΎΠΊ:** " + event.getPlayerName() + "\n" +
                        "**Π”ΠΎΠΌΠ΅Π½:** " + event.getDomain() + "\n" +
                        "**Онлайн на домСнС:** " + info.getCurrentOnline(),
                        0x00FF00 // Π·Π΅Π»Π΅Π½Ρ‹ΠΉ
                    );
                    sendWebhook(embed);
                });
            }
        });

        // Бтатистика ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 5 ΠΌΠΈΠ½ΡƒΡ‚
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(() -> {
            api.stats().getGlobalStats().thenAccept(stats -> {
                String embed = createDiscordEmbed(
                    "πŸ“Š Бтатистика сСрвСра",
                    "**ΠžΠ±Ρ‰ΠΈΠΉ ΠΎΠ½Π»Π°ΠΉΠ½:** " + stats.getTotalOnline() + "\n" +
                    "**Активных Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²:** " + stats.getTotalDomains() + "\n" +
                    "**ΠŸΠΎΠΏΡƒΠ»ΡΡ€Π½Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½:** " + stats.getMostPopularDomain(),
                    0xFFAA00 // ΠΎΡ€Π°Π½ΠΆΠ΅Π²Ρ‹ΠΉ
                );
                sendWebhook(embed);
            });
        }, 5, 5, TimeUnit.MINUTES);
    }
}

🌐 Π’Π΅Π±-панСль с live обновлСниями

βŽ—
βœ“
public class WebPanelIntegration {
    private final Set<WebSocketSession> sessions = ConcurrentHashMap.newKeySet();

    public void setupWebPanel() {
        DomainInfoAPI api = DomainInfoAPI.getInstance();

        // ΠžΡ‚ΠΏΡ€Π°Π²Π»ΡΠ΅ΠΌ события Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ
        api.events().registerDomainListener(new DomainEventListener() {
            @Override
            public void onPlayerJoinDomain(DomainPlayerJoinEvent event) {
                Map<String, Object> data = Map.of(
                    "type", "player_join",
                    "player", event.getPlayerName(),
                    "domain", event.getDomain(),
                    "timestamp", event.getTimestamp().toString()
                );
                broadcastToWeb(data);
            }
        });

        // Бтатистика ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ 10 сСкунд
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(() -> {
            api.stats().getGlobalStats().thenAccept(stats -> {
                Map<String, Object> data = Map.of(
                    "type", "stats_update",
                    "totalOnline", stats.getTotalOnline(),
                    "domains", stats.getDomainDistribution(),
                    "timestamp", Instant.now().toString()
                );
                broadcastToWeb(data);
            });
        }, 0, 10, TimeUnit.SECONDS);
    }

    private void broadcastToWeb(Map<String, Object> data) {
        String json = convertToJSON(data);
        sessions.forEach(session -> {
            try {
                session.sendMessage(new TextMessage(json));
            } catch (Exception e) {
                sessions.remove(session);
            }
        });
    }
}

πŸ›‘οΈ БистСма бСзопасности

βŽ—
βœ“
public class SecuritySystem {
    private final Set<String> suspiciousIPs = ConcurrentHashMap.newKeySet();
    private final Map<String, Integer> connectionCounts = new ConcurrentHashMap<>();

    public void setupSecurity() {
        DomainInfoAPI api = DomainInfoAPI.getInstance();

        api.events().registerPlayerListener(new PlayerEventListener() {
            @Override
            public void onPlayerConnect(PlayerConnectEvent event) {
                String ip = event.getPlayerIP();
                String player = event.getPlayerName();

                // ΠŸΠΎΠ΄ΡΡ‡Π΅Ρ‚ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ с IP
                int connections = connectionCounts.merge(ip, 1, Integer::sum);

                // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° мноТСствСнныС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
                if (connections > 3) {
                    System.out.println("⚠️ ΠŸΠΎΠ΄ΠΎΠ·Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ с IP: " + ip + 
                                     " (" + connections + " ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ)");
                    suspiciousIPs.add(ip);
                    notifyAdmins("ΠŸΠΎΠ΄ΠΎΠ·Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ IP: " + ip + " (ΠΈΠ³Ρ€ΠΎΠΊ: " + player + ")");
                }

                // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° VPN (асинхронно)
                CompletableFuture.runAsync(() -> checkVPN(ip, player));

                // Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ всСх ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ
                logConnection(player, event.getDomain(), ip, event.getTimestamp());
            }

            @Override
            public void onPlayerDisconnect(PlayerDisconnectEvent event) {
                // ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° счСтчика Ρ‡Π΅Ρ€Π΅Π· 5 ΠΌΠΈΠ½ΡƒΡ‚
                ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
                scheduler.schedule(() -> {
                    connectionCounts.remove(event.getPlayerIP());
                }, 5, TimeUnit.MINUTES);
            }
        });
    }

    private void checkVPN(String ip, String player) {
        // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‡Π΅Ρ€Π΅Π· VPN API (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, IPQualityScore)
        boolean isVPN = callVPNAPI(ip);
        if (isVPN) {
            System.out.println("🚫 VPN ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½: " + player + " (" + ip + ")");
            notifyAdmins("VPN ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅: " + player + " с IP " + maskIP(ip));
        }
    }
}

πŸ“ˆ БистСма Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠΈ

βŽ—
βœ“
public class AnalyticsSystem {
    private final Map<String, DomainAnalytics> domainStats = new ConcurrentHashMap<>();

    public void setupAnalytics() {
        DomainInfoAPI api = DomainInfoAPI.getInstance();

        api.events().registerDomainListener(new DomainEventListener() {
            @Override
            public void onPlayerJoinDomain(DomainPlayerJoinEvent event) {
                String domain = event.getDomain();

                domainStats.computeIfAbsent(domain, k -> new DomainAnalytics())
                          .recordJoin(event.getTimestamp());

                // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ ΠΏΠΈΠΊΠΎΠ²Ρ‹Π΅ значСния
                api.domains().getDomainInfo(domain).ifPresent(info -> {
                    int currentOnline = info.getCurrentOnline();
                    DomainAnalytics analytics = domainStats.get(domain);

                    if (currentOnline > analytics.getPeakOnline()) {
                        analytics.setPeakOnline(currentOnline);
                        System.out.println("πŸŽ‰ Новый Ρ€Π΅ΠΊΠΎΡ€Π΄ для " + domain + ": " + currentOnline + " ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²!");

                        // Π£Π²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ Π² Discord
                        sendDiscordMessage("πŸŽ‰ **Новый Ρ€Π΅ΠΊΠΎΡ€Π΄!**\n" +
                                         "Π”ΠΎΠΌΠ΅Π½ `" + domain + "` достиг **" + currentOnline + "** ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² ΠΎΠ½Π»Π°ΠΉΠ½!");
                    }
                });
            }
        });

        // Π•ΠΆΠ΅Π΄Π½Π΅Π²Π½Ρ‹ΠΉ ΠΎΡ‚Ρ‡Π΅Ρ‚
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(this::generateDailyReport, 0, 24, TimeUnit.HOURS);
    }

    private void generateDailyReport() {
        DomainInfoAPI api = DomainInfoAPI.getInstance();

        api.stats().getGlobalStats().thenAccept(stats -> {
            StringBuilder report = new StringBuilder();
            report.append("πŸ“Š **Π•ΠΆΠ΅Π΄Π½Π΅Π²Π½Ρ‹ΠΉ ΠΎΡ‚Ρ‡Π΅Ρ‚**\n\n");
            report.append("**ΠžΠ±Ρ‰Π°Ρ статистика:**\n");
            report.append("β€’ ΠŸΠΈΠΊΠΎΠ²Ρ‹ΠΉ ΠΎΠ½Π»Π°ΠΉΠ½: ").append(stats.getTotalOnline()).append("\n");
            report.append("β€’ Активных Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²: ").append(stats.getTotalDomains()).append("\n");
            report.append("β€’ ΠŸΠΎΠΏΡƒΠ»ΡΡ€Π½Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½: ").append(stats.getMostPopularDomain()).append("\n\n");

            report.append("**Π’ΠΎΠΏ Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²:**\n");
            api.stats().getTopDomainsByOnline(5).thenAccept(top -> {
                top.forEach((domain, online) -> {
                    report.append("β€’ `").append(domain).append("`: ").append(online).append(" ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ²\n");
                });

                sendDiscordMessage(report.toString());
                saveReportToFile(report.toString());
            });
        });
    }
}

πŸ“‹ Π‘ΠΏΡ€Π°Π²ΠΎΡ‡Π½ΠΈΠΊ Data классов

DomainInfo

βŽ—
βœ“
1
2
3
4
5
6
7
public class DomainInfo {
    String getDomain()                    // НазваниС домСна
    int getCurrentOnline()                // Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ½Π»Π°ΠΉΠ½
    List<String> getOnlinePlayers()       // Бписок ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² ΠΎΠ½Π»Π°ΠΉΠ½
    boolean isActive()                    // АктивСн Π»ΠΈ Π΄ΠΎΠΌΠ΅Π½
    LocalDateTime getLastActivity()       // ВрСмя послСднСй активности
}

DomainStats

βŽ—
βœ“
1
2
3
4
5
6
7
8
public class DomainStats {
    String getDomain()                    // НазваниС домСна
    int getTotalConnections()             // ВсСго ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π·Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄
    int getUniqueePlayers()               // Π£Π½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² Π·Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄
    int getCurrentOnline()                // Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ½Π»Π°ΠΉΠ½ (сСрвис)
    int getDatabaseOnline()               // Онлайн Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…
    boolean isSynced()                    // Π‘ΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π»ΠΈ Π΄Π°Π½Π½Ρ‹Π΅
}

PlayerInfo

βŽ—
βœ“
public class PlayerInfo {
    String getPlayerName()                // Ник ΠΈΠ³Ρ€ΠΎΠΊΠ°
    UUID getPlayerUuid()                  // UUID ΠΈΠ³Ρ€ΠΎΠΊΠ°
    String getCurrentDomain()             // Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ Π΄ΠΎΠΌΠ΅Π½ (null Ссли ΠΎΡ„Ρ„Π»Π°ΠΉΠ½)
    String getLastKnownIP()               // ПослСдний извСстный IP
    LocalDateTime getFirstJoin()          // ВрСмя ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
    LocalDateTime getLastJoin()           // ВрСмя послСднСго ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
    int getTotalJoins()                   // ΠžΠ±Ρ‰Π΅Π΅ количСство ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ
    boolean isOnline()                    // Онлайн Π»ΠΈ ΠΈΠ³Ρ€ΠΎΠΊ сСйчас
}

PlayerHistory

βŽ—
βœ“
1
2
3
4
5
6
public class PlayerHistory {
    String getDomain()                    // Π”ΠΎΠΌΠ΅Π½ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
    String getPlayerIP()                  // IP адрСс
    LocalDateTime getJoinTime()           // ВрСмя ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
    int getTotalJoinsOnDomain()           // ВсСго ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΊ этому Π΄ΠΎΠΌΠ΅Π½Ρƒ
}

GlobalStats

βŽ—
βœ“
1
2
3
4
5
6
7
public class GlobalStats {
    int getTotalOnline()                  // ΠžΠ±Ρ‰ΠΈΠΉ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° всСх Π΄ΠΎΠΌΠ΅Π½Π°Ρ…
    int getTotalDomains()                 // ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… Π΄ΠΎΠΌΠ΅Π½ΠΎΠ²
    int getTotalPlayersInDatabase()       // ВсСго ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…
    Map<String, Integer> getDomainDistribution()  // РаспрСдСлСниС ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² ΠΏΠΎ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌ
    String getMostPopularDomain()         // Π‘Π°ΠΌΡ‹ΠΉ популярный Π΄ΠΎΠΌΠ΅Π½
}

🎯 Бобытия - ΠΏΠΎΠ»Π½Ρ‹ΠΉ список

DomainPlayerJoinEvent

βŽ—
βœ“
1
2
3
4
5
String getPlayerName()                   // Ник ΠΈΠ³Ρ€ΠΎΠΊΠ°
String getDomain()                       // Π”ΠΎΠΌΠ΅Π½
String getPlayerIP()                     // IP адрСс
LocalDateTime getTimestamp()             // ВрСмя события
int getNewOnlineCount()                  // НовоС количСство ΠΎΠ½Π»Π°ΠΉΠ½

DomainPlayerLeaveEvent

βŽ—
βœ“
1
2
3
4
5
String getPlayerName()                   // Ник ΠΈΠ³Ρ€ΠΎΠΊΠ°
String getDomain()                       // Π”ΠΎΠΌΠ΅Π½
String getPlayerIP()                     // IP адрСс
LocalDateTime getTimestamp()             // ВрСмя события
int getNewOnlineCount()                  // НовоС количСство ΠΎΠ½Π»Π°ΠΉΠ½

PlayerConnectEvent

βŽ—
βœ“
1
2
3
4
5
6
String getPlayerName()                   // Ник ΠΈΠ³Ρ€ΠΎΠΊΠ°
UUID getPlayerUuid()                     // UUID ΠΈΠ³Ρ€ΠΎΠΊΠ°
String getPlayerIP()                     // IP адрСс
String getDomain()                       // Π”ΠΎΠΌΠ΅Π½ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
LocalDateTime getTimestamp()             // ВрСмя ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
boolean isFirstJoin()                    // ΠŸΠ΅Ρ€Π²ΠΎΠ΅ Π»ΠΈ это ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

PlayerDisconnectEvent

βŽ—
βœ“
1
2
3
4
5
6
String getPlayerName()                   // Ник ΠΈΠ³Ρ€ΠΎΠΊΠ°
UUID getPlayerUuid()                     // UUID ΠΈΠ³Ρ€ΠΎΠΊΠ°
String getPlayerIP()                     // IP адрСс
String getDomain()                       // Π”ΠΎΠΌΠ΅Π½ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
LocalDateTime getTimestamp()             // ВрСмя ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ
long getSessionDuration()                // Π”Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ сСссии (мс)

PlayerSwitchDomainEvent

βŽ—
βœ“
1
2
3
4
5
6
String getPlayerName()                   // Ник ΠΈΠ³Ρ€ΠΎΠΊΠ°
UUID getPlayerUuid()                     // UUID ΠΈΠ³Ρ€ΠΎΠΊΠ°
String getPlayerIP()                     // IP адрСс
String getFromDomain()                   // Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ Π΄ΠΎΠΌΠ΅Π½
String getToDomain()                     // Π¦Π΅Π»Π΅Π²ΠΎΠΉ Π΄ΠΎΠΌΠ΅Π½
LocalDateTime getTimestamp()             // ВрСмя ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

⚠️ Π’Π°ΠΆΠ½Ρ‹Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΊΠΈ

ΠΡΠΈΠ½Ρ…Ρ€ΠΎΠ½Π½ΠΎΡΡ‚ΡŒ

  • ВсС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠ΅ CompletableFuture, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ асинхронно
  • НС Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠΉΡ‚Π΅ основной ΠΏΠΎΡ‚ΠΎΠΊ сСрвСра
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ .thenAccept(), .thenApply() для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ²

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° доступности

βŽ—
βœ“
1
2
3
4
5
6
// ВсСгда провСряйтС Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ API
DomainInfoAPI api = DomainInfoAPI.getInstance();
if (api == null || !api.isAvailable()) {
    // API нСдоступно
    return;
}

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок

βŽ—
βœ“
1
2
3
4
api.domains().getDomainStats("example.com").exceptionally(throwable -> {
    System.err.println("Ошибка получСния статистики: " + throwable.getMessage());
    return null; // ΠΈΠ»ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
});

πŸ“¦ Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ API ΠΊΠ°ΠΊ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ

Maven

βŽ—
βœ“
1
2
3
4
5
6
7
<dependency>
    <groupId>ua.tyulpan</groupId>
    <artifactId>eeDomainInfo</artifactId>
    <version>VERSION</version>
    <scope>system</scope>
    <systemPath>path/to/eeDomainInfo-VERSION.jar</systemPath>
</dependency>

Gradle

βŽ—
βœ“
1
2
3
dependencies {
    compileOnly files('path/to/eeDomainInfo-VERSION.jar')
}

ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ

  • Бобытия Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ асинхронно ΠΈ Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ сСрвСр
  • Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ тяТСлых ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π² листСнСрах событий
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΏΡƒΠ» ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² для Π΄ΠΎΠ»Π³ΠΈΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ

Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ

  • ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π°, маскируйтС IP адрСса ΠΏΡ€ΠΈ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ: 192.168.1.1 β†’ 192.168.*.*
  • НС Π»ΠΎΠ³ΠΈΡ€ΡƒΠΉΡ‚Π΅ UUID Π² ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Π²ΠΈΠ΄Π΅ (ΠΏΠΎ возмоТности)
  • НС Π΄ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ людям Π² ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π΅ (ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ)

Β© 2025 tyulpan | eeDomainInfo API

Edit

Pub: 05 Aug 2025 22:13 UTC

Edit: 05 Aug 2025 23:34 UTC

Views: 28