Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,23 @@ public CompletableFuture<String> requestRegionExport(int x, int y, int z, int si
int requestId = nextRegionExportRequestId.getAndIncrement();
CompletableFuture<String> future = new CompletableFuture<>();
pendingRegionExports.put(requestId, future);
Minecraft minecraft = Minecraft.getMinecraft();
EntityPlayer player = minecraft.thePlayer;
int dimensionId = player != null && player.worldObj != null && player.worldObj.provider != null
? player.worldObj.provider.dimensionId
: 0;
GuideNhNetwork.channel()
.sendToServer(
new GuideNhRegionExportRequestMessage(requestId, x, y, z, sizeX, sizeY, sizeZ, includeEntities));
new GuideNhRegionExportRequestMessage(
requestId,
dimensionId,
x,
y,
z,
sizeX,
sizeY,
sizeZ,
includeEntities));
return future;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import net.minecraft.util.ResourceLocation;

import com.hfstudio.guidenh.guide.Guide;
import com.hfstudio.guidenh.guide.internal.structure.GuideNhServerStructureAccess;

public class GuideCommand extends CommandBase {

Expand Down Expand Up @@ -59,6 +60,12 @@ public void processCommand(ICommandSender sender, String[] args) throws CommandE
.openGuide(player, guideId, null);
}
case "reload" -> {
if (!sender.canCommandSenderUseCommand(
GuideNhServerStructureAccess.STRUCTURE_PERMISSION_LEVEL,
getCommandName())) {
send(sender, GuidebookText.CommandStructurePermissionDenied);
return;
}
boolean ok = GuideMEProxy.instance()
.reloadResources();
if (ok) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.hfstudio.guidenh.guide.internal.structure;

import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;

import com.hfstudio.guidenh.config.ModConfig;

public class GuideNhServerStructureAccess {

public static final String STRUCTURE_COMMAND_NAME = "guidenh";
public static final int STRUCTURE_PERMISSION_LEVEL = 3;

private GuideNhServerStructureAccess() {}

public static boolean canUseSceneExport(EntityPlayerMP player) {
return isSceneExportEnabled() && (isSinglePlayerServer() || hasStructurePermission(player));
}

public static boolean hasStructurePermission(EntityPlayerMP player) {
return player != null && player.canCommandSenderUseCommand(STRUCTURE_PERMISSION_LEVEL, STRUCTURE_COMMAND_NAME);
}

public static boolean isSceneExportEnabled() {
return ModConfig.ui.sceneExportEnabled;
}

public static boolean isSameDimension(EntityPlayerMP player, int dimensionId) {
return player != null && player.worldObj != null
&& player.worldObj.provider != null
&& player.worldObj.provider.dimensionId == dimensionId;
}

private static boolean isSinglePlayerServer() {
MinecraftServer server = MinecraftServer.getServer();
return server != null && server.isSinglePlayer();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.hfstudio.guidenh.integration.ae2.network;

import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.WorldServer;

import com.hfstudio.guidenh.guide.internal.structure.GuideNhServerStructureAccess;
import com.hfstudio.guidenh.integration.Mods;
import com.hfstudio.guidenh.integration.ae2.Ae2BaseTileNetworkStreamPreview;

Expand All @@ -17,6 +19,7 @@ public class GuideNhAe2BaseTileNetworkBatchServerHandler

@Override
public IMessage onMessage(GuideNhAe2BaseTileNetworkBatchRequestMessage message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
long corr = message.getCorrId();
int dim = message.getDim();
int[] xyz = message.getXyz();
Expand All @@ -25,7 +28,11 @@ public IMessage onMessage(GuideNhAe2BaseTileNetworkBatchRequestMessage message,
n = Math.max(0, xyz.length / 3);
}

if (!Mods.AE2.isModLoaded() || n <= 0 || n > GuideNhAe2BaseTileNetworkBatchRequestMessage.MAX_POSITIONS) {
if (player == null || !Mods.AE2.isModLoaded()
|| !GuideNhServerStructureAccess.canUseSceneExport(player)
|| !GuideNhServerStructureAccess.isSameDimension(player, dim)
|| n <= 0
|| n > GuideNhAe2BaseTileNetworkBatchRequestMessage.MAX_POSITIONS) {
return new GuideNhAe2BaseTileNetworkBatchReplyMessage(corr, new byte[0][]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import java.io.IOException;

import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.util.ForgeDirection;

import com.hfstudio.guidenh.guide.internal.structure.GuideNhServerStructureAccess;
import com.hfstudio.guidenh.integration.Mods;
import com.hfstudio.guidenh.integration.ae2.Ae2CableBusPartStreamCodec;
import com.hfstudio.guidenh.integration.ae2.Ae2CableBusSideStreams;
Expand All @@ -25,6 +27,7 @@ public class GuideNhAe2CableBatchServerHandler

@Override
public IMessage onMessage(GuideNhAe2CableBatchRequestMessage message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
long corr = message.getCorrId();
int dim = message.getDim();
int[] xyz = message.getXyz();
Expand All @@ -33,7 +36,11 @@ public IMessage onMessage(GuideNhAe2CableBatchRequestMessage message, MessageCon
n = Math.max(0, xyz.length / 3);
}

if (!Mods.AE2.isModLoaded() || n <= 0 || n > GuideNhAe2CableBatchRequestMessage.MAX_POSITIONS) {
if (player == null || !Mods.AE2.isModLoaded()
|| !GuideNhServerStructureAccess.canUseSceneExport(player)
|| !GuideNhServerStructureAccess.isSameDimension(player, dim)
|| n <= 0
|| n > GuideNhAe2CableBatchRequestMessage.MAX_POSITIONS) {
return new GuideNhAe2CableBatchReplyMessage(corr, new byte[0], new byte[0], new int[0], new byte[0][]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public class GuideNhCustomPayloadLimits {

public static final int MAX_PAYLOAD_BYTES = 28 * 1024;
public static final int MAX_STRUCTURE_BYTES_PER_PACKET = 27 * 1024;
public static final int MAX_STRUCTURE_TRANSFER_BYTES = 8 * 1024 * 1024;
public static final long STRUCTURE_TRANSFER_TTL_MILLIS = 30_000L;

private GuideNhCustomPayloadLimits() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
public class GuideNhRegionExportRequestMessage implements IMessage {

private int requestId;
private int dimensionId;
private int x;
private int y;
private int z;
Expand All @@ -16,9 +17,10 @@ public class GuideNhRegionExportRequestMessage implements IMessage {

public GuideNhRegionExportRequestMessage() {}

public GuideNhRegionExportRequestMessage(int requestId, int x, int y, int z, int sizeX, int sizeY, int sizeZ,
boolean includeEntities) {
public GuideNhRegionExportRequestMessage(int requestId, int dimensionId, int x, int y, int z, int sizeX, int sizeY,
int sizeZ, boolean includeEntities) {
this.requestId = requestId;
this.dimensionId = dimensionId;
this.x = x;
this.y = y;
this.z = z;
Expand All @@ -32,6 +34,10 @@ public int getRequestId() {
return requestId;
}

public int getDimensionId() {
return dimensionId;
}

public int getX() {
return x;
}
Expand Down Expand Up @@ -63,6 +69,7 @@ public boolean isIncludeEntities() {
@Override
public void fromBytes(ByteBuf buf) {
requestId = buf.readInt();
dimensionId = buf.readInt();
x = buf.readInt();
y = buf.readInt();
z = buf.readInt();
Expand All @@ -75,6 +82,7 @@ public void fromBytes(ByteBuf buf) {
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(requestId);
buf.writeInt(dimensionId);
buf.writeInt(x);
buf.writeInt(y);
buf.writeInt(z);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.minecraft.util.AxisAlignedBB;

import com.hfstudio.guidenh.guide.internal.item.RegionWandItem;
import com.hfstudio.guidenh.guide.internal.structure.GuideNhServerStructureAccess;
import com.hfstudio.guidenh.guide.internal.structure.GuideStructureVolume;

import cpw.mods.fml.common.network.simpleimpl.IMessage;
Expand All @@ -22,6 +23,13 @@ public IMessage onMessage(GuideNhRegionExportRequestMessage message, MessageCont
if (player == null) {
return null;
}
if (!GuideNhServerStructureAccess.canUseSceneExport(player)) {
GuideNhNetwork.channel()
.sendTo(
GuideNhRegionExportReplyMessage.error(message.getRequestId(), "Scene export is not allowed"),
player);
return null;
}
try {
String structureText = exportRegion(player, message);
if (structureText == null) {
Expand Down Expand Up @@ -50,6 +58,9 @@ private String exportRegion(EntityPlayerMP player, GuideNhRegionExportRequestMes
|| GuideStructureVolume.exceedsLimit(sizeX, sizeY, sizeZ, RegionWandItem.MAX_EXPORT_BLOCKS)) {
return null;
}
if (!GuideNhServerStructureAccess.isSameDimension(player, message.getDimensionId())) {
return null;
}
int x = message.getX();
int y = message.getY();
int z = message.getZ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
public class GuideNhStructureChunkAssembler {

private final byte[][] chunks;
private final long expiresAtMillis;
private boolean discarded;
private int received;
private int totalBytes;

Expand All @@ -16,10 +18,14 @@ public GuideNhStructureChunkAssembler(int chunkCount) {
throw new IllegalArgumentException("Invalid structure chunk count: " + chunkCount);
}
this.chunks = new byte[chunkCount][];
this.expiresAtMillis = System.currentTimeMillis() + GuideNhCustomPayloadLimits.STRUCTURE_TRANSFER_TTL_MILLIS;
}

@Nullable
public synchronized String accept(GuideNhStructureRequestMessage message) {
if (isExpired()) {
return null;
}
int index = message.getChunkIndex();
if (message.getChunkCount() != chunks.length || index < 0 || index >= chunks.length) {
return null;
Expand All @@ -32,6 +38,10 @@ public synchronized String accept(GuideNhStructureRequestMessage message) {
chunks[index] = bytes;
received++;
totalBytes += bytes.length;
if (totalBytes > GuideNhCustomPayloadLimits.MAX_STRUCTURE_TRANSFER_BYTES) {
discarded = true;
return null;
}
}
if (received != chunks.length) {
return null;
Expand All @@ -46,4 +56,8 @@ public synchronized String accept(GuideNhStructureRequestMessage message) {
}
return out.toString(StandardCharsets.UTF_8);
}

public boolean isExpired() {
return discarded || System.currentTimeMillis() > expiresAtMillis;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.util.ChatComponentTranslation;

import com.hfstudio.guidenh.guide.internal.GuidebookText;
import com.hfstudio.guidenh.guide.internal.structure.GuideNhServerStructureAccess;
import com.hfstudio.guidenh.guide.internal.structure.GuideNhStructureRuntime;
import com.hfstudio.guidenh.guide.internal.structure.GuideStructureMemoryStore;
import com.hfstudio.guidenh.guide.internal.structure.GuideStructureWorldPlacementTarget;
Expand All @@ -25,18 +26,26 @@ public IMessage onMessage(GuideNhStructureRequestMessage message, MessageContext
if (player == null) {
return null;
}
pruneExpiredTransfers();
var playerId = player.getUniqueID();
var sessionStore = GuideNhStructureRuntime.getServerSessionStore();

try {
byte action = message.getAction();
String structureText = message.getStructureText();
if (message.isChunkedStructureTransfer()) {
if (!GuideNhServerStructureAccess.canUseSceneExport(player)) {
send(player, GuidebookText.CommandStructurePermissionDenied);
return null;
}
TransferKey key = new TransferKey(playerId, message.getAction(), message.getTransferId());
GuideNhStructureChunkAssembler assembler = CHUNK_TRANSFERS
.computeIfAbsent(key, ignored -> new GuideNhStructureChunkAssembler(message.getChunkCount()));
structureText = assembler.accept(message);
if (structureText == null) {
if (assembler.isExpired()) {
CHUNK_TRANSFERS.remove(key, assembler);
}
return null;
}
CHUNK_TRANSFERS.remove(key);
Expand All @@ -45,10 +54,14 @@ public IMessage onMessage(GuideNhStructureRequestMessage message, MessageContext

switch (action) {
case GuideNhStructureRequestMessage.ACTION_CACHE:
if (!GuideNhServerStructureAccess.canUseSceneExport(player)) {
send(player, GuidebookText.CommandStructurePermissionDenied);
break;
}
sessionStore.remember(playerId, "client-cache", structureText);
break;
case GuideNhStructureRequestMessage.ACTION_IMPORT_AND_PLACE:
if (!player.canCommandSenderUseCommand(3, "guidenh")) {
if (!GuideNhServerStructureAccess.hasStructurePermission(player)) {
send(player, GuidebookText.CommandStructurePermissionDenied);
break;
}
Expand All @@ -69,7 +82,7 @@ public IMessage onMessage(GuideNhStructureRequestMessage message, MessageContext
message.getZ());
break;
case GuideNhStructureRequestMessage.ACTION_PLACE_ALL:
if (!player.canCommandSenderUseCommand(3, "guidenh")) {
if (!GuideNhServerStructureAccess.hasStructurePermission(player)) {
send(player, GuidebookText.CommandStructurePermissionDenied);
break;
}
Expand Down Expand Up @@ -112,6 +125,13 @@ public static String getErrorMessage(Throwable throwable) {
.getSimpleName();
}

private static void pruneExpiredTransfers() {
CHUNK_TRANSFERS.entrySet()
.removeIf(
entry -> entry.getValue()
.isExpired());
}

private static final class TransferKey {

private final UUID playerId;
Expand Down