Compare commits
2 Commits
752b116e30
...
c0fe432ab0
| Author | SHA1 | Date | |
|---|---|---|---|
| c0fe432ab0 | |||
| 06ad85d6df |
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/popa.iml" filepath="$PROJECT_DIR$/popa.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@ -36,6 +36,13 @@ import org.bukkit.event.player.PlayerExpChangeEvent;
|
|||||||
import org.bukkit.event.entity.EntityDeathEvent;
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||||
|
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
|
||||||
|
|
||||||
public final class popa extends JavaPlugin implements Listener {
|
public final class popa extends JavaPlugin implements Listener {
|
||||||
@ -55,6 +62,9 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
private ScheduledExecutorService scheduler;
|
private ScheduledExecutorService scheduler;
|
||||||
private Gson gson;
|
private Gson gson;
|
||||||
private final Map<UUID, Long> lastActivityTimes = new HashMap<>();
|
private final Map<UUID, Long> lastActivityTimes = new HashMap<>();
|
||||||
|
private final Map<UUID, Boolean> afkStates = new HashMap<>();
|
||||||
|
private long afkThresholdMillis;
|
||||||
|
private String afkPrefix;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
@ -157,6 +167,12 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
getLogger().info("Marketplace URL: " + marketplaceUrl);
|
getLogger().info("Marketplace URL: " + marketplaceUrl);
|
||||||
getLogger().info("Bonuses URL: " + bonusesUrl);
|
getLogger().info("Bonuses URL: " + bonusesUrl);
|
||||||
getLogger().info("Server IP: " + serverIp);
|
getLogger().info("Server IP: " + serverIp);
|
||||||
|
|
||||||
|
afkThresholdMillis = getConfig().getLong("afk-threshold-seconds", 60) * 1000L;
|
||||||
|
afkPrefix = getConfig().getString("afk-prefix", "[AFK] ");
|
||||||
|
|
||||||
|
// Периодически проверяем, кто ушёл в AFK (на основном потоке)
|
||||||
|
Bukkit.getScheduler().runTaskTimer(this, this::checkAfkTransitions, 20L, 20L * 5L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -189,14 +205,49 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerMove(PlayerMoveEvent event) {
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
// Игнорируем микродвижения (изменение направления взгляда)
|
if (!event.getFrom().toVector().equals(event.getTo().toVector())) {
|
||||||
if (event.getFrom().getX() != event.getTo().getX() ||
|
markActivity(event.getPlayer());
|
||||||
event.getFrom().getY() != event.getTo().getY() ||
|
|
||||||
event.getFrom().getZ() != event.getTo().getZ()) {
|
|
||||||
lastActivityTimes.put(event.getPlayer().getUniqueId(), System.currentTimeMillis());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChat(AsyncPlayerChatEvent event) {
|
||||||
|
// чат — асинхронный, переключаемся на основной поток
|
||||||
|
Bukkit.getScheduler().runTask(this, () -> markActivity(event.getPlayer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onCommand(PlayerCommandPreprocessEvent event) {
|
||||||
|
markActivity(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInteract(PlayerInteractEvent event) {
|
||||||
|
markActivity(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInvClick(InventoryClickEvent event) {
|
||||||
|
if (event.getWhoClicked() instanceof Player p) {
|
||||||
|
markActivity(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockPlace(BlockPlaceEvent event) {
|
||||||
|
markActivity(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockBreak(BlockBreakEvent event) {
|
||||||
|
markActivity(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onHotbar(PlayerItemHeldEvent event) {
|
||||||
|
markActivity(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
@ -217,6 +268,9 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
|
|
||||||
// сразу обновим онлайн-лист на бэкенде
|
// сразу обновим онлайн-лист на бэкенде
|
||||||
sendOnlinePlayersUpdate();
|
sendOnlinePlayersUpdate();
|
||||||
|
|
||||||
|
lastActivityTimes.put(playerId, System.currentTimeMillis());
|
||||||
|
afkStates.put(playerId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -249,6 +303,9 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
|
|
||||||
// Восстанавливаем базовые атрибуты
|
// Восстанавливаем базовые атрибуты
|
||||||
player.getAttribute(Attribute.MAX_HEALTH).setBaseValue(20.0);
|
player.getAttribute(Attribute.MAX_HEALTH).setBaseValue(20.0);
|
||||||
|
|
||||||
|
lastActivityTimes.remove(playerId);
|
||||||
|
afkStates.remove(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -269,6 +326,68 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
sendEventToBackend(payload);
|
sendEventToBackend(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void pushOnlineUpdateAsync() {
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(this, this::sendOnlinePlayersUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void markActivity(Player player) {
|
||||||
|
UUID id = player.getUniqueId();
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
lastActivityTimes.put(id, now);
|
||||||
|
|
||||||
|
if (afkStates.getOrDefault(id, false)) {
|
||||||
|
afkStates.put(id, false);
|
||||||
|
player.sendMessage("Вы больше не AFK");
|
||||||
|
|
||||||
|
// 1) опционально: отдельное событие выхода из AFK
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
|
||||||
|
sendEventToBackend(String.format(
|
||||||
|
"{\"event_type\":\"player_afk_end\",\"player_id\":\"%s\",\"player_name\":\"%s\",\"server_ip\":\"%s\",\"timestamp\":%d}",
|
||||||
|
id, player.getName(), serverIp, now
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2) и сразу пушим обновление списка онлайна (чтобы бэкенд обновился мгновенно)
|
||||||
|
pushOnlineUpdateAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setAfk(Player player) {
|
||||||
|
UUID id = player.getUniqueId();
|
||||||
|
if (afkStates.getOrDefault(id, false)) return;
|
||||||
|
|
||||||
|
afkStates.put(id, true);
|
||||||
|
player.sendMessage("Вы AFK");
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
|
||||||
|
sendEventToBackend(String.format(
|
||||||
|
"{\"event_type\":\"player_afk_start\",\"player_id\":\"%s\",\"player_name\":\"%s\",\"server_ip\":\"%s\",\"timestamp\":%d}",
|
||||||
|
id, player.getName(), serverIp, System.currentTimeMillis()
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
pushOnlineUpdateAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAfkTransitions() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||||
|
UUID id = p.getUniqueId();
|
||||||
|
|
||||||
|
// если ещё нет активности — считаем что активен “сейчас”
|
||||||
|
long last = lastActivityTimes.getOrDefault(id, now);
|
||||||
|
lastActivityTimes.putIfAbsent(id, last);
|
||||||
|
|
||||||
|
boolean isAfk = afkStates.getOrDefault(id, false);
|
||||||
|
boolean shouldBeAfk = (now - last) > afkThresholdMillis;
|
||||||
|
|
||||||
|
if (!isAfk && shouldBeAfk) {
|
||||||
|
setAfk(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void sendOnlinePlayersUpdate() {
|
private void sendOnlinePlayersUpdate() {
|
||||||
StringBuilder playersJson = new StringBuilder("[");
|
StringBuilder playersJson = new StringBuilder("[");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
@ -278,18 +397,8 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
UUID playerId = entry.getKey();
|
UUID playerId = entry.getKey();
|
||||||
String playerName = playerNames.get(playerId);
|
String playerName = playerNames.get(playerId);
|
||||||
Long lastActivity = lastActivityTimes.get(playerId);
|
Long lastActivity = lastActivityTimes.get(playerId);
|
||||||
|
boolean isAfk = ((currentTime - lastActivity) > afkThresholdMillis);
|
||||||
// Если нет последней активности — считаем, что игрок "не виден" бэкенду
|
String nameForSite = isAfk ? (afkPrefix + playerName) : playerName;
|
||||||
if (lastActivity == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
long inactiveSeconds = (currentTime - lastActivity) / 1000;
|
|
||||||
|
|
||||||
// Больше минуты не двигался — не отправляем в список активных
|
|
||||||
if (inactiveSeconds > afkTimeoutSeconds) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
long onlineTime = (currentTime - entry.getValue()) / 1000;
|
long onlineTime = (currentTime - entry.getValue()) / 1000;
|
||||||
|
|
||||||
@ -297,8 +406,8 @@ public final class popa extends JavaPlugin implements Listener {
|
|||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
playersJson.append(String.format(
|
playersJson.append(String.format(
|
||||||
"{\"player_id\":\"%s\",\"player_name\":\"%s\",\"online_time\":%d}",
|
"{\"player_id\":\"%s\",\"player_name\":\"%s\",\"online_time\":%d,\"afk\":%s}",
|
||||||
playerId, playerName, onlineTime
|
playerId, nameForSite, onlineTime, isAfk ? "true" : "false"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user