Fabric API

Fabric API

108M Downloads

at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:218) when adding in elementCounts of StructurePool

J-K-Tech opened this issue ยท 11 comments

commented

i have noticed that it isnt an ImmutableList but just a simple List variable so i should be able to add since the List used by this variable extends Collection

that is the full log after the error happens:

[12:19:24] [Server thread/ERROR] (Minecraft) Encountered an unexpected exception
java.lang.UnsupportedOperationException: null
at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:218) ~[guava-21.0.jar:?]
at com.jktech.kstruct.main.AddStruct(main.java:28) ~[main/:?]
at com.jktech.kstruct.main.SetNewStruct(main.java:33) ~[main/:?]
at net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents.lambda$static$0(ServerLifecycleEvents.java:37) ~[fabric-lifecycle-events-v1-1.4.4+a02b446318.jar:?]
at net.minecraft.server.MinecraftServer.handler$zbh000$beforeSetupServer(MinecraftServer.java:1991) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:728) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:272) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at java.lang.Thread.run(Thread.java:831) [?:?]
[12:19:24] [Server thread/WARN] (FileUtil) Configuration conflict: there is more than one oshi.architecture.properties file on the classpath
[12:19:25] [Server thread/ERROR] (Minecraft) This crash report has been saved to: /home/komi/Documents/strucgen/run/crash-reports/crash-2022-03-03_12.19.25-server.txt
[12:19:25] [Server thread/INFO] (Minecraft) Stopping server
[12:19:25] [Server thread/INFO] (Minecraft) Saving players
[12:19:25] [Server thread/INFO] (Minecraft) Saving worlds
[12:19:25] [Server thread/ERROR] (Minecraft) Exception stopping the server
java.lang.NullPointerException: Cannot invoke "net.minecraft.server.world.ServerWorld.getWorldBorder()" because "serverWorld2" is null
at net.minecraft.server.MinecraftServer.save(MinecraftServer.java:630) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at net.minecraft.server.MinecraftServer.shutdown(MinecraftServer.java:674) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at net.minecraft.server.integrated.IntegratedServer.shutdown(IntegratedServer.java:192) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:787) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:272) ~[minecraft-1.17.1-mapped-net.fabricmc.yarn-1.17.1+build.30-v2.jar:?]
at java.lang.Thread.run(Thread.java:831) [?:?]
AL lib: (EE) alc_cleanup: 1 device not closed

Process finished with exit code 130 (interrupted by signal 2: SIGINT)
the game simply freezes and does nothing
this is my accessor class:

@Mixin(StructurePool.class)
public interface poolaccessor{
    @Accessor
    List<StructurePoolElement> getElements();
    @Accessor
    List<Pair<StructurePoolElement, Integer>> getElementCounts();
}

and this is the part of the code i use to add structures to the pool elementCounts list:
((poolaccessor)trupool).getElementCounts().add(new Pair<>(element, Integer.valueOf(weight)));

commented

An arbitrary Collection or List can be either modifiable or unmodifiable (this is documented in those interfaces' javadoc), so just ImmutableList not being in the type signature doesn't guarantee anything. In this case, the lists happen to be immutable.

Since you're on MC 1.17.1, I think you can use Fabric's StructurePoolAddCallback to add to those lists.

commented

how does this works?
this is my code so far

package com.jktech.kstruct;

import com.jktech.kstruct.mixin.poolaccessor;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.structure.pool.StructurePool;
import net.minecraft.structure.pool.StructurePoolElement;
import net.minecraft.util.Identifier;
import com.mojang.datafixers.util.Pair;
import net.minecraft.util.registry.Registry;

import java.util.List;

public class main implements ModInitializer {

    @Override
    public void onInitialize() {
        ServerLifecycleEvents.SERVER_STARTING.register(this::SetNewStruct);
    }
    private void AddStruct(Registry<StructurePool> pool,Identifier id, String nbtpath, int weight){
        StructurePool trupool = pool.get(id);
        if (trupool==null){
            System.err.println("!!! [[ WOW!!! ]] structure file "+id.toString()+" doesn't exist!!!");
            return;}
        StructurePoolElement element = StructurePoolElement.ofSingle(nbtpath).apply(StructurePool.Projection.RIGID);
        for (int i = 0; i < weight; i++) {
            ((poolaccessor)trupool).getElements().add(element);
        }
        ((poolaccessor)trupool).getElementCounts().add(new Pair<>(element, Integer.valueOf(weight)));
    }
    public void SetNewStruct(MinecraftServer server){
        Registry<StructurePool> PoolRegistry = server.getRegistryManager().get(Registry.STRUCTURE_POOL_KEY);

        AddStruct(PoolRegistry, new Identifier("minecraft:village/desert/houses"),
                "mod:desert", 5);

    }
}
package com.jktech.kstruct.mixin;

import com.mojang.datafixers.util.Pair;
import net.minecraft.structure.pool.SinglePoolElement;
import net.minecraft.structure.pool.StructurePool;
import net.minecraft.structure.pool.StructurePoolElement;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

import java.util.List;

@Mixin(StructurePool.class)
public interface poolaccessor{
    @Accessor
    List<StructurePoolElement> getElements();
    @Accessor
    List<Pair<StructurePoolElement, Integer>> getElementCounts();
}
commented

An arbitrary Collection or List can be either modifiable or unmodifiable (this is documented in those interfaces' javadoc), so just ImmutableList not being in the type signature doesn't guarantee anything. In this case, the lists happen to be immutable.

Since you're on MC 1.17.1, I think you can use Fabric's StructurePoolAddCallback to add to those lists.

cant find StructurePoolAddFallback

commented

It's ...Callback not ...Fallback, you can use your IDE for help. Also make sure you're on the latest Fabric API.

commented

i put callback in the code... i just mistyped here.. since "f" and "c" is close
ive tried to search using ctrl+shift+f to find in all files including libraries and nothing was found.. i use intellij idea

commented

2022-03-07_10 50 39

An arbitrary Collection or List can be either modifiable or unmodifiable (this is documented in those interfaces' javadoc), so just ImmutableList not being in the type signature doesn't guarantee anything. In this case, the lists happen to be immutable.

Since you're on MC 1.17.1, I think you can use Fabric's StructurePoolAddCallback to add to those lists.

ok it is not working.
this is my code to add structures:

package com.jktech.minend.registry;
import net.fabricmc.fabric.api.structure.v1.StructurePoolAddCallback;
import net.minecraft.structure.pool.StructurePool;
import net.minecraft.structure.pool.StructurePoolElement;
import net.minecraft.structure.processor.StructureProcessorLists;
import net.minecraft.util.Identifier;

public class buildings {
    public static void regedit(){
        StructurePoolAddCallback.EVENT.register(structurePool -> {
            System.out.println("!!!  [[ WOW!!! ]]  its registering!!!");

            switch (structurePool.getId().toString()){
                case "minecraft:village/desert/houses":
                    System.out.println("!!!  [[ WOW!!! ]] its "+
                            Identifier.isValid("minend:village/desert/houses/desert_block_trader")+" ");
                    structurePool.addStructurePoolElement(StructurePoolElement.ofProcessedLegacySingle(
                            "minend:village/desert/houses/desert_block_trader",
                                StructureProcessorLists.HOUSING).apply(
                                StructurePool.Projection.RIGID),108);
                    break;
                case "minecraft:village/taiga/houses":
                    System.out.println("!!!  [[ WOW!!! ]]  its registered!!!");
                    structurePool.addStructurePoolElement(StructurePoolElement.ofProcessedLegacySingle(
                            "minend:village/taiga/houses",
                            StructureProcessorLists.HOUSING).apply(
                            StructurePool.Projection.RIGID),4);
                    break;
                case "minecraft:village/plains/houses":
                    System.out.println("!!!  [[ WOW!!! ]]  its registered!!!");
                    structurePool.addStructurePoolElement(StructurePoolElement.ofProcessedLegacySingle(
                            "minend:village/plains/houses",
                            StructureProcessorLists.HOUSING).apply(
                            StructurePool.Projection.RIGID),4);
                    break;
                case "minecraft:village/savanna/houses":
                    System.out.println("!!!  [[ WOW!!! ]]  its registered!!!");
                    structurePool.addStructurePoolElement(StructurePoolElement.ofProcessedLegacySingle(
                            "minend:village/savanna/houses",
                            StructureProcessorLists.HOUSING).apply(
                            StructurePool.Projection.RIGID),4);
                    break;
                case "minecraft:village/snowy/houses":
                    System.out.println("!!!  [[ WOW!!! ]]  its registered!!!");
                    structurePool.addStructurePoolElement(StructurePoolElement.ofProcessedLegacySingle(
                            "minend:village/snowy/houses",
                            StructureProcessorLists.HOUSING).apply(
                            StructurePool.Projection.RIGID),4);
                    break;
            }
        });
    }
}

it does show the registering and in the System.out.println("!!! [[ WOW!!! ]] its "+Identifier.isValid("minend:village/desert/houses/desert_block_trader")+" "); it outputs "!!! [[ WOW!!! ]] its true"
edit: also im testing in superflat desert world.
i know something changed because... look at the villages
2022-03-06_23 09 22
the building i created and isnt being generated (even with jigsaw):
2022-03-07_10 50 39

commented

https://github.com/FabricMC/fabric/blob/1.17/fabric-structure-api-v1/src/main/java/net/fabricmc/fabric/api/structure/v1/StructurePoolAddCallback.java

there is no structurepooladdcallback here ... at least the fabric api version im using. which version do i need?

commented

You can check the latest Fabric API for each MC version from https://fabricmc.net/develop/

commented

mine is 0.37.1 and is not new enough.. thank you i will update it.. also how do i update it?
edit: ive updated to 0.46.0 and i can find it now

commented

Please ask on discord in the mod dev channels if you require further support.