Skip to content

Commit

Permalink
feat: security security logic
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulvdberge committed Mar 31, 2024
1 parent 36789a1 commit 250e5bf
Show file tree
Hide file tree
Showing 19 changed files with 617 additions and 83 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Security Card

### Changed

- The permissions for a Security Card must be configured through the card itself, instead of via the Security Manager.
- The Security Card can be bound to other (currently online) players via its GUI.
- The binding of a Security Card can now be cleared.
- The Security Card tooltip and GUI now show whether the permission has been touched/changed in any way.

### Fixed

- Wireless Grid name not being correct in the GUI.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public interface PlatformPermission extends Permission {
Component getDescription();

Component getOwnerName();

boolean isAllowedByDefault();
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ protected AbstractGridScreen(final T menu,
}

@Override
protected void init() {
protected void init(final int rows) {
LOGGER.info("Initializing grid screen");

super.init();

if (searchField == null) {
searchField = new GridSearchBoxWidget(
font,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ public Component getDescription() {
public Component getOwnerName() {
return ContentNames.MOD;
}

@Override
public boolean isAllowedByDefault() {
return true;
}
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,182 @@
package com.refinedmods.refinedstorage2.platform.common.security;

import com.refinedmods.refinedstorage2.platform.api.PlatformApi;
import com.refinedmods.refinedstorage2.platform.api.security.PlatformPermission;
import com.refinedmods.refinedstorage2.platform.api.support.network.bounditem.SlotReference;
import com.refinedmods.refinedstorage2.platform.common.Platform;
import com.refinedmods.refinedstorage2.platform.common.content.Menus;
import com.refinedmods.refinedstorage2.platform.common.support.AbstractBaseContainerMenu;
import com.refinedmods.refinedstorage2.platform.common.support.stretching.ScreenSizeListener;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;

import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;

public class SecurityCardContainerMenu extends AbstractBaseContainerMenu implements ScreenSizeListener {
private final Inventory playerInventory;
private final List<Permission> permissions;
private final List<Permission> permissions = new ArrayList<>();
private final List<Player> players = new ArrayList<>();

@Nullable
private Player boundTo;

public SecurityCardContainerMenu(final int syncId,
final Inventory playerInventory,
final FriendlyByteBuf buf) {
super(Menus.INSTANCE.getSecurityCard(), syncId);
this.playerInventory = playerInventory;
this.permissions = new ArrayList<>();

this.disabledSlot = PlatformApi.INSTANCE.getSlotReference(buf).orElse(null);

final int amountOfPermissions = buf.readInt();
for (int i = 0; i < amountOfPermissions; ++i) {
final ResourceLocation id = buf.readResourceLocation();
final boolean allowed = buf.readBoolean();
final boolean dirty = buf.readBoolean();
PlatformApi.INSTANCE.getPermissionRegistry().get(id).ifPresent(permission -> permissions.add(new Permission(
id,
permission.getName(),
permission.getDescription(),
permission.getOwnerName()
permission.getOwnerName(),
allowed,
dirty
)));
}

if (buf.readBoolean()) {
this.boundTo = new Player(buf.readUUID(), buf.readUtf());
}

final int amountOfPlayers = buf.readInt();
for (int i = 0; i < amountOfPlayers; ++i) {
final UUID id = buf.readUUID();
final String name = buf.readUtf();
players.add(new Player(id, name));
}
}

SecurityCardContainerMenu(final int syncId, final Inventory playerInventory) {
SecurityCardContainerMenu(final int syncId, final Inventory playerInventory, final SlotReference disabledSlot) {
super(Menus.INSTANCE.getSecurityCard(), syncId);
this.playerInventory = playerInventory;
this.permissions = new ArrayList<>();
this.disabledSlot = disabledSlot;
}

List<Permission> getPermissions() {
return permissions;
}

List<Player> getPlayers() {
return players;
}

@Nullable
Player getBoundTo() {
return boundTo;
}

@Override
public void initSlots(final int playerInventoryY) {
resetSlots();
addPlayerInventory(playerInventory, 8, playerInventoryY);
}

record Permission(ResourceLocation id, Component name, Component description, Component ownerName) {
public void setPermission(final ResourceLocation permissionId, final boolean allowed) {
if (disabledSlot == null) {
return;
}
disabledSlot.resolve(playerInventory.player).ifPresent(stack -> setPermission(permissionId, allowed, stack));
}

private void setPermission(final ResourceLocation permissionId, final boolean allowed, final ItemStack stack) {
if (stack.getItem() instanceof SecurityCardItem securityCardItem) {
securityCardItem.getModel(stack).setPermission(permissionId, allowed);
}
}

public void resetPermissionServer(final ResourceLocation permissionId) {
if (disabledSlot == null) {
return;
}
disabledSlot.resolve(playerInventory.player).ifPresent(stack -> resetPermissionServer(permissionId, stack));
}

private void resetPermissionServer(final ResourceLocation permissionId, final ItemStack stack) {
if (stack.getItem() instanceof SecurityCardItem securityCardItem) {
securityCardItem.getModel(stack).resetPermission(permissionId);
}
}

public void setBoundPlayer(final MinecraftServer server, @Nullable final UUID playerId) {
if (disabledSlot == null) {
return;
}
disabledSlot.resolve(playerInventory.player).ifPresent(stack -> setBoundPlayer(server, playerId, stack));
}

private void setBoundPlayer(final MinecraftServer server, @Nullable final UUID playerId, final ItemStack stack) {
if (stack.getItem() instanceof SecurityCardItem securityCardItem) {
final ServerPlayer player = playerId == null ? null : server.getPlayerList().getPlayer(playerId);
securityCardItem.getModel(stack).setBoundPlayer(player);
}
}

Permission changePermission(final ResourceLocation permissionId, final boolean selected) {
Platform.INSTANCE.getClientToServerCommunications().sendSecurityCardPermission(permissionId, selected);
return updatePermissionLocally(permissionId, selected, true);
}

Permission resetPermission(final ResourceLocation permissionId) {
final PlatformPermission permission = PlatformApi.INSTANCE.getPermissionRegistry()
.get(permissionId)
.orElseThrow();
final boolean allowed = permission.isAllowedByDefault();
Platform.INSTANCE.getClientToServerCommunications().sendSecurityCardResetPermission(permissionId);
return updatePermissionLocally(permissionId, allowed, false);
}

private Permission updatePermissionLocally(final ResourceLocation permissionId,
final boolean allowed,
final boolean dirty) {
final Permission localPermission = permissions.stream().filter(p -> p.id().equals(permissionId))
.findFirst()
.orElseThrow();
final int index = permissions.indexOf(localPermission);
final Permission updatedLocalPermission = new Permission(
localPermission.id(),
localPermission.name(),
localPermission.description(),
localPermission.ownerName(),
allowed,
dirty
);
permissions.set(index, updatedLocalPermission);
return updatedLocalPermission;
}

void changeBoundPlayer(@Nullable final Player player) {
Platform.INSTANCE.getClientToServerCommunications().sendSecurityCardBoundPlayer(
player == null ? null : player.id()
);
this.boundTo = player;
}

record Permission(ResourceLocation id,
Component name,
Component description,
Component ownerName,
boolean allowed,
boolean dirty) {
}

record Player(UUID id, String name) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.refinedmods.refinedstorage2.platform.common.content.ContentNames;
import com.refinedmods.refinedstorage2.platform.common.support.containermenu.ExtendedMenuProvider;

import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

Expand All @@ -19,19 +20,40 @@

class SecurityCardExtendedMenuProvider implements ExtendedMenuProvider {
private final SlotReference slotReference;
private final SecurityCardModel model;

SecurityCardExtendedMenuProvider(final SlotReference slotReference) {
SecurityCardExtendedMenuProvider(final SlotReference slotReference, final SecurityCardModel model) {
this.slotReference = slotReference;
this.model = model;
}

@Override
public void writeScreenOpeningData(final ServerPlayer player, final FriendlyByteBuf buf) {
PlatformApi.INSTANCE.writeSlotReference(slotReference, buf);

final List<PlatformPermission> permissions = PlatformApi.INSTANCE.getPermissionRegistry().getAll();
buf.writeInt(permissions.size());
for (final PlatformPermission permission : permissions) {
final ResourceLocation id = PlatformApi.INSTANCE.getPermissionRegistry().getId(permission).orElseThrow();
buf.writeResourceLocation(id);
buf.writeBoolean(model.isAllowed(permission));
buf.writeBoolean(model.isDirty(permission));
}

final boolean bound = model.getBoundPlayerId() != null && model.getBoundPlayerName() != null;
buf.writeBoolean(bound);
if (bound) {
buf.writeUUID(model.getBoundPlayerId());
buf.writeUtf(model.getBoundPlayerName());
}

final List<ServerPlayer> players = player.getServer() == null
? Collections.emptyList()
: player.getServer().getPlayerList().getPlayers();
buf.writeInt(players.size());
for (final ServerPlayer otherPlayer : players) {
buf.writeUUID(otherPlayer.getUUID());
buf.writeUtf(otherPlayer.getGameProfile().getName());
}
}

Expand All @@ -43,6 +65,6 @@ public Component getDisplayName() {
@Nullable
@Override
public AbstractContainerMenu createMenu(final int syncId, final Inventory inventory, final Player player) {
return new SecurityCardContainerMenu(syncId, inventory);
return new SecurityCardContainerMenu(syncId, inventory, slotReference);
}
}
Loading

0 comments on commit 250e5bf

Please sign in to comment.