at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:218) when adding in elementCounts of StructurePool
J-K-Tech opened this issue ยท 11 comments
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 closedProcess 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)));
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.
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();
}
An arbitrary
Collection
orList
can be either modifiable or unmodifiable (this is documented in those interfaces' javadoc), so justImmutableList
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
It's ...Callback
not ...Fallback
, you can use your IDE for help. Also make sure you're on the latest Fabric API.
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
An arbitrary
Collection
orList
can be either modifiable or unmodifiable (this is documented in those interfaces' javadoc), so justImmutableList
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
the building i created and isnt being generated (even with jigsaw):
there is no structurepooladdcallback here ... at least the fabric api version im using. which version do i need?
You can check the latest Fabric API for each MC version from https://fabricmc.net/develop/
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