mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2026-02-18 17:53:00 +01:00
Compare commits
17 Commits
commandson
...
pr/4925
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a71ef5fc2 | ||
|
|
38e0810f93 | ||
|
|
34fefc1e70 | ||
|
|
7f64987585 | ||
|
|
0603faff33 | ||
|
|
dc8a9102fe | ||
|
|
247d1732e2 | ||
|
|
140cd61fd6 | ||
|
|
4a2020d4af | ||
|
|
7f756c25ab | ||
|
|
715f7217f9 | ||
|
|
760e610226 | ||
|
|
e23e8d3884 | ||
|
|
a7762cd015 | ||
|
|
1781a996b9 | ||
|
|
2cc24db615 | ||
|
|
7e86701119 |
14
pom.xml
14
pom.xml
@@ -189,6 +189,10 @@
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>com.gmail.nossr50.mcmmo.metrics.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.tcoded.folialib</pattern>
|
||||
<shadedPattern>com.gmail.nossr50.mcmmo.folialib</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
<executions>
|
||||
@@ -245,6 +249,10 @@
|
||||
<id>placeholderapi</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>devmart-other</id>
|
||||
<url>https://nexuslite.gcnt.net/repos/other/</url>
|
||||
</repository>
|
||||
<!-- ... -->
|
||||
<!-- ... -->
|
||||
</repositories>
|
||||
@@ -372,5 +380,11 @@
|
||||
<version>32.0.0-jre</version> <!-- At this time Spigot is including 29.0 Guava classes that we are using -->
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tcoded</groupId>
|
||||
<artifactId>FoliaLib</artifactId>
|
||||
<version>0.2.4</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -136,14 +136,15 @@ public class BlockListener implements Listener {
|
||||
|
||||
final BlockFace direction = event.getDirection();
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(mcMMO.p, () -> {
|
||||
for (final Block block : event.getBlocks()) {
|
||||
final Block movedBlock = block.getRelative(direction);
|
||||
mcMMO.p.getFoliaLib().getImpl().runAtLocation(block.getLocation(), () -> {
|
||||
final Block movedBlock = block.getRelative(direction);
|
||||
|
||||
if(BlockUtils.isWithinWorldBounds(movedBlock)) {
|
||||
BlockUtils.setUnnaturalBlock(movedBlock);
|
||||
}
|
||||
}});
|
||||
if (BlockUtils.isWithinWorldBounds(movedBlock)) {
|
||||
BlockUtils.setUnnaturalBlock(movedBlock);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,8 @@ import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class WorldListener implements Listener {
|
||||
private final mcMMO plugin;
|
||||
|
||||
@@ -30,11 +32,12 @@ public class WorldListener implements Listener {
|
||||
if(WorldBlacklist.isWorldBlacklisted(event.getWorld()))
|
||||
return;
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(mcMMO.p, () -> {
|
||||
// Using 50 ms later as I do not know of a way to run one tick later (safely)
|
||||
plugin.getFoliaLib().getImpl().runLater(() -> {
|
||||
for (BlockState blockState : event.getBlocks()) {
|
||||
mcMMO.getPlaceStore().setFalse(blockState);
|
||||
}
|
||||
}, 1);
|
||||
}, 50, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,6 +53,8 @@ import com.gmail.nossr50.util.skills.SkillTools;
|
||||
import com.gmail.nossr50.util.skills.SmeltingTracker;
|
||||
import com.gmail.nossr50.util.upgrade.UpgradeManager;
|
||||
import com.gmail.nossr50.worldguard.WorldGuardManager;
|
||||
import com.tcoded.folialib.FoliaLib;
|
||||
import com.tcoded.folialib.impl.ServerImplementation;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.shatteredlands.shatt.backup.ZipLibrary;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
@@ -74,6 +76,7 @@ import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class mcMMO extends JavaPlugin {
|
||||
|
||||
@@ -137,6 +140,9 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
private GeneralConfig generalConfig;
|
||||
private AdvancedConfig advancedConfig;
|
||||
|
||||
private FoliaLib foliaLib;
|
||||
|
||||
// private RepairConfig repairConfig;
|
||||
// private SalvageConfig salvageConfig;
|
||||
// private PersistentDataConfig persistentDataConfig;
|
||||
@@ -167,6 +173,9 @@ public class mcMMO extends JavaPlugin {
|
||||
//Filter out any debug messages (if debug/verbose logging is not enabled)
|
||||
getLogger().setFilter(new LogFilter(this));
|
||||
|
||||
//Folia lib plugin instance
|
||||
foliaLib = new FoliaLib(this);
|
||||
|
||||
setupFilePaths();
|
||||
generalConfig = new GeneralConfig(getDataFolder()); //Load before skillTools
|
||||
skillTools = new SkillTools(this); //Load after general config
|
||||
@@ -229,18 +238,19 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
if(serverAPIOutdated)
|
||||
{
|
||||
Bukkit
|
||||
.getScheduler()
|
||||
.scheduleSyncRepeatingTask(this,
|
||||
foliaLib
|
||||
.getImpl()
|
||||
.runTimer(
|
||||
() -> getLogger().severe("You are running an outdated version of "+platformManager.getServerSoftware()+", mcMMO will not work unless you update to a newer version!"),
|
||||
20, 20*60*30);
|
||||
20 * 50L, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
|
||||
|
||||
if(platformManager.getServerSoftware() == ServerSoftwareType.CRAFT_BUKKIT)
|
||||
{
|
||||
Bukkit.getScheduler()
|
||||
.scheduleSyncRepeatingTask(this,
|
||||
foliaLib
|
||||
.getImpl()
|
||||
.runTimer(
|
||||
() -> getLogger().severe("We have detected you are using incompatible server software, our best guess is that you are using CraftBukkit. mcMMO requires Spigot or Paper, if you are not using CraftBukkit, you will still need to update your custom server software before mcMMO will work."),
|
||||
20, 20*60*30);
|
||||
20 * 50L, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
} else {
|
||||
registerEvents();
|
||||
@@ -391,7 +401,7 @@ public class mcMMO extends JavaPlugin {
|
||||
}
|
||||
|
||||
LogUtils.debug(mcMMO.p.getLogger(), "Canceling all tasks...");
|
||||
getServer().getScheduler().cancelTasks(this); // This removes our tasks
|
||||
getFoliaLib().getImpl().cancelAllTasks(); // This removes our tasks
|
||||
LogUtils.debug(mcMMO.p.getLogger(), "Unregister all events...");
|
||||
HandlerList.unregisterAll(this); // Cancel event registrations
|
||||
|
||||
@@ -621,11 +631,11 @@ public class mcMMO extends JavaPlugin {
|
||||
}
|
||||
|
||||
private void registerCustomRecipes() {
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
|
||||
getFoliaLib().getImpl().runLater(() -> {
|
||||
if (generalConfig.getChimaeraEnabled()) {
|
||||
getServer().addRecipe(ChimaeraWing.getChimaeraWingRecipe());
|
||||
}
|
||||
}, 40);
|
||||
}, 40 * 50, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void scheduleTasks() {
|
||||
@@ -635,10 +645,10 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
long saveIntervalTicks = Math.max(minute, generalConfig.getSaveInterval() * minute);
|
||||
|
||||
new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
|
||||
new SaveTimerTask().runTaskTimer(saveIntervalTicks, saveIntervalTicks);
|
||||
|
||||
// Cleanup the backups folder
|
||||
new CleanBackupsTask().runTaskAsynchronously(mcMMO.p);
|
||||
getFoliaLib().getImpl().runAsync(new CleanBackupsTask());
|
||||
|
||||
// Old & Powerless User remover
|
||||
long purgeIntervalTicks = generalConfig.getPurgeInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
|
||||
@@ -770,4 +780,8 @@ public class mcMMO extends JavaPlugin {
|
||||
public @NotNull AdvancedConfig getAdvancedConfig() {
|
||||
return advancedConfig;
|
||||
}
|
||||
|
||||
public @NotNull FoliaLib getFoliaLib() {
|
||||
return foliaLib;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,22 +5,26 @@ import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.party.PartyManager;
|
||||
import com.gmail.nossr50.runnables.player.PlayerProfileSaveTask;
|
||||
import com.gmail.nossr50.util.LogUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import com.tcoded.folialib.wrapper.task.WrappedTask;
|
||||
|
||||
public class SaveTimerTask extends BukkitRunnable {
|
||||
@Override
|
||||
public void run() {
|
||||
LogUtils.debug(mcMMO.p.getLogger(), "[User Data] Saving...");
|
||||
// All player data will be saved periodically through this
|
||||
int count = 1;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) {
|
||||
new PlayerProfileSaveTask(mcMMOPlayer.getProfile(), false).runTaskLaterAsynchronously(mcMMO.p, count);
|
||||
count++;
|
||||
}
|
||||
public class SaveTimerTask {
|
||||
public WrappedTask runTaskTimer(long delay, long period) {
|
||||
return mcMMO.p.getFoliaLib().getImpl().runTimer(() -> {
|
||||
LogUtils.debug(mcMMO.p.getLogger(), "[User Data] Saving...");
|
||||
// All player data will be saved periodically through this
|
||||
int count = 1;
|
||||
|
||||
for (McMMOPlayer mcMMOPlayer : UserManager.getPlayers()) {
|
||||
new PlayerProfileSaveTask(mcMMOPlayer.getProfile(), false).runTaskLaterAsynchronously(mcMMO.p, count);
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
PartyManager.saveParties();
|
||||
PartyManager.saveParties();
|
||||
}, delay * Misc.TICK_CONVERSION_FACTOR, period * Misc.TICK_CONVERSION_FACTOR, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ public class DatabaseConversionTask extends BukkitRunnable {
|
||||
public void run() {
|
||||
sourceDatabase.convertUsers(mcMMO.getDatabaseManager());
|
||||
|
||||
mcMMO.p.getServer().getScheduler().runTask(mcMMO.p, () -> sender.sendMessage(message));
|
||||
mcMMO.p.getFoliaLib().getImpl().runNextTick(() -> sender.sendMessage(message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class UUIDUpdateAsyncTask implements Runnable {
|
||||
@@ -109,11 +110,11 @@ public class UUIDUpdateAsyncTask implements Runnable {
|
||||
|
||||
// Bukkit runnables don't let themselves reschedule themselves, so we are a pseudo bukkit runnable.
|
||||
private void runTaskLaterAsynchronously(mcMMO plugin, int delay) {
|
||||
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, this, delay);
|
||||
plugin.getFoliaLib().getImpl().runLaterAsync(this, delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, this);
|
||||
plugin.getFoliaLib().getImpl().runAsync(this);
|
||||
}
|
||||
|
||||
private static UUID toUUID(String id) {
|
||||
|
||||
@@ -27,6 +27,7 @@ public final class Misc {
|
||||
|
||||
public static final int TIME_CONVERSION_FACTOR = 1000;
|
||||
public static final int TICK_CONVERSION_FACTOR = 20;
|
||||
public static final int TICK_MS_CONVERSION_FACTOR = 50;
|
||||
|
||||
public static final int PLAYER_RESPAWN_COOLDOWN_SECONDS = 5;
|
||||
public static final double SKILL_MESSAGE_MAX_SENDING_DISTANCE = 10.0;
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class NotificationManager {
|
||||
|
||||
@@ -296,7 +297,7 @@ public class NotificationManager {
|
||||
String localeMessage = LocaleLoader.getString("Broadcasts.LevelUpMilestone", mmoPlayer.getPlayer().getDisplayName(), level, mcMMO.p.getSkillTools().getLocalizedSkillName(primarySkillType));
|
||||
Component message = LegacyComponentSerializer.legacySection().deserialize(localeMessage).hoverEvent(levelMilestoneHover);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(mcMMO.p, () -> audience.sendMessage(Identity.nil(), message), 0);
|
||||
mcMMO.p.getFoliaLib().getImpl().runNextTick(() -> audience.sendMessage(Identity.nil(), message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,7 +332,7 @@ public class NotificationManager {
|
||||
String localeMessage = LocaleLoader.getString("Broadcasts.PowerLevelUpMilestone", mmoPlayer.getPlayer().getDisplayName(), powerLevel);
|
||||
Component message = LegacyComponentSerializer.legacySection().deserialize(localeMessage).hoverEvent(levelMilestoneHover);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(mcMMO.p, () -> audience.sendMessage(Identity.nil(), message), 0);
|
||||
mcMMO.p.getFoliaLib().getImpl().runNextTick(() -> audience.sendMessage(Identity.nil(), message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,10 @@ import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.scoreboards.ScoreboardManager.SidebarType;
|
||||
import com.gmail.nossr50.util.skills.SkillTools;
|
||||
import com.tcoded.folialib.wrapper.task.WrappedTask;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.scoreboard.DisplaySlot;
|
||||
import org.bukkit.scoreboard.Objective;
|
||||
import org.bukkit.scoreboard.Score;
|
||||
@@ -32,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ScoreboardWrapper {
|
||||
public static final String SIDE_OBJECTIVE = "mcMMO_sideObjective";
|
||||
@@ -86,38 +85,40 @@ public class ScoreboardWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitTask updateTask = null;
|
||||
public WrappedTask updateTask = null;
|
||||
|
||||
private class ScoreboardQuickUpdate extends BukkitRunnable {
|
||||
@Override
|
||||
public void run() {
|
||||
updateSidebar();
|
||||
updateTask = null;
|
||||
private class ScoreboardQuickUpdate {
|
||||
public WrappedTask runTaskLater(long delay) {
|
||||
return mcMMO.p.getFoliaLib().getImpl().runLater(() -> {
|
||||
updateSidebar();
|
||||
updateTask = null;
|
||||
}, delay * Misc.TICK_CONVERSION_FACTOR, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitTask revertTask = null;
|
||||
public WrappedTask revertTask = null;
|
||||
|
||||
private class ScoreboardChangeTask extends BukkitRunnable {
|
||||
@Override
|
||||
public void run() {
|
||||
tryRevertBoard();
|
||||
revertTask = null;
|
||||
private class ScoreboardChangeTask {
|
||||
public WrappedTask runTaskLater(long delay) {
|
||||
return mcMMO.p.getFoliaLib().getImpl().runLater(() -> {
|
||||
tryRevertBoard();
|
||||
revertTask = null;
|
||||
}, delay * Misc.TICK_CONVERSION_FACTOR, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitTask cooldownTask = null;
|
||||
public WrappedTask cooldownTask = null;
|
||||
|
||||
private class ScoreboardCooldownTask extends BukkitRunnable {
|
||||
@Override
|
||||
public void run() {
|
||||
// Stop updating if it's no longer something displaying cooldowns
|
||||
if (isBoardShown() && (isSkillScoreboard() || isCooldownScoreboard())) {
|
||||
doSidebarUpdateSoon();
|
||||
}
|
||||
else {
|
||||
stopCooldownUpdating();
|
||||
}
|
||||
private class ScoreboardCooldownTask {
|
||||
public WrappedTask runTaskTimer(long delay, long period) {
|
||||
return mcMMO.p.getFoliaLib().getImpl().runTimer(() -> {
|
||||
// Stop updating if it's no longer something displaying cooldowns
|
||||
if (isBoardShown() && (isSkillScoreboard() || isCooldownScoreboard())) {
|
||||
doSidebarUpdateSoon();
|
||||
} else {
|
||||
stopCooldownUpdating();
|
||||
}
|
||||
}, delay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +126,7 @@ public class ScoreboardWrapper {
|
||||
public void doSidebarUpdateSoon() {
|
||||
if (updateTask == null) {
|
||||
// To avoid spamming the scheduler, store the instance and run 2 ticks later
|
||||
updateTask = new ScoreboardQuickUpdate().runTaskLater(mcMMO.p, 2L);
|
||||
updateTask = new ScoreboardQuickUpdate().runTaskLater(2L);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,7 +134,7 @@ public class ScoreboardWrapper {
|
||||
if (cooldownTask == null) {
|
||||
// Repeat every 5 seconds.
|
||||
// Cancels once all cooldowns are done, using stopCooldownUpdating().
|
||||
cooldownTask = new ScoreboardCooldownTask().runTaskTimer(mcMMO.p, 5 * Misc.TICK_CONVERSION_FACTOR, 5 * Misc.TICK_CONVERSION_FACTOR);
|
||||
cooldownTask = new ScoreboardCooldownTask().runTaskTimer(5 * Misc.TICK_CONVERSION_FACTOR, 5 * Misc.TICK_CONVERSION_FACTOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,7 +217,7 @@ public class ScoreboardWrapper {
|
||||
}
|
||||
|
||||
player.setScoreboard(scoreboard);
|
||||
revertTask = new ScoreboardChangeTask().runTaskLater(mcMMO.p, ticks);
|
||||
revertTask = new ScoreboardChangeTask().runTaskLater(ticks);
|
||||
|
||||
// TODO is there any way to do the time that looks acceptable?
|
||||
// player.sendMessage(LocaleLoader.getString("Commands.Scoreboard.Timer", StringUtils.capitalize(sidebarType.toString().toLowerCase(Locale.ENGLISH)), ticks / 20F));
|
||||
@@ -426,7 +427,7 @@ public class ScoreboardWrapper {
|
||||
NotificationManager.sendPlayerInformationChatOnlyPrefixed(player, "Scoreboard.Recovery");
|
||||
|
||||
initBoard(); //Start over
|
||||
Bukkit.getScheduler().runTaskLater(mcMMO.p, () -> ScoreboardManager.retryLastSkillBoard(player), 0);
|
||||
mcMMO.p.getFoliaLib().getImpl().runLater(() -> ScoreboardManager.retryLastSkillBoard(player), 0, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class CombatUtils {
|
||||
|
||||
@@ -982,6 +983,6 @@ public final class CombatUtils {
|
||||
* @param entity the projectile
|
||||
*/
|
||||
public static void delayArrowMetaCleanup(@NotNull Projectile entity) {
|
||||
Bukkit.getServer().getScheduler().runTaskLater(mcMMO.p, () -> cleanupArrowMetadata(entity), 20*60);
|
||||
mcMMO.p.getFoliaLib().getImpl().runLater(() -> cleanupArrowMetadata(entity), 1000 * 60, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ website: https://www.mcmmo.org
|
||||
main: com.gmail.nossr50.mcMMO
|
||||
softdepend: [WorldGuard, CombatTag, HealthBar, PlaceholderAPI]
|
||||
load: POSTWORLD
|
||||
folia-supported: true
|
||||
api-version: 1.13
|
||||
|
||||
commands:
|
||||
|
||||
Reference in New Issue
Block a user