mirror of
https://github.com/Aust1n46/VentureChat.git
synced 2025-05-22 18:09:06 +00:00
Tweaked player data system to better handle offline UUID's.
This commit is contained in:
parent
6f5fb0976a
commit
f00b123d9e
@ -1,53 +1,11 @@
|
||||
#===============================================================
|
||||
# MineverseChat Config =
|
||||
# Author: Aust1n46 =
|
||||
# MineverseChat Bungee Config =
|
||||
# Author: Aust1n46 =
|
||||
#===============================================================
|
||||
|
||||
# - regex1,regex2
|
||||
# Simple regex tips: Use \b to "cut" a section of the word or phrase. Example: \bass,donuts
|
||||
# Example filtered sentence: You are an ass. Will become: You are an donuts.
|
||||
# Example filtered sentence: You caught a bass. Will stay: You caught a bass.
|
||||
# Example filtered sentence: You are an asshole. Will become: You are an donutshole.
|
||||
# Default filters by Jabelpeeps
|
||||
filters:
|
||||
- (\banus),donuts
|
||||
- (\ba+r*(se+|ss+(?!(ass|um|oc|ign)).*?|s*e*h+[o0]*[l1]+e*[sz]*)\b),donuts
|
||||
- (b[i1]a?tch(es)?),puppy
|
||||
- Carpet Muncher,cookie monster
|
||||
- (\bc((?!ook\b)[o0]+c*|aw)k\W?(sucker|s*|he[ea]*d)\b),rooster
|
||||
- (\b[ck]r+a+p+(er|s|z)?\b),poopoo
|
||||
- (\bcum+\b),go
|
||||
- (\b[ck](u*n+|[l1]+[i1]+)t+[sz]*\b),peach
|
||||
- (\bd[1i](c?k(head)?|[l1]+d[o0])e?[sz]?\b),rooster
|
||||
- (\bd[1i]+n+g+u+s+),discus
|
||||
- f u c k( e r)?,nono
|
||||
- (\bfai*g+[oei1]*t*[sz]*\b),cigar
|
||||
- Fudge Packer,fine person
|
||||
- (\b(m[uo]+th[ae]r?)?(f|ph)uc*k*(e[rn]|ah*|ing?|)[sz]?\b),oh dear
|
||||
- (\b(j(ac|er|ur)k\W?(of+))|(ji[sz]+i*m*)\b),bake brownies
|
||||
- (\b(ma+s+te?rbai?te?[rs]?|wank(er)?[sz]?)\b),bake brownies
|
||||
- orafi(s|ce),rooster
|
||||
- (\bp+[e3]+[ai]*n+[i1!ua]+s+),rooster
|
||||
- (\bp[i1]s+(flap|face|drop)?),peepee
|
||||
- (\bsh[i1!y]t+(er?|y|head)?[sz]*),poopoo
|
||||
- (\bva[1i]?[gj]+[i1]+na+\b),peach
|
||||
- vu[1l]+va,peach
|
||||
- planet ?minecraft,another dimension
|
||||
- pmc,another dimension
|
||||
- ((\d+\.){3}\d+),another dimension
|
||||
|
||||
# {playerto} : player receivings name
|
||||
# {playerfrom} : player sendings name
|
||||
tellformatto: Default
|
||||
tellformatfrom: Default
|
||||
tellformatspy: Default
|
||||
replyformatto: Default
|
||||
replyformatfrom: Default
|
||||
replyformatspy: Default
|
||||
|
||||
tellcolor: white
|
||||
|
||||
# enable bungeecord messaging
|
||||
messaging: true
|
||||
# enable bungeecord muting
|
||||
muting: true
|
||||
# If you're running a "cracked" server, player data might not be stored properly, and thus, you are on your own.
|
||||
# If you run your server in offline mode, you might have to reset your player data when switching to online mode!
|
||||
# If you see this warning by accident and you are using BungeeCord, make sure you have properly setup IP Forwarding.
|
||||
# https://www.spigotmc.org/wiki/bungeecord-ip-forwarding/
|
||||
# No player data will be saved in offline mode unless you set this acknowledgement to 'true'
|
||||
offline_server_acknowledgement: false
|
@ -1,6 +1,6 @@
|
||||
#===============================================================
|
||||
# VentureChat Config =
|
||||
# Author: Aust1n46 =
|
||||
# Author: Aust1n46 =
|
||||
#===============================================================
|
||||
|
||||
# - regex1,regex2
|
||||
|
@ -1,6 +1,6 @@
|
||||
#===============================================================
|
||||
# VentureChat Config =
|
||||
# Author: Aust1n46 =
|
||||
# Author: Aust1n46 =
|
||||
#===============================================================
|
||||
|
||||
# - regex1,regex2
|
||||
|
@ -49,7 +49,6 @@ public class MineverseChatPlayer {
|
||||
private boolean rangedSpy;
|
||||
private boolean messageToggle;
|
||||
private boolean bungeeToggle;
|
||||
private boolean tempData;
|
||||
|
||||
//buttons variable no longer used
|
||||
//mail variable no longer used
|
||||
@ -59,10 +58,6 @@ public class MineverseChatPlayer {
|
||||
}
|
||||
|
||||
public MineverseChatPlayer(UUID uuid, String name, ChatChannel currentChannel, Set<UUID> ignores, Set<String> listening, HashMap<String, Integer> mutes, Set<String> blockedCommands, boolean host, UUID party, boolean filter, boolean notifications, String nickname, String jsonFormat, boolean spy, boolean commandSpy, boolean rangedSpy, boolean messageToggle, boolean bungeeToggle) {
|
||||
this(uuid, name, currentChannel, ignores, listening, mutes, blockedCommands, host, party, filter, notifications, nickname, jsonFormat, spy, commandSpy, rangedSpy, messageToggle, bungeeToggle, false);
|
||||
}
|
||||
|
||||
public MineverseChatPlayer(UUID uuid, String name, ChatChannel currentChannel, Set<UUID> ignores, Set<String> listening, HashMap<String, Integer> mutes, Set<String> blockedCommands, boolean host, UUID party, boolean filter, boolean notifications, String nickname, String jsonFormat, boolean spy, boolean commandSpy, boolean rangedSpy, boolean messageToggle, boolean bungeeToggle, boolean tempData) {
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.currentChannel = currentChannel;
|
||||
@ -93,11 +88,6 @@ public class MineverseChatPlayer {
|
||||
this.spam = new HashMap<ChatChannel, List<Integer>>();
|
||||
this.messageToggle = messageToggle;
|
||||
this.bungeeToggle = bungeeToggle;
|
||||
this.tempData = tempData;
|
||||
}
|
||||
|
||||
public boolean isTempData() {
|
||||
return tempData;
|
||||
}
|
||||
|
||||
public boolean getBungeeToggle() {
|
||||
|
@ -4,6 +4,8 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@ -17,20 +19,26 @@ import mineverse.Aust1n46.chat.bungee.command.GlobalMuteAll;
|
||||
import mineverse.Aust1n46.chat.bungee.command.GlobalUnmute;
|
||||
import mineverse.Aust1n46.chat.bungee.command.GlobalUnmuteAll;
|
||||
import mineverse.Aust1n46.chat.database.BungeePlayerData;
|
||||
import mineverse.Aust1n46.chat.utilities.UUIDFetcher;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.event.ServerDisconnectEvent;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
import net.md_5.bungee.config.ConfigurationProvider;
|
||||
import net.md_5.bungee.config.YamlConfiguration;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
//This is the main class for the BungeeCord version of the plugin.
|
||||
public class MineverseChatBungee extends Plugin implements Listener {
|
||||
private static MineverseChatBungee instance;
|
||||
private Configuration bungeeConfig;
|
||||
public Map<String, String> ignore = new HashMap<String, String>();
|
||||
public Map<String, Boolean> spy = new HashMap<String, Boolean>();
|
||||
public static Set<SynchronizedMineverseChatPlayer> players = new HashSet<SynchronizedMineverseChatPlayer>();
|
||||
@ -40,6 +48,20 @@ public class MineverseChatBungee extends Plugin implements Listener {
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
||||
if(!getDataFolder().exists()) {
|
||||
getDataFolder().mkdir();
|
||||
}
|
||||
File config = new File(getDataFolder(), "bungeeconfig.yml");
|
||||
try {
|
||||
if(!config.exists()) {
|
||||
Files.copy(getResourceAsStream("bungeeconfig.yml"), config.toPath());
|
||||
}
|
||||
bungeeConfig = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "bungeeconfig.yml"));
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
BungeePlayerData.loadLegacyBungeePlayerData();
|
||||
BungeePlayerData.loadBungeePlayerData();
|
||||
|
||||
@ -73,6 +95,10 @@ public class MineverseChatBungee extends Plugin implements Listener {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Configuration getBungeeConfig() {
|
||||
return bungeeConfig;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(ServerSwitchEvent event) {
|
||||
updatePlayerNames();
|
||||
@ -83,6 +109,11 @@ public class MineverseChatBungee extends Plugin implements Listener {
|
||||
updatePlayerNames();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoinNetwork(PostLoginEvent event) {
|
||||
UUIDFetcher.checkOfflineUUIDWarningBungee(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
private void updatePlayerNames() {
|
||||
try {
|
||||
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
|
||||
|
@ -14,6 +14,7 @@ import java.util.UUID;
|
||||
import mineverse.Aust1n46.chat.api.SynchronizedMineverseChatPlayer;
|
||||
import mineverse.Aust1n46.chat.bungee.MineverseChatBungee;
|
||||
import mineverse.Aust1n46.chat.utilities.Format;
|
||||
import mineverse.Aust1n46.chat.utilities.UUIDFetcher;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
@ -40,6 +41,10 @@ public class BungeePlayerData {
|
||||
Configuration playerData = ConfigurationProvider.getProvider(YamlConfiguration.class).load(sync);
|
||||
for(String uuidString : playerData.getKeys()) {
|
||||
UUID uuid = UUID.fromString(uuidString);
|
||||
if(UUIDFetcher.shouldSkipOfflineUUIDBungee(uuid)) {
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - Skipping Offline UUID: " + uuid)));
|
||||
continue;
|
||||
}
|
||||
Set<String> listening = new HashSet<String>();
|
||||
StringTokenizer l = new StringTokenizer(playerData.getString(uuidString + ".channels"), ",");
|
||||
while(l.hasMoreTokens()) {
|
||||
@ -97,6 +102,12 @@ public class BungeePlayerData {
|
||||
Configuration bungeePlayerDataFileConfiguration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(bungeePlayerDataFile);
|
||||
String uuidString = bungeePlayerDataFile.getName().replace(".yml", "");
|
||||
UUID uuid = UUID.fromString(uuidString);
|
||||
if(UUIDFetcher.shouldSkipOfflineUUIDBungee(uuid)) {
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - Skipping Offline UUID: " + uuid)));
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - File will be skipped and deleted.")));
|
||||
bungeePlayerDataFile.delete();
|
||||
return;
|
||||
}
|
||||
Set<String> listening = new HashSet<String>();
|
||||
StringTokenizer l = new StringTokenizer(bungeePlayerDataFileConfiguration.getString("channels"), ",");
|
||||
while(l.hasMoreTokens()) {
|
||||
@ -133,6 +144,9 @@ public class BungeePlayerData {
|
||||
public static void saveBungeePlayerData() {
|
||||
try {
|
||||
for(SynchronizedMineverseChatPlayer p : MineverseChatBungee.players) {
|
||||
if(UUIDFetcher.shouldSkipOfflineUUIDBungee(p.getUUID())) {
|
||||
return;
|
||||
}
|
||||
File bungeePlayerDataFile = new File(BUNGEE_PLAYER_DATA_DIRECTORY_PATH, p.getUUID() + ".yml");
|
||||
if(!bungeePlayerDataFile.exists()) {
|
||||
bungeePlayerDataFile.createNewFile();
|
||||
|
@ -21,6 +21,7 @@ import mineverse.Aust1n46.chat.MineverseChat;
|
||||
import mineverse.Aust1n46.chat.api.MineverseChatPlayer;
|
||||
import mineverse.Aust1n46.chat.channel.ChatChannel;
|
||||
import mineverse.Aust1n46.chat.utilities.Format;
|
||||
import mineverse.Aust1n46.chat.utilities.UUIDFetcher;
|
||||
|
||||
/**
|
||||
* Class for reading and writing player data.
|
||||
@ -42,6 +43,10 @@ public class PlayerData {
|
||||
FileConfiguration playerData = YamlConfiguration.loadConfiguration(legacyPlayerDataFile);
|
||||
for(String uuidString : playerData.getConfigurationSection("players").getKeys(false)) {
|
||||
UUID uuid = UUID.fromString(uuidString);
|
||||
if(UUIDFetcher.shouldSkipOfflineUUID(uuid)) {
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - Skipping Offline UUID: " + uuid));
|
||||
continue;
|
||||
}
|
||||
String name = playerData.getConfigurationSection("players." + uuid).getString("name");
|
||||
String currentChannelName = playerData.getConfigurationSection("players." + uuid).getString("current");
|
||||
ChatChannel currentChannel = ChatChannel.isChannel(currentChannelName) ? ChatChannel.getChannel(currentChannelName) : ChatChannel.getDefaultChannel();
|
||||
@ -130,6 +135,12 @@ public class PlayerData {
|
||||
FileConfiguration playerDataFileYamlConfiguration = YamlConfiguration.loadConfiguration(playerDataFile);
|
||||
String uuidString = playerDataFile.getName().replace(".yml", "");
|
||||
UUID uuid = UUID.fromString(uuidString);
|
||||
if(UUIDFetcher.shouldSkipOfflineUUID(uuid)) {
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - Skipping Offline UUID: " + uuid));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - File will be skipped and deleted."));
|
||||
playerDataFile.delete();
|
||||
return;
|
||||
}
|
||||
String name = playerDataFileYamlConfiguration.getString("name");
|
||||
String currentChannelName = playerDataFileYamlConfiguration.getString("current");
|
||||
ChatChannel currentChannel = ChatChannel.isChannel(currentChannelName) ? ChatChannel.getChannel(currentChannelName) : ChatChannel.getDefaultChannel();
|
||||
@ -188,7 +199,7 @@ public class PlayerData {
|
||||
}
|
||||
|
||||
public static void savePlayerData(MineverseChatPlayer mcp) {
|
||||
if(mcp == null || mcp.isTempData() || (!mcp.isOnline() && !mcp.wasModified())) {
|
||||
if(mcp == null || UUIDFetcher.shouldSkipOfflineUUID(mcp.getUUID()) || (!mcp.isOnline() && !mcp.wasModified())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
@ -54,8 +54,7 @@ public class LoginListener implements Listener {
|
||||
if(mcp == null) {
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName();
|
||||
UUID uuid = UUIDFetcher.getUUIDFromPlayer(player);
|
||||
boolean tempData = UUIDFetcher.uuidIsOffline(uuid);
|
||||
UUID uuid = player.getUniqueId();
|
||||
ChatChannel current = ChatChannel.getDefaultChannel();
|
||||
Set<UUID> ignores = new HashSet<UUID>();
|
||||
Set<String> listening = new HashSet<String>();
|
||||
@ -63,9 +62,10 @@ public class LoginListener implements Listener {
|
||||
HashMap<String, Integer> mutes = new HashMap<String, Integer>();
|
||||
Set<String> blockedCommands = new HashSet<String>();
|
||||
String jsonFormat = "Default";
|
||||
mcp = new MineverseChatPlayer(uuid, name, current, ignores, listening, mutes, blockedCommands, false, null, true, true, name, jsonFormat, false, false, false, true, true, tempData);
|
||||
mcp = new MineverseChatPlayer(uuid, name, current, ignores, listening, mutes, blockedCommands, false, null, true, true, name, jsonFormat, false, false, false, true, true);
|
||||
MineverseChat.players.add(mcp);
|
||||
}
|
||||
UUIDFetcher.checkOfflineUUIDWarning(mcp.getUUID());
|
||||
mcp.setName(event.getPlayer().getName());
|
||||
if(!event.getPlayer().getDisplayName().equals(mcp.getName())) {
|
||||
mcp.setNickname(event.getPlayer().getDisplayName());
|
||||
|
@ -13,13 +13,17 @@ import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import mineverse.Aust1n46.chat.MineverseChat;
|
||||
import mineverse.Aust1n46.chat.bungee.MineverseChatBungee;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
|
||||
//This class is used to query the Mojang servers to verify UUID's.
|
||||
public class UUIDFetcher implements Callable<Map<String, UUID>> { //unimplemented
|
||||
private static final double PROFILES_PER_REQUEST = 100;
|
||||
@ -111,17 +115,37 @@ public class UUIDFetcher implements Callable<Map<String, UUID>> { //unimplemente
|
||||
return uuid.version() == 3;
|
||||
}
|
||||
|
||||
public static UUID getUUIDFromPlayer(Player player) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
if(uuidIsOffline(uuid)) {
|
||||
public static boolean shouldSkipOfflineUUID(UUID uuid) {
|
||||
return (uuidIsOffline(uuid) && !MineverseChat.getInstance().getConfig().getBoolean("offline_server_acknowledgement", false));
|
||||
}
|
||||
|
||||
public static boolean shouldSkipOfflineUUIDBungee(UUID uuid) {
|
||||
return (uuidIsOffline(uuid) && !MineverseChatBungee.getInstance().getBungeeConfig().getBoolean("offline_server_acknowledgement", false));
|
||||
}
|
||||
|
||||
public static void checkOfflineUUIDWarning(UUID uuid) {
|
||||
if(shouldSkipOfflineUUID(uuid)) {
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - Detected Offline UUID!"));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - If you are using BungeeCord, make sure you have properly setup IP Forwarding."));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - https://www.spigotmc.org/wiki/bungeecord-ip-forwarding/"));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - You can access this wiki page from the log file or just Google it."));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - If you're running a \"cracked\" server, player data might not be stored properly, and thus, you are on your own."));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - If you run your server in offline mode, you might have to reset your player data when switching to online mode!"));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - If you run your server in offline mode, you will probably lose your player data when switching to online mode!"));
|
||||
Bukkit.getConsoleSender().sendMessage(Format.FormatStringAll("&8[&eVentureChat&8]&c - No player data will be saved in offline mode unless you set the \"cracked\" server acknowledgement in the config!"));
|
||||
}
|
||||
return uuid;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkOfflineUUIDWarningBungee(UUID uuid) {
|
||||
if(shouldSkipOfflineUUIDBungee(uuid)) {
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - Detected Offline UUID!")));
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - If you are using BungeeCord, make sure you have properly setup IP Forwarding.")));
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - https://www.spigotmc.org/wiki/bungeecord-ip-forwarding/")));
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - You can access this wiki page from the log file or just Google it.")));
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - If you're running a \"cracked\" server, player data might not be stored properly, and thus, you are on your own.")));
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - If you run your server in offline mode, you will probably lose your player data when switching to online mode!")));
|
||||
ProxyServer.getInstance().getConsole().sendMessage(TextComponent.fromLegacyText(Format.FormatStringAll("&8[&eVentureChat&8]&c - No player data will be saved in offline mode unless you set the \"cracked\" server acknowledgement in the config!")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user