Skip to content

Commit 4f3663c

Browse files
committed
Allow overriding computer/floppy capacity
This adds a new "computercraft:storage_capacity" component to items (and "Capacity" NBT tag to BEs), that overrides the capacity for the given item. Fixes #1814
1 parent 53425c1 commit 4f3663c

File tree

12 files changed

+128
-37
lines changed

12 files changed

+128
-37
lines changed

Diff for: projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java

+12
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
import dan200.computercraft.shared.util.ComponentMap;
9494
import dan200.computercraft.shared.util.DataComponentUtil;
9595
import dan200.computercraft.shared.util.NonNegativeId;
96+
import dan200.computercraft.shared.util.StorageCapacity;
9697
import net.minecraft.commands.CommandSourceStack;
9798
import net.minecraft.commands.synchronization.ArgumentTypeInfo;
9899
import net.minecraft.commands.synchronization.SingletonArgumentInfo;
@@ -316,6 +317,17 @@ private static <T> RegistryEntry<DataComponentType<T>> register(String name, Una
316317
.persistent(NonNegativeId.CODEC).networkSynchronized(NonNegativeId.STREAM_CODEC)
317318
);
318319

320+
/**
321+
* The storage capacity of a computer or disk.
322+
*
323+
* @see AbstractComputerItem
324+
* @see PocketComputerItem
325+
* @see DiskItem
326+
*/
327+
public static final RegistryEntry<DataComponentType<StorageCapacity>> STORAGE_CAPACITY = register("storage_capacity", b -> b
328+
.persistent(StorageCapacity.CODEC).networkSynchronized(StorageCapacity.STREAM_CODEC)
329+
);
330+
319331
/**
320332
* The left upgrade of a turtle.
321333
*

Diff for: projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import net.minecraft.core.component.DataComponentMap;
2424
import net.minecraft.core.component.DataComponents;
2525
import net.minecraft.nbt.CompoundTag;
26+
import net.minecraft.nbt.Tag;
2627
import net.minecraft.network.chat.Component;
2728
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
2829
import net.minecraft.world.Container;
@@ -43,10 +44,12 @@ public abstract class AbstractComputerBlockEntity extends BlockEntity implements
4344
private static final String NBT_ID = "ComputerId";
4445
private static final String NBT_LABEL = "Label";
4546
private static final String NBT_ON = "On";
47+
private static final String NBT_CAPACITY = "Capacity";
4648

4749
private @Nullable UUID instanceID = null;
4850
private int computerID = -1;
4951
protected @Nullable String label = null;
52+
protected long storageCapacity = -1;
5053
private boolean on = false;
5154
boolean startOn = false;
5255
private boolean fresh = false;
@@ -143,6 +146,7 @@ public void saveAdditional(CompoundTag nbt, HolderLookup.Provider registries) {
143146
// Save ID, label and power state
144147
if (computerID >= 0) nbt.putInt(NBT_ID, computerID);
145148
if (label != null) nbt.putString(NBT_LABEL, label);
149+
if (storageCapacity > 0) nbt.putLong(NBT_CAPACITY, storageCapacity);
146150
nbt.putBoolean(NBT_ON, on);
147151

148152
lockCode.addToTag(nbt);
@@ -164,6 +168,7 @@ protected void loadServer(CompoundTag nbt, HolderLookup.Provider registries) {
164168
// Load ID, label and power state
165169
computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1;
166170
label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null;
171+
storageCapacity = nbt.contains(NBT_CAPACITY, Tag.TAG_ANY_NUMERIC) ? nbt.getLong(NBT_CAPACITY) : -1;
167172
on = startOn = nbt.getBoolean(NBT_ON);
168173

169174
lockCode = LockCode.fromTag(nbt);
@@ -174,6 +179,7 @@ protected void applyImplicitComponents(DataComponentInput component) {
174179
super.applyImplicitComponents(component);
175180
label = DataComponentUtil.getCustomName(component.get(DataComponents.CUSTOM_NAME));
176181
computerID = NonNegativeId.getId(component.get(ModRegistry.DataComponents.COMPUTER_ID.get()));
182+
storageCapacity = StorageCapacity.getOrDefault(component.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), -1);
177183
lockCode = component.getOrDefault(DataComponents.LOCK, LockCode.NO_LOCK);
178184
}
179185

@@ -182,6 +188,7 @@ protected void collectImplicitComponents(DataComponentMap.Builder builder) {
182188
super.collectImplicitComponents(builder);
183189
builder.set(ModRegistry.DataComponents.COMPUTER_ID.get(), NonNegativeId.of(computerID));
184190
builder.set(DataComponents.CUSTOM_NAME, label == null ? null : Component.literal(label));
191+
builder.set(ModRegistry.DataComponents.STORAGE_CAPACITY.get(), storageCapacity > 0 ? new StorageCapacity(storageCapacity) : null);
185192
if (lockCode != LockCode.NO_LOCK) builder.set(DataComponents.LOCK, lockCode);
186193
}
187194

@@ -191,6 +198,7 @@ public void removeComponentsFromTag(CompoundTag tag) {
191198
super.removeComponentsFromTag(tag);
192199
tag.remove(NBT_ID);
193200
tag.remove(NBT_LABEL);
201+
tag.remove(NBT_CAPACITY);
194202
tag.remove(LockCode.TAG_LOCK);
195203
}
196204

@@ -397,14 +405,16 @@ public final ClientboundBlockEntityDataPacket getUpdatePacket() {
397405
public CompoundTag getUpdateTag(HolderLookup.Provider registries) {
398406
// We need this for pick block on the client side.
399407
var nbt = super.getUpdateTag(registries);
400-
if (label != null) nbt.putString(NBT_LABEL, label);
401408
if (computerID >= 0) nbt.putInt(NBT_ID, computerID);
409+
if (label != null) nbt.putString(NBT_LABEL, label);
410+
if (storageCapacity > 0) nbt.putLong(NBT_CAPACITY, storageCapacity);
402411
return nbt;
403412
}
404413

405414
protected void loadClient(CompoundTag nbt, HolderLookup.Provider registries) {
406-
label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null;
407415
computerID = nbt.contains(NBT_ID) ? nbt.getInt(NBT_ID) : -1;
416+
label = nbt.contains(NBT_LABEL) ? nbt.getString(NBT_LABEL) : null;
417+
storageCapacity = nbt.contains(NBT_CAPACITY, Tag.TAG_ANY_NUMERIC) ? nbt.getLong(NBT_CAPACITY) : -1;
408418
}
409419

410420
protected void transferStateFrom(AbstractComputerBlockEntity copy) {
@@ -413,6 +423,7 @@ protected void transferStateFrom(AbstractComputerBlockEntity copy) {
413423
instanceID = copy.instanceID;
414424
computerID = copy.computerID;
415425
label = copy.label;
426+
storageCapacity = copy.storageCapacity;
416427
on = copy.on;
417428
startOn = copy.startOn;
418429
lockCode = copy.lockCode;

Diff for: projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/ComputerBlockEntity.java

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ protected ServerComputer createComputer(int id) {
3535
return new ServerComputer((ServerLevel) getLevel(), getBlockPos(), ServerComputer.properties(id, getFamily())
3636
.label(getLabel())
3737
.terminalSize(ConfigSpec.computerTermWidth.get(), ConfigSpec.computerTermHeight.get())
38+
.storageCapacity(storageCapacity)
3839
);
3940
}
4041

Diff for: projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java

+18-14
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
2222
import dan200.computercraft.shared.computer.terminal.TerminalState;
2323
import dan200.computercraft.shared.config.Config;
24+
import dan200.computercraft.shared.config.ConfigSpec;
2425
import dan200.computercraft.shared.network.NetworkMessage;
2526
import dan200.computercraft.shared.network.client.ClientNetworkContext;
2627
import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
@@ -49,15 +50,9 @@ public class ServerComputer implements ComputerEnvironment, ComputerEvents.Recei
4950
private final NetworkedTerminal terminal;
5051
private final AtomicBoolean terminalChanged = new AtomicBoolean(false);
5152

52-
private int ticksSincePing;
53+
private final long storageCapacity;
5354

54-
@Deprecated
55-
public ServerComputer(
56-
ServerLevel level, BlockPos position, int computerID, @Nullable String label, ComputerFamily family, int terminalWidth, int terminalHeight,
57-
ComponentMap baseComponents
58-
) {
59-
this(level, position, properties(computerID, family).label(label).terminalSize(terminalWidth, terminalHeight).addComponents(baseComponents));
60-
}
55+
private int ticksSincePing;
6156

6257
public ServerComputer(ServerLevel level, BlockPos position, Properties properties) {
6358
this.level = level;
@@ -68,6 +63,8 @@ public ServerComputer(ServerLevel level, BlockPos position, Properties propertie
6863
terminal = new NetworkedTerminal(properties.terminalWidth, properties.terminalHeight, family != ComputerFamily.NORMAL, this::markTerminalChanged);
6964
metrics = context.metrics().createMetricObserver(this);
7065

66+
storageCapacity = properties.storageCapacity;
67+
7168
var componentBuilder = ComponentMap.builder();
7269
componentBuilder.add(ComponentMap.METRICS, metrics);
7370
if (family == ComputerFamily.COMMAND) {
@@ -269,21 +266,22 @@ public final WorkMonitor getMainThreadMonitor() {
269266

270267
@Override
271268
public final WritableMount createRootMount() {
272-
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + computer.getID(), Config.computerSpaceLimit);
269+
var capacity = storageCapacity <= 0 ? ConfigSpec.computerSpaceLimit.get() : storageCapacity;
270+
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + computer.getID(), capacity);
273271
}
274272

275273
public static Properties properties(int computerID, ComputerFamily family) {
276274
return new Properties(computerID, family);
277275
}
278276

279277
public static final class Properties {
280-
281278
private final int computerID;
282279
private @Nullable String label;
283280
private final ComputerFamily family;
284281

285282
private int terminalWidth = Config.DEFAULT_COMPUTER_TERM_WIDTH;
286283
private int terminalHeight = Config.DEFAULT_COMPUTER_TERM_HEIGHT;
284+
private long storageCapacity = -1;
287285
private final ComponentMap.Builder components = ComponentMap.builder();
288286

289287
private Properties(int computerID, ComputerFamily family) {
@@ -303,13 +301,19 @@ public Properties terminalSize(int width, int height) {
303301
return this;
304302
}
305303

306-
public <T> Properties addComponent(ComputerComponent<T> component, T value) {
307-
components.add(component, value);
304+
/**
305+
* Override the storage capacity for this computer.
306+
*
307+
* @param capacity The capacity for this computer's drive, or {@code -1} to use the default.
308+
* @return {@code this}, for chaining.
309+
*/
310+
public Properties storageCapacity(long capacity) {
311+
storageCapacity = capacity;
308312
return this;
309313
}
310314

311-
private Properties addComponents(ComponentMap components) {
312-
this.components.add(components);
315+
public <T> Properties addComponent(ComputerComponent<T> component, T value) {
316+
components.add(component, value);
313317
return this;
314318
}
315319
}

Diff for: projects/common/src/main/java/dan200/computercraft/shared/computer/items/AbstractComputerItem.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
import dan200.computercraft.api.media.IMedia;
1010
import dan200.computercraft.shared.ModRegistry;
1111
import dan200.computercraft.shared.computer.blocks.AbstractComputerBlock;
12-
import dan200.computercraft.shared.config.Config;
12+
import dan200.computercraft.shared.config.ConfigSpec;
1313
import dan200.computercraft.shared.util.DataComponentUtil;
14+
import dan200.computercraft.shared.util.StorageCapacity;
1415
import net.minecraft.ChatFormatting;
1516
import net.minecraft.core.HolderLookup;
1617
import net.minecraft.core.component.DataComponents;
@@ -53,6 +54,9 @@ public boolean setLabel(ItemStack stack, @Nullable String label) {
5354
@Override
5455
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
5556
var id = stack.get(ModRegistry.DataComponents.COMPUTER_ID.get());
56-
return id != null ? ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + id.id(), Config.computerSpaceLimit) : null;
57+
if (id == null) return null;
58+
59+
var capacity = StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), ConfigSpec.computerSpaceLimit);
60+
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + id.id(), capacity);
5761
}
5862
}

Diff for: projects/common/src/main/java/dan200/computercraft/shared/config/Config.java

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
* @see ConfigSpec The definition of our config values.
1313
*/
1414
public final class Config {
15-
public static int computerSpaceLimit = 1000 * 1000;
16-
public static int floppySpaceLimit = 125 * 1000;
1715
public static int uploadMaxSize = 512 * 1024; // 512 KB
1816
public static boolean commandRequireCreative = true;
1917

Diff for: projects/common/src/main/java/dan200/computercraft/shared/config/ConfigSpec.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ private ConfigSpec() {
9797
{ // General computers
9898
computerSpaceLimit = builder
9999
.comment("The disk space limit for computers and turtles, in bytes.")
100-
.define("computer_space_limit", Config.computerSpaceLimit);
100+
.define("computer_space_limit", 1000 * 1000);
101101

102102
floppySpaceLimit = builder
103103
.comment("The disk space limit for floppy disks, in bytes.")
104-
.define("floppy_space_limit", Config.floppySpaceLimit);
104+
.define("floppy_space_limit", 125 * 1000);
105105

106106
uploadMaxSize = builder
107107
.comment("""
@@ -384,8 +384,6 @@ or a single method (computercraft:inventory#pushItems).
384384

385385
public static void syncServer(@Nullable Path path) {
386386
// General
387-
Config.computerSpaceLimit = computerSpaceLimit.get();
388-
Config.floppySpaceLimit = floppySpaceLimit.get();
389387
Config.uploadMaxSize = uploadMaxSize.get();
390388
CoreConfig.maximumFilesOpen = maximumFilesOpen.get();
391389
CoreConfig.defaultComputerSettings = defaultComputerSettings.get();

Diff for: projects/common/src/main/java/dan200/computercraft/shared/media/items/DiskItem.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
import dan200.computercraft.api.media.IMedia;
1111
import dan200.computercraft.core.util.Colour;
1212
import dan200.computercraft.shared.ModRegistry;
13-
import dan200.computercraft.shared.config.Config;
13+
import dan200.computercraft.shared.config.ConfigSpec;
1414
import dan200.computercraft.shared.util.NonNegativeId;
15+
import dan200.computercraft.shared.util.StorageCapacity;
1516
import net.minecraft.ChatFormatting;
1617
import net.minecraft.core.BlockPos;
1718
import net.minecraft.core.HolderLookup;
@@ -64,7 +65,8 @@ public boolean setLabel(ItemStack stack, @Nullable String label) {
6465
@Override
6566
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
6667
var diskID = NonNegativeId.getOrCreate(level.getServer(), stack, ModRegistry.DataComponents.DISK_ID.get(), "disk");
67-
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "disk/" + diskID, Config.floppySpaceLimit);
68+
var capacity = StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), ConfigSpec.floppySpaceLimit);
69+
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "disk/" + diskID, capacity);
6870
}
6971

7072
public static int getDiskID(ItemStack stack) {

Diff for: projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java

+9-10
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,13 @@
1818
import dan200.computercraft.shared.computer.core.ServerComputerRegistry;
1919
import dan200.computercraft.shared.computer.core.ServerContext;
2020
import dan200.computercraft.shared.computer.items.ServerComputerReference;
21-
import dan200.computercraft.shared.config.Config;
21+
import dan200.computercraft.shared.config.ConfigSpec;
2222
import dan200.computercraft.shared.network.container.ComputerContainerData;
2323
import dan200.computercraft.shared.pocket.core.PocketBrain;
2424
import dan200.computercraft.shared.pocket.core.PocketHolder;
2525
import dan200.computercraft.shared.pocket.core.PocketServerComputer;
2626
import dan200.computercraft.shared.pocket.inventory.PocketComputerMenuProvider;
27-
import dan200.computercraft.shared.util.DataComponentUtil;
28-
import dan200.computercraft.shared.util.IDAssigner;
29-
import dan200.computercraft.shared.util.InventoryUtil;
30-
import dan200.computercraft.shared.util.NonNegativeId;
27+
import dan200.computercraft.shared.util.*;
3128
import net.minecraft.ChatFormatting;
3229
import net.minecraft.core.HolderLookup;
3330
import net.minecraft.network.chat.Component;
@@ -198,7 +195,9 @@ private PocketBrain getOrCreateBrain(ServerLevel level, PocketHolder holder, Ite
198195
var computerID = NonNegativeId.getOrCreate(level.getServer(), stack, ModRegistry.DataComponents.COMPUTER_ID.get(), IDAssigner.COMPUTER);
199196
var brain = new PocketBrain(
200197
holder, getUpgradeWithData(stack),
201-
ServerComputer.properties(computerID, getFamily()).label(getLabel(stack))
198+
ServerComputer.properties(computerID, getFamily())
199+
.label(getLabel(stack))
200+
.storageCapacity(StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), -1))
202201
);
203202
var computer = brain.computer();
204203

@@ -265,10 +264,10 @@ public boolean setLabel(ItemStack stack, @Nullable String label) {
265264
@Override
266265
public @Nullable Mount createDataMount(ItemStack stack, ServerLevel level) {
267266
var id = stack.get(ModRegistry.DataComponents.COMPUTER_ID.get());
268-
if (id != null) {
269-
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + id.id(), Config.computerSpaceLimit);
270-
}
271-
return null;
267+
if (id == null) return null;
268+
269+
var capacity = StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), ConfigSpec.computerSpaceLimit);
270+
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + id.id(), capacity);
272271
}
273272

274273
private static boolean isMarkedOn(ItemStack stack) {

Diff for: projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlockEntity.java

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ protected ServerComputer createComputer(int id) {
8282
var computer = new ServerComputer((ServerLevel) getLevel(), getBlockPos(), ServerComputer.properties(id, getFamily())
8383
.label(getLabel())
8484
.terminalSize(Config.TURTLE_TERM_WIDTH, Config.TURTLE_TERM_HEIGHT)
85+
.storageCapacity(storageCapacity)
8586
.addComponent(ComputerComponents.TURTLE, brain)
8687
);
8788
brain.setupComputer(computer);

Diff for: projects/common/src/main/java/dan200/computercraft/shared/util/NonNegativeId.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
public record NonNegativeId(int id) {
2727
public static final Codec<NonNegativeId> CODEC = ExtraCodecs.NON_NEGATIVE_INT.xmap(NonNegativeId::new, NonNegativeId::id);
2828

29-
public static final StreamCodec<ByteBuf, NonNegativeId> STREAM_CODEC = ByteBufCodecs.INT.map(NonNegativeId::new, NonNegativeId::id);
29+
public static final StreamCodec<ByteBuf, NonNegativeId> STREAM_CODEC = ByteBufCodecs.VAR_INT.map(NonNegativeId::new, NonNegativeId::id);
3030

3131
public NonNegativeId {
3232
if (id < 0) throw new IllegalArgumentException("ID must be >= 0");

0 commit comments

Comments
 (0)