From 3b9679589b1ff1a149feeeb29c8eabc96adcc20f Mon Sep 17 00:00:00 2001
From: Thom van den Akker
Date: Wed, 15 Jan 2025 22:27:40 +0100
Subject: [PATCH] Improve permission handling around interaction events
---
.../core/blocks/huts/BlockStash.java | 4 +-
.../gui/AbstractWindowModuleBuilding.java | 5 +-
.../core/client/gui/WindowPostBox.java | 4 +-
.../gui/citizen/AbstractWindowCitizen.java | 6 +-
.../core/client/gui/map/WindowColonyMap.java | 4 +-
.../client/gui/townhall/WindowMainPage.java | 68 +---
.../buildings/views/AbstractBuildingView.java | 5 +-
.../ColonyPermissionEventHandler.java | 330 +++++++++---------
.../core/entity/citizen/EntityCitizen.java | 16 +-
.../core/entity/visitor/VisitorCitizen.java | 16 +-
.../core/network/NetworkChannel.java | 3 +-
.../server/AbstractColonyServerMessage.java | 44 +--
.../server/colony/InteractionClose.java | 9 +
.../server/colony/InteractionResponse.java | 9 +
.../server/colony/OpenInventoryMessage.java | 171 ---------
.../OpenBuildingInventoryMessage.java | 72 ++++
.../citizen/OpenCitizenInventoryMessage.java | 87 +++++
17 files changed, 405 insertions(+), 448 deletions(-)
delete mode 100755 src/main/java/com/minecolonies/core/network/messages/server/colony/OpenInventoryMessage.java
create mode 100644 src/main/java/com/minecolonies/core/network/messages/server/colony/building/OpenBuildingInventoryMessage.java
create mode 100644 src/main/java/com/minecolonies/core/network/messages/server/colony/citizen/OpenCitizenInventoryMessage.java
diff --git a/src/main/java/com/minecolonies/core/blocks/huts/BlockStash.java b/src/main/java/com/minecolonies/core/blocks/huts/BlockStash.java
index 345d022d6ed..7afd7a49a06 100755
--- a/src/main/java/com/minecolonies/core/blocks/huts/BlockStash.java
+++ b/src/main/java/com/minecolonies/core/blocks/huts/BlockStash.java
@@ -10,7 +10,7 @@
import com.minecolonies.api.tileentities.MinecoloniesTileEntities;
import com.minecolonies.core.tileentities.TileEntityColonyBuilding;
import com.minecolonies.core.Network;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.building.OpenBuildingInventoryMessage;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.entity.player.Player;
@@ -99,7 +99,7 @@ public InteractionResult use(
&& building.getColony() != null
&& building.getColony().getPermissions().hasPermission(player, Action.ACCESS_HUTS))
{
- Network.getNetwork().sendToServer(new OpenInventoryMessage(building));
+ Network.getNetwork().sendToServer(new OpenBuildingInventoryMessage(building));
}
}
return InteractionResult.SUCCESS;
diff --git a/src/main/java/com/minecolonies/core/client/gui/AbstractWindowModuleBuilding.java b/src/main/java/com/minecolonies/core/client/gui/AbstractWindowModuleBuilding.java
index c71fad0d798..e5fee8e3a1f 100644
--- a/src/main/java/com/minecolonies/core/client/gui/AbstractWindowModuleBuilding.java
+++ b/src/main/java/com/minecolonies/core/client/gui/AbstractWindowModuleBuilding.java
@@ -5,7 +5,7 @@
import com.minecolonies.api.colony.buildings.views.IBuildingView;
import com.minecolonies.core.Network;
import com.minecolonies.core.colony.buildings.views.AbstractBuildingView;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.building.OpenBuildingInventoryMessage;
import com.minecolonies.core.network.messages.server.colony.building.BuildRequestMessage;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.client.resources.sounds.SimpleSoundInstance;
@@ -14,7 +14,6 @@
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.contents.TranslatableContents;
import net.minecraft.sounds.SoundEvents;
-import org.jetbrains.annotations.NotNull;
import static com.minecolonies.api.util.constant.TranslationConstants.*;
import static com.minecolonies.api.util.constant.WindowConstants.*;
@@ -121,7 +120,7 @@ else if (buttonLabel.equalsIgnoreCase(ACTION_CANCEL_DECONSTRUCTION))
*/
private void inventoryClicked()
{
- Network.getNetwork().sendToServer(new OpenInventoryMessage(building));
+ Network.getNetwork().sendToServer(new OpenBuildingInventoryMessage(building));
}
@Override
diff --git a/src/main/java/com/minecolonies/core/client/gui/WindowPostBox.java b/src/main/java/com/minecolonies/core/client/gui/WindowPostBox.java
index d69773767a1..bdb78a5eb9d 100755
--- a/src/main/java/com/minecolonies/core/client/gui/WindowPostBox.java
+++ b/src/main/java/com/minecolonies/core/client/gui/WindowPostBox.java
@@ -10,7 +10,7 @@
import com.minecolonies.api.util.constant.Constants;
import com.minecolonies.core.Network;
import com.minecolonies.core.colony.buildings.views.AbstractBuildingView;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.building.OpenBuildingInventoryMessage;
import com.minecolonies.core.network.messages.server.colony.building.postbox.PostBoxRequestMessage;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.EnchantedBookItem;
@@ -104,7 +104,7 @@ public WindowPostBox(final AbstractBuildingView buildingView)
*/
private void inventoryClicked()
{
- Network.getNetwork().sendToServer(new OpenInventoryMessage(buildingView));
+ Network.getNetwork().sendToServer(new OpenBuildingInventoryMessage(buildingView));
}
/**
diff --git a/src/main/java/com/minecolonies/core/client/gui/citizen/AbstractWindowCitizen.java b/src/main/java/com/minecolonies/core/client/gui/citizen/AbstractWindowCitizen.java
index 0a63b434cee..832fdc0da68 100644
--- a/src/main/java/com/minecolonies/core/client/gui/citizen/AbstractWindowCitizen.java
+++ b/src/main/java/com/minecolonies/core/client/gui/citizen/AbstractWindowCitizen.java
@@ -8,7 +8,7 @@
import com.minecolonies.core.Network;
import com.minecolonies.core.client.gui.AbstractWindowRequestTree;
import com.minecolonies.core.colony.buildings.views.AbstractBuildingView;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.citizen.OpenCitizenInventoryMessage;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
@@ -35,8 +35,8 @@ public AbstractWindowCitizen(final ICitizenDataView citizen, final String ui)
registerButton("requestIcon", () -> new RequestWindowCitizen(citizen).open());
PaneBuilders.tooltipBuilder().hoverPane(findPaneByID("requestIcon")).build().setText(Component.translatable("com.minecolonies.coremod.gui.citizen.requests"));
- registerButton("inventoryTab", () -> Network.getNetwork().sendToServer(new OpenInventoryMessage(colony, citizen.getName(), citizen.getEntityId())));
- registerButton("inventoryIcon", () -> Network.getNetwork().sendToServer(new OpenInventoryMessage(colony, citizen.getName(), citizen.getEntityId())));
+ registerButton("inventoryTab", () -> Network.getNetwork().sendToServer(new OpenCitizenInventoryMessage(citizen)));
+ registerButton("inventoryIcon", () -> Network.getNetwork().sendToServer(new OpenCitizenInventoryMessage(citizen)));
PaneBuilders.tooltipBuilder().hoverPane(findPaneByID("inventoryIcon")).build().setText(Component.translatable("com.minecolonies.coremod.gui.citizen.inventory"));
registerButton("happinessTab", () -> new HappinessWindowCitizen(citizen).open());
diff --git a/src/main/java/com/minecolonies/core/client/gui/map/WindowColonyMap.java b/src/main/java/com/minecolonies/core/client/gui/map/WindowColonyMap.java
index de6f4866a61..4d01ce9a967 100644
--- a/src/main/java/com/minecolonies/core/client/gui/map/WindowColonyMap.java
+++ b/src/main/java/com/minecolonies/core/client/gui/map/WindowColonyMap.java
@@ -21,7 +21,7 @@
import com.minecolonies.core.colony.buildings.workerbuildings.BuildingTownHall;
import com.minecolonies.core.entity.citizen.EntityCitizen;
import com.minecolonies.core.network.messages.client.colony.ColonyListMessage;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.building.OpenBuildingInventoryMessage;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
@@ -130,7 +130,7 @@ public WindowColonyMap(final IBuildingView building)
*/
private void inventoryClicked()
{
- Network.getNetwork().sendToServer(new OpenInventoryMessage(building));
+ Network.getNetwork().sendToServer(new OpenBuildingInventoryMessage(building));
}
/**
diff --git a/src/main/java/com/minecolonies/core/client/gui/townhall/WindowMainPage.java b/src/main/java/com/minecolonies/core/client/gui/townhall/WindowMainPage.java
index 64b8455c478..e07ac29e7d7 100644
--- a/src/main/java/com/minecolonies/core/client/gui/townhall/WindowMainPage.java
+++ b/src/main/java/com/minecolonies/core/client/gui/townhall/WindowMainPage.java
@@ -50,41 +50,13 @@ public class WindowMainPage extends AbstractWindowTownHall
/**
* Is the special feature unlocked.
*/
- private static AtomicBoolean isFeatureUnlocked = new AtomicBoolean(false);
-
- /**
- * Drop down list for style.
- */
- private DropDownList colorDropDownList;
-
- /**
- * Drop down list for style.
- */
- private DropDownList textureDropDownList;
-
- /**
- * Drop down list for name style.
- */
- private DropDownList nameStyleDropDownList;
-
- /**
- * The initial texture index.
- */
- private int initialTextureIndex;
-
- /**
- * The initial texture index.
- */
- private int initialNamePackIndex;
-
-
+ private static final AtomicBoolean isFeatureUnlocked = new AtomicBoolean(false);
/**
* Label for the colony name.
*/
private final Text title;
-
/**
* Constructor for the town hall window.
*
@@ -93,9 +65,9 @@ public class WindowMainPage extends AbstractWindowTownHall
public WindowMainPage(final BuildingTownHall.View building)
{
super(building, "layoutactions.xml");
- initDropDowns();
+ this.title = findPaneOfTypeByID(LABEL_BUILDING_NAME, Text.class);
- title = findPaneOfTypeByID(LABEL_BUILDING_NAME, Text.class);
+ initDropDowns();
registerButton(BUTTON_CHANGE_SPEC, this::doNothing);
registerButton(BUTTON_RENAME, this::renameClicked);
@@ -109,13 +81,6 @@ public WindowMainPage(final BuildingTownHall.View building)
registerButton(BUTTON_BANNER_PICKER, this::openBannerPicker);
registerButton(BUTTON_RESET_TEXTURE, this::resetTextureStyle);
- this.colorDropDownList.setSelectedIndex(building.getColony().getTeamColonyColor().ordinal());
- this.textureDropDownList.setSelectedIndex(TEXTURE_PACKS.indexOf(building.getColony().getTextureStyleId()));
- this.initialTextureIndex = textureDropDownList.getSelectedIndex();
-
- this.nameStyleDropDownList.setSelectedIndex(building.getColony().getNameFileIds().indexOf(building.getColony().getNameStyle()));
- this.initialNamePackIndex = nameStyleDropDownList.getSelectedIndex();
-
checkFeatureUnlock();
}
@@ -139,11 +104,8 @@ private void initDropDowns()
{
findPaneOfTypeByID(DROPDOWN_COLOR_ID, DropDownList.class).setEnabled(enabled);
- colorDropDownList = findPaneOfTypeByID(DROPDOWN_COLOR_ID, DropDownList.class);
- colorDropDownList.setHandler(this::onDropDownListChanged);
-
final List textColors = Arrays.stream(ChatFormatting.values()).filter(ChatFormatting::isColor).toList();
-
+ final DropDownList colorDropDownList = findPaneOfTypeByID(DROPDOWN_COLOR_ID, DropDownList.class);
colorDropDownList.setDataProvider(new DropDownList.DataProvider()
{
@Override
@@ -163,9 +125,10 @@ public String getLabel(final int index)
return "";
}
});
+ colorDropDownList.setSelectedIndex(building.getColony().getTeamColonyColor().ordinal());
+ colorDropDownList.setHandler(this::onDropDownListChanged);
- textureDropDownList = findPaneOfTypeByID(DROPDOWN_TEXT_ID, DropDownList.class);
- textureDropDownList.setHandler(this::toggleTexture);
+ final DropDownList textureDropDownList = findPaneOfTypeByID(DROPDOWN_TEXT_ID, DropDownList.class);
textureDropDownList.setDataProvider(new DropDownList.DataProvider()
{
@Override
@@ -180,9 +143,10 @@ public String getLabel(final int index)
return TEXTURE_PACKS.get(index);
}
});
+ textureDropDownList.setSelectedIndex(TEXTURE_PACKS.indexOf(building.getColony().getTextureStyleId()));
+ textureDropDownList.setHandler(this::toggleTexture);
- nameStyleDropDownList = findPaneOfTypeByID(DROPDOWN_NAME_ID, DropDownList.class);
- nameStyleDropDownList.setHandler(this::toggleNameFile);
+ final DropDownList nameStyleDropDownList = findPaneOfTypeByID(DROPDOWN_NAME_ID, DropDownList.class);
nameStyleDropDownList.setDataProvider(new DropDownList.DataProvider()
{
@Override
@@ -197,6 +161,8 @@ public String getLabel(final int index)
return building.getColony().getNameFileIds().get(index);
}
});
+ nameStyleDropDownList.setSelectedIndex(building.getColony().getNameFileIds().indexOf(building.getColony().getNameStyle()));
+ nameStyleDropDownList.setHandler(this::toggleNameFile);
}
/**
@@ -206,10 +172,7 @@ public String getLabel(final int index)
*/
private void toggleTexture(final DropDownList dropDownList)
{
- if (dropDownList.getSelectedIndex() != initialTextureIndex)
- {
- Network.getNetwork().sendToServer(new ColonyTextureStyleMessage(building.getColony(), TEXTURE_PACKS.get(dropDownList.getSelectedIndex())));
- }
+ Network.getNetwork().sendToServer(new ColonyTextureStyleMessage(building.getColony(), TEXTURE_PACKS.get(dropDownList.getSelectedIndex())));
}
/**
@@ -219,10 +182,7 @@ private void toggleTexture(final DropDownList dropDownList)
*/
private void toggleNameFile(final DropDownList dropDownList)
{
- if (dropDownList.getSelectedIndex() != initialNamePackIndex)
- {
- Network.getNetwork().sendToServer(new ColonyNameStyleMessage(building.getColony(), building.getColony().getNameFileIds().get(dropDownList.getSelectedIndex())));
- }
+ Network.getNetwork().sendToServer(new ColonyNameStyleMessage(building.getColony(), building.getColony().getNameFileIds().get(dropDownList.getSelectedIndex())));
}
/**
diff --git a/src/main/java/com/minecolonies/core/colony/buildings/views/AbstractBuildingView.java b/src/main/java/com/minecolonies/core/colony/buildings/views/AbstractBuildingView.java
index 52e719e378a..f4f3e561733 100755
--- a/src/main/java/com/minecolonies/core/colony/buildings/views/AbstractBuildingView.java
+++ b/src/main/java/com/minecolonies/core/colony/buildings/views/AbstractBuildingView.java
@@ -21,10 +21,9 @@
import com.minecolonies.core.client.gui.WindowHutMinPlaceholder;
import com.minecolonies.core.client.gui.huts.WindowHutWorkerModulePlaceholder;
import com.minecolonies.core.colony.buildings.moduleviews.WorkerBuildingModuleView;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.building.OpenBuildingInventoryMessage;
import com.minecolonies.core.network.messages.server.colony.building.HutRenameMessage;
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
-import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
@@ -358,7 +357,7 @@ public void openGui(final boolean shouldOpenInv)
{
if (shouldOpenInv)
{
- Network.getNetwork().sendToServer(new OpenInventoryMessage(this));
+ Network.getNetwork().sendToServer(new OpenBuildingInventoryMessage(this));
}
else
{
diff --git a/src/main/java/com/minecolonies/core/colony/permissions/ColonyPermissionEventHandler.java b/src/main/java/com/minecolonies/core/colony/permissions/ColonyPermissionEventHandler.java
index 4345fc182e3..78e3e2bf8e7 100755
--- a/src/main/java/com/minecolonies/core/colony/permissions/ColonyPermissionEventHandler.java
+++ b/src/main/java/com/minecolonies/core/colony/permissions/ColonyPermissionEventHandler.java
@@ -8,10 +8,8 @@
import com.minecolonies.api.colony.permissions.Action;
import com.minecolonies.api.colony.permissions.Explosions;
import com.minecolonies.api.colony.permissions.PermissionEvent;
-import com.minecolonies.api.entity.citizen.AbstractEntityCitizen;
import com.minecolonies.api.items.ModTags;
import com.minecolonies.api.util.EntityUtils;
-import com.minecolonies.api.util.ItemStackUtils;
import com.minecolonies.api.util.MessageUtils;
import com.minecolonies.core.MineColonies;
import com.minecolonies.core.blocks.BlockDecorationController;
@@ -24,21 +22,20 @@
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BlockTags;
+import net.minecraft.world.Container;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
-import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.animal.horse.Llama;
import net.minecraft.world.entity.monster.Enemy;
import net.minecraft.world.entity.monster.Monster;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.PotionItem;
+import net.minecraft.world.item.ThrowablePotionItem;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
-import net.minecraft.world.level.block.AirBlock;
-import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
@@ -58,7 +55,6 @@
import java.util.Map;
import java.util.UUID;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
import static com.minecolonies.api.util.constant.Constants.TICKS_SECOND;
import static com.minecolonies.api.util.constant.TranslationConstants.PERMISSION_DENIED;
@@ -94,58 +90,39 @@ public ColonyPermissionEventHandler(final Colony colony)
}
/**
- * BlockEvent.PlaceEvent handler.
- *
- * @param event BlockEvent.PlaceEvent
+ * BlockEvent.EntityPlaceEvent handler.
+ *
+ * Allow under the following circumstances:
+ *
+ * - The entity is not a player.
+ * - Colony protection is off.
+ * - The event did not happen inside the current colony.
+ *
+ * Deny under the following circumstances:
+ *
+ * - The block is a hut block, but the player has no {@link Action#PLACE_HUTS} permission.
+ * - Anything else, but the player has no {@link Action#PLACE_BLOCKS} permission.
+ *
+ *
*/
@SubscribeEvent
public void on(final BlockEvent.EntityPlaceEvent event)
{
- final Action action = event.getPlacedBlock().getBlock() instanceof AbstractBlockHut ? Action.PLACE_HUTS : Action.PLACE_BLOCKS;
- if (MineColonies.getConfig().getServer().enableColonyProtection.get() && checkBlockEventDenied(event.getLevel(),
- event.getPos(),
- event.getEntity(),
- event.getPlacedBlock(),
- action))
+ if (!(event.getEntity() instanceof Player player))
{
- cancelEvent(event, event.getEntity(), colony, action, event.getPos());
+ return;
}
- }
- /**
- * This method returns TRUE if this event should be denied.
- *
- * @param worldIn the world to check in
- * @param posIn the block to check
- * @param entity the player who tries
- * @param blockState the state that block is in
- * @param action the action that was performed on the position
- * @return true if canceled
- */
- private boolean checkBlockEventDenied(
- final LevelAccessor worldIn, final BlockPos posIn, final Entity entity, final BlockState blockState,
- final Action action)
- {
- if (entity instanceof Player)
+ if (!MineColonies.getConfig().getServer().enableColonyProtection.get() || !colony.isCoordInColony(player.level(), event.getPos()))
{
- @NotNull final Player player = EntityUtils.getPlayerOfFakePlayer((Player) entity, entity.level);
- if (colony.isCoordInColony(entity.level, posIn))
- {
- if (blockState.getBlock() instanceof AbstractBlockHut
- && colony.getPermissions().hasPermission(player, action))
- {
- return false;
- }
+ return;
+ }
- return !colony.getPermissions().hasPermission(player, action);
- }
+ final Action action = event.getPlacedBlock().getBlock() instanceof AbstractBlockHut ? Action.PLACE_HUTS : Action.PLACE_BLOCKS;
+ if (colony.getPermissions().hasPermission(player, action))
+ {
+ cancelEvent(event, event.getEntity(), colony, action, event.getPos());
}
- /*
- * - We are not inside the colony
- * - We are in but not denied
- * - The placer is not a player.
- */
- return false;
}
/**
@@ -163,42 +140,35 @@ private void cancelEvent(final Event event, @Nullable final Entity entity, final
if (event.isCancelable())
{
event.setCanceled(true);
- if (entity == null)
- {
- if (colony.hasTownHall())
- {
- colony.getBuildingManager().getTownHall().addPermissionEvent(new PermissionEvent(null, "-", action, pos));
- }
- return;
- }
+
+ final UUID uuid = entity != null ? entity.getUUID() : null;
+ final String name = entity != null ? entity.getName().getString() : "-";
if (colony.hasTownHall())
{
- colony.getBuildingManager().getTownHall().addPermissionEvent(new PermissionEvent(entity.getUUID(), entity.getName().getString(), action, pos));
+ colony.getBuildingManager().getTownHall().addPermissionEvent(new PermissionEvent(uuid, name, action, pos));
}
-
if (entity instanceof FakePlayer)
{
return;
}
- final long worldTime = entity.level.getGameTime();
- if (!lastPlayerNotificationTick.containsKey(entity.getUUID())
- || lastPlayerNotificationTick.get(entity.getUUID()) + (TICKS_SECOND * 10)
- < worldTime)
- {
- MessageUtils.format(PERMISSION_DENIED).sendTo((Player) entity);
- lastPlayerNotificationTick.put(entity.getUUID(), worldTime);
- playerAttempts.put(entity.getUUID(), 0);
- }
- else
+ if (entity instanceof Player player)
{
- if (playerAttempts.compute(entity.getUUID(), (uuid, count) -> count == null ? 1 : count + 1) > 10)
+ MessageUtils.format(PERMISSION_DENIED).sendTo(player);
+
+ final long worldTime = entity.level.getGameTime();
+ if (!lastPlayerNotificationTick.containsKey(uuid) || lastPlayerNotificationTick.get(uuid) + (TICKS_SECOND * 10) < worldTime)
+ {
+ lastPlayerNotificationTick.put(uuid, worldTime);
+ playerAttempts.put(uuid, 0);
+ }
+ else
{
- if (entity instanceof LivingEntity living)
+ if (playerAttempts.merge(uuid, 1, Integer::sum) > 10)
{
- playerAttempts.put(entity.getUUID(), 0);
- living.addEffect(new MobEffectInstance(MobEffects.LEVITATION, TICKS_SECOND * 10));
+ playerAttempts.removeInt(uuid);
+ player.addEffect(new MobEffectInstance(MobEffects.LEVITATION, TICKS_SECOND * 10));
}
}
}
@@ -221,7 +191,7 @@ public void on(final BlockEvent.BreakEvent event)
if (event.getState().getBlock() instanceof AbstractBlockHut)
{
- @Nullable final IBuilding building = IColonyManager.getInstance().getBuilding(event.getPlayer().level, event.getPos());
+ final IBuilding building = IColonyManager.getInstance().getBuilding(event.getPlayer().level, event.getPos());
if (building == null)
{
return;
@@ -241,7 +211,7 @@ public void on(final BlockEvent.BreakEvent event)
if (!building.getColony().getPermissions().hasPermission(event.getPlayer(), Action.BREAK_HUTS))
{
- if (checkEventCancelation(Action.BREAK_HUTS, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPos()))
+ if (checkEventCancellation(Action.BREAK_HUTS, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPos()))
{
return;
}
@@ -256,7 +226,7 @@ public void on(final BlockEvent.BreakEvent event)
}
else if (event.getState().getBlock() instanceof BlockDecorationController)
{
- if (checkEventCancelation(Action.BREAK_HUTS, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPos()))
+ if (checkEventCancellation(Action.BREAK_HUTS, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPos()))
{
return;
}
@@ -264,7 +234,7 @@ else if (event.getState().getBlock() instanceof BlockDecorationController)
}
else
{
- checkEventCancelation(Action.BREAK_BLOCKS, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPos());
+ checkEventCancellation(Action.BREAK_BLOCKS, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPos());
}
}
@@ -285,7 +255,7 @@ public void on(final ExplosionEvent.Detonate event)
final Predicate getBlocksInColony = pos -> colony.isCoordInColony(eventWorld, pos);
Predicate getEntitiesInColony = entity -> (!(entity instanceof Enemy) || (entity instanceof Llama))
&& colony.isCoordInColony(entity.getCommandSenderWorld(), entity.blockPosition());
- switch(MineColonies.getConfig().getServer().turnOffExplosionsInColonies.get())
+ switch (MineColonies.getConfig().getServer().turnOffExplosionsInColonies.get())
{
case DAMAGE_NOTHING:
// if any entity is in colony -> remove from list
@@ -293,17 +263,12 @@ public void on(final ExplosionEvent.Detonate event)
// intentional fall-through to next case.
case DAMAGE_PLAYERS:
// if non-mob or llama entity is in colony -> remove from list
- final List entitiesToRemove = event.getAffectedEntities().stream()
- .filter(getEntitiesInColony)
- .filter(entity -> !(entity instanceof ServerPlayer))
- .collect(Collectors.toList());
+ final List entitiesToRemove = event.getAffectedEntities().stream().filter(getEntitiesInColony).filter(entity -> !(entity instanceof ServerPlayer)).toList();
event.getAffectedEntities().removeAll(entitiesToRemove);
// intentional fall-through to next case.
case DAMAGE_ENTITIES:
// if block is in colony -> remove from list
- final List blocksToRemove = event.getAffectedBlocks().stream()
- .filter(getBlocksInColony)
- .collect(Collectors.toList());
+ final List blocksToRemove = event.getAffectedBlocks().stream().filter(getBlocksInColony).toList();
event.getAffectedBlocks().removeAll(blocksToRemove);
break;
case DAMAGE_EVERYTHING:
@@ -329,82 +294,116 @@ public void on(final ExplosionEvent.Start event)
}
/**
- * PlayerInteractEvent handler.
+ * PlayerInteractEvent.RightClickBlock handler.
*
- * Check, if a player right clicked a block. Deny if: - If the block is in colony - block is AbstractBlockHut - player has not permission
+ * Allow under the following circumstances:
+ *
+ * - Colony protection is off.
+ * - The event did not happen inside the current colony.
+ *
+ * Deny under the following circumstances:
+ *
+ * - The block is a hut block, but the player has no {@link Action#ACCESS_HUTS} permission.
+ * - The block is a toggleable (door, trapdoor, fence gate, etc.), but the player has no {@link Action#ACCESS_TOGGLEABLES} permission.
+ * - The block is a container block (chest, furnace, etc.), but the player has no {@link Action#OPEN_CONTAINER} permission.
+ * - The block is free to interact block/position, but the player has no {@link Action#ACCESS_FREE_BLOCKS} permission.
+ * - Anything else, but the player has no {@link Action#RIGHTCLICK_BLOCK} permission.
+ *
+ *
*
- * @param event PlayerInteractEvent
+ * @param event the event instance.
*/
@SubscribeEvent
- public void on(final PlayerInteractEvent event)
+ public void on(final PlayerInteractEvent.RightClickBlock event)
{
- if (colony.isCoordInColony(event.getLevel(), event.getPos())
- && !(event instanceof PlayerInteractEvent.EntityInteract || event instanceof PlayerInteractEvent.EntityInteractSpecific))
+ if (!MineColonies.getConfig().getServer().enableColonyProtection.get() || !colony.isCoordInColony(event.getLevel(), event.getPos()))
{
- final BlockState state = event.getLevel().getBlockState(event.getPos());
- final Block block = state.getBlock();
+ return;
+ }
- // Huts
- if (event instanceof PlayerInteractEvent.RightClickBlock && block instanceof AbstractBlockHut
- && !colony.getPermissions().hasPermission(event.getEntity(), Action.ACCESS_HUTS))
+ final Permissions perms = colony.getPermissions();
+ final BlockState state = event.getLevel().getBlockState(event.getPos());
+ final BlockEntity entity = event.getLevel().getBlockEntity(event.getPos());
+ final Block block = state.getBlock();
+
+ // Interaction with hut blocks
+ if (block instanceof AbstractBlockHut)
+ {
+ if (!perms.hasPermission(event.getEntity(), Action.ACCESS_HUTS))
{
cancelEvent(event, event.getEntity(), colony, Action.ACCESS_HUTS, event.getPos());
- return;
}
-
- final Permissions perms = colony.getPermissions();
-
- if (isFreeToInteractWith(block, event.getPos())
- && perms.hasPermission(event.getEntity(), Action.ACCESS_FREE_BLOCKS))
+ }
+ // Interact with toggleables
+ else if (state.is(BlockTags.DOORS) || state.is(BlockTags.TRAPDOORS) || state.is(BlockTags.FENCE_GATES))
+ {
+ if (!perms.hasPermission(event.getEntity(), Action.ACCESS_TOGGLEABLES))
{
- return;
+ cancelEvent(event, event.getEntity(), colony, Action.ACCESS_TOGGLEABLES, event.getPos());
}
-
- if ((state.is(BlockTags.DOORS) || state.is(BlockTags.FENCE_GATES)) && perms.hasPermission(event.getEntity(), Action.ACCESS_TOGGLEABLES))
+ }
+ // Interact with any container
+ else if (entity instanceof Container)
+ {
+ if (!perms.hasPermission(event.getEntity(), Action.OPEN_CONTAINER))
{
- return;
+ cancelEvent(event, event.getEntity(), colony, Action.OPEN_CONTAINER, event.getPos());
}
-
- if (MineColonies.getConfig().getServer().enableColonyProtection.get())
+ }
+ // Free interaction blocks
+ else if (isFreeToInteractWith(block, event.getPos()))
+ {
+ if (!perms.hasPermission(event.getEntity(), Action.ACCESS_FREE_BLOCKS))
{
- if (!perms.hasPermission(event.getEntity(), Action.RIGHTCLICK_BLOCK) && !(block instanceof AirBlock))
- {
- checkEventCancelation(Action.RIGHTCLICK_BLOCK, event.getEntity(), event.getLevel(), event, event.getPos());
- return;
- }
-
- if (block instanceof BaseEntityBlock && !perms.hasPermission(event.getEntity(),
- Action.OPEN_CONTAINER))
- {
- cancelEvent(event, event.getEntity(), colony, Action.OPEN_CONTAINER, event.getPos());
- return;
- }
-
- if (event.getLevel().getBlockEntity(event.getPos()) != null && !perms.hasPermission(event.getEntity(), Action.RIGHTCLICK_ENTITY))
- {
- checkEventCancelation(Action.RIGHTCLICK_ENTITY, event.getEntity(), event.getLevel(), event, event.getPos());
- return;
- }
-
- final ItemStack stack = event.getItemStack();
- if (ItemStackUtils.isEmpty(stack) || stack.isEdible())
- {
- return;
- }
+ cancelEvent(event, event.getEntity(), colony, Action.ACCESS_FREE_BLOCKS, event.getPos());
+ }
+ }
+ // Interact with anything else
+ else
+ {
+ if (!perms.hasPermission(event.getEntity(), Action.RIGHTCLICK_BLOCK) && !state.isAir())
+ {
+ cancelEvent(event, event.getEntity(), colony, Action.RIGHTCLICK_BLOCK, event.getPos());
+ }
+ }
+ }
+ /**
+ * PlayerInteractEvent.RightClickItem handler.
+ *
+ * Allow under the following circumstances:
+ *
+ * - Colony protection is off.
+ * - The event did not happen inside the current colony.
+ *
+ * Denies under the following circumstances:
+ *
+ * - The player attempts to throw a potion, but the player has no {@link Action#THROW_POTION} permission.
+ * - The player attempts to use the scan tool, but the player has no {@link Action#USE_SCAN_TOOL} permission.
+ *
+ *
+ *
+ * @param event the event instance.
+ */
+ @SubscribeEvent
+ public void on(final PlayerInteractEvent.RightClickItem event)
+ {
+ if (!MineColonies.getConfig().getServer().enableColonyProtection.get() || !colony.isCoordInColony(event.getLevel(), event.getPos()))
+ {
+ return;
+ }
- if (stack.getItem() instanceof PotionItem)
- {
- checkEventCancelation(Action.THROW_POTION, event.getEntity(), event.getLevel(), event, event.getPos());
- return;
- }
+ final ItemStack stack = event.getItemStack();
- if (stack.getItem() instanceof ItemScanTool
- && !perms.hasPermission(event.getEntity(), Action.USE_SCAN_TOOL))
- {
- cancelEvent(event, event.getEntity(), colony, Action.USE_SCAN_TOOL, event.getPos());
- }
- }
+ // Potion throwing
+ if (stack.getItem() instanceof ThrowablePotionItem)
+ {
+ checkEventCancellation(Action.THROW_POTION, event.getEntity(), event.getLevel(), event, event.getPos());
+ }
+ // Using scan tool
+ else if (stack.getItem() instanceof ItemScanTool)
+ {
+ checkEventCancellation(Action.USE_SCAN_TOOL, event.getEntity(), event.getLevel(), event, event.getPos());
}
}
@@ -441,7 +440,7 @@ public void on(final PlayerInteractEvent.EntityInteract event)
return;
}
- checkEventCancelation(Action.RIGHTCLICK_ENTITY, event.getEntity(), event.getLevel(), event, event.getPos());
+ checkEventCancellation(Action.RIGHTCLICK_ENTITY, event.getEntity(), event.getLevel(), event, event.getPos());
}
/**
@@ -451,20 +450,14 @@ public void on(final PlayerInteractEvent.EntityInteract event)
* @param playerIn the player.
* @param world the world.
* @param event the event.
- * @param pos the position. Can be null if no target was provided to the event.
+ * @param pos the position. Can be null if no target was provided to the event.
* @return true if canceled.
*/
- private boolean checkEventCancelation(
- final Action action, @NotNull final Player playerIn, @NotNull final Level world, @NotNull final Event event,
- @Nullable final BlockPos pos)
+ private boolean checkEventCancellation(final Action action, @NotNull final Player playerIn, @NotNull final Level world, @NotNull final Event event, @Nullable final BlockPos pos)
{
@NotNull final Player player = EntityUtils.getPlayerOfFakePlayer(playerIn, world);
- BlockPos positionToCheck = pos;
- if (null == positionToCheck)
- {
- positionToCheck = player.blockPosition();
- }
+ final BlockPos positionToCheck = pos != null ? pos : player.blockPosition();
if (MineColonies.getConfig().getServer().enableColonyProtection.get()
&& colony.isCoordInColony(player.getCommandSenderWorld(), positionToCheck)
&& !colony.getPermissions().hasPermission(player, action))
@@ -497,7 +490,7 @@ public void on(final PlayerInteractEvent.EntityInteractSpecific event)
{
return;
}
- checkEventCancelation(Action.RIGHTCLICK_ENTITY, event.getEntity(), event.getLevel(), event, event.getPos());
+ checkEventCancellation(Action.RIGHTCLICK_ENTITY, event.getEntity(), event.getLevel(), event, event.getPos());
}
/**
@@ -510,7 +503,7 @@ public void on(final PlayerInteractEvent.EntityInteractSpecific event)
@SubscribeEvent
public void on(final ItemTossEvent event)
{
- if (checkEventCancelation(Action.TOSS_ITEM, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPlayer().blockPosition()))
+ if (checkEventCancellation(Action.TOSS_ITEM, event.getPlayer(), event.getPlayer().getCommandSenderWorld(), event, event.getPlayer().blockPosition()))
{
event.getPlayer().getInventory().add(event.getEntity().getItem());
}
@@ -526,7 +519,7 @@ public void on(final ItemTossEvent event)
@SubscribeEvent
public void on(final EntityItemPickupEvent event)
{
- checkEventCancelation(Action.PICKUP_ITEM, event.getEntity(), event.getEntity().getCommandSenderWorld(), event, event.getEntity().blockPosition());
+ checkEventCancellation(Action.PICKUP_ITEM, event.getEntity(), event.getEntity().getCommandSenderWorld(), event, event.getEntity().blockPosition());
}
/**
@@ -539,16 +532,16 @@ public void on(final EntityItemPickupEvent event)
@SubscribeEvent
public void on(final FillBucketEvent event)
{
- @Nullable BlockPos targetBlockPos = null;
- if (event.getTarget() instanceof BlockHitResult)
+ BlockPos targetBlockPos = null;
+ if (event.getTarget() instanceof BlockHitResult result)
{
- targetBlockPos = ((BlockHitResult) event.getTarget()).getBlockPos();
+ targetBlockPos = result.getBlockPos();
}
- else if (event.getTarget() instanceof EntityHitResult)
+ else if (event.getTarget() instanceof EntityHitResult result)
{
- targetBlockPos = ((EntityHitResult) event.getTarget()).getEntity().blockPosition();
+ targetBlockPos = result.getEntity().blockPosition();
}
- checkEventCancelation(Action.FILL_BUCKET, event.getEntity(), event.getEntity().getCommandSenderWorld(), event, targetBlockPos);
+ checkEventCancellation(Action.FILL_BUCKET, event.getEntity(), event.getEntity().getCommandSenderWorld(), event, targetBlockPos);
}
/**
@@ -561,7 +554,7 @@ else if (event.getTarget() instanceof EntityHitResult)
@SubscribeEvent
public void on(final ArrowLooseEvent event)
{
- checkEventCancelation(Action.SHOOT_ARROW, event.getEntity(), event.getEntity().getCommandSenderWorld(), event, event.getEntity().blockPosition());
+ checkEventCancellation(Action.SHOOT_ARROW, event.getEntity(), event.getEntity().getCommandSenderWorld(), event, event.getEntity().blockPosition());
}
/**
@@ -570,16 +563,16 @@ public void on(final ArrowLooseEvent event)
* Check if the entity that is getting hurt is a player,
* players that get hurt by other players are handled elsewhere,
* this here is handling players getting hurt by citizens.
- * @param event
+ * @param event the event instance.
*/
@SubscribeEvent
public void on(final LivingHurtEvent event)
{
- if (event.getEntity() instanceof ServerPlayer
+ if (event.getEntity() instanceof ServerPlayer player
&& event.getSource().getEntity() instanceof EntityCitizen
&& ((EntityCitizen) event.getSource().getEntity()).getCitizenColonyHandler().getColonyId() == colony.getID()
&& colony.getRaiderManager().isRaided()
- && !colony.getPermissions().hasPermission((Player) event.getEntity(), Action.GUARDS_ATTACK))
+ && !colony.getPermissions().hasPermission(player, Action.GUARDS_ATTACK))
{
event.setCanceled(true);
}
@@ -600,15 +593,14 @@ public void on(final AttackEntityEvent event)
return;
}
- @NotNull final Player player = EntityUtils.getPlayerOfFakePlayer(event.getEntity(), event.getEntity().getCommandSenderWorld());
+ final Player player = EntityUtils.getPlayerOfFakePlayer(event.getEntity(), event.getEntity().getCommandSenderWorld());
if (MineColonies.getConfig().getServer().enableColonyProtection.get()
&& colony.isCoordInColony(player.getCommandSenderWorld(), player.blockPosition()))
{
final Permissions perms = colony.getPermissions();
- if (event.getTarget() instanceof EntityCitizen)
+ if (event.getTarget() instanceof final EntityCitizen citizen)
{
- final AbstractEntityCitizen citizen = (AbstractEntityCitizen) event.getTarget();
if (citizen.getCitizenJobHandler().getColonyJob() instanceof AbstractJobGuard && perms.hasPermission(event.getEntity(), Action.GUARDS_ATTACK))
{
return;
diff --git a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java
index 4a4297986ef..a436150bef5 100755
--- a/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java
+++ b/src/main/java/com/minecolonies/core/entity/citizen/EntityCitizen.java
@@ -64,7 +64,7 @@
import com.minecolonies.core.network.messages.client.VanillaParticleMessage;
import com.minecolonies.core.network.messages.client.colony.ColonyViewCitizenViewMessage;
import com.minecolonies.core.network.messages.client.colony.PlaySoundForCitizenMessage;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.citizen.OpenCitizenInventoryMessage;
import com.minecolonies.core.util.TeleportHelper;
import com.minecolonies.core.util.citizenutils.CitizenItemUtils;
import net.minecraft.core.BlockPos;
@@ -374,14 +374,14 @@ public InteractionResult checkAndHandleImportantInteractions(final Player player
if (CompatibilityUtils.getWorldFromCitizen(this).isClientSide && iColonyView != null)
{
- if (player.isShiftKeyDown() && !isInvisible())
+ final ICitizenDataView citizenDataView = getCitizenDataView();
+ if (citizenDataView != null && !isInvisible())
{
- Network.getNetwork().sendToServer(new OpenInventoryMessage(iColonyView, this.getName().getString(), this.getId()));
- }
- else
- {
- final ICitizenDataView citizenDataView = getCitizenDataView();
- if (citizenDataView != null && !isInvisible())
+ if (player.isShiftKeyDown())
+ {
+ Network.getNetwork().sendToServer(new OpenCitizenInventoryMessage(citizenDataView));
+ }
+ else
{
new WindowInteraction(citizenDataView).open();
}
diff --git a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java
index f6427bfc7f8..98cbb3d6708 100644
--- a/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java
+++ b/src/main/java/com/minecolonies/core/entity/visitor/VisitorCitizen.java
@@ -28,7 +28,7 @@
import com.minecolonies.core.entity.citizen.citizenhandlers.CitizenSleepHandler;
import com.minecolonies.core.entity.pathfinding.navigation.MovementHandler;
import com.minecolonies.core.network.messages.client.ItemParticleEffectMessage;
-import com.minecolonies.core.network.messages.server.colony.OpenInventoryMessage;
+import com.minecolonies.core.network.messages.server.colony.citizen.OpenCitizenInventoryMessage;
import com.minecolonies.core.util.citizenutils.CitizenItemUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
@@ -426,14 +426,14 @@ public InteractionResult checkAndHandleImportantInteractions(final Player player
if (CompatibilityUtils.getWorldFromCitizen(this).isClientSide)
{
- if (player.isShiftKeyDown())
+ final ICitizenDataView citizenDataView = getCitizenDataView();
+ if (citizenDataView != null && !isInvisible())
{
- Network.getNetwork().sendToServer(new OpenInventoryMessage(iColonyView, this.getName().getString(), this.getId()));
- }
- else
- {
- final ICitizenDataView citizenDataView = getCitizenDataView();
- if (citizenDataView != null)
+ if (player.isShiftKeyDown())
+ {
+ Network.getNetwork().sendToServer(new OpenCitizenInventoryMessage(citizenDataView));
+ }
+ else
{
new WindowInteraction(citizenDataView).open();
}
diff --git a/src/main/java/com/minecolonies/core/network/NetworkChannel.java b/src/main/java/com/minecolonies/core/network/NetworkChannel.java
index 76759c65569..0718ea23181 100755
--- a/src/main/java/com/minecolonies/core/network/NetworkChannel.java
+++ b/src/main/java/com/minecolonies/core/network/NetworkChannel.java
@@ -132,7 +132,8 @@ public void registerCommonMessages()
// Colony Request messages
registerMessage(++idx, BuildRequestMessage.class, BuildRequestMessage::new);
- registerMessage(++idx, OpenInventoryMessage.class, OpenInventoryMessage::new);
+ registerMessage(++idx, OpenBuildingInventoryMessage.class, OpenBuildingInventoryMessage::new);
+ registerMessage(++idx, OpenCitizenInventoryMessage.class, OpenCitizenInventoryMessage::new);
registerMessage(++idx, TownHallRenameMessage.class, TownHallRenameMessage::new);
registerMessage(++idx, MinerSetLevelMessage.class, MinerSetLevelMessage::new);
registerMessage(++idx, RecallCitizenMessage.class, RecallCitizenMessage::new);
diff --git a/src/main/java/com/minecolonies/core/network/messages/server/AbstractColonyServerMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/AbstractColonyServerMessage.java
index 977630c911f..2dcccbdebf7 100755
--- a/src/main/java/com/minecolonies/core/network/messages/server/AbstractColonyServerMessage.java
+++ b/src/main/java/com/minecolonies/core/network/messages/server/AbstractColonyServerMessage.java
@@ -16,7 +16,7 @@
import org.jetbrains.annotations.Nullable;
import static com.minecolonies.api.util.constant.TranslationConstants.HUT_BLOCK_MISSING_COLONY;
-import static com.minecolonies.api.util.constant.translation.ToolTranslationConstants.TOOL_PERMISSION_SCEPTER_PERMISSION_DENY;
+import static com.minecolonies.api.util.constant.TranslationConstants.PERMISSION_DENIED;
public abstract class AbstractColonyServerMessage implements IMessage
{
@@ -116,35 +116,35 @@ public final LogicalSide getExecutionSide()
public final void onExecute(final net.minecraftforge.network.NetworkEvent.Context ctxIn, final boolean isLogicalServer)
{
final ServerPlayer player = ctxIn.getSender();
+ if (player == null)
+ {
+ return;
+ }
+
final IColony colony = IColonyManager.getInstance().getColonyByDimension(colonyId, dimensionId);
- if (colony != null)
+ if (colony == null)
{
- if (!ownerOnly() && permissionNeeded() != null && !colony.getPermissions().hasPermission(player, permissionNeeded()))
- {
- if (player == null)
- {
- return;
- }
+ MessageUtils.format(HUT_BLOCK_MISSING_COLONY, this.getClass().getSimpleName()).sendTo(player);
+ return;
+ }
- MessageUtils.format(TOOL_PERMISSION_SCEPTER_PERMISSION_DENY).sendTo(player);
- return;
- }
- else if (ownerOnly() && (player == null || colony.getPermissions().getOwner().equals(player.getUUID())))
+ if (ownerOnly())
+ {
+ if (!colony.getPermissions().getOwner().equals(player.getUUID()))
{
- if (player == null)
- {
- return;
- }
-
- MessageUtils.format(TOOL_PERMISSION_SCEPTER_PERMISSION_DENY).sendTo(player);
+ MessageUtils.format(PERMISSION_DENIED).sendTo(player);
return;
}
-
- onExecute(ctxIn, isLogicalServer, colony);
}
- else
+ else if (permissionNeeded() != null)
{
- MessageUtils.format(HUT_BLOCK_MISSING_COLONY, this.getClass().getSimpleName()).sendTo(player);
+ if (!colony.getPermissions().hasPermission(player, permissionNeeded()))
+ {
+ MessageUtils.format(PERMISSION_DENIED).sendTo(player);
+ return;
+ }
}
+
+ onExecute(ctxIn, isLogicalServer, colony);
}
}
diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionClose.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionClose.java
index d1c3c7ee867..2bfc8621ec2 100755
--- a/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionClose.java
+++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionClose.java
@@ -2,6 +2,7 @@
import com.minecolonies.api.colony.ICitizenData;
import com.minecolonies.api.colony.IColony;
+import com.minecolonies.api.colony.permissions.Action;
import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
@@ -9,6 +10,7 @@
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* Message to trigger a response handler close on the server side.
@@ -52,6 +54,13 @@ public InteractionClose(
this.key = key;
}
+ @Override
+ @Nullable
+ public Action permissionNeeded()
+ {
+ return null;
+ }
+
/**
* Transformation from a byteStream to the variables.
*
diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionResponse.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionResponse.java
index aef20040edd..7a42ce4bada 100755
--- a/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionResponse.java
+++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/InteractionResponse.java
@@ -2,6 +2,7 @@
import com.minecolonies.api.colony.ICitizenData;
import com.minecolonies.api.colony.IColony;
+import com.minecolonies.api.colony.permissions.Action;
import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceKey;
@@ -9,6 +10,7 @@
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* Message to trigger a response handler on the server side.
@@ -60,6 +62,13 @@ public InteractionResponse(
this.responseId = responseId;
}
+ @Override
+ @Nullable
+ public Action permissionNeeded()
+ {
+ return null;
+ }
+
/**
* Transformation from a byteStream to the variables.
*
diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/OpenInventoryMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/OpenInventoryMessage.java
deleted file mode 100755
index a94a24bb47b..00000000000
--- a/src/main/java/com/minecolonies/core/network/messages/server/colony/OpenInventoryMessage.java
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.minecolonies.core.network.messages.server.colony;
-
-import com.minecolonies.api.colony.IColony;
-import com.minecolonies.api.colony.IColonyView;
-import com.minecolonies.api.colony.buildings.views.IBuildingView;
-import com.minecolonies.api.entity.citizen.AbstractEntityCitizen;
-import com.minecolonies.core.tileentities.TileEntityGrave;
-import com.minecolonies.core.tileentities.TileEntityRack;
-import com.minecolonies.api.util.BlockPosUtil;
-import com.minecolonies.api.util.CompatibilityUtils;
-import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage;
-import net.minecraft.core.BlockPos;
-import net.minecraft.network.FriendlyByteBuf;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.util.StringUtil;
-import net.minecraft.world.MenuProvider;
-import net.minecraft.world.level.block.entity.BlockEntity;
-import net.minecraftforge.network.NetworkEvent;
-import net.minecraftforge.network.NetworkHooks;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Message sent to open an inventory.
- */
-public class OpenInventoryMessage extends AbstractColonyServerMessage
-{
- /***
- * The inventory name.
- */
- private String name;
-
- /**
- * The inventory type.
- */
- private InventoryType inventoryType;
-
- /**
- * The entities id.
- */
- private int entityID;
-
- /**
- * The position of the inventory block/entity.
- */
- private BlockPos tePos;
-
- /**
- * Empty public constructor.
- */
- public OpenInventoryMessage()
- {
- super();
- }
-
- /**
- * Creates an open inventory message for the citizen.
- *
- * @param name the name of the citizen.
- * @param id its id.
- * @param colony the colony of the network message
- */
- public OpenInventoryMessage(IColonyView colony, @NotNull final String name, final int id)
- {
- super(colony);
- inventoryType = InventoryType.INVENTORY_CITIZEN;
- this.name = name;
- this.entityID = id;
- }
-
- /**
- * Creates an open inventory message for a building.
- *
- * @param building the building we're executing on.
- */
- public OpenInventoryMessage(final IBuildingView building)
- {
- super(building.getColony());
- inventoryType = InventoryType.INVENTORY_CHEST;
- name = "";
- tePos = building.getID();
- }
-
- @Override
- public void fromBytesOverride(@NotNull final FriendlyByteBuf buf)
- {
-
- inventoryType = InventoryType.values()[buf.readInt()];
- name = buf.readUtf(32767);
- switch (inventoryType)
- {
- case INVENTORY_CITIZEN:
- entityID = buf.readInt();
- break;
- case INVENTORY_CHEST:
- tePos = buf.readBlockPos();
- break;
- }
- }
-
- @Override
- public void toBytesOverride(@NotNull final FriendlyByteBuf buf)
- {
-
- buf.writeInt(inventoryType.ordinal());
- buf.writeUtf(name);
- switch (inventoryType)
- {
- case INVENTORY_CITIZEN:
- buf.writeInt(entityID);
- break;
- case INVENTORY_CHEST:
- buf.writeBlockPos(tePos);
- break;
- }
- }
-
- @Override
- protected void onExecute(final NetworkEvent.Context ctxIn, final boolean isLogicalServer, final IColony colony)
- {
- final ServerPlayer player = ctxIn.getSender();
- if (player == null)
- {
- return;
- }
- switch (inventoryType)
- {
- case INVENTORY_CITIZEN:
- doCitizenInventory(player);
- break;
- case INVENTORY_CHEST:
- doHutInventory(player, colony);
- break;
- default:
- break;
- }
- }
-
- private void doCitizenInventory(final ServerPlayer player)
- {
- @Nullable final AbstractEntityCitizen citizen = (AbstractEntityCitizen) CompatibilityUtils.getWorldFromEntity(player).getEntity(entityID);
- if (citizen != null)
- {
- if (!StringUtil.isNullOrEmpty(name))
- {
- citizen.getInventoryCitizen().setCustomName(name);
- }
-
- NetworkHooks.openScreen(player, citizen, packetBuffer -> packetBuffer.writeVarInt(citizen.getCitizenColonyHandler().getColonyId()).writeVarInt(citizen.getCivilianID()));
- }
- }
-
- private void doHutInventory(final ServerPlayer player, final IColony colony)
- {
- final BlockEntity tileEntity = BlockPosUtil.getTileEntity(player.level, tePos);
-
- if(tileEntity instanceof TileEntityRack || tileEntity instanceof TileEntityGrave)
- {
- NetworkHooks.openScreen(player, (MenuProvider) tileEntity, packetBuffer -> packetBuffer.writeVarInt(colony.getID()).writeBlockPos(tileEntity.getBlockPos()));
- }
- }
-
- /**
- * Type of inventory.
- */
- private enum InventoryType
- {
- INVENTORY_CITIZEN,
- INVENTORY_CHEST
- }
-}
diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/building/OpenBuildingInventoryMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/building/OpenBuildingInventoryMessage.java
new file mode 100644
index 00000000000..b90bab2e34e
--- /dev/null
+++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/building/OpenBuildingInventoryMessage.java
@@ -0,0 +1,72 @@
+package com.minecolonies.core.network.messages.server.colony.building;
+
+import com.minecolonies.api.colony.IColony;
+import com.minecolonies.api.colony.buildings.views.IBuildingView;
+import com.minecolonies.api.util.BlockPosUtil;
+import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage;
+import com.minecolonies.core.tileentities.TileEntityRack;
+import net.minecraft.core.BlockPos;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraftforge.network.NetworkEvent;
+import net.minecraftforge.network.NetworkHooks;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Message sent to open the inventory of a building.
+ */
+public class OpenBuildingInventoryMessage extends AbstractColonyServerMessage
+{
+ /**
+ * The position of the building.
+ */
+ private BlockPos buildingPos;
+
+ /**
+ * Empty public constructor.
+ */
+ public OpenBuildingInventoryMessage()
+ {
+ super();
+ }
+
+ /**
+ * Creates an open inventory message for a building.
+ *
+ * @param building the building we're executing on.
+ */
+ public OpenBuildingInventoryMessage(final IBuildingView building)
+ {
+ super(building.getColony());
+ buildingPos = building.getID();
+ }
+
+ @Override
+ protected void onExecute(final NetworkEvent.Context ctxIn, final boolean isLogicalServer, final IColony colony)
+ {
+ final ServerPlayer player = ctxIn.getSender();
+ if (player == null)
+ {
+ return;
+ }
+
+ final BlockEntity tileEntity = BlockPosUtil.getTileEntity(player.level, buildingPos);
+ if (tileEntity instanceof TileEntityRack tileEntityRack)
+ {
+ NetworkHooks.openScreen(player, tileEntityRack, packetBuffer -> packetBuffer.writeVarInt(colony.getID()).writeBlockPos(tileEntity.getBlockPos()));
+ }
+ }
+
+ @Override
+ public void toBytesOverride(@NotNull final FriendlyByteBuf buf)
+ {
+ buf.writeBlockPos(buildingPos);
+ }
+
+ @Override
+ public void fromBytesOverride(@NotNull final FriendlyByteBuf buf)
+ {
+ buildingPos = buf.readBlockPos();
+ }
+}
diff --git a/src/main/java/com/minecolonies/core/network/messages/server/colony/citizen/OpenCitizenInventoryMessage.java b/src/main/java/com/minecolonies/core/network/messages/server/colony/citizen/OpenCitizenInventoryMessage.java
new file mode 100644
index 00000000000..fa6b8ac3537
--- /dev/null
+++ b/src/main/java/com/minecolonies/core/network/messages/server/colony/citizen/OpenCitizenInventoryMessage.java
@@ -0,0 +1,87 @@
+package com.minecolonies.core.network.messages.server.colony.citizen;
+
+import com.minecolonies.api.colony.ICitizenDataView;
+import com.minecolonies.api.colony.IColony;
+import com.minecolonies.api.entity.citizen.AbstractEntityCitizen;
+import com.minecolonies.api.util.CompatibilityUtils;
+import com.minecolonies.core.network.messages.server.AbstractColonyServerMessage;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.util.StringUtil;
+import net.minecraft.world.entity.Entity;
+import net.minecraftforge.network.NetworkEvent;
+import net.minecraftforge.network.NetworkHooks;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Message sent to open a citizen inventory.
+ */
+public class OpenCitizenInventoryMessage extends AbstractColonyServerMessage
+{
+ /**
+ * The entity its id.
+ */
+ private int entityID;
+
+ /***
+ * The inventory name.
+ */
+ private String name;
+
+ /**
+ * Empty public constructor.
+ */
+ public OpenCitizenInventoryMessage()
+ {
+ super();
+ }
+
+ /**
+ * Creates an open inventory message for the citizen.
+ *
+ * @param citizen the citizen.
+ */
+ public OpenCitizenInventoryMessage(final ICitizenDataView citizen)
+ {
+ super(citizen.getColony());
+ this.entityID = citizen.getEntityId();
+ this.name = citizen.getName();
+ }
+
+ @Override
+ protected void onExecute(final NetworkEvent.Context ctxIn, final boolean isLogicalServer, final IColony colony)
+ {
+ final ServerPlayer player = ctxIn.getSender();
+ if (player == null)
+ {
+ return;
+ }
+
+ final Entity entity = CompatibilityUtils.getWorldFromEntity(player).getEntity(entityID);
+ if (entity instanceof AbstractEntityCitizen citizen)
+ {
+ if (!StringUtil.isNullOrEmpty(name))
+ {
+ citizen.getInventoryCitizen().setCustomName(name);
+ }
+
+ NetworkHooks.openScreen(player,
+ citizen,
+ packetBuffer -> packetBuffer.writeVarInt(citizen.getCitizenColonyHandler().getColonyId()).writeVarInt(citizen.getCivilianID()));
+ }
+ }
+
+ @Override
+ public void toBytesOverride(@NotNull final FriendlyByteBuf buf)
+ {
+ buf.writeInt(entityID);
+ buf.writeUtf(name);
+ }
+
+ @Override
+ public void fromBytesOverride(@NotNull final FriendlyByteBuf buf)
+ {
+ entityID = buf.readInt();
+ name = buf.readUtf();
+ }
+}