geforkt von Mirrors/Paper
Optimized Light Level Comparisons
Use an optimized method to test if a block position meets a desired light level. This method benefits from returning as soon as the desired light level matches. Also Optimize Grass more
Dieser Commit ist enthalten in:
Ursprung
148f3809ca
Commit
7c7f8b83ab
@ -1,4 +1,4 @@
|
||||
From af80def89b8b7064581e872b121842e79a182369 Mon Sep 17 00:00:00 2001
|
||||
From 79f474e20de6c1d0267e736b5310a2054523816f Mon Sep 17 00:00:00 2001
|
||||
From: Sudzzy <originmc@outlook.com>
|
||||
Date: Wed, 2 Mar 2016 14:48:03 -0600
|
||||
Subject: [PATCH] Disable explosion knockback
|
||||
@ -19,10 +19,10 @@ index 78a1e59..6fce2b3 100644
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
index b864c5a..f3fdd4c 100644
|
||||
index 8122cae..d24987b 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -853,12 +853,14 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -854,12 +854,14 @@ public abstract class EntityLiving extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ index b864c5a..f3fdd4c 100644
|
||||
this.world.broadcastEntityEffect(this, (byte) 2);
|
||||
}
|
||||
|
||||
@@ -882,6 +884,8 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -883,6 +885,8 @@ public abstract class EntityLiving extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ index b864c5a..f3fdd4c 100644
|
||||
SoundEffect soundeffect = this.bS();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
|
||||
index afe402e..cd2fb14 100644
|
||||
index 5bb2510..418ee29 100644
|
||||
--- a/src/main/java/net/minecraft/server/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/server/Explosion.java
|
||||
@@ -145,7 +145,7 @@ public class Explosion {
|
||||
@ -69,5 +69,5 @@ index afe402e..cd2fb14 100644
|
||||
}
|
||||
}
|
||||
--
|
||||
2.7.3
|
||||
2.7.4
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 1630cb02eea11c5c6a1d5b71c2ec173a5f4d7cc0 Mon Sep 17 00:00:00 2001
|
||||
From 9f7f98e15f55f83febc8e32b4e98f89f516109b2 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 3 Mar 2016 04:00:11 -0600
|
||||
Subject: [PATCH] Timings v2
|
||||
@ -328,7 +328,7 @@ index cf58f74..38bc9c0 100644
|
||||
|
||||
public void recalcPosition() {
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
index f3fdd4c..d2f7cc2 100644
|
||||
index d24987b..1d5ea58 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -24,7 +24,7 @@ import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
@ -340,7 +340,7 @@ index f3fdd4c..d2f7cc2 100644
|
||||
|
||||
public abstract class EntityLiving extends Entity {
|
||||
|
||||
@@ -1688,7 +1688,6 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -1693,7 +1693,6 @@ public abstract class EntityLiving extends Entity {
|
||||
}
|
||||
|
||||
public void m() {
|
||||
@ -348,7 +348,7 @@ index f3fdd4c..d2f7cc2 100644
|
||||
super.m();
|
||||
this.cu();
|
||||
if (!this.world.isClientSide) {
|
||||
@@ -1761,9 +1760,7 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -1766,9 +1765,7 @@ public abstract class EntityLiving extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,7 +358,7 @@ index f3fdd4c..d2f7cc2 100644
|
||||
double d0 = this.locX - this.lastX;
|
||||
double d1 = this.locZ - this.lastZ;
|
||||
float f = (float) (d0 * d0 + d1 * d1);
|
||||
@@ -1832,8 +1829,6 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -1837,8 +1834,6 @@ public abstract class EntityLiving extends Entity {
|
||||
} else {
|
||||
this.bo = 0;
|
||||
}
|
||||
@ -367,7 +367,7 @@ index f3fdd4c..d2f7cc2 100644
|
||||
}
|
||||
|
||||
protected float h(float f, float f1) {
|
||||
@@ -1898,7 +1893,6 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -1903,7 +1898,6 @@ public abstract class EntityLiving extends Entity {
|
||||
}
|
||||
|
||||
this.world.methodProfiler.a("ai");
|
||||
@ -375,7 +375,7 @@ index f3fdd4c..d2f7cc2 100644
|
||||
if (this.cf()) {
|
||||
this.bc = false;
|
||||
this.bd = 0.0F;
|
||||
@@ -1909,7 +1903,6 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -1914,7 +1908,6 @@ public abstract class EntityLiving extends Entity {
|
||||
this.doTick();
|
||||
this.world.methodProfiler.b();
|
||||
}
|
||||
@ -383,7 +383,7 @@ index f3fdd4c..d2f7cc2 100644
|
||||
|
||||
this.world.methodProfiler.b();
|
||||
this.world.methodProfiler.a("jump");
|
||||
@@ -1932,14 +1925,10 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -1937,14 +1930,10 @@ public abstract class EntityLiving extends Entity {
|
||||
this.be *= 0.98F;
|
||||
this.bf *= 0.9F;
|
||||
this.r();
|
||||
@ -528,7 +528,7 @@ index d898428..f579d28 100644
|
||||
private static Map<String, Class<? extends TileEntity>> f = Maps.newHashMap();
|
||||
private static Map<Class<? extends TileEntity>, String> g = Maps.newHashMap();
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 1815f79..21b0986 100644
|
||||
index fc38527..98df4f4 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -18,11 +18,11 @@ import com.google.common.collect.Maps;
|
||||
|
@ -1,14 +1,14 @@
|
||||
From fe207a679722e373b467c738106f8a5566bb9b8c Mon Sep 17 00:00:00 2001
|
||||
From cb235b47d0b86defc04f886883da0a4cdae9ab81 Mon Sep 17 00:00:00 2001
|
||||
From: mrapple <tony@oc.tc>
|
||||
Date: Sun, 25 Nov 2012 13:43:39 -0600
|
||||
Subject: [PATCH] Add methods for working with arrows stuck in living entities
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
index d2f7cc2..e5d1fe0 100644
|
||||
index 1d5ea58..34abdd4 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -1265,10 +1265,12 @@ public abstract class EntityLiving extends Entity {
|
||||
@@ -1270,10 +1270,12 @@ public abstract class EntityLiving extends Entity {
|
||||
return (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue();
|
||||
}
|
||||
|
||||
@ -43,5 +43,5 @@ index 6f25d18..693d5cb 100644
|
||||
+ // Paper end
|
||||
}
|
||||
--
|
||||
2.7.2
|
||||
2.7.4
|
||||
|
||||
|
97
Spigot-Server-Patches/0093-Add-World-Util-Methods.patch
Normale Datei
97
Spigot-Server-Patches/0093-Add-World-Util-Methods.patch
Normale Datei
@ -0,0 +1,97 @@
|
||||
From 965df3c371af6bc8f0725dbaa14200f65cf61785 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 18 Mar 2016 20:16:03 -0400
|
||||
Subject: [PATCH] Add World Util Methods
|
||||
|
||||
Methods that can be used for other patches to help improve logic.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index b356aa6..dafe3b2 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -156,6 +156,12 @@ public abstract class World implements IBlockAccess {
|
||||
return (CraftServer) Bukkit.getServer();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public Chunk getChunkIfLoaded(BlockPosition blockposition) {
|
||||
+ return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public Chunk getChunkIfLoaded(int x, int z) {
|
||||
return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x, z);
|
||||
}
|
||||
@@ -628,6 +634,41 @@ public abstract class World implements IBlockAccess {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - test if meets light level, return faster
|
||||
+ // logic copied from below
|
||||
+ public boolean isLightLevel(BlockPosition blockposition, int level) {
|
||||
+ if (isValidLocation(blockposition)) {
|
||||
+ if (this.getType(blockposition).f()) {
|
||||
+ if (this.c(blockposition.up(), false) >= level) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (this.c(blockposition.east(), false) >= level) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (this.c(blockposition.west(), false) >= level) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (this.c(blockposition.south(), false) >= level) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ if (this.c(blockposition.north(), false) >= level) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ } else {
|
||||
+ if (blockposition.getY() >= 256) {
|
||||
+ blockposition = new BlockPosition(blockposition.getX(), 255, blockposition.getZ());
|
||||
+ }
|
||||
+
|
||||
+ Chunk chunk = this.getChunkAtWorldCoords(blockposition);
|
||||
+ return chunk.a(blockposition, this.J) >= level;
|
||||
+ }
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public int getLightLevel(BlockPosition blockposition) {
|
||||
return this.c(blockposition, true);
|
||||
}
|
||||
@@ -742,6 +783,27 @@ public abstract class World implements IBlockAccess {
|
||||
return this.worldProvider.n()[this.getLightLevel(blockposition)];
|
||||
}
|
||||
|
||||
+ // Paper start - reduces need to do isLoaded before getType
|
||||
+ public IBlockData getTypeIfLoaded(BlockPosition blockposition) {
|
||||
+ // CraftBukkit start - tree generation
|
||||
+ if (captureTreeGeneration) {
|
||||
+ Iterator<BlockState> it = capturedBlockStates.iterator();
|
||||
+ while (it.hasNext()) {
|
||||
+ BlockState previous = it.next();
|
||||
+ if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) {
|
||||
+ return CraftMagicNumbers.getBlock(previous.getTypeId()).fromLegacyData(previous.getRawData());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ Chunk chunk = this.getChunkIfLoaded(blockposition);
|
||||
+ if (chunk != null) {
|
||||
+ return this.isValidLocation(blockposition) ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData();
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public IBlockData getType(BlockPosition blockposition) {
|
||||
// CraftBukkit start - tree generation
|
||||
if (captureTreeGeneration) {
|
||||
--
|
||||
2.7.4
|
||||
|
135
Spigot-Server-Patches/0094-Optimized-Light-Level-Comparisons.patch
Normale Datei
135
Spigot-Server-Patches/0094-Optimized-Light-Level-Comparisons.patch
Normale Datei
@ -0,0 +1,135 @@
|
||||
From d2745c17b2cd8c0c9edf0d6cc7adeee17cdd4432 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 18 Mar 2016 21:22:56 -0400
|
||||
Subject: [PATCH] Optimized Light Level Comparisons
|
||||
|
||||
Use an optimized method to test if a block position meets a desired light level.
|
||||
|
||||
This method benefits from returning as soon as the desired light level matches.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockCrops.java b/src/main/java/net/minecraft/server/BlockCrops.java
|
||||
index 7c909d8..5d6e6cb 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockCrops.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockCrops.java
|
||||
@@ -48,7 +48,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement
|
||||
|
||||
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
|
||||
super.b(world, blockposition, iblockdata, random);
|
||||
- if (world.getLightLevel(blockposition.up()) >= 9) {
|
||||
+ if (world.isLightLevel(blockposition.up(), 9)) { // Paper
|
||||
int i = this.x(iblockdata);
|
||||
|
||||
if (i < this.g()) {
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockGrass.java b/src/main/java/net/minecraft/server/BlockGrass.java
|
||||
index fe55848..8fc736d 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockGrass.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockGrass.java
|
||||
@@ -29,7 +29,8 @@ public class BlockGrass extends Block implements IBlockFragilePlantElement {
|
||||
|
||||
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
|
||||
if (!world.isClientSide) {
|
||||
- if (world.getLightLevel(blockposition.up()) < 4 && world.getType(blockposition.up()).c() > 2) {
|
||||
+ int lightLevel = -1; // Paper
|
||||
+ if (world.getType(blockposition.up()).c() > 2 && (lightLevel = world.getLightLevel(blockposition.up())) < 4) { // Paper - move light check to end to avoid unneeded light lookups
|
||||
// CraftBukkit start
|
||||
// world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData());
|
||||
org.bukkit.World bworld = world.getWorld();
|
||||
@@ -44,18 +45,25 @@ public class BlockGrass extends Block implements IBlockFragilePlantElement {
|
||||
}
|
||||
// CraftBukkit end
|
||||
} else {
|
||||
- if (world.getLightLevel(blockposition.up()) >= 9) {
|
||||
+ // Paper start
|
||||
+ // If light was calculated above, reuse it, else grab it
|
||||
+ if (lightLevel == -1) {
|
||||
+ lightLevel = world.getLightLevel(blockposition.up());
|
||||
+ }
|
||||
+ if (lightLevel >= 9) {
|
||||
+ // Paper end
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
BlockPosition blockposition1 = blockposition.a(random.nextInt(3) - 1, random.nextInt(5) - 3, random.nextInt(3) - 1);
|
||||
|
||||
- if (blockposition1.getY() >= 0 && blockposition1.getY() < 256 && !world.isLoaded(blockposition1)) {
|
||||
+ IBlockData iblockdata2 = world.getTypeIfLoaded(blockposition1); // Paper - moved up
|
||||
+ if (iblockdata2 == null) { // Paper
|
||||
return;
|
||||
}
|
||||
|
||||
IBlockData iblockdata1 = world.getType(blockposition1.up());
|
||||
- IBlockData iblockdata2 = world.getType(blockposition1);
|
||||
+ //IBlockData iblockdata2 = world.getTypeIfLoaded(blockposition1); // Paper - moved up
|
||||
|
||||
- if (iblockdata2.getBlock() == Blocks.DIRT && iblockdata2.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && world.getLightLevel(blockposition1.up()) >= 4 && iblockdata1.c() <= 2) {
|
||||
+ if (iblockdata2.getBlock() == Blocks.DIRT && iblockdata2.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && iblockdata1.c() <= 2 && world.isLightLevel(blockposition1.up(), 4)) { // Paper - move last check before isLightLevel to avoid unneeded light checks
|
||||
// CraftBukkit start
|
||||
// world.setTypeUpdate(blockposition1, Blocks.GRASS.getBlockData());
|
||||
org.bukkit.World bworld = world.getWorld();
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockSapling.java b/src/main/java/net/minecraft/server/BlockSapling.java
|
||||
index 8b34250..b6de103 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockSapling.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockSapling.java
|
||||
@@ -34,7 +34,7 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
|
||||
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
|
||||
if (!world.isClientSide) {
|
||||
super.b(world, blockposition, iblockdata, random);
|
||||
- if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(Math.max(2, (int) (((100 / world.spigotConfig.saplingModifier) * 7) + 0.5F))) == 0) { // Spigot
|
||||
+ if (world.isLightLevel(blockposition.up(), 9) && random.nextInt(Math.max(2, (int) (((100 / world.spigotConfig.saplingModifier) * 7) + 0.5F))) == 0) { // Spigot // Paper
|
||||
// CraftBukkit start
|
||||
world.captureTreeGeneration = true;
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockStem.java b/src/main/java/net/minecraft/server/BlockStem.java
|
||||
index 097d11e..d0fa4ae 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockStem.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockStem.java
|
||||
@@ -47,7 +47,7 @@ public class BlockStem extends BlockPlant implements IBlockFragilePlantElement {
|
||||
|
||||
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
|
||||
super.b(world, blockposition, iblockdata, random);
|
||||
- if (world.getLightLevel(blockposition.up()) >= 9) {
|
||||
+ if (world.isLightLevel(blockposition.up(), 9)) { // Paper
|
||||
float f = BlockCrops.a((Block) this, world, blockposition);
|
||||
|
||||
if (random.nextInt((int) ((100 / (this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier)) * (25.0F / f)) + 1) == 0) { // Spigot
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityMonster.java b/src/main/java/net/minecraft/server/EntityMonster.java
|
||||
index 64f4754..6dc21fb 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityMonster.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityMonster.java
|
||||
@@ -118,17 +118,17 @@ public abstract class EntityMonster extends EntityCreature implements IMonster {
|
||||
if (this.world.b(EnumSkyBlock.SKY, blockposition) > this.random.nextInt(32)) {
|
||||
return false;
|
||||
} else {
|
||||
- int i = this.world.getLightLevel(blockposition);
|
||||
-
|
||||
+ //int i = this.world.getLightLevel(blockposition); // Paper
|
||||
+ boolean passes; // Paper
|
||||
if (this.world.V()) {
|
||||
int j = this.world.af();
|
||||
|
||||
this.world.c(10);
|
||||
- i = this.world.getLightLevel(blockposition);
|
||||
+ passes = world.isLightLevel(blockposition, this.random.nextInt(8)); // Paper
|
||||
this.world.c(j);
|
||||
- }
|
||||
+ } else { passes = world.isLightLevel(blockposition, this.random.nextInt(8)); } // Paper
|
||||
|
||||
- return i <= this.random.nextInt(8);
|
||||
+ return passes; // Paper
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java
|
||||
index 949452c..d6c07a2 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityZombie.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityZombie.java
|
||||
@@ -194,7 +194,7 @@ public class EntityZombie extends EntityMonster {
|
||||
int j1 = j + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1);
|
||||
int k1 = k + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1);
|
||||
|
||||
- if (this.world.getType(new BlockPosition(i1, j1 - 1, k1)).q() && this.world.getLightLevel(new BlockPosition(i1, j1, k1)) < 10) {
|
||||
+ if (this.world.getType(new BlockPosition(i1, j1 - 1, k1)).q() && !this.world.isLightLevel(new BlockPosition(i1, j1, k1), 10)) { // Paper
|
||||
entityzombie.setPosition((double) i1, (double) j1, (double) k1);
|
||||
if (!this.world.isPlayerNearby((double) i1, (double) j1, (double) k1, 7.0D) && this.world.a(entityzombie.getBoundingBox(), (Entity) entityzombie) && this.world.getCubes(entityzombie, entityzombie.getBoundingBox()).isEmpty() && !this.world.containsLiquid(entityzombie.getBoundingBox())) {
|
||||
this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit
|
||||
--
|
||||
2.7.4
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren