Patcher requirement re-initialization fixes
This commit is contained in:
@@ -355,17 +355,19 @@ public class ContentPatcher{
|
|||||||
}, value, true);
|
}, value, true);
|
||||||
}else if(value instanceof JsonValue jsv && object instanceof Block bl && jsv.isObject() && field.equals("consumes")){
|
}else if(value instanceof JsonValue jsv && object instanceof Block bl && jsv.isObject() && field.equals("consumes")){
|
||||||
modifiedField(bl, "consumeBuilder", Reflect.<Seq<Consume>>get(Block.class, bl, "consumeBuilder").copy());
|
modifiedField(bl, "consumeBuilder", Reflect.<Seq<Consume>>get(Block.class, bl, "consumeBuilder").copy());
|
||||||
|
modifiedField(bl, "consumers", Reflect.<Consume[]>get(Block.class, bl, "consumers"));
|
||||||
boolean hadItems = bl.hasItems, hadLiquids = bl.hasLiquids, hadPower = bl.hasPower, acceptedItems = bl.acceptsItems;
|
boolean hadItems = bl.hasItems, hadLiquids = bl.hasLiquids, hadPower = bl.hasPower, acceptedItems = bl.acceptsItems;
|
||||||
reset(() -> {
|
reset(() -> {
|
||||||
|
bl.reinitializeConsumers();
|
||||||
bl.hasItems = hadItems;
|
bl.hasItems = hadItems;
|
||||||
bl.hasLiquids = hadLiquids;
|
bl.hasLiquids = hadLiquids;
|
||||||
bl.hasPower = hadPower;
|
bl.hasPower = hadPower;
|
||||||
bl.acceptsItems = acceptedItems;
|
bl.acceptsItems = acceptedItems;
|
||||||
});
|
});
|
||||||
after(bl::reinitializeConsumers);
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
parser.readBlockConsumers(bl, jsv);
|
parser.readBlockConsumers(bl, jsv);
|
||||||
|
bl.reinitializeConsumers();
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
Log.err(e);
|
Log.err(e);
|
||||||
warn("Failed to read consumers for '@': @", bl, Strings.getSimpleMessage(e));
|
warn("Failed to read consumers for '@': @", bl, Strings.getSimpleMessage(e));
|
||||||
|
|||||||
@@ -716,6 +716,8 @@ public class Block extends UnlockableContent implements Senseable{
|
|||||||
super.afterPatch();
|
super.afterPatch();
|
||||||
barMap.clear();
|
barMap.clear();
|
||||||
setBars();
|
setBars();
|
||||||
|
offset = ((size + 1) % 2) * tilesize / 2f;
|
||||||
|
sizeOffset = -((size - 1) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean consumesItem(Item item){
|
public boolean consumesItem(Item item){
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import mindustry.type.*;
|
|||||||
import mindustry.world.blocks.defense.turrets.*;
|
import mindustry.world.blocks.defense.turrets.*;
|
||||||
import mindustry.world.blocks.production.*;
|
import mindustry.world.blocks.production.*;
|
||||||
import mindustry.world.blocks.units.*;
|
import mindustry.world.blocks.units.*;
|
||||||
|
import mindustry.world.consumers.*;
|
||||||
import mindustry.world.meta.*;
|
import mindustry.world.meta.*;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.junit.jupiter.params.*;
|
import org.junit.jupiter.params.*;
|
||||||
@@ -62,7 +63,7 @@ public class PatcherTests{
|
|||||||
assertArrayEquals(new ItemStack[]{new ItemStack(Items.surgeAlloy, 10)}, plan.requirements);
|
assertArrayEquals(new ItemStack[]{new ItemStack(Items.surgeAlloy, 10)}, plan.requirements);
|
||||||
assertEquals(100f, plan.time);
|
assertEquals(100f, plan.time);
|
||||||
|
|
||||||
Vars.state.patcher.unapply();
|
resetAfter();
|
||||||
|
|
||||||
plan = ((UnitFactory)Blocks.groundFactory).plans.find(u -> u.unit == UnitTypes.flare);
|
plan = ((UnitFactory)Blocks.groundFactory).plans.find(u -> u.unit == UnitTypes.flare);
|
||||||
|
|
||||||
@@ -70,7 +71,35 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitWeapons() throws Exception{
|
void reconstructorPlans() throws Exception{
|
||||||
|
var reconstructor = ((Reconstructor)Blocks.additiveReconstructor);
|
||||||
|
var prev = reconstructor.upgrades;
|
||||||
|
var prevConsumes = reconstructor.<ConsumeItems>findConsumer(c -> c instanceof ConsumeItems).items;
|
||||||
|
|
||||||
|
Vars.state.patcher.apply(Seq.with(
|
||||||
|
"""
|
||||||
|
block.additive-reconstructor.upgrades: [[dagger, flare]]
|
||||||
|
block.additive-reconstructor.consumes: {
|
||||||
|
remove: items
|
||||||
|
items: [surge-alloy/10, copper/20]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
));
|
||||||
|
|
||||||
|
assertNoWarnings();
|
||||||
|
var plan = reconstructor.upgrades.get(0);
|
||||||
|
assertArrayEquals(new UnitType[]{UnitTypes.dagger, UnitTypes.flare}, plan);
|
||||||
|
assertArrayEquals(reconstructor.<ConsumeItems>findConsumer(c -> c instanceof ConsumeItems).items, ItemStack.with(Items.surgeAlloy, 10, Items.copper, 20));
|
||||||
|
|
||||||
|
resetAfter();
|
||||||
|
|
||||||
|
assertEquals(prev, reconstructor.upgrades);
|
||||||
|
assertArrayEquals(reconstructor.<ConsumeItems>findConsumer(c -> c instanceof ConsumeItems).items, prevConsumes);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void unitWeapons() throws Exception{
|
||||||
UnitTypes.dagger.checkStats();
|
UnitTypes.dagger.checkStats();
|
||||||
UnitTypes.dagger.stats.add(Stat.charge, 999);
|
UnitTypes.dagger.stats.add(Stat.charge, 999);
|
||||||
assertNotNull(UnitTypes.dagger.stats.toMap().get(StatCat.general).get(Stat.charge));
|
assertNotNull(UnitTypes.dagger.stats.toMap().get(StatCat.general).get(Stat.charge));
|
||||||
@@ -85,6 +114,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
|
assertNoWarnings();
|
||||||
assertEquals(3, UnitTypes.dagger.weapons.size);
|
assertEquals(3, UnitTypes.dagger.weapons.size);
|
||||||
assertEquals("navanax-weapon", UnitTypes.dagger.weapons.get(2).name);
|
assertEquals("navanax-weapon", UnitTypes.dagger.weapons.get(2).name);
|
||||||
assertEquals(LightningBulletType.class, UnitTypes.dagger.weapons.get(2).bullet.getClass());
|
assertEquals(LightningBulletType.class, UnitTypes.dagger.weapons.get(2).bullet.getClass());
|
||||||
@@ -97,7 +127,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitWeaponReassign() throws Exception{
|
void uUnitWeaponReassign() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.dagger.weapons: [
|
unit.dagger.weapons: [
|
||||||
{
|
{
|
||||||
@@ -122,7 +152,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitAbilities() throws Exception{
|
void unitAbilities() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.dagger.abilities.+: {
|
unit.dagger.abilities.+: {
|
||||||
type: ShieldArcAbility
|
type: ShieldArcAbility
|
||||||
@@ -140,7 +170,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitAbilitiesArray() throws Exception{
|
void unitAbilitiesArray() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.dagger.abilities.+: [
|
unit.dagger.abilities.+: [
|
||||||
{
|
{
|
||||||
@@ -167,7 +197,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitTypeObject() throws Exception{
|
void unitTypeObject() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
{
|
{
|
||||||
"name": "object syntax",
|
"name": "object syntax",
|
||||||
@@ -177,11 +207,11 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitFlagsArray() throws Exception{
|
void unitFlagsArray() throws Exception{
|
||||||
int oldLength = UnitTypes.dagger.targetFlags.length;
|
int oldLength = UnitTypes.dagger.targetFlags.length;
|
||||||
|
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
@@ -200,7 +230,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitFlags() throws Exception{
|
void unitFlags() throws Exception{
|
||||||
int oldLength = UnitTypes.dagger.targetFlags.length;
|
int oldLength = UnitTypes.dagger.targetFlags.length;
|
||||||
|
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
@@ -216,7 +246,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnitType() throws Exception{
|
void unitType() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.dagger.type: legs
|
unit.dagger.type: legs
|
||||||
"""));
|
"""));
|
||||||
@@ -230,7 +260,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCannotPatch() throws Exception{
|
void cannotPatch() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
block.conveyor.size: 2
|
block.conveyor.size: 2
|
||||||
"""));
|
"""));
|
||||||
@@ -240,7 +270,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGibberish() throws Exception{
|
void gibberish() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
}[35209509()jfkjhadsf,
|
}[35209509()jfkjhadsf,
|
||||||
,,,,,[]
|
,,,,,[]
|
||||||
@@ -251,7 +281,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNoIdAssign() throws Exception{
|
void noIdAssign() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
block.router.id: 9231
|
block.router.id: 9231
|
||||||
"""));
|
"""));
|
||||||
@@ -260,7 +290,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testUnknownFieldWarn() throws Exception{
|
void unknownFieldWarn() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.dagger.weapons.+: {
|
unit.dagger.weapons.+: {
|
||||||
bullet: {
|
bullet: {
|
||||||
@@ -274,7 +304,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testObjectFloatMap() throws Exception{
|
void objectFloatMap() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
block.mechanical-drill.drillMultipliers: {
|
block.mechanical-drill.drillMultipliers: {
|
||||||
titanium: 2.0
|
titanium: 2.0
|
||||||
@@ -288,7 +318,7 @@ public class PatcherTests{
|
|||||||
block.mechanical-drill.drillMultipliers.surge-alloy: 10
|
block.mechanical-drill.drillMultipliers.surge-alloy: 10
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
assertEquals(2f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.titanium, 0f));
|
assertEquals(2f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.titanium, 0f));
|
||||||
assertEquals(3f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.copper, 0f));
|
assertEquals(3f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.copper, 0f));
|
||||||
assertEquals(10f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.surgeAlloy, 0f));
|
assertEquals(10f, ((Drill)Blocks.mechanicalDrill).drillMultipliers.get(Items.surgeAlloy, 0f));
|
||||||
@@ -300,7 +330,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSpecificArrayRequirements() throws Exception{
|
void specificArrayRequirements() throws Exception{
|
||||||
ItemStack[] reqs = Blocks.scatter.requirements.clone();
|
ItemStack[] reqs = Blocks.scatter.requirements.clone();
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
block.scatter.requirements: {
|
block.scatter.requirements: {
|
||||||
@@ -309,17 +339,18 @@ public class PatcherTests{
|
|||||||
block.duo.requirements: [titanium/5, surge-alloy/20]
|
block.duo.requirements: [titanium/5, surge-alloy/20]
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
assertEquals(Blocks.scatter.requirements[0], new ItemStack(Items.surgeAlloy, 10));
|
assertEquals(Blocks.scatter.requirements[0], new ItemStack(Items.surgeAlloy, 10));
|
||||||
assertEquals(Blocks.scatter.requirements[1], reqs[1]);
|
assertEquals(Blocks.scatter.requirements[1], reqs[1]);
|
||||||
assertEquals(Blocks.duo.requirements[0], new ItemStack(Items.titanium, 5));
|
assertEquals(Blocks.duo.requirements[0], new ItemStack(Items.titanium, 5));
|
||||||
|
|
||||||
|
|
||||||
Vars.logic.reset();
|
Vars.logic.reset();
|
||||||
assertArrayEquals(reqs, Blocks.scatter.requirements);
|
assertArrayEquals(reqs, Blocks.scatter.requirements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testAttributes() throws Exception{
|
void attributes() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
block.grass.attributes: {
|
block.grass.attributes: {
|
||||||
oil: 99
|
oil: 99
|
||||||
@@ -327,7 +358,7 @@ public class PatcherTests{
|
|||||||
block.grass.attributes.heat: 77
|
block.grass.attributes.heat: 77
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
assertEquals(99, Blocks.grass.attributes.get(Attribute.oil));
|
assertEquals(99, Blocks.grass.attributes.get(Attribute.oil));
|
||||||
assertEquals(77, Blocks.grass.attributes.get(Attribute.heat));
|
assertEquals(77, Blocks.grass.attributes.get(Attribute.heat));
|
||||||
|
|
||||||
@@ -338,7 +369,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testNoResolution() throws Exception{
|
void noResolution() throws Exception{
|
||||||
String name = Pathfinder.class.getCanonicalName();
|
String name = Pathfinder.class.getCanonicalName();
|
||||||
|
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
@@ -351,12 +382,12 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSetMultiAdd() throws Exception{
|
void setMultiAdd() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.dagger.immunities.+: [slow, fast]
|
unit.dagger.immunities.+: [slow, fast]
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
assertTrue(UnitTypes.dagger.immunities.contains(StatusEffects.slow));
|
assertTrue(UnitTypes.dagger.immunities.contains(StatusEffects.slow));
|
||||||
assertTrue(UnitTypes.dagger.immunities.contains(StatusEffects.fast));
|
assertTrue(UnitTypes.dagger.immunities.contains(StatusEffects.fast));
|
||||||
|
|
||||||
@@ -367,7 +398,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testAmmoReassign() throws Exception{
|
void ammoReassign() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
block.fuse.ammoTypes: {
|
block.fuse.ammoTypes: {
|
||||||
titanium: "-"
|
titanium: "-"
|
||||||
@@ -381,7 +412,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
assertTrue(((ItemTurret)Blocks.fuse).ammoTypes.containsKey(Items.surgeAlloy));
|
assertTrue(((ItemTurret)Blocks.fuse).ammoTypes.containsKey(Items.surgeAlloy));
|
||||||
assertFalse(((ItemTurret)Blocks.fuse).ammoTypes.containsKey(Items.titanium));
|
assertFalse(((ItemTurret)Blocks.fuse).ammoTypes.containsKey(Items.titanium));
|
||||||
assertEquals(100, ((ItemTurret)Blocks.fuse).ammoTypes.get(Items.surgeAlloy).damage);
|
assertEquals(100, ((ItemTurret)Blocks.fuse).ammoTypes.get(Items.surgeAlloy).damage);
|
||||||
@@ -393,13 +424,13 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIndexAccess() throws Exception{
|
void indexAccess() throws Exception{
|
||||||
float oldDamage = UnitTypes.dagger.weapons.first().bullet.damage;
|
float oldDamage = UnitTypes.dagger.weapons.first().bullet.damage;
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.dagger.weapons.0.bullet.damage: 100
|
unit.dagger.weapons.0.bullet.damage: 100
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
assertEquals(100, UnitTypes.dagger.weapons.first().bullet.damage);
|
assertEquals(100, UnitTypes.dagger.weapons.first().bullet.damage);
|
||||||
|
|
||||||
Vars.logic.reset();
|
Vars.logic.reset();
|
||||||
@@ -408,7 +439,7 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testAddWeapon() throws Exception{
|
void addWeapon() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
unit.flare.weapons.+: {
|
unit.flare.weapons.+: {
|
||||||
x: 0
|
x: 0
|
||||||
@@ -421,13 +452,13 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertNoWarnings();
|
||||||
assertEquals(3, UnitTypes.flare.weapons.size);
|
assertEquals(3, UnitTypes.flare.weapons.size);
|
||||||
assertEquals(100, UnitTypes.flare.weapons.peek().bullet.damage);
|
assertEquals(100, UnitTypes.flare.weapons.peek().bullet.damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBigPatch() throws Exception{
|
void bigPatch() throws Exception{
|
||||||
Vars.state.patcher.apply(Seq.with("""
|
Vars.state.patcher.apply(Seq.with("""
|
||||||
item: {
|
item: {
|
||||||
fissile-matter: {
|
fissile-matter: {
|
||||||
@@ -485,6 +516,10 @@ public class PatcherTests{
|
|||||||
}
|
}
|
||||||
"""));
|
"""));
|
||||||
|
|
||||||
|
assertNoWarnings();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void assertNoWarnings(){
|
||||||
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
assertEquals(new Seq<>(), Vars.state.patcher.patches.first().warnings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user