fixes
This commit is contained in:
parent
6bf526305b
commit
eccf850d11
|
|
@ -4,7 +4,9 @@
|
||||||
"Bash(./gradlew tasks:*)",
|
"Bash(./gradlew tasks:*)",
|
||||||
"Bash(./gradlew build:*)",
|
"Bash(./gradlew build:*)",
|
||||||
"Bash(./gradlew compileJava:*)",
|
"Bash(./gradlew compileJava:*)",
|
||||||
"Bash(./gradlew clean build:*)"
|
"Bash(./gradlew clean build:*)",
|
||||||
|
"Bash(.gradlew clean build)",
|
||||||
|
"Bash(gradlew.bat clean build)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP client for HubGW API integration.
|
* HTTP client for HubGW API integration.
|
||||||
|
|
@ -22,9 +24,9 @@ public class HubGWClient {
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
private static final Gson GSON = new GsonBuilder().create();
|
private static final Gson GSON = new GsonBuilder().create();
|
||||||
|
|
||||||
// Circuit breaker to prevent log spam
|
// Circuit breaker to prevent log spam (thread-safe with atomics)
|
||||||
private volatile long lastErrorLogTime = 0;
|
private final AtomicLong lastErrorLogTime = new AtomicLong(0);
|
||||||
private volatile int consecutiveErrors = 0;
|
private final AtomicInteger consecutiveErrors = new AtomicInteger(0);
|
||||||
private static final long ERROR_LOG_COOLDOWN_MS = 60_000; // 1 minute
|
private static final long ERROR_LOG_COOLDOWN_MS = 60_000; // 1 minute
|
||||||
private static final int ERROR_THRESHOLD = 3;
|
private static final int ERROR_THRESHOLD = 3;
|
||||||
|
|
||||||
|
|
@ -215,52 +217,54 @@ public class HubGWClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log HTTP error with circuit breaker logic.
|
* Log HTTP error with circuit breaker logic (thread-safe).
|
||||||
*/
|
*/
|
||||||
private void logHttpError(String endpoint, int statusCode, String responseBody) {
|
private void logHttpError(String endpoint, int statusCode, String responseBody) {
|
||||||
consecutiveErrors++;
|
int errorCount = consecutiveErrors.incrementAndGet();
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
if (consecutiveErrors == 1 || (now - lastErrorLogTime) > ERROR_LOG_COOLDOWN_MS) {
|
long lastLog = lastErrorLogTime.get();
|
||||||
|
|
||||||
|
if (errorCount == 1 || (now - lastLog) > ERROR_LOG_COOLDOWN_MS) {
|
||||||
if (Config.enableDebugLogging) {
|
if (Config.enableDebugLogging) {
|
||||||
LOGGER.warn("API request failed: {} returned {} - Response: {}", endpoint, statusCode, responseBody);
|
LOGGER.warn("API request failed: {} returned {} - Response: {}", endpoint, statusCode, responseBody);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warn("API request failed: {} returned {}", endpoint, statusCode);
|
LOGGER.warn("API request failed: {} returned {}", endpoint, statusCode);
|
||||||
}
|
}
|
||||||
lastErrorLogTime = now;
|
lastErrorLogTime.set(now);
|
||||||
|
|
||||||
if (consecutiveErrors > ERROR_THRESHOLD) {
|
if (errorCount > ERROR_THRESHOLD) {
|
||||||
LOGGER.warn("API has failed {} times consecutively. Further errors will be throttled.", consecutiveErrors);
|
LOGGER.warn("API has failed {} times consecutively. Further errors will be throttled.", errorCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log API connection error with circuit breaker logic.
|
* Log API connection error with circuit breaker logic (thread-safe).
|
||||||
*/
|
*/
|
||||||
private void logApiError(String message, Throwable ex) {
|
private void logApiError(String message, Throwable ex) {
|
||||||
consecutiveErrors++;
|
int errorCount = consecutiveErrors.incrementAndGet();
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
if (consecutiveErrors == 1 || (now - lastErrorLogTime) > ERROR_LOG_COOLDOWN_MS) {
|
long lastLog = lastErrorLogTime.get();
|
||||||
LOGGER.warn("{}: {} (consecutive errors: {})", message, ex.getMessage(), consecutiveErrors);
|
|
||||||
lastErrorLogTime = now;
|
|
||||||
|
|
||||||
if (consecutiveErrors > ERROR_THRESHOLD) {
|
if (errorCount == 1 || (now - lastLog) > ERROR_LOG_COOLDOWN_MS) {
|
||||||
LOGGER.warn("API has failed {} times consecutively. Further errors will be throttled.", consecutiveErrors);
|
LOGGER.warn("{}: {} (consecutive errors: {})", message, ex.getMessage(), errorCount);
|
||||||
|
lastErrorLogTime.set(now);
|
||||||
|
|
||||||
|
if (errorCount > ERROR_THRESHOLD) {
|
||||||
|
LOGGER.warn("API has failed {} times consecutively. Further errors will be throttled.", errorCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset error counter after successful request.
|
* Reset error counter after successful request (thread-safe).
|
||||||
*/
|
*/
|
||||||
private void resetErrorCounter() {
|
private void resetErrorCounter() {
|
||||||
if (consecutiveErrors > 0) {
|
int previousErrors = consecutiveErrors.getAndSet(0);
|
||||||
if (consecutiveErrors > ERROR_THRESHOLD) {
|
if (previousErrors > ERROR_THRESHOLD) {
|
||||||
LOGGER.info("API connection restored after {} consecutive errors", consecutiveErrors);
|
LOGGER.info("API connection restored after {} consecutive errors", previousErrors);
|
||||||
}
|
|
||||||
consecutiveErrors = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ import org.itqop.HubmcEssentials.util.LocationUtil;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /goto command - Custom teleport command with cooldowns and logging.
|
* /goto command - Custom teleport command with cooldowns and logging.
|
||||||
*
|
*
|
||||||
|
|
@ -82,55 +84,60 @@ public class GotoCommand {
|
||||||
String cooldownType = "tp|" + target.getGameProfile().getName();
|
String cooldownType = "tp|" + target.getGameProfile().getName();
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, cooldownType).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, cooldownType).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save current location for /back
|
// Set cooldown FIRST
|
||||||
LocationStorage.saveLocation(player);
|
return CooldownService.createCooldown(playerUuid, cooldownType, Config.cooldownGoto).thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Store from location for teleport history
|
// NOW perform action - save location and teleport
|
||||||
Vec3 fromPos = player.position();
|
LocationStorage.saveLocation(player);
|
||||||
String fromWorld = LocationUtil.getWorldId(player.level());
|
|
||||||
|
|
||||||
// Teleport to target
|
// Store from location for teleport history
|
||||||
boolean success = LocationUtil.teleportPlayer(
|
Vec3 fromPos = player.position();
|
||||||
player,
|
String fromWorld = LocationUtil.getWorldId(player.level());
|
||||||
target.serverLevel(),
|
|
||||||
target.getX(),
|
|
||||||
target.getY(),
|
|
||||||
target.getZ(),
|
|
||||||
target.getYRot(),
|
|
||||||
target.getXRot()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (success) {
|
// Teleport to target
|
||||||
MessageUtil.sendSuccess(player, "Телепортация к игроку §6" + target.getGameProfile().getName());
|
boolean teleportSuccess = LocationUtil.teleportPlayer(
|
||||||
|
player,
|
||||||
// Log teleport history
|
target.serverLevel(),
|
||||||
TeleportHistoryRequest historyRequest = new TeleportHistoryRequest(
|
target.getX(),
|
||||||
playerUuid,
|
target.getY(),
|
||||||
fromWorld,
|
target.getZ(),
|
||||||
fromPos.x, fromPos.y, fromPos.z,
|
target.getYRot(),
|
||||||
LocationUtil.getWorldId(target.level()),
|
target.getXRot()
|
||||||
target.getX(), target.getY(), target.getZ(),
|
|
||||||
"to_player",
|
|
||||||
target.getGameProfile().getName()
|
|
||||||
);
|
);
|
||||||
TeleportService.logTeleport(historyRequest);
|
|
||||||
|
|
||||||
// Set cooldown
|
if (teleportSuccess) {
|
||||||
CooldownService.createCooldown(playerUuid, cooldownType, Config.cooldownGoto);
|
MessageUtil.sendSuccess(player, "Телепортация к игроку §6" + target.getGameProfile().getName());
|
||||||
} else {
|
|
||||||
MessageUtil.sendError(player, "Ошибка телепортации");
|
// Log teleport history
|
||||||
}
|
TeleportHistoryRequest historyRequest = new TeleportHistoryRequest(
|
||||||
|
playerUuid,
|
||||||
|
fromWorld,
|
||||||
|
fromPos.x, fromPos.y, fromPos.z,
|
||||||
|
LocationUtil.getWorldId(target.level()),
|
||||||
|
target.getX(), target.getY(), target.getZ(),
|
||||||
|
"to_player",
|
||||||
|
target.getGameProfile().getName()
|
||||||
|
);
|
||||||
|
TeleportService.logTeleport(historyRequest);
|
||||||
|
} else {
|
||||||
|
MessageUtil.sendError(player, "Ошибка телепортации");
|
||||||
|
}
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -227,54 +234,59 @@ public class GotoCommand {
|
||||||
String cooldownType = "tp|coords";
|
String cooldownType = "tp|coords";
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, cooldownType).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, cooldownType).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save current location for /back
|
// Set cooldown FIRST
|
||||||
LocationStorage.saveLocation(player);
|
return CooldownService.createCooldown(playerUuid, cooldownType, Config.cooldownGoto).thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Store from location for teleport history
|
// NOW perform action - save location and teleport
|
||||||
Vec3 fromPos = player.position();
|
LocationStorage.saveLocation(player);
|
||||||
String fromWorld = LocationUtil.getWorldId(player.level());
|
|
||||||
|
|
||||||
// Teleport to coordinates
|
// Store from location for teleport history
|
||||||
boolean success = LocationUtil.teleportPlayer(
|
Vec3 fromPos = player.position();
|
||||||
player,
|
String fromWorld = LocationUtil.getWorldId(player.level());
|
||||||
player.serverLevel(),
|
|
||||||
location.x,
|
|
||||||
location.y,
|
|
||||||
location.z
|
|
||||||
);
|
|
||||||
|
|
||||||
if (success) {
|
// Teleport to coordinates
|
||||||
MessageUtil.sendSuccess(player, "Телепортация на координаты: " +
|
boolean teleportSuccess = LocationUtil.teleportPlayer(
|
||||||
MessageUtil.formatCoords(location.x, location.y, location.z));
|
player,
|
||||||
|
player.serverLevel(),
|
||||||
// Log teleport history
|
location.x,
|
||||||
TeleportHistoryRequest historyRequest = new TeleportHistoryRequest(
|
location.y,
|
||||||
playerUuid,
|
location.z
|
||||||
fromWorld,
|
|
||||||
fromPos.x, fromPos.y, fromPos.z,
|
|
||||||
LocationUtil.getWorldId(player.level()),
|
|
||||||
location.x, location.y, location.z,
|
|
||||||
"to_coords",
|
|
||||||
MessageUtil.formatCoords(location.x, location.y, location.z)
|
|
||||||
);
|
);
|
||||||
TeleportService.logTeleport(historyRequest);
|
|
||||||
|
|
||||||
// Set cooldown
|
if (teleportSuccess) {
|
||||||
CooldownService.createCooldown(playerUuid, cooldownType, Config.cooldownGoto);
|
MessageUtil.sendSuccess(player, "Телепортация на координаты: " +
|
||||||
} else {
|
MessageUtil.formatCoords(location.x, location.y, location.z));
|
||||||
MessageUtil.sendError(player, "Ошибка телепортации");
|
|
||||||
}
|
// Log teleport history
|
||||||
|
TeleportHistoryRequest historyRequest = new TeleportHistoryRequest(
|
||||||
|
playerUuid,
|
||||||
|
fromWorld,
|
||||||
|
fromPos.x, fromPos.y, fromPos.z,
|
||||||
|
LocationUtil.getWorldId(player.level()),
|
||||||
|
location.x, location.y, location.z,
|
||||||
|
"to_coords",
|
||||||
|
MessageUtil.formatCoords(location.x, location.y, location.z)
|
||||||
|
);
|
||||||
|
TeleportService.logTeleport(historyRequest);
|
||||||
|
} else {
|
||||||
|
MessageUtil.sendError(player, "Ошибка телепортации");
|
||||||
|
}
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /pot command - Apply potion effects to player.
|
* /pot command - Apply potion effects to player.
|
||||||
|
|
@ -82,38 +83,43 @@ public class PotCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply effect
|
// Set cooldown FIRST
|
||||||
MobEffect effect = effectHolder.get().value();
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownPot).thenAccept(success -> {
|
||||||
int durationTicks = durationSeconds * 20; // Convert seconds to ticks
|
if (!success) {
|
||||||
MobEffectInstance effectInstance = new MobEffectInstance(
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
effectHolder.get(),
|
return;
|
||||||
durationTicks,
|
}
|
||||||
amplifier,
|
|
||||||
false, // ambient
|
|
||||||
true, // visible particles
|
|
||||||
true // show icon
|
|
||||||
);
|
|
||||||
|
|
||||||
player.addEffect(effectInstance);
|
// NOW perform action - apply effect
|
||||||
|
MobEffect effect = effectHolder.get().value();
|
||||||
|
int durationTicks = durationSeconds * 20; // Convert seconds to ticks
|
||||||
|
MobEffectInstance effectInstance = new MobEffectInstance(
|
||||||
|
effectHolder.get(),
|
||||||
|
durationTicks,
|
||||||
|
amplifier,
|
||||||
|
false, // ambient
|
||||||
|
true, // visible particles
|
||||||
|
true // show icon
|
||||||
|
);
|
||||||
|
|
||||||
// Get effect display name
|
player.addEffect(effectInstance);
|
||||||
String effectDisplayName = effect.getDisplayName().getString();
|
|
||||||
MessageUtil.sendSuccess(player, "Эффект применен: §6" + effectDisplayName +
|
|
||||||
"§a (Уровень " + (amplifier + 1) + ", " + durationSeconds + " сек.)");
|
|
||||||
|
|
||||||
// Set cooldown
|
// Get effect display name
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownPot);
|
String effectDisplayName = effect.getDisplayName().getString();
|
||||||
|
MessageUtil.sendSuccess(player, "Эффект применен: §6" + effectDisplayName +
|
||||||
|
"§a (Уровень " + (amplifier + 1) + ", " + durationSeconds + " сек.)");
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time control commands - Set world time.
|
* Time control commands - Set world time.
|
||||||
* Commands: /day, /night, /morning, /evening
|
* Commands: /day, /night, /morning, /evening
|
||||||
|
|
@ -66,27 +68,32 @@ public class TimeCommand {
|
||||||
String cooldownType = "time|" + timeType;
|
String cooldownType = "time|" + timeType;
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, cooldownType).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, cooldownType).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set world time
|
// Set cooldown FIRST
|
||||||
ServerLevel level = player.serverLevel();
|
return CooldownService.createCooldown(playerUuid, cooldownType, Config.cooldownTime).thenAccept(success -> {
|
||||||
level.setDayTime(timeValue);
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Send success message
|
// NOW perform action - set world time
|
||||||
String timeDisplayName = getTimeDisplayName(timeType);
|
ServerLevel level = player.serverLevel();
|
||||||
MessageUtil.sendSuccess(player, "Время установлено: §6" + timeDisplayName);
|
level.setDayTime(timeValue);
|
||||||
|
|
||||||
// Set cooldown
|
// Send success message
|
||||||
CooldownService.createCooldown(playerUuid, cooldownType, Config.cooldownTime);
|
String timeDisplayName = getTimeDisplayName(timeType);
|
||||||
|
MessageUtil.sendSuccess(player, "Время установлено: §6" + timeDisplayName);
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ import org.itqop.HubmcEssentials.util.LocationUtil;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /top command - Teleport to the highest block above player.
|
* /top command - Teleport to the highest block above player.
|
||||||
* Permission: hubmc.cmd.top
|
* Permission: hubmc.cmd.top
|
||||||
|
|
@ -48,50 +50,56 @@ public class TopCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageUtil.sendInfo(player, "Поиск самого высокого блока...");
|
// Set cooldown FIRST
|
||||||
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownTop).thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Find highest block
|
// NOW perform action - find highest block and teleport
|
||||||
ServerLevel level = player.serverLevel();
|
MessageUtil.sendInfo(player, "Поиск самого высокого блока...");
|
||||||
BlockPos currentPos = player.blockPosition();
|
|
||||||
int highestY = findHighestBlock(level, currentPos.getX(), currentPos.getZ());
|
|
||||||
|
|
||||||
if (highestY == -1) {
|
// Find highest block
|
||||||
MessageUtil.sendError(player, "Не удалось найти безопасную локацию");
|
ServerLevel level = player.serverLevel();
|
||||||
return;
|
BlockPos currentPos = player.blockPosition();
|
||||||
}
|
int highestY = findHighestBlock(level, currentPos.getX(), currentPos.getZ());
|
||||||
|
|
||||||
// Save current location for /back
|
if (highestY == -1) {
|
||||||
LocationStorage.saveLocation(player);
|
MessageUtil.sendError(player, "Не удалось найти безопасную локацию");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Teleport player
|
// Save current location for /back
|
||||||
boolean success = LocationUtil.teleportPlayer(
|
LocationStorage.saveLocation(player);
|
||||||
player,
|
|
||||||
level,
|
|
||||||
currentPos.getX() + 0.5,
|
|
||||||
highestY + 1,
|
|
||||||
currentPos.getZ() + 0.5
|
|
||||||
);
|
|
||||||
|
|
||||||
if (success) {
|
// Teleport player
|
||||||
MessageUtil.sendSuccess(player, "Телепортация на самый высокий блок: " +
|
boolean teleportSuccess = LocationUtil.teleportPlayer(
|
||||||
MessageUtil.formatCoords(currentPos.getX(), highestY + 1, currentPos.getZ()));
|
player,
|
||||||
|
level,
|
||||||
|
currentPos.getX() + 0.5,
|
||||||
|
highestY + 1,
|
||||||
|
currentPos.getZ() + 0.5
|
||||||
|
);
|
||||||
|
|
||||||
// Set cooldown
|
if (teleportSuccess) {
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownTop);
|
MessageUtil.sendSuccess(player, "Телепортация на самый высокий блок: " +
|
||||||
} else {
|
MessageUtil.formatCoords(currentPos.getX(), highestY + 1, currentPos.getZ()));
|
||||||
MessageUtil.sendError(player, "Ошибка телепортации");
|
} else {
|
||||||
}
|
MessageUtil.sendError(player, "Ошибка телепортации");
|
||||||
|
}
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.itqop.HubmcEssentials.Config;
|
import org.itqop.HubmcEssentials.Config;
|
||||||
import org.itqop.HubmcEssentials.api.dto.cooldown.CooldownCheckResponse;
|
import org.itqop.HubmcEssentials.api.dto.cooldown.CooldownCheckResponse;
|
||||||
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
|
|
@ -24,7 +26,7 @@ public class ClearCommand {
|
||||||
|
|
||||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
||||||
dispatcher.register(Commands.literal("clear")
|
dispatcher.register(Commands.literal("clear")
|
||||||
.requires(source -> source.isPlayer())
|
.requires(CommandSourceStack::isPlayer)
|
||||||
.executes(ClearCommand::execute));
|
.executes(ClearCommand::execute));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,23 +45,29 @@ public class ClearCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear inventory
|
// Set cooldown FIRST to prevent race condition
|
||||||
player.getInventory().clearContent();
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownClear)
|
||||||
MessageUtil.sendSuccess(player, "Инвентарь очищен");
|
.thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set cooldown
|
// NOW perform action (cooldown already set)
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownClear);
|
player.getInventory().clearContent();
|
||||||
|
MessageUtil.sendSuccess(player, "Инвентарь очищен");
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /ec command - Open player's ender chest.
|
* /ec command - Open player's ender chest.
|
||||||
* Permission: hubmc.cmd.ec
|
* Permission: hubmc.cmd.ec
|
||||||
|
|
@ -46,25 +48,30 @@ public class EcCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open ender chest
|
// Set cooldown FIRST
|
||||||
player.openMenu(new SimpleMenuProvider(
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownEc).thenAccept(success -> {
|
||||||
(id, playerInventory, p) -> ChestMenu.threeRows(id, playerInventory, player.getEnderChestInventory()),
|
if (!success) {
|
||||||
Component.literal("Эндер-сундук")
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
));
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set cooldown
|
// NOW perform action - open ender chest
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownEc);
|
player.openMenu(new SimpleMenuProvider(
|
||||||
|
(id, playerInventory, p) -> ChestMenu.threeRows(id, playerInventory, player.getEnderChestInventory()),
|
||||||
|
Component.literal("Эндер-сундук")
|
||||||
|
));
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /hat command - Wear held item as a hat.
|
* /hat command - Wear held item as a hat.
|
||||||
* Permission: hubmc.cmd.hat
|
* Permission: hubmc.cmd.hat
|
||||||
|
|
@ -52,28 +54,33 @@ public class HatCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current helmet
|
// Set cooldown FIRST
|
||||||
ItemStack currentHelmet = player.getItemBySlot(EquipmentSlot.HEAD);
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownHat).thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Swap hand item with helmet
|
// NOW perform action - swap hand item with helmet
|
||||||
player.setItemSlot(EquipmentSlot.HEAD, handItem.copy());
|
ItemStack currentHelmet = player.getItemBySlot(EquipmentSlot.HEAD);
|
||||||
player.setItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND, currentHelmet);
|
|
||||||
|
|
||||||
MessageUtil.sendSuccess(player, "Предмет надет на голову");
|
// Swap hand item with helmet
|
||||||
|
player.setItemSlot(EquipmentSlot.HEAD, handItem.copy());
|
||||||
|
player.setItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND, currentHelmet);
|
||||||
|
|
||||||
// Set cooldown
|
MessageUtil.sendSuccess(player, "Предмет надет на голову");
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownHat);
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /repair all command - Repair all items in inventory and armor.
|
* /repair all command - Repair all items in inventory and armor.
|
||||||
* Permission: hubmc.cmd.repair.all
|
* Permission: hubmc.cmd.repair.all
|
||||||
|
|
@ -46,46 +48,51 @@ public class RepairAllCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repair all items
|
// Set cooldown FIRST
|
||||||
int repairedCount = 0;
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownRepairAll).thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
// Repair inventory items
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
|
return;
|
||||||
ItemStack item = player.getInventory().getItem(i);
|
|
||||||
if (!item.isEmpty() && item.isDamageableItem() && item.isDamaged()) {
|
|
||||||
item.setDamageValue(0);
|
|
||||||
repairedCount++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Repair armor
|
// NOW perform action - repair all items
|
||||||
for (ItemStack armorItem : player.getArmorSlots()) {
|
int repairedCount = 0;
|
||||||
if (!armorItem.isEmpty() && armorItem.isDamageableItem() && armorItem.isDamaged()) {
|
|
||||||
armorItem.setDamageValue(0);
|
// Repair inventory items
|
||||||
repairedCount++;
|
for (int i = 0; i < player.getInventory().getContainerSize(); i++) {
|
||||||
|
ItemStack item = player.getInventory().getItem(i);
|
||||||
|
if (!item.isEmpty() && item.isDamageableItem() && item.isDamaged()) {
|
||||||
|
item.setDamageValue(0);
|
||||||
|
repairedCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (repairedCount == 0) {
|
// Repair armor
|
||||||
MessageUtil.sendInfo(player, "Нет поврежденных предметов");
|
for (ItemStack armorItem : player.getArmorSlots()) {
|
||||||
return;
|
if (!armorItem.isEmpty() && armorItem.isDamageableItem() && armorItem.isDamaged()) {
|
||||||
}
|
armorItem.setDamageValue(0);
|
||||||
|
repairedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MessageUtil.sendSuccess(player, "Отремонтировано предметов: " + repairedCount);
|
if (repairedCount == 0) {
|
||||||
|
MessageUtil.sendInfo(player, "Нет поврежденных предметов");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Set cooldown
|
MessageUtil.sendSuccess(player, "Отремонтировано предметов: " + repairedCount);
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownRepairAll);
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import org.itqop.HubmcEssentials.util.LocationUtil;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /back command - Teleport to last location.
|
* /back command - Teleport to last location.
|
||||||
* Permission: hubmc.cmd.back
|
* Permission: hubmc.cmd.back
|
||||||
|
|
@ -55,64 +57,69 @@ public class BackCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get last location
|
// Set cooldown FIRST
|
||||||
LocationStorage.LastLocation lastLoc = LocationStorage.getLastLocation(player);
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownBack).thenAccept(success -> {
|
||||||
if (lastLoc == null) {
|
if (!success) {
|
||||||
MessageUtil.sendError(player, "Нет сохраненной позиции для возврата");
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse world dimension
|
// NOW perform action - get last location and teleport
|
||||||
ResourceLocation worldLocation = ResourceLocation.tryParse(lastLoc.getWorldId());
|
LocationStorage.LastLocation lastLoc = LocationStorage.getLastLocation(player);
|
||||||
if (worldLocation == null) {
|
if (lastLoc == null) {
|
||||||
MessageUtil.sendError(player, "Неверный мир");
|
MessageUtil.sendError(player, "Нет сохраненной позиции для возврата");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceKey<net.minecraft.world.level.Level> worldKey = ResourceKey.create(
|
// Parse world dimension
|
||||||
Registries.DIMENSION,
|
ResourceLocation worldLocation = ResourceLocation.tryParse(lastLoc.getWorldId());
|
||||||
worldLocation
|
if (worldLocation == null) {
|
||||||
);
|
MessageUtil.sendError(player, "Неверный мир");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ServerLevel targetLevel = context.getSource().getServer().getLevel(worldKey);
|
ResourceKey<net.minecraft.world.level.Level> worldKey = ResourceKey.create(
|
||||||
if (targetLevel == null) {
|
Registries.DIMENSION,
|
||||||
MessageUtil.sendError(player, "Мир не найден");
|
worldLocation
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Save current location before teleporting
|
ServerLevel targetLevel = context.getSource().getServer().getLevel(worldKey);
|
||||||
LocationStorage.saveLocation(player);
|
if (targetLevel == null) {
|
||||||
|
MessageUtil.sendError(player, "Мир не найден");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Teleport player
|
// Save current location before teleporting
|
||||||
boolean success = LocationUtil.teleportPlayer(
|
LocationStorage.saveLocation(player);
|
||||||
player,
|
|
||||||
targetLevel,
|
|
||||||
lastLoc.getX(),
|
|
||||||
lastLoc.getY(),
|
|
||||||
lastLoc.getZ(),
|
|
||||||
lastLoc.getYaw(),
|
|
||||||
lastLoc.getPitch()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (success) {
|
// Teleport player
|
||||||
MessageUtil.sendSuccess(player, "Телепортация на последнюю позицию");
|
boolean teleportSuccess = LocationUtil.teleportPlayer(
|
||||||
} else {
|
player,
|
||||||
MessageUtil.sendError(player, "Ошибка телепортации");
|
targetLevel,
|
||||||
}
|
lastLoc.getX(),
|
||||||
|
lastLoc.getY(),
|
||||||
|
lastLoc.getZ(),
|
||||||
|
lastLoc.getYaw(),
|
||||||
|
lastLoc.getPitch()
|
||||||
|
);
|
||||||
|
|
||||||
// Set cooldown
|
if (teleportSuccess) {
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownBack);
|
MessageUtil.sendSuccess(player, "Телепортация на последнюю позицию");
|
||||||
|
} else {
|
||||||
|
MessageUtil.sendError(player, "Ошибка телепортации");
|
||||||
|
}
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import net.minecraft.commands.Commands;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.itqop.HubmcEssentials.Config;
|
import org.itqop.HubmcEssentials.Config;
|
||||||
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
|
|
@ -43,25 +45,31 @@ public class FeedCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feed player
|
// Set cooldown FIRST to prevent race condition
|
||||||
player.getFoodData().setFoodLevel(20);
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownFeed)
|
||||||
player.getFoodData().setSaturation(20.0f);
|
.thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MessageUtil.sendSuccess(player, "Вы сыты");
|
// NOW perform action (cooldown already set)
|
||||||
|
player.getFoodData().setFoodLevel(20);
|
||||||
|
player.getFoodData().setSaturation(20.0f);
|
||||||
|
|
||||||
// Set cooldown
|
MessageUtil.sendSuccess(player, "Вы сыты");
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownFeed);
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.commands.Commands;
|
import net.minecraft.commands.Commands;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.itqop.HubmcEssentials.Config;
|
import org.itqop.HubmcEssentials.Config;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
|
|
@ -43,29 +45,35 @@ public class HealCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heal player
|
// Set cooldown FIRST to prevent race condition
|
||||||
player.setHealth(player.getMaxHealth());
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownHeal)
|
||||||
player.getFoodData().setFoodLevel(20);
|
.thenAccept(success -> {
|
||||||
player.getFoodData().setSaturation(20.0f);
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove negative effects (optional)
|
// NOW perform action (cooldown already set)
|
||||||
player.removeAllEffects();
|
player.setHealth(player.getMaxHealth());
|
||||||
|
player.getFoodData().setFoodLevel(20);
|
||||||
|
player.getFoodData().setSaturation(20.0f);
|
||||||
|
|
||||||
MessageUtil.sendSuccess(player, "Вы полностью исцелены");
|
// Remove negative effects (optional)
|
||||||
|
player.removeAllEffects();
|
||||||
|
|
||||||
// Set cooldown
|
MessageUtil.sendSuccess(player, "Вы полностью исцелены");
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownHeal);
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /near [radius] command - Show nearby players.
|
* /near [radius] command - Show nearby players.
|
||||||
|
|
@ -52,34 +53,39 @@ public class NearCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find nearby players
|
// Set cooldown FIRST
|
||||||
List<ServerPlayer> nearbyPlayers = PlayerUtil.getPlayersNear(player, radius);
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownNear).thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
if (nearbyPlayers.isEmpty()) {
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
MessageUtil.sendInfo(player, "Поблизости нет игроков (радиус: " + radius + " блоков)");
|
return;
|
||||||
} else {
|
|
||||||
MessageUtil.sendInfo(player, "§eИгроки поблизости (радиус: " + radius + " блоков):");
|
|
||||||
|
|
||||||
for (ServerPlayer nearby : nearbyPlayers) {
|
|
||||||
double distance = player.distanceTo(nearby);
|
|
||||||
String distanceStr = MessageUtil.formatDistance(distance);
|
|
||||||
MessageUtil.sendInfo(player, " §7- §f" + nearby.getName().getString() + " §7(" + distanceStr + ")");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Set cooldown
|
// NOW perform action - find nearby players
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownNear);
|
List<ServerPlayer> nearbyPlayers = PlayerUtil.getPlayersNear(player, radius);
|
||||||
|
|
||||||
|
if (nearbyPlayers.isEmpty()) {
|
||||||
|
MessageUtil.sendInfo(player, "Поблизости нет игроков (радиус: " + radius + " блоков)");
|
||||||
|
} else {
|
||||||
|
MessageUtil.sendInfo(player, "§eИгроки поблизости (радиус: " + radius + " блоков):");
|
||||||
|
|
||||||
|
for (ServerPlayer nearby : nearbyPlayers) {
|
||||||
|
double distance = player.distanceTo(nearby);
|
||||||
|
String distanceStr = MessageUtil.formatDistance(distance);
|
||||||
|
MessageUtil.sendInfo(player, " §7- §f" + nearby.getName().getString() + " §7(" + distanceStr + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
import org.itqop.HubmcEssentials.util.MessageUtil;
|
import org.itqop.HubmcEssentials.util.MessageUtil;
|
||||||
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
import org.itqop.HubmcEssentials.util.PlayerUtil;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /repair command - Repair item in hand.
|
* /repair command - Repair item in hand.
|
||||||
* Permission: hubmc.cmd.repair
|
* Permission: hubmc.cmd.repair
|
||||||
|
|
@ -63,24 +65,28 @@ public class RepairCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repair item
|
// Set cooldown FIRST
|
||||||
handItem.setDamageValue(0);
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownRepair).thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MessageUtil.sendSuccess(player, "Предмет отремонтирован");
|
// NOW perform action - repair item
|
||||||
|
handItem.setDamageValue(0);
|
||||||
// Set cooldown
|
MessageUtil.sendSuccess(player, "Предмет отремонтирован");
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownRepair);
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import net.minecraft.commands.Commands;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import org.itqop.HubmcEssentials.Config;
|
import org.itqop.HubmcEssentials.Config;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
import org.itqop.HubmcEssentials.api.service.CooldownService;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
import org.itqop.HubmcEssentials.permission.PermissionManager;
|
||||||
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
import org.itqop.HubmcEssentials.permission.PermissionNodes;
|
||||||
|
|
@ -53,51 +55,58 @@ public class RtpCommand {
|
||||||
String playerUuid = PlayerUtil.getUUIDString(player);
|
String playerUuid = PlayerUtil.getUUIDString(player);
|
||||||
|
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenAccept(cooldownResponse -> {
|
CooldownService.checkCooldown(playerUuid, COOLDOWN_TYPE).thenCompose(cooldownResponse -> {
|
||||||
if (cooldownResponse == null) {
|
if (cooldownResponse == null) {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cooldownResponse.isActive()) {
|
if (cooldownResponse.isActive()) {
|
||||||
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
MessageUtil.sendCooldownMessage(player, cooldownResponse.getRemainingSeconds());
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageUtil.sendInfo(player, "Поиск безопасной локации...");
|
MessageUtil.sendInfo(player, "Поиск безопасной локации...");
|
||||||
|
|
||||||
// Find random safe location
|
// Find random safe location (synchronous, fast operation)
|
||||||
ServerLevel level = player.serverLevel();
|
ServerLevel level = player.serverLevel();
|
||||||
Optional<RandomLocation> randomLoc = findSafeRandomLocation(level);
|
Optional<RandomLocation> randomLoc = findSafeRandomLocation(level);
|
||||||
|
|
||||||
if (randomLoc.isEmpty()) {
|
if (randomLoc.isEmpty()) {
|
||||||
MessageUtil.sendError(player, "Не удалось найти безопасную локацию");
|
MessageUtil.sendError(player, "Не удалось найти безопасную локацию");
|
||||||
return;
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
RandomLocation loc = randomLoc.get();
|
RandomLocation loc = randomLoc.get();
|
||||||
|
|
||||||
// Save current location for /back
|
// Set cooldown FIRST to prevent race condition (only if location found)
|
||||||
LocationStorage.saveLocation(player);
|
return CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownRtp)
|
||||||
|
.thenAccept(success -> {
|
||||||
|
if (!success) {
|
||||||
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Teleport player
|
// NOW perform teleport (cooldown already set)
|
||||||
boolean success = LocationUtil.teleportPlayer(
|
// Save current location for /back
|
||||||
player,
|
LocationStorage.saveLocation(player);
|
||||||
level,
|
|
||||||
loc.x,
|
|
||||||
loc.y,
|
|
||||||
loc.z
|
|
||||||
);
|
|
||||||
|
|
||||||
if (success) {
|
// Teleport player
|
||||||
MessageUtil.sendSuccess(player, "Телепортация на случайную локацию: " +
|
boolean tpSuccess = LocationUtil.teleportPlayer(
|
||||||
MessageUtil.formatCoords(loc.x, loc.y, loc.z));
|
player,
|
||||||
} else {
|
level,
|
||||||
MessageUtil.sendError(player, "Ошибка телепортации");
|
loc.x,
|
||||||
}
|
loc.y,
|
||||||
|
loc.z
|
||||||
|
);
|
||||||
|
|
||||||
// Set cooldown
|
if (tpSuccess) {
|
||||||
CooldownService.createCooldown(playerUuid, COOLDOWN_TYPE, Config.cooldownRtp);
|
MessageUtil.sendSuccess(player, "Телепортация на случайную локацию: " +
|
||||||
|
MessageUtil.formatCoords(loc.x, loc.y, loc.z));
|
||||||
|
} else {
|
||||||
|
MessageUtil.sendError(player, "Ошибка телепортации");
|
||||||
|
}
|
||||||
|
});
|
||||||
}).exceptionally(ex -> {
|
}).exceptionally(ex -> {
|
||||||
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
MessageUtil.sendError(player, MessageUtil.API_UNAVAILABLE);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,27 @@ public final class LocationUtil {
|
||||||
if (feet.is(Blocks.FIRE) || head.is(Blocks.FIRE)) {
|
if (feet.is(Blocks.FIRE) || head.is(Blocks.FIRE)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (ground.is(Blocks.MAGMA_BLOCK)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ground.is(Blocks.CAMPFIRE) || ground.is(Blocks.SOUL_CAMPFIRE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (feet.is(Blocks.CACTUS) || head.is(Blocks.CACTUS) || ground.is(Blocks.CACTUS)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (feet.is(Blocks.SWEET_BERRY_BUSH) || ground.is(Blocks.SWEET_BERRY_BUSH)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (feet.is(Blocks.WITHER_ROSE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (feet.is(Blocks.POWDER_SNOW) || head.is(Blocks.POWDER_SNOW)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (feet.is(Blocks.POINTED_DRIPSTONE) || head.is(Blocks.POINTED_DRIPSTONE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue