Skip to content

Commit

Permalink
Nether portal flag
Browse files Browse the repository at this point in the history
Prevents nether portal from being created in region
Already created portal will work
  • Loading branch information
SergeyDertan committed Apr 19, 2019
1 parent 321471d commit 7118251
Show file tree
Hide file tree
Showing 13 changed files with 148 additions and 28 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
SRegionProtector is a nukkit plugin that allows players to protect their regions.
## Download
* [NukkitX.com](https://nukkitx.com/resources/sregionprotector.164/)
* [GoogleDrive](https://drive.google.com/file/d/1eCtg4VsgBcNEMaApQJRn5yW5YP_fAUd9/view?usp=sharing)
* [GoogleDrive](https://drive.google.com/file/d/1aQJ1U2J_toxUKHs266ikN0MJE8jTwcOq/view?usp=sharing)
* [All versions](https://drive.google.com/drive/folders/1Z98RAPGY-7NK49ktsBYkZgafUB50r7NC?usp=sharing)
## Features
* GUI
* API for another plugins
* Lots of flags
* Flexible settings
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>sergeydertan.sregionprotector</groupId>
<artifactId>SRegionProtector</artifactId>
<version>19.2</version>
<version>19.3</version>
<name>SRegionProtector</name>
<description>Flexible region protection plugin for nukkit</description>
<url>https://github.com/SergeyDertan/SRegionProtector</url>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import Sergey_Dertan.SRegionProtector.Region.Chunk.ChunkManager;
import Sergey_Dertan.SRegionProtector.Region.Flags.RegionFlags;
import Sergey_Dertan.SRegionProtector.Region.Region;
import Sergey_Dertan.SRegionProtector.Utils.Pair;
import Sergey_Dertan.SRegionProtector.Utils.Tags;
import cn.nukkit.Player;
import cn.nukkit.block.*;
Expand All @@ -27,15 +28,16 @@
import cn.nukkit.event.redstone.RedstoneUpdateEvent;
import cn.nukkit.event.weather.LightningStrikeEvent;
import cn.nukkit.item.ItemID;
import cn.nukkit.level.EnumLevel;
import cn.nukkit.level.Position;
import cn.nukkit.level.Sound;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.BlockFace;
import cn.nukkit.math.Vector3;
import it.unimi.dsi.fastutil.objects.Object2BooleanArrayMap;
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;

import java.util.Collection;
import java.util.Iterator;
import java.util.*;

@SuppressWarnings({"WeakerAccess", "unused"})
public final class RegionEventsHandler implements Listener {
Expand All @@ -50,6 +52,9 @@ public final class RegionEventsHandler implements Listener {
private final Object2BooleanMap<Class> isMonster;
private final Class monster; //mobplugin

private final Pair<Vector3, Integer>[] portalBlocks;

@SuppressWarnings("unchecked")
public RegionEventsHandler(ChunkManager chunkManager, boolean[] flagsStatus, boolean[] needMessage, boolean prioritySystem) {
this.chunkManager = chunkManager;
this.flagsStatus = flagsStatus;
Expand All @@ -64,6 +69,60 @@ public RegionEventsHandler(ChunkManager chunkManager, boolean[] flagsStatus, boo
} catch (ClassNotFoundException ignore) {
}
this.monster = monster;

this.portalBlocks = this.netherPortalBlocks();
}

/**
* @see BlockNetherPortal#spawnPortal(Position)
*/
private Pair[] netherPortalBlocks() {
Map<Vector3, Integer> blocks = new HashMap<>();

blocks.put(new Vector3(1), BlockID.OBSIDIAN);
blocks.put(new Vector3(2), BlockID.OBSIDIAN);

//z=1
blocks.put(new Vector3(0, 0, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(1, 0, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(2, 0, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(3, 0, 1), BlockID.OBSIDIAN);
//z=2
blocks.put(new Vector3(1, 0, 2), BlockID.OBSIDIAN);
blocks.put(new Vector3(2, 0, 2), BlockID.OBSIDIAN);
//z=1
//y=1
blocks.put(new Vector3(0, 1, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(1, 1, 1), BlockID.NETHER_PORTAL);
blocks.put(new Vector3(2, 1, 1), BlockID.NETHER_PORTAL);
blocks.put(new Vector3(3, 1, 1), BlockID.OBSIDIAN);
//y=2
//z=1
blocks.put(new Vector3(0, 2, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(1, 2, 1), BlockID.NETHER_PORTAL);
blocks.put(new Vector3(2, 2, 1), BlockID.NETHER_PORTAL);
blocks.put(new Vector3(3, 2, 1), BlockID.OBSIDIAN);
//y=3
blocks.put(new Vector3(0, 3, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(1, 3, 1), BlockID.NETHER_PORTAL);
blocks.put(new Vector3(2, 3, 1), BlockID.NETHER_PORTAL);
blocks.put(new Vector3(3, 3, 1), BlockID.OBSIDIAN);
//y=4
blocks.put(new Vector3(0, 4, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(1, 4, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(2, 4, 1), BlockID.OBSIDIAN);
blocks.put(new Vector3(3, 4, 1), BlockID.OBSIDIAN);

for (int x = -1; x < 4; x++) {
for (int y = 1; y < 4; y++) {
for (int z = -1; z < 3; z++) {
blocks.putIfAbsent(new Vector3(x, y, z), BlockID.AIR);
}
}
}
List<Pair<Vector3, Integer>> blockss = new ArrayList<>();
blocks.forEach((k, v) -> blockss.add(new Pair<>(k, v)));
return blockss.toArray(new Pair[0]);
}

//break & minefarm flags
Expand Down Expand Up @@ -355,6 +414,40 @@ public void levelLoad(LevelLoadEvent e) {
}
}

//prevent nether portal from spawning in region
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void entityPortalEnter(EntityPortalEnterEvent e) {
if (!this.flagsStatus[RegionFlags.FLAG_NETHER_PORTAL]) return;
if (e.getPortalType() != EntityPortalEnterEvent.PortalType.NETHER) return;
Position portal = EnumLevel.moveToNether(e.getEntity()).floor();
if (portal == null) return;

for (int x = -1; x < 2; x++) {
for (int z = -1; z < 2; z++) {
int chunkX = (portal.getFloorX() >> 4) + x;
int chunkZ = (portal.getFloorZ() >> 4) + z;
FullChunk chunk = portal.level.getChunk(chunkX, chunkZ, true);
if (chunk == null || !(chunk.isGenerated() || chunk.isPopulated())) {
portal.level.generateChunk(chunkX, chunkZ, true);
}
}
}

for (Pair<Vector3, Integer> block : this.portalBlocks) {
Vector3 pos = portal.add(block.key).floor();
if (portal.level.getBlockIdAt((int) pos.x, (int) pos.y, (int) pos.z) != block.value) {
Region region = this.chunkManager.getRegion(pos, portal.level.getName());
if (region != null && region.getFlagState(RegionFlags.FLAG_NETHER_PORTAL)) {
e.setCancelled();
if (e.getEntity() instanceof Player) {
Messenger.getInstance().sendMessage(((Player) e.getEntity()), "region.protected." + RegionFlags.getFlagName(RegionFlags.FLAG_NETHER_PORTAL));
}
break;
}
}
}
}

private boolean canInteractWith(int flag, Position pos, Player player) {
if (!this.flagsStatus[flag]) return false;
Chunk chunk = this.chunkManager.getChunk((long) pos.x, (long) pos.z, pos.level.getName(), true, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public final class FlagsPage implements Page {
this.flagToBlock[RegionFlags.FLAG_MINEFARM] = BlockID.DIAMOND_ORE;
this.flagToBlock[RegionFlags.FLAG_POTION_LAUNCH] = ItemID.SPLASH_POTION;
this.flagToBlock[RegionFlags.FLAG_HEAL] = ItemID.GOLDEN_APPLE;
this.flagToBlock[RegionFlags.FLAG_NETHER_PORTAL] = BlockID.NETHER_PORTAL;
this.flagToBlock[RegionFlags.FLAG_SELL] = ItemID.EMERALD;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@
import Sergey_Dertan.SRegionProtector.Region.Flags.Flag.RegionFlag;
import Sergey_Dertan.SRegionProtector.Region.Flags.Flag.RegionSellFlag;
import Sergey_Dertan.SRegionProtector.Region.Flags.Flag.RegionTeleportFlag;
import Sergey_Dertan.SRegionProtector.Region.Flags.RegionFlags;
import Sergey_Dertan.SRegionProtector.Region.Region;
import Sergey_Dertan.SRegionProtector.Utils.Utils;
import cn.nukkit.math.Vector3;
import com.alibaba.fastjson.JSON;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.*;

import static Sergey_Dertan.SRegionProtector.Region.Flags.RegionFlags.*;
import static Sergey_Dertan.SRegionProtector.Utils.Tags.*;
Expand Down Expand Up @@ -95,11 +92,11 @@ public static Region fromDataObject(RegionDataObject dataObject, RegionFlag[] fl
}

public static Region fromDataObject(RegionDataObject dataObject, FlagListDataObject flagsDataObject) {
return fromDataObject(dataObject, fromDataObject(flagsDataObject));
return fromDataObject(dataObject, fromDataObject(flagsDataObject).toArray(new RegionFlag[0]));
}

public static RegionFlag[] fromDataObject(FlagListDataObject dataObject) {
RegionFlag[] flags = new RegionFlag[RegionFlags.FLAG_AMOUNT];
public static List<RegionFlag> fromDataObject(FlagListDataObject dataObject) {
List<RegionFlag> flags = new ArrayList<>();
Boolean[] state = JSON.parseArray(dataObject.state, Boolean.class).toArray(new Boolean[0]);
@SuppressWarnings("unchecked")
Map<String, Object> teleportData = (Map<String, Object>) JSON.parse(dataObject.teleportData);
Expand All @@ -109,24 +106,24 @@ public static RegionFlag[] fromDataObject(FlagListDataObject dataObject) {
double y = ((Number) teleportData.get(Y_TAG)).doubleValue();
double z = ((Number) teleportData.get(Z_TAG)).doubleValue();
String level = (String) teleportData.get(LEVEL_TAG);
flags[i] = new RegionTeleportFlag(state[i], new Vector3(x, y, z), level);
flags.add(new RegionTeleportFlag(state[i], new Vector3(x, y, z), level));
continue;
}
if (i == FLAG_SELL) {
flags[i] = new RegionSellFlag(state[i], dataObject.sellData);
flags.add(new RegionSellFlag(state[i], dataObject.sellData));
continue;
}
flags[i] = new RegionFlag(state[i]);
flags.add(new RegionFlag(state[i]));
}
return flags;
}

public static FlagListDataObject toDataObject(Map<String, Map<String, Object>> data) { //for the yaml data provider
FlagListDataObject dataObject = new FlagListDataObject();
boolean[] state = new boolean[RegionFlags.FLAG_AMOUNT];
List<Boolean> state = new ArrayList<>();
for (Map.Entry<String, Map<String, Object>> flag : data.entrySet()) {
if (getFlagId(flag.getKey()) == FLAG_INVALID) continue;
state[getFlagId(flag.getKey())] = (Boolean) flag.getValue().get(STATE_TAG);
state.add(getFlagId(flag.getKey()), (Boolean) flag.getValue().get(STATE_TAG));
if (getFlagId(flag.getKey()) == FLAG_SELL) {
dataObject.sellData = ((Number) flag.getValue().getOrDefault(PRICE_TAG, -1L)).longValue();
}
Expand All @@ -141,7 +138,7 @@ public static FlagListDataObject toDataObject(Map<String, Map<String, Object>> d
dataObject.teleportData = JSON.toJSONString(teleport);
}
}
dataObject.state = JSON.toJSONString(state);
dataObject.state = JSON.toJSONString(state.toArray(new Boolean[0]));
return dataObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings({"WeakerAccess", "unused"})
Expand Down Expand Up @@ -57,8 +58,9 @@ public abstract class RegionFlags {
public static final int FLAG_SMART_DOORS = 31;
public static final int FLAG_MINEFARM = 32;
public static final int FLAG_FALL_DAMAGE = 33;
public static final int FLAG_NETHER_PORTAL = 34;

public static final int FLAG_AMOUNT = 34;
public static final int FLAG_AMOUNT = 35;

public static final RegionFlag[] defaults = new RegionFlag[FLAG_AMOUNT];
public static final Permission[] permissions = new Permission[FLAG_AMOUNT];
Expand Down Expand Up @@ -103,6 +105,7 @@ public abstract class RegionFlags {
flagList.put(FLAG_SMART_DOORS, "smart-doors");
flagList.put(FLAG_MINEFARM, "minefarm");
flagList.put(FLAG_FALL_DAMAGE, "fall-damage");
flagList.put(FLAG_NETHER_PORTAL, "nether-portal");
flags = ImmutableBiMap.copyOf(flagList);

Map<String, Integer> aAliases = new HashMap<>(FLAG_AMOUNT);
Expand Down Expand Up @@ -150,6 +153,7 @@ public abstract class RegionFlags {
fState.put(FLAG_SMART_DOORS, false);
fState.put(FLAG_MINEFARM, false);
fState.put(FLAG_FALL_DAMAGE, false);
fState.put(FLAG_NETHER_PORTAL, true);

state = ImmutableMap.copyOf(fState);
}
Expand Down Expand Up @@ -190,10 +194,9 @@ public static boolean getStateFromString(String state, int flag) {
throw new RuntimeException("Wrong state");
}

public static void fixMissingFlags(RegionFlag[] flags) {
for (int i = 0; i < FLAG_AMOUNT; ++i) {
if (flags[i] != null) continue;
flags[i] = defaults[i].clone();
public static void fixMissingFlags(List<RegionFlag> flags) {
for (int i = flags.size(); i < FLAG_AMOUNT; ++i) {
flags.add(defaults[i].clone());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ public void init() {

FlagListDataObject flags = this.provider.loadFlags(name);

RegionFlag[] flagList = Converter.fromDataObject(flags);
List<RegionFlag> flagList = Converter.fromDataObject(flags);

boolean needUpdate = false;
if (flagList.length < FLAG_AMOUNT) {
if (flagList.size() < FLAG_AMOUNT) {
needUpdate = true;
fixMissingFlags(flagList);
}

Region region = new Region(name, creator, level, priority, minX, minY, minZ, maxX, maxY, maxZ, owners, members, flagList);
Region region = new Region(name, creator, level, priority, minX, minY, minZ, maxX, maxY, maxZ, owners, members, flagList.toArray(new RegionFlag[0]));

region.needUpdate = needUpdate;

Expand Down
17 changes: 17 additions & 0 deletions src/main/java/Sergey_Dertan/SRegionProtector/Utils/Pair.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package Sergey_Dertan.SRegionProtector.Utils;

import java.util.Objects;

public final class Pair<F, S> {

public F key;
Expand All @@ -9,4 +11,19 @@ public Pair(F key, S value) {
this.key = key;
this.value = value;
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof Pair) {
Pair pair = (Pair) obj;
return Objects.equals(this.key, pair.key) && Objects.equals(this.value, pair.value);
}
return false;
}

@Override
public int hashCode() {
return (this.key != null ? this.key.hashCode() : 0) * 13 + (this.value != null ? this.value.hashCode() : 0);
}
}
1 change: 1 addition & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ active-flags:
smart-doors: true
minefarm: true
fall-damage: true
nether-portal: true
display:
place: true
break: true
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/lang/eng.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ region.protected.ender-pearl: "You can`t use enderpearl in this region"
region.protected.chest-access: "You can`t use chests in this region"
region.protected.sleep: "You can`t use bed in this region"
region.protected.fire: "You can`t ignite blocks in this region"
region.protected.fall_damage: "You can`t take fall damage in this region"
region.protected.fall-damage: "You can`t take fall damage in this region"
region.protected.nether-portal: "Nether portal can`t be created in region"

region.selection.pos1: "First pos set"
region.selection.pos2: "Second pos set"
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/lang/rus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ region.protected.ender-pearl: "Вы не можете использовать
region.protected.chest-access: "Вы не можете использовать сундуки в этом регионе"
region.protected.sleep: "Вы не можете использовать кровать в этом регионе"
region.protected.fire: "Вы не можете поджигать в этом регионе"
region.protected.fall_damage: "Вы не можете получать урон от падения в этом регионе"
region.protected.fall-damage: "Вы не можете получать урон от падения в этом регионе"
region.protected.nether-portal: "Портал не может быть создан в этом регионе"

region.selection.pos1: "Первая точка установлена"
region.selection.pos2: "Вторая точка установлена"
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,10 @@ permissions:
sregionprotector.region.flag.chunk_loader:
default: op
sregionprotector.region.flag.smart_doors:
default: op
default: true
sregionprotector.region.flag.minefarm:
default: op
sregionprotector.region.flag.fall_damage:
default: op
sregionprotector.region.flag.nether_portal:
default: op
2 changes: 2 additions & 0 deletions src/main/resources/region-settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ default-flags:
smart-doors: true
minefarm: false
fall-damage: false
nether-portal: true
need-message:
move: false
place: true
Expand All @@ -55,6 +56,7 @@ need-message:
sleep: true
minefarm: false
fall-damage: false
nether-portal: true
max-region-name-length: 10
min-region-name-length: 3
# 1 second = 20 ticks
Expand Down

0 comments on commit 7118251

Please sign in to comment.