mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-22 13:16:45 +01:00
Merge branch 'v5' into v6
# Conflicts: # Bukkit/build.gradle # Bukkit/pom.xml # Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java # Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEventListener.java # Bukkit/src/main/java/com/plotsquared/bukkit/uuid/BungeePermsUUIDService.java # Core/src/main/java/com/plotsquared/core/PlotPlatform.java # Core/src/main/java/com/plotsquared/core/command/DebugPaste.java # Core/src/main/java/com/plotsquared/core/command/Grant.java # build.gradle
This commit is contained in:
commit
544d57c720
@ -13,6 +13,7 @@ repositories {
|
|||||||
url = "https://papermc.io/repo/repository/maven-public/"
|
url = "https://papermc.io/repo/repository/maven-public/"
|
||||||
}
|
}
|
||||||
maven { url = "https://ci.ender.zone/plugin/repository/everything/" }
|
maven { url = "https://ci.ender.zone/plugin/repository/everything/" }
|
||||||
|
maven { url = "https://mvn.intellectualsites.com/content/repositories/releases" }
|
||||||
maven { url = "https://mvn.intellectualsites.com/content/repositories/snapshots" }
|
maven { url = "https://mvn.intellectualsites.com/content/repositories/snapshots" }
|
||||||
maven { url = "https://repo.wea-ondara.net/repository/public/" }
|
maven { url = "https://repo.wea-ondara.net/repository/public/" }
|
||||||
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||||
@ -28,7 +29,6 @@ dependencies {
|
|||||||
implementation("org.spigotmc:spigot-api:1.16.2-R0.1-SNAPSHOT")
|
implementation("org.spigotmc:spigot-api:1.16.2-R0.1-SNAPSHOT")
|
||||||
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.2.0-SNAPSHOT") {
|
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.2.0-SNAPSHOT") {
|
||||||
exclude(module: "bukkit")
|
exclude(module: "bukkit")
|
||||||
|
|
||||||
}
|
}
|
||||||
compile("io.papermc:paperlib:1.0.4")
|
compile("io.papermc:paperlib:1.0.4")
|
||||||
implementation("net.kyori:text-adapter-bukkit:3.0.3")
|
implementation("net.kyori:text-adapter-bukkit:3.0.3")
|
||||||
@ -45,7 +45,7 @@ dependencies {
|
|||||||
implementation('net.kyori:adventure-text-minimessage:4.0.0-SNAPSHOT')
|
implementation('net.kyori:adventure-text-minimessage:4.0.0-SNAPSHOT')
|
||||||
compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false }
|
compile("se.hyperver.hyperverse:Core:0.6.0-SNAPSHOT"){ transitive = false }
|
||||||
compile('com.sk89q:squirrelid:1.0.0-SNAPSHOT'){ transitive = false }
|
compile('com.sk89q:squirrelid:1.0.0-SNAPSHOT'){ transitive = false }
|
||||||
compile('be.maximvdw:MVdWPlaceholderAPI:3.1.1-SNAPSHOT'){ transitive = false }
|
compile('be.maximvdw:MVdWPlaceholderAPI:3.1.1'){ transitive = false }
|
||||||
// logging
|
// logging
|
||||||
implementation('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1')
|
implementation('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1')
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>be.maximvdw</groupId>
|
<groupId>be.maximvdw</groupId>
|
||||||
<artifactId>MVdWPlaceholderAPI</artifactId>
|
<artifactId>MVdWPlaceholderAPI</artifactId>
|
||||||
<version>3.1.1-SNAPSHOT</version>
|
<version>3.1.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
@ -59,7 +59,6 @@ import com.plotsquared.bukkit.util.UpdateUtility;
|
|||||||
import com.plotsquared.bukkit.util.task.BukkitTaskManager;
|
import com.plotsquared.bukkit.util.task.BukkitTaskManager;
|
||||||
import com.plotsquared.bukkit.util.task.PaperTimeConverter;
|
import com.plotsquared.bukkit.util.task.PaperTimeConverter;
|
||||||
import com.plotsquared.bukkit.util.task.SpigotTimeConverter;
|
import com.plotsquared.bukkit.util.task.SpigotTimeConverter;
|
||||||
import com.plotsquared.bukkit.uuid.BungeePermsUUIDService;
|
|
||||||
import com.plotsquared.bukkit.uuid.EssentialsUUIDService;
|
import com.plotsquared.bukkit.uuid.EssentialsUUIDService;
|
||||||
import com.plotsquared.bukkit.uuid.LuckPermsUUIDService;
|
import com.plotsquared.bukkit.uuid.LuckPermsUUIDService;
|
||||||
import com.plotsquared.bukkit.uuid.OfflinePlayerUUIDService;
|
import com.plotsquared.bukkit.uuid.OfflinePlayerUUIDService;
|
||||||
@ -423,14 +422,6 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
|
|||||||
luckPermsUUIDService = null;
|
luckPermsUUIDService = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final BungeePermsUUIDService bungeePermsUUIDService;
|
|
||||||
if (Settings.UUID.SERVICE_BUNGEE_PERMS && Bukkit.getPluginManager().getPlugin("BungeePerms") != null) {
|
|
||||||
bungeePermsUUIDService = new BungeePermsUUIDService();
|
|
||||||
logger.info("(UUID) Using BungeePerms as a complementary UUID service");
|
|
||||||
} else {
|
|
||||||
bungeePermsUUIDService = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final EssentialsUUIDService essentialsUUIDService;
|
final EssentialsUUIDService essentialsUUIDService;
|
||||||
if (Settings.UUID.SERVICE_ESSENTIALSX && Bukkit.getPluginManager().getPlugin("Essentials") != null) {
|
if (Settings.UUID.SERVICE_ESSENTIALSX && Bukkit.getPluginManager().getPlugin("Essentials") != null) {
|
||||||
essentialsUUIDService = new EssentialsUUIDService();
|
essentialsUUIDService = new EssentialsUUIDService();
|
||||||
@ -463,10 +454,6 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
|
|||||||
this.impromptuPipeline.registerService(luckPermsUUIDService);
|
this.impromptuPipeline.registerService(luckPermsUUIDService);
|
||||||
this.backgroundPipeline.registerService(luckPermsUUIDService);
|
this.backgroundPipeline.registerService(luckPermsUUIDService);
|
||||||
}
|
}
|
||||||
if (bungeePermsUUIDService != null) {
|
|
||||||
this.impromptuPipeline.registerService(bungeePermsUUIDService);
|
|
||||||
this.backgroundPipeline.registerService(bungeePermsUUIDService);
|
|
||||||
}
|
|
||||||
if (essentialsUUIDService != null) {
|
if (essentialsUUIDService != null) {
|
||||||
this.impromptuPipeline.registerService(essentialsUUIDService);
|
this.impromptuPipeline.registerService(essentialsUUIDService);
|
||||||
this.backgroundPipeline.registerService(essentialsUUIDService);
|
this.backgroundPipeline.registerService(essentialsUUIDService);
|
||||||
@ -1047,13 +1034,21 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
|
|||||||
return new BukkitPlotGenerator(world, generator, this.plotAreaManager);
|
return new BukkitPlotGenerator(world, generator, this.plotAreaManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public List<Map.Entry<Map.Entry<String, String>, Boolean>> getPluginIds() {
|
@Override public String getPluginList() {
|
||||||
List<Map.Entry<Map.Entry<String, String>, Boolean>> names = new ArrayList<>();
|
StringBuilder msg = new StringBuilder();
|
||||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
Plugin[] plugins = Bukkit.getServer().getPluginManager().getPlugins();
|
||||||
Map.Entry<String, String> id = new AbstractMap.SimpleEntry<>(plugin.getName(), plugin.getDescription().getVersion());
|
msg.append("Plugins (").append(plugins.length).append("): \n");
|
||||||
names.add(new AbstractMap.SimpleEntry<>(id, plugin.isEnabled()));
|
for (Plugin p : plugins) {
|
||||||
|
msg.append(" - ").append(p.getName()).append(":").append("\n")
|
||||||
|
.append(" • Version: ").append(p.getDescription().getVersion()).append("\n")
|
||||||
|
.append(" • Enabled: ").append(p.isEnabled()).append("\n")
|
||||||
|
.append(" • Main: ").append(p.getDescription().getMain()).append("\n")
|
||||||
|
.append(" • Authors: ").append(p.getDescription().getAuthors()).append("\n")
|
||||||
|
.append(" • Load Before: ").append(p.getDescription().getLoadBefore()).append("\n")
|
||||||
|
.append(" • Dependencies: ").append(p.getDescription().getDepend()).append("\n")
|
||||||
|
.append(" • Soft Dependencies: ").append(p.getDescription().getSoftDepend()).append("\n");
|
||||||
}
|
}
|
||||||
return names;
|
return msg.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public com.plotsquared.core.location.World<?> getPlatformWorld(@Nonnull final String worldName) {
|
@Override @Nonnull public com.plotsquared.core.location.World<?> getPlatformWorld(@Nonnull final String worldName) {
|
||||||
@ -1061,7 +1056,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public Audience getConsoleAudience() {
|
@Override @Nonnull public Audience getConsoleAudience() {
|
||||||
return BukkitUtil.BUKKIT_AUDIENCES.audience(Bukkit.getConsoleSender());
|
return BukkitUtil.BUKKIT_AUDIENCES.console();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public String getPluginName() {
|
@Override public String getPluginName() {
|
||||||
|
@ -229,18 +229,24 @@ public class PaperListener implements Listener {
|
|||||||
}
|
}
|
||||||
Plot plot = location.getOwnedPlotAbs();
|
Plot plot = location.getOwnedPlotAbs();
|
||||||
if (plot == null) {
|
if (plot == null) {
|
||||||
|
EntityType type = event.getType();
|
||||||
if (!area.isMobSpawning()) {
|
if (!area.isMobSpawning()) {
|
||||||
EntityType type = event.getType();
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DROPPED_ITEM:
|
case DROPPED_ITEM:
|
||||||
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
|
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
|
||||||
event.setShouldAbortSpawn(true);
|
event.setShouldAbortSpawn(true);
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
case PLAYER:
|
case PLAYER:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (type.isAlive()) {
|
||||||
|
event.setShouldAbortSpawn(true);
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!area.isMiscSpawnUnowned() && !type.isAlive()) {
|
||||||
event.setShouldAbortSpawn(true);
|
event.setShouldAbortSpawn(true);
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ import org.bukkit.FluidCollisionMode;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.data.Waterlogged;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.entity.ArmorStand;
|
import org.bukkit.entity.ArmorStand;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@ -1118,9 +1119,16 @@ public class PlayerEventListener extends PlotListener implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onBucketEmpty(PlayerBucketEmptyEvent event) {
|
public void onBucketEmpty(PlayerBucketEmptyEvent event) {
|
||||||
BlockFace bf = event.getBlockFace();
|
BlockFace bf = event.getBlockFace();
|
||||||
Block block =
|
final Block block;
|
||||||
event.getBlockClicked().getLocation().add(bf.getModX(), bf.getModY(), bf.getModZ())
|
// if the block can be waterlogged, the event might waterlog the block
|
||||||
.getBlock();
|
// sometimes
|
||||||
|
if (event.getBlockClicked().getBlockData() instanceof Waterlogged) {
|
||||||
|
block = event.getBlockClicked();
|
||||||
|
} else {
|
||||||
|
block = event.getBlockClicked().getLocation()
|
||||||
|
.add(bf.getModX(), bf.getModY(), bf.getModZ())
|
||||||
|
.getBlock();
|
||||||
|
}
|
||||||
Location location = BukkitUtil.adapt(block.getLocation());
|
Location location = BukkitUtil.adapt(block.getLocation());
|
||||||
PlotArea area = location.getPlotArea();
|
PlotArea area = location.getPlotArea();
|
||||||
if (area == null) {
|
if (area == null) {
|
||||||
|
@ -142,8 +142,6 @@ public interface PlotPlatform<P> extends LocaleHolder {
|
|||||||
return getInjector().getInstance(Key.get(IndependentPlotGenerator.class, DefaultGenerator.class));
|
return getInjector().getInstance(Key.get(IndependentPlotGenerator.class, DefaultGenerator.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Map.Entry<Map.Entry<String, String>, Boolean>> getPluginIds();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the backup manager instance
|
* Get the backup manager instance
|
||||||
*
|
*
|
||||||
@ -256,6 +254,8 @@ public interface PlotPlatform<P> extends LocaleHolder {
|
|||||||
*/
|
*/
|
||||||
@Nonnull Audience getConsoleAudience();
|
@Nonnull Audience getConsoleAudience();
|
||||||
|
|
||||||
|
String getPluginList();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the caption maps
|
* Load the caption maps
|
||||||
*/
|
*/
|
||||||
|
@ -103,28 +103,21 @@ public class DebugPaste extends SubCommand {
|
|||||||
.append("\n");
|
.append("\n");
|
||||||
b.append("online_mode: ").append(!Settings.UUID.OFFLINE).append(';')
|
b.append("online_mode: ").append(!Settings.UUID.OFFLINE).append(';')
|
||||||
.append(!Settings.UUID.OFFLINE).append('\n');
|
.append(!Settings.UUID.OFFLINE).append('\n');
|
||||||
b.append("Plugins:");
|
b.append(PlotSquared.platform().getPluginList());
|
||||||
for (Map.Entry<Map.Entry<String, String>, Boolean> pluginInfo : PlotSquared
|
|
||||||
.platform().getPluginIds()) {
|
|
||||||
Map.Entry<String, String> nameVersion = pluginInfo.getKey();
|
|
||||||
String name = nameVersion.getKey();
|
|
||||||
String version = nameVersion.getValue();
|
|
||||||
boolean enabled = pluginInfo.getValue();
|
|
||||||
b.append("\n ").append(name).append(":\n ").append("version: '")
|
|
||||||
.append(version).append('\'').append("\n enabled: ").append(enabled);
|
|
||||||
}
|
|
||||||
b.append("\n\n# YAY! Now, let's see what we can find in your JVM\n");
|
b.append("\n\n# YAY! Now, let's see what we can find in your JVM\n");
|
||||||
Runtime runtime = Runtime.getRuntime();
|
Runtime runtime = Runtime.getRuntime();
|
||||||
RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
||||||
b.append("Uptime: ").append(
|
b.append("Uptime: ")
|
||||||
TimeUnit.MINUTES.convert(rb.getUptime(), TimeUnit.MILLISECONDS) + " minutes")
|
.append(TimeUnit.MINUTES.convert(rb.getUptime(), TimeUnit.MILLISECONDS))
|
||||||
|
.append(" minutes")
|
||||||
.append('\n');
|
.append('\n');
|
||||||
b.append("JVM Flags: ").append(rb.getInputArguments()).append('\n');
|
b.append("JVM Flags: ").append(rb.getInputArguments()).append('\n');
|
||||||
b.append("Free Memory: ").append(runtime.freeMemory() / 1024 / 1024 + " MB")
|
b.append("Free Memory: ").append(runtime.freeMemory() / 1024 / 1024).append(" MB")
|
||||||
.append('\n');
|
.append('\n');
|
||||||
b.append("Max Memory: ").append(runtime.maxMemory() / 1024 / 1024 + " MB")
|
b.append("Max Memory: ").append(runtime.maxMemory() / 1024 / 1024).append(" MB")
|
||||||
|
.append('\n');
|
||||||
|
b.append("Total Memory: ").append(runtime.totalMemory() / 1024 / 1024).append(" MB")
|
||||||
.append('\n');
|
.append('\n');
|
||||||
b.append("Total Memory: ").append(runtime.totalMemory() / 1024 / 1024 + " MB").append('\n');
|
|
||||||
b.append("Available Processors: ").append(runtime.availableProcessors()).append('\n');
|
b.append("Available Processors: ").append(runtime.availableProcessors()).append('\n');
|
||||||
b.append("Java Name: ").append(rb.getVmName()).append('\n');
|
b.append("Java Name: ").append(rb.getVmName()).append('\n');
|
||||||
b.append("Java Version: '").append(System.getProperty("java.version"))
|
b.append("Java Version: '").append(System.getProperty("java.version"))
|
||||||
|
@ -39,11 +39,11 @@ import com.plotsquared.core.util.task.RunnableVal;
|
|||||||
import com.plotsquared.core.util.task.RunnableVal2;
|
import com.plotsquared.core.util.task.RunnableVal2;
|
||||||
import com.plotsquared.core.util.task.RunnableVal3;
|
import com.plotsquared.core.util.task.RunnableVal3;
|
||||||
import net.kyori.adventure.text.minimessage.Template;
|
import net.kyori.adventure.text.minimessage.Template;
|
||||||
|
import com.plotsquared.core.uuid.UUIDMapping;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -86,8 +86,8 @@ public class Grant extends Command {
|
|||||||
Template.of("value", String.valueOf(uuids))
|
Template.of("value", String.valueOf(uuids))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
final UUID uuid = uuids.toArray(new UUID[0])[0];
|
final UUIDMapping uuid = uuids.toArray(new UUIDMapping[0])[0];
|
||||||
PlotPlayer<?> pp = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
|
PlotPlayer<?> pp = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid.getUuid());
|
||||||
if (pp != null) {
|
if (pp != null) {
|
||||||
try (final MetaDataAccess<Integer> access = pp.accessPersistentMetaData(
|
try (final MetaDataAccess<Integer> access = pp.accessPersistentMetaData(
|
||||||
PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) {
|
PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) {
|
||||||
@ -99,7 +99,7 @@ public class Grant extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DBFunc.getPersistentMeta(uuid, new RunnableVal<Map<String, byte[]>>() {
|
DBFunc.getPersistentMeta(uuid.getUuid(), new RunnableVal<Map<String, byte[]>>() {
|
||||||
@Override public void run(Map<String, byte[]> value) {
|
@Override public void run(Map<String, byte[]> value) {
|
||||||
final byte[] array = value.get("grantedPlots");
|
final byte[] array = value.get("grantedPlots");
|
||||||
if (arg0.equals("check")) { // check
|
if (arg0.equals("check")) { // check
|
||||||
@ -123,7 +123,7 @@ public class Grant extends Command {
|
|||||||
boolean replace = array != null;
|
boolean replace = array != null;
|
||||||
String key = "grantedPlots";
|
String key = "grantedPlots";
|
||||||
byte[] rawData = Ints.toByteArray(amount);
|
byte[] rawData = Ints.toByteArray(amount);
|
||||||
DBFunc.addPersistentMeta(uuid, key, rawData, replace);
|
DBFunc.addPersistentMeta(uuid.getUuid(), key, rawData, replace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -267,8 +267,6 @@ public class Settings extends Config {
|
|||||||
public static boolean SERVICE_BUKKIT = true;
|
public static boolean SERVICE_BUKKIT = true;
|
||||||
@Comment("Whether the EssentialsX service is enabled")
|
@Comment("Whether the EssentialsX service is enabled")
|
||||||
public static boolean SERVICE_ESSENTIALSX = true;
|
public static boolean SERVICE_ESSENTIALSX = true;
|
||||||
@Comment("Whether the BungeePerms service is enabled")
|
|
||||||
public static boolean SERVICE_BUNGEE_PERMS = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ public enum CommonSetupSteps implements SetupStep {
|
|||||||
|
|
||||||
private static boolean isValidWorldName(String s) {
|
private static boolean isValidWorldName(String s) {
|
||||||
return s.chars().allMatch((i) -> {
|
return s.chars().allMatch((i) -> {
|
||||||
return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46;
|
return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 65 && i <= 90 || i >= 48 && i <= 57 || i == 46;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user