Advanced Peripherals

Advanced Peripherals

29M Downloads

Refined System Overflow problem

LunaLorea opened this issue ยท 13 comments

commented

Describe

When Refined storage is used in combination with drawers from Functional Storage the external storage can get so big that the number overflows.

Steps to reproduce

Playing FTB Stoneblock 3 1.7.1 Downloaded with the FTB App (I couldn't figure out what version of your mod is used :/ )

Place RS controller and connect a drawer with 4 netherite upgrades as external Storage
Place Computer with rsBridge inbetween next to the controller

2023-08-01_20 07 27

read the max external storage as such:

local rsb = peripheral.find("rsBridge")
amount = rsb.getMaxItemExternalStorage()
print(amount)

2023-08-01_20 03 55

output: 2,147,483,647

2023-08-01_20 08 23

now add a second drawer without any upgrades

2023-08-01_20 05 40

when i execute the script again the number overflows and becomes negative

2023-08-01_20 09 36

Let me know if you need more information or if i need to create a bug report somewhere else
~Luna <3

Multiplayer?

Yes

Version

1.18.2-0.7.30r (Latest 1.18.2)

Minecraft, Forge and maybe other related mods versions

FTB StoneBlock 3 1.7.1

Screenshots or Videos

No response

Crashlog/log

No response

commented

src\main\java\de\srendi\advancedperipherals\common\addons\refinedstorage\RefinedStorage.java

public static int getMaxItemExternalStorage(INetwork network) {
    int total = 0;
    for (IStorage<ItemStack> store : network.getItemStorageCache().getStorages()) {
        if (store instanceof IExternalStorage<ItemStack> externalStorage) {
            total += externalStorage.getCapacity();
        }
    }
    return total;
}

In the RS api
src/main/java/com/refinedmods/refinedstorage/api/storage/externalstorage/IExternalStorage.java

    /**
     * @return the capacity of the connected storage
     */
    long getCapacity();
}

the method getCapacity() returns a long type integer. I think the bug appears when the return of getCapacity() gets added to the total. ( I havent looked deeper into the getCapacity method so maybe theres an error somewhere deeper down the line but I would suggest changing it here and see if it solves the problem)

So to fix the bug I think we just need to keep using the long type. maybe like this?

public static int getMaxItemExternalStorage(INetwork network) {
    long total = 0L;
    for (IStorage<ItemStack> store : network.getItemStorageCache().getStorages()) {
        if (store instanceof IExternalStorage<ItemStack> externalStorage) {
            total += externalStorage.getCapacity();
        }
    }
    return total;
}

What do you think?

commented

Isn't drawer have infinity storage?
So just compare the capacities with Integer.MAX_VALUE may help.

commented
public static long getMaxItemExternalStorage(INetwork network) {
    long total = 0;
    for (IStorage<ItemStack> store : network.getItemStorageCache().getStorages()) {
        if (store instanceof IExternalStorage<ItemStack> externalStorage) {
            long cap = externalStorage.getCapacity();
            if(total >= Long.MAX_VALUE - cap){ // total + cap >= long.max
              total = Long.MAX_VALUE
           }else{
              total += cap
           }
        }
    }
    return total;
}
commented

Not infinite, it's a signed 64-bit integer

What do you think?

That's right, but you would also need to set the return type of the method to long

commented

I see, so my solution just completely avoid the overflow issue with whatever or how many storages you have

commented

The same may be true for fluid storage when using fluid drawers.

commented

Isn't drawer have infinity storage?

no, drawers with 4 netherite upgrades can store 31^2-1 or 2147483647 items. So as soon as you have more storage than 1 fully upgraded drawer the 32bit int isn't enough to count the entire storage.

commented
public static int getMaxItemExternalStorage(INetwork network) {
    int total = 0;
    for (IStorage<ItemStack> store : network.getItemStorageCache().getStorages()) {
        if (store instanceof IExternalStorage<ItemStack> externalStorage) {
            int cap = externalStorage.getCapacity();
            if(total >= Integer.MAX_VALUE - cap){ // total + cap >= intmax
              total = Integer.MAX_VALUE
           }else{
              total += cap
           }
        }
    }
    return total;
}

Tbh that's quite unecessary and still wouldn't work if the whole system has a higher storage capacity than a 32-bit signed integer. So just switching to long would be sufficient.

This also needs to be adapted to the fluid system and the ME Bridge

commented
public static long getMaxItemExternalStorage(INetwork network) {
    long total = 0L;
    for (IStorage<ItemStack> store : network.getItemStorageCache().getStorages()) {
        if (store instanceof IExternalStorage<ItemStack> externalStorage) {
            total += externalStorage.getCapacity();
        }
    }
    return total;
}

this would solve the issue for external item storage with the RS system
same would have to be done to disk storage ( with 64k storage cells this probably isn't necessary but there are mods that offer bigger cells like Extra Disks

also as you said for the fluid system and the ME Bridge

This also needs to be adapted to the fluid system and the ME Bridge

commented

Yep, that should work just fine

commented

Interesting issue, a shame that I never thought about this

Thanks for reporting

commented

src/main/java/de/srendi/advancedperipherals/common/addons/appliedenergistics/AppEngApi.java

public static long getTotalItemStorage(IGridNode node) {
        long total = 0;

The ME Bridge already uses the long type, so it only fluid and item, internal and external storage of the rs bridge

commented

This issue got fixed, if someone wants to try it, they can download it from here