mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2025-01-31 20:41:28 +01:00
Fixed priorities and parent-child regions, I believe. More testing is required. Removed dated CSVDatabaseTest.
This commit is contained in:
parent
474562455d
commit
dd14f3c469
@ -19,10 +19,10 @@
|
|||||||
package com.sk89q.worldguard.protection.managers;
|
package com.sk89q.worldguard.protection.managers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
import com.sk89q.worldedit.Vector;
|
import com.sk89q.worldedit.Vector;
|
||||||
import com.sk89q.worldguard.LocalPlayer;
|
import com.sk89q.worldguard.LocalPlayer;
|
||||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||||
@ -138,16 +138,24 @@ public ProtectedRegion getRegion(String id) {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ApplicableRegionSet getApplicableRegions(Vector pt) {
|
public ApplicableRegionSet getApplicableRegions(Vector pt) {
|
||||||
List<ProtectedRegion> appRegions =
|
TreeSet<ProtectedRegion> appRegions =
|
||||||
new ArrayList<ProtectedRegion>();
|
new TreeSet<ProtectedRegion>();
|
||||||
|
|
||||||
for (ProtectedRegion region : regions.values()) {
|
for (ProtectedRegion region : regions.values()) {
|
||||||
if (region.contains(pt)) {
|
if (region.contains(pt)) {
|
||||||
appRegions.add(region);
|
appRegions.add(region);
|
||||||
|
|
||||||
|
ProtectedRegion parent = region.getParent();
|
||||||
|
|
||||||
|
while (parent != null) {
|
||||||
|
if (!appRegions.contains(parent)) {
|
||||||
|
appRegions.add(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(appRegions);
|
|
||||||
|
|
||||||
return new ApplicableRegionSet(appRegions, regions.get("__global__"));
|
return new ApplicableRegionSet(appRegions, regions.get("__global__"));
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
import com.sk89q.worldedit.*;
|
import com.sk89q.worldedit.*;
|
||||||
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
|
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -303,8 +303,10 @@ public void setFlags(Map<Flag<?>, Object> flags) {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int compareTo(ProtectedRegion other) {
|
public int compareTo(ProtectedRegion other) {
|
||||||
if (priority == other.priority) {
|
if (id.equals(other.id)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (priority == other.priority) {
|
||||||
|
return 1;
|
||||||
} else if (priority > other.priority) {
|
} else if (priority > other.priority) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
@ -340,6 +342,27 @@ public static boolean isValidId(String id) {
|
|||||||
return idPattern.matcher(id).matches();
|
return idPattern.matcher(id).matches();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash code.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode(){
|
||||||
|
return id.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this region has the same ID as another region.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof ProtectedRegion)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtectedRegion other = (ProtectedRegion) obj;
|
||||||
|
return other.getId().equals(getId());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when setting a curParent would create a circular inheritance
|
* Thrown when setting a curParent would create a circular inheritance
|
||||||
* situation.
|
* situation.
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package com.sk89q.worldguard.protection;
|
package com.sk89q.worldguard.protection;
|
||||||
|
|
||||||
|
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||||
|
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||||
import com.sk89q.worldguard.protection.managers.FlatRegionManager;
|
import com.sk89q.worldguard.protection.managers.FlatRegionManager;
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||||
@ -34,6 +36,7 @@
|
|||||||
import com.sk89q.worldguard.TestPlayer;
|
import com.sk89q.worldguard.TestPlayer;
|
||||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
public class ApplicableRegionSetTest {
|
public class ApplicableRegionSetTest {
|
||||||
static String COURTYARD_ID = "courtyard";
|
static String COURTYARD_ID = "courtyard";
|
||||||
@ -108,31 +111,33 @@ void setUpFountainRegion() throws Exception {
|
|||||||
|
|
||||||
fountain = region;
|
fountain = region;
|
||||||
fountain.setParent(courtyard);
|
fountain.setParent(courtyard);
|
||||||
|
fountain.setFlag(DefaultFlag.FIRE_SPREAD, StateFlag.State.DENY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUpNoFireRegion() throws Exception {
|
void setUpNoFireRegion() throws Exception {
|
||||||
ProtectedRegion region = new ProtectedCuboidRegion(NO_FIRE_ID,
|
ProtectedRegion region = new ProtectedCuboidRegion(NO_FIRE_ID,
|
||||||
new BlockVector(100, 100, 100), new BlockVector(200, 200, 200));
|
new BlockVector(100, 100, 100), new BlockVector(200, 200, 200));
|
||||||
manager.addRegion(region);
|
manager.addRegion(region);
|
||||||
|
region.setFlag(DefaultFlag.FIRE_SPREAD, StateFlag.State.DENY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonBuildFlag() {
|
public void testNonBuildFlag() {
|
||||||
/*ApplicableRegionSet appl;
|
ApplicableRegionSet appl;
|
||||||
|
|
||||||
// Outside
|
// Outside
|
||||||
appl = manager.getApplicableRegions(outside);
|
appl = manager.getApplicableRegions(outside);
|
||||||
//assertTrue(appl.isStateFlagAllowed(AreaFlags.FLAG_FIRE_SPREAD));
|
assertTrue(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
// Inside courtyard
|
// Inside courtyard
|
||||||
appl = manager.getApplicableRegions(inCourtyard);
|
appl = manager.getApplicableRegions(inCourtyard);
|
||||||
//assertTrue(appl.isStateFlagAllowed(AreaFlags.FLAG_FIRE_SPREAD));
|
assertTrue(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
// Inside fountain
|
// Inside fountain
|
||||||
appl = manager.getApplicableRegions(inFountain);
|
appl = manager.getApplicableRegions(inFountain);
|
||||||
//assertFalse(appl.isStateFlagAllowed(AreaFlags.FLAG_FIRE_SPREAD));
|
assertFalse(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
|
|
||||||
// Inside no fire zone
|
// Inside no fire zone
|
||||||
appl = manager.getApplicableRegions(inNoFire);
|
appl = manager.getApplicableRegions(inNoFire);
|
||||||
//assertFalse(appl.isStateFlagAllowed(AreaFlags.FLAG_FIRE_SPREAD));*/
|
assertFalse(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -154,6 +159,11 @@ public void testPlayer1BuildAccess() {
|
|||||||
public void testPlayer2BuildAccess() {
|
public void testPlayer2BuildAccess() {
|
||||||
ApplicableRegionSet appl;
|
ApplicableRegionSet appl;
|
||||||
|
|
||||||
|
HashSet<ProtectedRegion> test = new HashSet<ProtectedRegion>();
|
||||||
|
test.add(courtyard);
|
||||||
|
test.add(fountain);
|
||||||
|
System.out.println(test);
|
||||||
|
|
||||||
// Outside
|
// Outside
|
||||||
appl = manager.getApplicableRegions(outside);
|
appl = manager.getApplicableRegions(outside);
|
||||||
assertTrue(appl.canBuild(player2));
|
assertTrue(appl.canBuild(player2));
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
// $Id$
|
|
||||||
/*
|
|
||||||
* WorldGuard
|
|
||||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sk89q.worldguard.protection;
|
|
||||||
|
|
||||||
import com.sk89q.worldguard.protection.databases.CSVDatabase;
|
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import com.sk89q.worldedit.BlockVector;
|
|
||||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
|
||||||
|
|
||||||
|
|
||||||
public class CSVDatabaseTest {
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLoadSave() throws Exception {
|
|
||||||
File temp = File.createTempFile("worldguard_csv_test", ".tmp");
|
|
||||||
temp.deleteOnExit();
|
|
||||||
|
|
||||||
Map<String,ProtectedRegion> regions =
|
|
||||||
new HashMap<String,ProtectedRegion>();
|
|
||||||
regions.put("test1", getTestRegion1());
|
|
||||||
regions.put("test2", getTestRegion2());
|
|
||||||
|
|
||||||
CSVDatabase writeDB = new CSVDatabase(temp);
|
|
||||||
writeDB.setRegions(regions);
|
|
||||||
writeDB.save();
|
|
||||||
|
|
||||||
CSVDatabase readDB = new CSVDatabase(temp);
|
|
||||||
readDB.load();
|
|
||||||
|
|
||||||
Map<String,ProtectedRegion> loaded = readDB.getRegions();
|
|
||||||
|
|
||||||
ProtectedRegion region1 = loaded.get("test1");
|
|
||||||
checkTestRegion1(region1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkTestRegion1(ProtectedRegion region) {
|
|
||||||
/* AreaFlags flags = new AreaFlags();
|
|
||||||
flags.setFlag(AreaFlags.FLAG_FIRE_SPREAD, State.ALLOW);
|
|
||||||
flags.setFlag(AreaFlags.FLAG_PVP, State.DENY);
|
|
||||||
flags.setFlag(AreaFlags.FLAG_LIGHTER, State.DENY);
|
|
||||||
region.setFlags(flags);
|
|
||||||
|
|
||||||
assertEquals(region.getFlags(), flags);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProtectedRegion getTestRegion1() {
|
|
||||||
BlockVector min = new BlockVector(1, 2, 3);
|
|
||||||
BlockVector max = new BlockVector(4, 5, 6);
|
|
||||||
|
|
||||||
ProtectedRegion region = new ProtectedCuboidRegion("test2", min, max);
|
|
||||||
|
|
||||||
/* AreaFlags flags = new AreaFlags();
|
|
||||||
flags.setFlag(AreaFlags.FLAG_FIRE_SPREAD, State.ALLOW);
|
|
||||||
flags.setFlag(AreaFlags.FLAG_PVP, State.DENY);
|
|
||||||
flags.setFlag(AreaFlags.FLAG_LIGHTER, State.DENY);
|
|
||||||
region.setFlags(flags);
|
|
||||||
*/
|
|
||||||
DefaultDomain domain = new DefaultDomain();
|
|
||||||
domain.addGroup("members");
|
|
||||||
domain.addGroup("sturmehs");
|
|
||||||
domain.addPlayer("hollie");
|
|
||||||
domain.addPlayer("chad");
|
|
||||||
domain.addPlayer("tetsu");
|
|
||||||
region.setOwners(domain);
|
|
||||||
|
|
||||||
region.setPriority(444);
|
|
||||||
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProtectedRegion getTestRegion2() {
|
|
||||||
BlockVector min = new BlockVector(7, 8, 9);
|
|
||||||
BlockVector max = new BlockVector(10, 11, 12);
|
|
||||||
|
|
||||||
ProtectedRegion region = new ProtectedCuboidRegion("test2", min, max);
|
|
||||||
/*
|
|
||||||
AreaFlags flags = new AreaFlags();
|
|
||||||
flags.setFlag(AreaFlags.FLAG_FIRE_SPREAD, State.ALLOW);
|
|
||||||
flags.setFlag(AreaFlags.FLAG_PVP, State.ALLOW);
|
|
||||||
flags.setFlag(AreaFlags.FLAG_LIGHTER, State.DENY);
|
|
||||||
region.setFlags(flags);
|
|
||||||
*/
|
|
||||||
|
|
||||||
DefaultDomain domain = new DefaultDomain();
|
|
||||||
domain.addGroup("admins");
|
|
||||||
domain.addPlayer("jon");
|
|
||||||
domain.addPlayer("ester");
|
|
||||||
domain.addPlayer("amy");
|
|
||||||
region.setOwners(domain);
|
|
||||||
|
|
||||||
region.setPriority(555);
|
|
||||||
|
|
||||||
return region;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,142 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* WorldGuard
|
||||||
|
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import org.junit.Before;
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.BlockVector2D;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldguard.TestPlayer;
|
||||||
|
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||||
|
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||||
|
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||||
|
import com.sk89q.worldguard.protection.managers.FlatRegionManager;
|
||||||
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
|
import com.sk89q.worldguard.protection.regions.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class RegionPriorityTest {
|
||||||
|
static String COURTYARD_ID = "courtyard";
|
||||||
|
static String FOUNTAIN_ID = "fountain";
|
||||||
|
static String NO_FIRE_ID = "nofire";
|
||||||
|
static String MEMBER_GROUP = "member";
|
||||||
|
static String COURTYARD_GROUP = "courtyard";
|
||||||
|
|
||||||
|
Vector inFountain = new Vector(2, 2, 2);
|
||||||
|
Vector inCourtyard = new Vector(7, 7, 7);
|
||||||
|
Vector outside = new Vector(15, 15, 15);
|
||||||
|
RegionManager manager;
|
||||||
|
ProtectedRegion globalRegion;
|
||||||
|
ProtectedRegion courtyard;
|
||||||
|
ProtectedRegion fountain;
|
||||||
|
TestPlayer player1;
|
||||||
|
TestPlayer player2;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
setUpGlobalRegion();
|
||||||
|
|
||||||
|
manager = new FlatRegionManager(null);
|
||||||
|
|
||||||
|
setUpPlayers();
|
||||||
|
setUpCourtyardRegion();
|
||||||
|
setUpFountainRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUpPlayers() {
|
||||||
|
player1 = new TestPlayer("tetsu");
|
||||||
|
player1.addGroup(MEMBER_GROUP);
|
||||||
|
player1.addGroup(COURTYARD_GROUP);
|
||||||
|
|
||||||
|
player2 = new TestPlayer("alex");
|
||||||
|
player2.addGroup(MEMBER_GROUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUpGlobalRegion() {
|
||||||
|
globalRegion = new GlobalProtectedRegion("__global__");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUpCourtyardRegion() {
|
||||||
|
DefaultDomain domain = new DefaultDomain();
|
||||||
|
domain.addGroup(COURTYARD_GROUP);
|
||||||
|
|
||||||
|
ArrayList<BlockVector2D> points = new ArrayList<BlockVector2D>();
|
||||||
|
points.add(new BlockVector2D(0, 0));
|
||||||
|
points.add(new BlockVector2D(10, 0));
|
||||||
|
points.add(new BlockVector2D(10, 10));
|
||||||
|
points.add(new BlockVector2D(0, 10));
|
||||||
|
|
||||||
|
//ProtectedRegion region = new ProtectedCuboidRegion(COURTYARD_ID, new BlockVector(0, 0, 0), new BlockVector(10, 10, 10));
|
||||||
|
ProtectedRegion region = new ProtectedPolygonalRegion(COURTYARD_ID, points, 0, 10);
|
||||||
|
|
||||||
|
region.setOwners(domain);
|
||||||
|
manager.addRegion(region);
|
||||||
|
|
||||||
|
courtyard = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUpFountainRegion() throws Exception {
|
||||||
|
DefaultDomain domain = new DefaultDomain();
|
||||||
|
domain.addGroup(MEMBER_GROUP);
|
||||||
|
|
||||||
|
ProtectedRegion region = new ProtectedCuboidRegion(FOUNTAIN_ID,
|
||||||
|
new BlockVector(0, 0, 0), new BlockVector(5, 5, 5));
|
||||||
|
region.setMembers(domain);
|
||||||
|
manager.addRegion(region);
|
||||||
|
|
||||||
|
fountain = region;
|
||||||
|
fountain.setParent(courtyard);
|
||||||
|
fountain.setFlag(DefaultFlag.FIRE_SPREAD, StateFlag.State.DENY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoPriorities() throws Exception {
|
||||||
|
ApplicableRegionSet appl;
|
||||||
|
|
||||||
|
appl = manager.getApplicableRegions(inCourtyard);
|
||||||
|
assertTrue(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
|
appl = manager.getApplicableRegions(inFountain);
|
||||||
|
assertFalse(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPriorities() throws Exception {
|
||||||
|
ApplicableRegionSet appl;
|
||||||
|
|
||||||
|
courtyard.setPriority(5);
|
||||||
|
appl = manager.getApplicableRegions(inCourtyard);
|
||||||
|
assertTrue(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
|
appl = manager.getApplicableRegions(inFountain);
|
||||||
|
assertTrue(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPriorities2() throws Exception {
|
||||||
|
ApplicableRegionSet appl;
|
||||||
|
|
||||||
|
fountain.setPriority(5);
|
||||||
|
appl = manager.getApplicableRegions(inCourtyard);
|
||||||
|
assertTrue(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
|
appl = manager.getApplicableRegions(inFountain);
|
||||||
|
assertFalse(appl.allows(DefaultFlag.FIRE_SPREAD));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user