mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-25 06:36:45 +01:00
Add Set<?> serializer + fix some errors
This commit is contained in:
parent
ffa35d0179
commit
8eba1dda1f
@ -69,6 +69,7 @@ import org.bukkit.Material;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Config Manager handles initializing, loading, and unloading registers for all configs that mcMMO uses
|
* The Config Manager handles initializing, loading, and unloading registers for all configs that mcMMO uses
|
||||||
@ -261,14 +262,12 @@ public final class ConfigManager {
|
|||||||
customSerializers = TypeSerializers.getDefaultSerializers().newChild();
|
customSerializers = TypeSerializers.getDefaultSerializers().newChild();
|
||||||
|
|
||||||
mcMMO.p.getLogger().info("Registering custom type serializers for Configurate...");
|
mcMMO.p.getLogger().info("Registering custom type serializers for Configurate...");
|
||||||
customSerializers.registerType(new TypeToken<PrimarySkillType>() {
|
customSerializers.registerType(new TypeToken<PrimarySkillType>() {}, new CustomEnumValueSerializer());
|
||||||
}, new CustomEnumValueSerializer());
|
customSerializers.registerType(new TypeToken<Material>() {}, new CustomEnumValueSerializer());
|
||||||
customSerializers.registerType(new TypeToken<Material>() {
|
customSerializers.registerType(new TypeToken<PartyFeature>() {}, new CustomEnumValueSerializer());
|
||||||
}, new CustomEnumValueSerializer());
|
customSerializers.registerType(new TypeToken<FormulaType>() {}, new CustomEnumValueSerializer());
|
||||||
customSerializers.registerType(new TypeToken<PartyFeature>() {
|
customSerializers.registerType(new TypeToken<Set<?>>() {}, new SetSerializer());
|
||||||
}, new CustomEnumValueSerializer());
|
|
||||||
customSerializers.registerType(new TypeToken<FormulaType>() {
|
|
||||||
}, new CustomEnumValueSerializer());
|
|
||||||
customSerializers.registerType(TypeToken.of(Repairable.class), new RepairableSerializer());
|
customSerializers.registerType(TypeToken.of(Repairable.class), new RepairableSerializer());
|
||||||
customSerializers.registerType(TypeToken.of(Salvageable.class), new SalvageableSerializer());
|
customSerializers.registerType(TypeToken.of(Salvageable.class), new SalvageableSerializer());
|
||||||
customSerializers.registerType(TypeToken.of(MinecraftMaterialWrapper.class), new MinecraftMaterialWrapperSerializer());
|
customSerializers.registerType(TypeToken.of(MinecraftMaterialWrapper.class), new MinecraftMaterialWrapperSerializer());
|
||||||
|
@ -303,16 +303,6 @@ public class MainConfig extends ConfigValidated {
|
|||||||
return getBooleanValue(DOUBLE_DROPS, StringUtils.getCapitalized(skill.toString()), StringUtils.getPrettyItemString(material).replace(" ", "_"));
|
return getBooleanValue(DOUBLE_DROPS, StringUtils.getCapitalized(skill.toString()), StringUtils.getPrettyItemString(material).replace(" ", "_"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Acrobatics */
|
|
||||||
public boolean getDodgeLightningDisabled() {
|
|
||||||
return getBooleanValue(SKILLS, ACROBATICS, PREVENT + DODGE + LIGHTNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Alchemy */
|
|
||||||
public boolean getEnabledForHoppers() {
|
|
||||||
return getBooleanValue(SKILLS, ALCHEMY, ENABLED + FOR_HOPPERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getPreventHopperTransferIngredients() {
|
public boolean getPreventHopperTransferIngredients() {
|
||||||
return getBooleanValue(SKILLS, ALCHEMY, PREVENT_HOPPER_TRANSFER_INGREDIENTS);
|
return getBooleanValue(SKILLS, ALCHEMY, PREVENT_HOPPER_TRANSFER_INGREDIENTS);
|
||||||
}
|
}
|
||||||
@ -321,10 +311,6 @@ public class MainConfig extends ConfigValidated {
|
|||||||
return getBooleanValue(SKILLS, ALCHEMY, PREVENT_HOPPER_TRANSFER_BOTTLES);
|
return getBooleanValue(SKILLS, ALCHEMY, PREVENT_HOPPER_TRANSFER_BOTTLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getUnarmedItemsAsUnarmed() {
|
|
||||||
return getBooleanValue(SKILLS, UNARMED, ITEMS + AS + UNARMED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Taming */
|
/* Taming */
|
||||||
public Material getTamingCOTWMaterial(EntityType type) {
|
public Material getTamingCOTWMaterial(EntityType type) {
|
||||||
return Material.matchMaterial(getStringValue(SKILLS, TAMING, CALL_OF_THE_WILD1, StringUtils.getPrettyEntityTypeString(type), ITEM + MATERIAL));
|
return Material.matchMaterial(getStringValue(SKILLS, TAMING, CALL_OF_THE_WILD1, StringUtils.getPrettyEntityTypeString(type), ITEM + MATERIAL));
|
||||||
@ -350,26 +336,4 @@ public class MainConfig extends ConfigValidated {
|
|||||||
return getDoubleValue(SKILLS, TAMING, CALL_OF_THE_WILD1, RANGE);
|
return getDoubleValue(SKILLS, TAMING, CALL_OF_THE_WILD1, RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Woodcutting */
|
|
||||||
public boolean getWoodcuttingDoubleDropsEnabled(BlockData material) {
|
|
||||||
return getBooleanValue(DOUBLE_DROPS, WOODCUTTING, StringUtils.getFriendlyConfigBlockDataString(material));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getTreeFellerSoundsEnabled() {
|
|
||||||
return getBooleanValue(SKILLS, WOODCUTTING, TREE_FELLER + SOUNDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* AFK Leveling */
|
|
||||||
public boolean getHerbalismPreventAFK() {
|
|
||||||
return getBooleanValue(SKILLS, HERBALISM, PREVENT_AFK + LEVELING);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PVP & PVE Settings */
|
|
||||||
public boolean getPVPEnabled(PrimarySkillType skill) {
|
|
||||||
return getBooleanValue(SKILLS, StringUtils.getCapitalized(skill.toString()), ENABLED + FOR_PVP);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean getPVEEnabled(PrimarySkillType skill) {
|
|
||||||
return getBooleanValue(SKILLS, StringUtils.getCapitalized(skill.toString()), ENABLED + FOR_PVE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.gmail.nossr50.config.hocon.serializers;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import ninja.leaping.configurate.ConfigurationNode;
|
||||||
|
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
|
||||||
|
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class SetSerializer implements TypeSerializer<Set<?>> {
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Set<?> deserialize(@NonNull TypeToken<?> type, @NonNull ConfigurationNode value) throws ObjectMappingException {
|
||||||
|
|
||||||
|
if (!(type.getType() instanceof ParameterizedType)) {
|
||||||
|
throw new ObjectMappingException("Raw types are not supported for collections");
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeToken<?> entryType = type.resolveType(Set.class.getTypeParameters()[0]);
|
||||||
|
TypeSerializer entrySerial = value.getOptions().getSerializers().get(entryType);
|
||||||
|
if (entrySerial == null) {
|
||||||
|
throw new ObjectMappingException("No applicable type serializer for type " + entryType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.hasListChildren()) {
|
||||||
|
List<? extends ConfigurationNode> values = value.getChildrenList();
|
||||||
|
Set<Object> ret = new HashSet<>(values.size());
|
||||||
|
for (ConfigurationNode ent : values) {
|
||||||
|
ret.add(entrySerial.deserialize(entryType, ent));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
Object unwrappedVal = value.getValue();
|
||||||
|
if (unwrappedVal != null) {
|
||||||
|
return Sets.newHashSet(deserialize(entryType, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(@NonNull TypeToken<?> type, @Nullable Set<?> obj, @NonNull ConfigurationNode value) throws ObjectMappingException {
|
||||||
|
if (!(type.getType() instanceof ParameterizedType)) {
|
||||||
|
throw new ObjectMappingException("Raw types are not supported for collections");
|
||||||
|
}
|
||||||
|
TypeToken<?> entryType = type.resolveType(Set.class.getTypeParameters()[0]);
|
||||||
|
TypeSerializer entrySerial = value.getOptions().getSerializers().get(entryType);
|
||||||
|
if (entrySerial == null) {
|
||||||
|
throw new ObjectMappingException("No applicable type serializer for type " + entryType);
|
||||||
|
}
|
||||||
|
value.setValue(ImmutableList.of());
|
||||||
|
for (Object ent : obj) {
|
||||||
|
entrySerial.serialize(entryType, ent, value.getAppendedNode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,60 @@
|
|||||||
package com.gmail.nossr50.config.hocon.skills.herbalism;
|
package com.gmail.nossr50.config.hocon.skills.herbalism;
|
||||||
|
|
||||||
|
import ninja.leaping.configurate.objectmapping.Setting;
|
||||||
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
|
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class ConfigHerbalism {
|
public class ConfigHerbalism {
|
||||||
|
|
||||||
|
private static final HashSet<String> DEFAULT_BONUS_DROPS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
DEFAULT_BONUS_DROPS = new HashSet<>();
|
||||||
|
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:beetroots");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:beetroot");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:brown_mushroom");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:cactus");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:carrots");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:carrot");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:cocoa");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:cocoa_beans");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:wheat");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:melon");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:melon_slice");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:potatoes");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:potato");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:pumpkin");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:red_mushroom");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:sugar_cane");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:vine");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:lily_pad");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:red_tulip");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:white_tulip");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:pink_tulip");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:orange_tulip");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:dandelion");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:poppy");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:blue_orchid");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:allium");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:azure_bluet");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:oxeye_daisy");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:sunflower");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:lilac");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:rose_bush");
|
||||||
|
DEFAULT_BONUS_DROPS.add("minecraft:peony");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Setting(value = "Bonus-Drops", comment = "The list of whitelisted bonus drops." +
|
||||||
|
"\nInclude both the source block and drops that can be doubled" +
|
||||||
|
"\nHerbalism and other gathering skills offer a chance to get extra drops when harvesting the block.")
|
||||||
|
private HashSet<String> herbalismDoubleDropWhiteList = DEFAULT_BONUS_DROPS;
|
||||||
|
|
||||||
|
public HashSet<String> getBonusDrops() {
|
||||||
|
return herbalismDoubleDropWhiteList;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -4,16 +4,17 @@ import ninja.leaping.configurate.objectmapping.Setting;
|
|||||||
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
|
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
import static org.bukkit.Material.*;
|
import static org.bukkit.Material.*;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class ConfigMining {
|
public class ConfigMining {
|
||||||
|
|
||||||
private static final ArrayList<String> DEFAULT_BONUS_DROPS;
|
private static final HashSet<String> DEFAULT_BONUS_DROPS;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
DEFAULT_BONUS_DROPS = new ArrayList<>();
|
DEFAULT_BONUS_DROPS = new HashSet<>();
|
||||||
|
|
||||||
DEFAULT_BONUS_DROPS.add(ANDESITE.getKey().toString());
|
DEFAULT_BONUS_DROPS.add(ANDESITE.getKey().toString());
|
||||||
DEFAULT_BONUS_DROPS.add(DIORITE.getKey().toString());
|
DEFAULT_BONUS_DROPS.add(DIORITE.getKey().toString());
|
||||||
@ -46,7 +47,7 @@ public class ConfigMining {
|
|||||||
|
|
||||||
@Setting(value = "Z-Bonus-Drops", comment = "Bonus drops will be allowed for these blocks." +
|
@Setting(value = "Z-Bonus-Drops", comment = "Bonus drops will be allowed for these blocks." +
|
||||||
"\nUse Minecraft friendly names for entries, not Bukkit material names.")
|
"\nUse Minecraft friendly names for entries, not Bukkit material names.")
|
||||||
private ArrayList<String> bonusDrops = DEFAULT_BONUS_DROPS;
|
private HashSet<String> bonusDrops = DEFAULT_BONUS_DROPS;
|
||||||
|
|
||||||
@Setting(value = "Sub-Skills")
|
@Setting(value = "Sub-Skills")
|
||||||
private ConfigMiningSubskills miningSubskills = new ConfigMiningSubskills();
|
private ConfigMiningSubskills miningSubskills = new ConfigMiningSubskills();
|
||||||
@ -63,7 +64,7 @@ public class ConfigMining {
|
|||||||
return getBlastMining().getDetonators();
|
return getBlastMining().getDetonators();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<String> getBonusDrops() {
|
public HashSet<String> getBonusDrops() {
|
||||||
return bonusDrops;
|
return bonusDrops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.gmail.nossr50.config.hocon.skills.unarmed;
|
package com.gmail.nossr50.config.hocon.skills.unarmed;
|
||||||
|
|
||||||
import ninja.leaping.configurate.objectmapping.Setting;
|
import ninja.leaping.configurate.objectmapping.Setting;
|
||||||
|
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
public class ConfigUnarmedDisarm {
|
public class ConfigUnarmedDisarm {
|
||||||
|
|
||||||
private static final boolean PREVENT_ITEM_THEFT = false;
|
private static final boolean PREVENT_ITEM_THEFT = false;
|
||||||
|
@ -3,6 +3,7 @@ package com.gmail.nossr50.core;
|
|||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ public class BonusDropManager {
|
|||||||
*
|
*
|
||||||
* @param materials target material list
|
* @param materials target material list
|
||||||
*/
|
*/
|
||||||
public void addToWhitelistByNameID(List<String> materials) {
|
public void addToWhitelistByNameID(Collection<String> materials) {
|
||||||
for (String material : materials) {
|
for (String material : materials) {
|
||||||
Material m = Material.matchMaterial(material);
|
Material m = Material.matchMaterial(material);
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
|
@ -115,7 +115,7 @@ public class DynamicSettingsManager {
|
|||||||
*/
|
*/
|
||||||
public void registerBonusDrops() {
|
public void registerBonusDrops() {
|
||||||
bonusDropManager.addToWhitelistByNameID(mcMMO.getConfigManager().getConfigMining().getBonusDrops());
|
bonusDropManager.addToWhitelistByNameID(mcMMO.getConfigManager().getConfigMining().getBonusDrops());
|
||||||
// bonusDropManager.addToWhitelistByNameID(mcMMO.getConfigManager().getConfigHerbalism().getBonusDrops());
|
bonusDropManager.addToWhitelistByNameID(mcMMO.getConfigManager().getConfigHerbalism().getBonusDrops());
|
||||||
// bonusDropManager.addToWhitelistByNameID(mcMMO.getConfigManager().getConfigWoodcutting().getBonusDrops());
|
// bonusDropManager.addToWhitelistByNameID(mcMMO.getConfigManager().getConfigWoodcutting().getBonusDrops());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,10 +485,8 @@ public class BlockListener implements Listener {
|
|||||||
*
|
*
|
||||||
* We don't need to check permissions here because they've already been checked for the ability to even activate.
|
* We don't need to check permissions here because they've already been checked for the ability to even activate.
|
||||||
*/
|
*/
|
||||||
if (mcMMOPlayer.getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.isLog(blockState) && MainConfig.getInstance().getTreeFellerSoundsEnabled()) {
|
|
||||||
SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ);
|
SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Player getPlayerFromFurnace(Block furnaceBlock) {
|
private Player getPlayerFromFurnace(Block furnaceBlock) {
|
||||||
List<MetadataValue> metadata = furnaceBlock.getMetadata(MetadataConstants.FURNACE_TRACKING_METAKEY);
|
List<MetadataValue> metadata = furnaceBlock.getMetadata(MetadataConstants.FURNACE_TRACKING_METAKEY);
|
||||||
|
@ -93,7 +93,7 @@ public class MiningManager extends SkillManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if ((mcMMO.getModManager().isCustomMiningBlock(blockState) && !mcMMO.getModManager().getBlock(blockState).isDoubleDropEnabled()) || !MainConfig.getInstance().getDoubleDropsEnabled(skill, material)) {
|
//if ((mcMMO.getModManager().isCustomMiningBlock(blockState) && !mcMMO.getModManager().getBlock(blockState).isDoubleDropEnabled()) || !MainConfig.getInstance().getDoubleDropsEnabled(skill, material)) {
|
||||||
if (!MainConfig.getInstance().getDoubleDropsEnabled(skill, blockState.getType()))
|
if (!mcMMO.getDynamicSettingsManager().getBonusDropManager().isBonusDropWhitelisted(blockState.getType()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
boolean silkTouch = player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH);
|
boolean silkTouch = player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH);
|
||||||
|
@ -57,7 +57,7 @@ public final class Woodcutting {
|
|||||||
Misc.dropItems(Misc.getBlockCenter(blockState), blockState.getBlock().getDrops());
|
Misc.dropItems(Misc.getBlockCenter(blockState), blockState.getBlock().getDrops());
|
||||||
}
|
}
|
||||||
else {*/
|
else {*/
|
||||||
if (MainConfig.getInstance().getWoodcuttingDoubleDropsEnabled(blockState.getBlockData())) {
|
if (mcMMO.getDynamicSettingsManager().getBonusDropManager().isBonusDropWhitelisted(blockState.getType())) {
|
||||||
Misc.dropItems(Misc.getBlockCenter(blockState), blockState.getBlock().getDrops());
|
Misc.dropItems(Misc.getBlockCenter(blockState), blockState.getBlock().getDrops());
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
|
Loading…
Reference in New Issue
Block a user