feat(D-01/C): consumer migration — 85 files migrated to V2 helpers
Phase 1 (state): PlayerBindState, PlayerCaptorManager, PlayerEquipment, PlayerDataRetrieval, PlayerLifecycle, PlayerShockCollar, StruggleAccessory Phase 2 (client): AnimationTickHandler, NpcAnimationTickHandler, 5 render handlers, DamselModel, 3 client mixins, SelfBondageInputHandler, SlaveManagementScreen, ActionPanel, SlaveEntryWidget, ModKeybindings Phase 3 (entities): 28 entity/AI files migrated to CollarHelper, BindModeHelper, PoseTypeHelper, createStack() Phase 4 (network): PacketSlaveAction, PacketMasterEquip, PacketAssignCellToCollar, PacketNpcCommand, PacketFurnitureForcemount Phase 5 (events): RestraintTaskTickHandler, PetPlayRestrictionHandler, PlayerEnslavementHandler, ChatEventHandler, LaborAttackPunishmentHandler Phase 6 (commands): BondageSubCommand, CollarCommand, NPCCommand, KidnapSetCommand Phase 7 (compat): MCAKidnappedAdapter, MCA mixins Phase 8 (misc): GagTalkManager, PetRequestManager, HangingCagePiece, BondageItemBlockEntity, TrappedChestBlockEntity, DispenserBehaviors, BondageItemLoaderUtility, RestraintApplicator, StruggleSessionManager, MovementStyleResolver, CampLifecycleManager Some files retain dual V1/V2 checks (instanceof V1 || V2Helper) for coexistence — V1-only branches removed in Branch D.
This commit is contained in:
@@ -7,8 +7,8 @@ import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.tiedup.remake.cells.CellDataV2;
|
||||
import com.tiedup.remake.cells.CellRegistryV2;
|
||||
import com.tiedup.remake.items.base.ItemCollar;
|
||||
import com.tiedup.remake.state.PlayerBindState;
|
||||
import com.tiedup.remake.v2.bondage.CollarHelper;
|
||||
import com.tiedup.remake.util.teleport.Position;
|
||||
import com.tiedup.remake.util.teleport.TeleportHelper;
|
||||
import com.tiedup.remake.v2.BodyRegionV2;
|
||||
@@ -160,8 +160,8 @@ public class CollarCommand {
|
||||
}
|
||||
|
||||
if (source.getEntity() instanceof ServerPlayer executor) {
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
collarItem.addOwner(collar, executor);
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
CollarHelper.addOwner(collar, executor);
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
@@ -195,8 +195,8 @@ public class CollarCommand {
|
||||
}
|
||||
|
||||
if (source.getEntity() instanceof ServerPlayer executor) {
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
collarItem.removeOwner(collar, executor.getUUID());
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
CollarHelper.removeOwner(collar, executor.getUUID());
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
@@ -230,8 +230,8 @@ public class CollarCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
collarItem.setNickname(collar, name);
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
CollarHelper.setNickname(collar, name);
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
@@ -261,8 +261,8 @@ public class CollarCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
collarItem.addOwner(collar, owner);
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
CollarHelper.addOwner(collar, owner);
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
@@ -296,8 +296,8 @@ public class CollarCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
collarItem.removeOwner(collar, owner.getUUID());
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
CollarHelper.removeOwner(collar, owner.getUUID());
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
@@ -348,8 +348,8 @@ public class CollarCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
collarItem.setCellId(collar, cell.getId());
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
CollarHelper.setCellId(collar, cell.getId());
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
@@ -388,8 +388,8 @@ public class CollarCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
if (!collarItem.hasCellAssigned(collar)) {
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
if (!CollarHelper.hasCellAssigned(collar)) {
|
||||
source.sendFailure(
|
||||
Component.literal("No cell assigned to collar")
|
||||
);
|
||||
@@ -397,7 +397,7 @@ public class CollarCommand {
|
||||
}
|
||||
|
||||
// Get cell position and teleport
|
||||
java.util.UUID cellId = collarItem.getCellId(collar);
|
||||
java.util.UUID cellId = CollarHelper.getCellId(collar);
|
||||
ServerLevel serverLevel = source.getLevel();
|
||||
CellDataV2 cell = CellRegistryV2.get(serverLevel).getCell(cellId);
|
||||
|
||||
@@ -449,7 +449,7 @@ public class CollarCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (collar.getItem() instanceof ItemCollar collarItem) {
|
||||
if (CollarHelper.isCollar(collar)) {
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
@@ -460,24 +460,24 @@ public class CollarCommand {
|
||||
false
|
||||
);
|
||||
|
||||
String nickname = collarItem.getNickname(collar);
|
||||
String nickname = CollarHelper.getNickname(collar);
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
"§7Nickname: §f" +
|
||||
(nickname.isEmpty() ? "None" : nickname)
|
||||
(nickname == null || nickname.isEmpty() ? "None" : nickname)
|
||||
),
|
||||
false
|
||||
);
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
"§7Has Owner: §f" + collarItem.hasOwner(collar)
|
||||
"§7Has Owner: §f" + CollarHelper.hasOwner(collar)
|
||||
),
|
||||
false
|
||||
);
|
||||
// Cell assignment
|
||||
java.util.UUID cellId = collarItem.getCellId(collar);
|
||||
java.util.UUID cellId = CollarHelper.getCellId(collar);
|
||||
if (cellId != null) {
|
||||
ServerLevel serverLevel = source.getLevel();
|
||||
CellRegistryV2 registry = CellRegistryV2.get(serverLevel);
|
||||
@@ -510,10 +510,12 @@ public class CollarCommand {
|
||||
);
|
||||
}
|
||||
|
||||
boolean locked = collar.getItem() instanceof com.tiedup.remake.items.base.ILockable lockable
|
||||
&& lockable.isLocked(collar);
|
||||
source.sendSuccess(
|
||||
() ->
|
||||
Component.literal(
|
||||
"§7Locked: §f" + collarItem.isLocked(collar)
|
||||
"§7Locked: §f" + locked
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
@@ -4,12 +4,10 @@ import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.tiedup.remake.items.ModItems;
|
||||
import com.tiedup.remake.items.base.BindVariant;
|
||||
import com.tiedup.remake.items.base.BlindfoldVariant;
|
||||
import com.tiedup.remake.items.base.EarplugsVariant;
|
||||
import com.tiedup.remake.items.base.GagVariant;
|
||||
import com.tiedup.remake.items.base.KnifeVariant;
|
||||
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -82,42 +80,18 @@ public class KidnapSetCommand {
|
||||
int given = 0;
|
||||
|
||||
// Binds
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getBind(BindVariant.ROPES), 8)
|
||||
);
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getBind(BindVariant.CHAIN), 4)
|
||||
);
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getBind(BindVariant.LEATHER_STRAPS), 4)
|
||||
);
|
||||
given += giveDataDrivenItems(player, "ropes", 8);
|
||||
given += giveDataDrivenItems(player, "chain", 4);
|
||||
given += giveDataDrivenItems(player, "leather_straps", 4);
|
||||
|
||||
// Gags
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG), 4)
|
||||
);
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getGag(GagVariant.BALL_GAG), 4)
|
||||
);
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getGag(GagVariant.TAPE_GAG), 4)
|
||||
);
|
||||
given += giveDataDrivenItems(player, "cloth_gag", 4);
|
||||
given += giveDataDrivenItems(player, "ball_gag", 4);
|
||||
given += giveDataDrivenItems(player, "tape_gag", 4);
|
||||
|
||||
// Blindfolds
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getBlindfold(BlindfoldVariant.CLASSIC), 4)
|
||||
);
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getBlindfold(BlindfoldVariant.MASK), 2)
|
||||
);
|
||||
given += giveDataDrivenItems(player, "classic_blindfold", 4);
|
||||
given += giveDataDrivenItems(player, "blindfold_mask", 2);
|
||||
|
||||
// Collars
|
||||
given += giveItem(
|
||||
@@ -155,10 +129,7 @@ public class KidnapSetCommand {
|
||||
given += giveItem(player, new ItemStack(ModItems.MASTER_KEY.get(), 1));
|
||||
|
||||
// Earplugs
|
||||
given += giveItem(
|
||||
player,
|
||||
new ItemStack(ModItems.getEarplugs(EarplugsVariant.CLASSIC), 4)
|
||||
);
|
||||
given += giveDataDrivenItems(player, "classic_earplugs", 4);
|
||||
|
||||
// Rope arrows
|
||||
given += giveItem(player, new ItemStack(ModItems.ROPE_ARROW.get(), 16));
|
||||
@@ -182,6 +153,18 @@ public class KidnapSetCommand {
|
||||
return finalGiven;
|
||||
}
|
||||
|
||||
private static int giveDataDrivenItems(ServerPlayer player, String itemName, int count) {
|
||||
int given = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
ItemStack stack = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", itemName));
|
||||
if (!stack.isEmpty()) {
|
||||
giveItem(player, stack);
|
||||
given++;
|
||||
}
|
||||
}
|
||||
return given;
|
||||
}
|
||||
|
||||
private static int giveItem(ServerPlayer player, ItemStack stack) {
|
||||
if (!player.getInventory().add(stack)) {
|
||||
// Drop on ground if inventory full
|
||||
|
||||
@@ -7,11 +7,9 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.tiedup.remake.entities.*;
|
||||
import com.tiedup.remake.entities.skins.EliteKidnapperSkinManager;
|
||||
import com.tiedup.remake.items.ModItems;
|
||||
import com.tiedup.remake.items.base.BindVariant;
|
||||
import com.tiedup.remake.items.base.BlindfoldVariant;
|
||||
import com.tiedup.remake.items.base.EarplugsVariant;
|
||||
import com.tiedup.remake.items.base.GagVariant;
|
||||
import com.tiedup.remake.state.IBondageState;
|
||||
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import com.tiedup.remake.v2.BodyRegionV2;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -507,7 +505,7 @@ public class NPCCommand {
|
||||
|
||||
npc.equip(
|
||||
BodyRegionV2.ARMS,
|
||||
new ItemStack(ModItems.getBind(BindVariant.ROPES))
|
||||
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes"))
|
||||
);
|
||||
context
|
||||
.getSource()
|
||||
@@ -538,7 +536,7 @@ public class NPCCommand {
|
||||
|
||||
npc.equip(
|
||||
BodyRegionV2.MOUTH,
|
||||
new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG))
|
||||
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag"))
|
||||
);
|
||||
context
|
||||
.getSource()
|
||||
@@ -571,7 +569,7 @@ public class NPCCommand {
|
||||
|
||||
npc.equip(
|
||||
BodyRegionV2.EYES,
|
||||
new ItemStack(ModItems.getBlindfold(BlindfoldVariant.CLASSIC))
|
||||
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold"))
|
||||
);
|
||||
context
|
||||
.getSource()
|
||||
@@ -656,10 +654,10 @@ public class NPCCommand {
|
||||
com.tiedup.remake.entities.AbstractTiedUpNpc npcEntity
|
||||
) {
|
||||
npcEntity.applyBondage(
|
||||
new ItemStack(ModItems.getBind(BindVariant.ROPES)),
|
||||
new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG)),
|
||||
new ItemStack(ModItems.getBlindfold(BlindfoldVariant.CLASSIC)),
|
||||
new ItemStack(ModItems.getEarplugs(EarplugsVariant.CLASSIC)),
|
||||
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes")),
|
||||
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag")),
|
||||
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold")),
|
||||
DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs")),
|
||||
new ItemStack(ModItems.CLASSIC_COLLAR.get()),
|
||||
ItemStack.EMPTY // No clothes
|
||||
);
|
||||
|
||||
@@ -9,12 +9,10 @@ import com.tiedup.remake.commands.CommandHelper;
|
||||
import com.tiedup.remake.core.SystemMessageManager;
|
||||
import com.tiedup.remake.items.ModItems;
|
||||
import com.tiedup.remake.items.base.AdjustmentHelper;
|
||||
import com.tiedup.remake.items.base.BindVariant;
|
||||
import com.tiedup.remake.items.base.BlindfoldVariant;
|
||||
import com.tiedup.remake.items.base.EarplugsVariant;
|
||||
import com.tiedup.remake.items.base.GagVariant;
|
||||
import com.tiedup.remake.items.base.ItemCollar;
|
||||
import com.tiedup.remake.network.ModNetwork;
|
||||
import com.tiedup.remake.v2.bondage.CollarHelper;
|
||||
import com.tiedup.remake.v2.bondage.datadriven.DataDrivenBondageItem;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import com.tiedup.remake.network.sync.PacketSyncBindState;
|
||||
import com.tiedup.remake.state.PlayerBindState;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
@@ -256,7 +254,7 @@ public class BondageSubCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemStack ropes = new ItemStack(ModItems.getBind(BindVariant.ROPES));
|
||||
ItemStack ropes = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes"));
|
||||
state.putBindOn(ropes);
|
||||
|
||||
CommandHelper.syncPlayerState(targetPlayer, state);
|
||||
@@ -387,7 +385,7 @@ public class BondageSubCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemStack gag = new ItemStack(ModItems.getGag(GagVariant.CLOTH_GAG));
|
||||
ItemStack gag = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag"));
|
||||
state.putGagOn(gag);
|
||||
|
||||
CommandHelper.syncPlayerState(targetPlayer, state);
|
||||
@@ -440,9 +438,7 @@ public class BondageSubCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemStack blindfold = new ItemStack(
|
||||
ModItems.getBlindfold(BlindfoldVariant.CLASSIC)
|
||||
);
|
||||
ItemStack blindfold = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold"));
|
||||
state.putBlindfoldOn(blindfold);
|
||||
|
||||
CommandHelper.syncPlayerState(targetPlayer, state);
|
||||
@@ -500,8 +496,7 @@ public class BondageSubCommand {
|
||||
ItemStack collar = new ItemStack(ModItems.CLASSIC_COLLAR.get());
|
||||
|
||||
if (context.getSource().getEntity() instanceof ServerPlayer executor) {
|
||||
ItemCollar collarItem = (ItemCollar) collar.getItem();
|
||||
collarItem.addOwner(collar, executor);
|
||||
CollarHelper.addOwner(collar, executor);
|
||||
}
|
||||
|
||||
state.putCollarOn(collar);
|
||||
@@ -1021,9 +1016,7 @@ public class BondageSubCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ItemStack earplugs = new ItemStack(
|
||||
ModItems.getEarplugs(EarplugsVariant.CLASSIC)
|
||||
);
|
||||
ItemStack earplugs = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs"));
|
||||
state.putEarplugsOn(earplugs);
|
||||
CommandHelper.syncPlayerState(targetPlayer, state);
|
||||
|
||||
@@ -1067,25 +1060,19 @@ public class BondageSubCommand {
|
||||
int applied = 0;
|
||||
|
||||
if (!state.isTiedUp()) {
|
||||
ItemStack ropes = new ItemStack(
|
||||
ModItems.getBind(BindVariant.ROPES)
|
||||
);
|
||||
ItemStack ropes = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes"));
|
||||
state.putBindOn(ropes);
|
||||
applied++;
|
||||
}
|
||||
|
||||
if (!state.isGagged()) {
|
||||
ItemStack gag = new ItemStack(
|
||||
ModItems.getGag(GagVariant.CLOTH_GAG)
|
||||
);
|
||||
ItemStack gag = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag"));
|
||||
state.putGagOn(gag);
|
||||
applied++;
|
||||
}
|
||||
|
||||
if (!state.isBlindfolded()) {
|
||||
ItemStack blindfold = new ItemStack(
|
||||
ModItems.getBlindfold(BlindfoldVariant.CLASSIC)
|
||||
);
|
||||
ItemStack blindfold = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold"));
|
||||
state.putBlindfoldOn(blindfold);
|
||||
applied++;
|
||||
}
|
||||
@@ -1095,17 +1082,14 @@ public class BondageSubCommand {
|
||||
if (
|
||||
context.getSource().getEntity() instanceof ServerPlayer executor
|
||||
) {
|
||||
ItemCollar collarItem = (ItemCollar) collar.getItem();
|
||||
collarItem.addOwner(collar, executor);
|
||||
CollarHelper.addOwner(collar, executor);
|
||||
}
|
||||
state.putCollarOn(collar);
|
||||
applied++;
|
||||
}
|
||||
|
||||
if (!state.hasEarplugs()) {
|
||||
ItemStack earplugs = new ItemStack(
|
||||
ModItems.getEarplugs(EarplugsVariant.CLASSIC)
|
||||
);
|
||||
ItemStack earplugs = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs"));
|
||||
state.putEarplugsOn(earplugs);
|
||||
applied++;
|
||||
}
|
||||
@@ -1167,21 +1151,15 @@ public class BondageSubCommand {
|
||||
|
||||
// First fully restrain
|
||||
if (!state.isTiedUp()) {
|
||||
ItemStack ropes = new ItemStack(
|
||||
ModItems.getBind(BindVariant.ROPES)
|
||||
);
|
||||
ItemStack ropes = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "ropes"));
|
||||
state.putBindOn(ropes);
|
||||
}
|
||||
if (!state.isGagged()) {
|
||||
ItemStack gag = new ItemStack(
|
||||
ModItems.getGag(GagVariant.CLOTH_GAG)
|
||||
);
|
||||
ItemStack gag = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "cloth_gag"));
|
||||
state.putGagOn(gag);
|
||||
}
|
||||
if (!state.isBlindfolded()) {
|
||||
ItemStack blindfold = new ItemStack(
|
||||
ModItems.getBlindfold(BlindfoldVariant.CLASSIC)
|
||||
);
|
||||
ItemStack blindfold = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_blindfold"));
|
||||
state.putBlindfoldOn(blindfold);
|
||||
}
|
||||
if (!state.hasCollar()) {
|
||||
@@ -1189,15 +1167,12 @@ public class BondageSubCommand {
|
||||
if (
|
||||
context.getSource().getEntity() instanceof ServerPlayer executor
|
||||
) {
|
||||
ItemCollar collarItem = (ItemCollar) collar.getItem();
|
||||
collarItem.addOwner(collar, executor);
|
||||
CollarHelper.addOwner(collar, executor);
|
||||
}
|
||||
state.putCollarOn(collar);
|
||||
}
|
||||
if (!state.hasEarplugs()) {
|
||||
ItemStack earplugs = new ItemStack(
|
||||
ModItems.getEarplugs(EarplugsVariant.CLASSIC)
|
||||
);
|
||||
ItemStack earplugs = DataDrivenBondageItem.createStack(new ResourceLocation("tiedup", "classic_earplugs"));
|
||||
state.putEarplugsOn(earplugs);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user