Skip to content

Commit

Permalink
fix: Actually fix off-thread access of ThreadLocalRandom
Browse files Browse the repository at this point in the history
This issue occurs in combination with Distant Horizons, because DH uses world generation threads to generate chunks for LODs. If you also have C2ME installed, it'll log an error for this.
  • Loading branch information
Steveplays28 committed Mar 31, 2024
1 parent ece1782 commit 1090448
Show file tree
Hide file tree
Showing 11 changed files with 27 additions and 22 deletions.
11 changes: 8 additions & 3 deletions src/main/java/com/github/nyuppo/config/Variants.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import net.minecraft.registry.tag.BiomeTags;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.random.CheckedRandom;
import net.minecraft.util.math.random.Random;
import net.minecraft.util.math.random.RandomSplitter;
import net.minecraft.world.biome.Biome;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -150,12 +152,15 @@ public static EntityType<?> getMob(String mobId) {
throw new IllegalArgumentException("Unknown mob identifier: " + mobId);
}

public static MobVariant getRandomVariant(EntityType<?> mob, Random random, @Nullable RegistryEntry<Biome> spawnBiome, @Nullable BreedingResultData breedingResultData, @Nullable Float moonSize) {
public static MobVariant getRandomVariant(EntityType<?> mob, long randomSeed, @Nullable RegistryEntry<Biome> spawnBiome, @Nullable BreedingResultData breedingResultData, @Nullable Float moonSize) {
ArrayList<MobVariant> variants = getVariants(mob);
if (variants.isEmpty()) {
return getDefaultVariant(mob);
}

// Split the random to ensure no off-thread access of ThreadLocalRandom occurs
// This fixes issues with Distant Horizons and C2ME
var random = new CheckedRandom(randomSeed);
// Handle modifiers
Iterator<MobVariant> i = variants.iterator();
MobVariant variant;
Expand Down Expand Up @@ -251,9 +256,9 @@ public static MobVariant getChildVariant(EntityType<?> mob, ServerWorld world, P
String[] parent2VariantId = parent2Nbt.getString("Variant").split(":");
MobVariant parent2Variant = Variants.getVariant(mob, new Identifier(parent2VariantId[0], parent2VariantId[1]));

return Variants.getRandomVariant(mob, world.getRandom(), world.getBiome(parent1.getBlockPos()), new BreedingResultData(parent1Variant, parent2Variant), null);
return Variants.getRandomVariant(mob, world.getRandom().nextLong(), world.getBiome(parent1.getBlockPos()), new BreedingResultData(parent1Variant, parent2Variant), null);
} else {
return Variants.getRandomVariant(mob, world.getRandom(), world.getBiome(parent1.getBlockPos()), null, null);
return Variants.getRandomVariant(mob, world.getRandom().nextLong(), world.getBiome(parent1.getBlockPos()), null, null);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/github/nyuppo/mixin/CatVariantsMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.CAT, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.CAT, ((CatEntity)(Object)this).getWorld().getRandom(), ((CatEntity)(Object)this).getWorld().getBiome(((CatEntity)(Object)this).getBlockPos()), null, ((CatEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.CAT, ((CatEntity)(Object)this).getWorld().getRandom().nextLong(), ((CatEntity)(Object)this).getWorld().getBiome(((CatEntity)(Object)this).getBlockPos()), null, ((CatEntity)(Object)this).getWorld().getMoonSize());
}

// Update all players in the event that this is from modifying entity data with a command
Expand All @@ -64,7 +64,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.CAT, world.getRandom(), world.getBiome(((CatEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.CAT, world.getRandom().nextLong(), world.getBiome(((CatEntity)(Object)this).getBlockPos()), null, world.getMoonSize());

if (world.toServerWorld().getStructureAccessor().getStructureContaining(((CatEntity)(Object)this).getBlockPos(), StructureTags.CATS_SPAWN_AS_BLACK).hasChildren()) {
MobVariant allBlack = Variants.getVariantNullable(EntityType.CAT, new Identifier("all_black"));
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/github/nyuppo/mixin/ChickenEggMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class ChickenEggMixin {
at = @At("STORE")
)
private ChickenEntity mixin(ChickenEntity chickenEntity) {
MobVariant variant = Variants.getRandomVariant(EntityType.CHICKEN, chickenEntity.getWorld().getRandom(), chickenEntity.getWorld().getBiome(chickenEntity.getBlockPos()), null, chickenEntity.getWorld().getMoonSize());
MobVariant variant = Variants.getRandomVariant(EntityType.CHICKEN, chickenEntity.getWorld().getRandom().nextLong(), chickenEntity.getWorld().getBiome(chickenEntity.getBlockPos()), null, chickenEntity.getWorld().getMoonSize());

NbtCompound newNbt = new NbtCompound();
chickenEntity.writeNbt(newNbt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.CHICKEN, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.CHICKEN, ((ChickenEntity)(Object)this).getWorld().getRandom(), ((ChickenEntity)(Object)this).getWorld().getBiome(((ChickenEntity)(Object)this).getBlockPos()), null, ((ChickenEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.CHICKEN, ((ChickenEntity)(Object)this).getWorld().getRandom().nextLong(), ((ChickenEntity)(Object)this).getWorld().getBiome(((ChickenEntity)(Object)this).getBlockPos()), null, ((ChickenEntity)(Object)this).getWorld().getMoonSize());
}

// Update all players in the event that this is from modifying entity data with a command
Expand All @@ -64,7 +64,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.CHICKEN, world.getRandom(), world.getBiome(((ChickenEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.CHICKEN, world.getRandom().nextLong(), world.getBiome(((ChickenEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
}

@Inject(
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/github/nyuppo/mixin/CowVariantsMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.COW, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.COW, ((CowEntity)(Object)this).getWorld().getRandom(), ((CowEntity)(Object)this).getWorld().getBiome(((CowEntity)(Object)this).getBlockPos()), null, ((CowEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.COW, ((CowEntity)(Object)this).getWorld().getRandom().nextLong(), ((CowEntity)(Object)this).getWorld().getBiome(((CowEntity)(Object)this).getBlockPos()), null, ((CowEntity)(Object)this).getWorld().getMoonSize());
}

// Update all players in the event that this is from modifying entity data with a command
Expand All @@ -62,7 +62,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.COW, world.getRandom(), world.getBiome(((CowEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.COW, world.getRandom().nextLong(), world.getBiome(((CowEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
}

@Inject(
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/github/nyuppo/mixin/PigVariantsMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.PIG, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.PIG, ((PigEntity)(Object)this).getWorld().getRandom(), ((PigEntity)(Object)this).getWorld().getBiome(((PigEntity)(Object)this).getBlockPos()), null, ((PigEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.PIG, ((PigEntity)(Object)this).getWorld().getRandom().nextLong(), ((PigEntity)(Object)this).getWorld().getBiome(((PigEntity)(Object)this).getBlockPos()), null, ((PigEntity)(Object)this).getWorld().getMoonSize());
}
isMuddy = nbt.getBoolean(MoreMobVariants.MUDDY_NBT_KEY);
muddyTimeLeft = nbt.getInt(MoreMobVariants.MUDDY_TIMEOUT_NBT_KEY);
Expand All @@ -72,7 +72,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.PIG, world.getRandom(), world.getBiome(((PigEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.PIG, world.getRandom().nextLong(), world.getBiome(((PigEntity)(Object)this).getBlockPos()), null, world.getMoonSize());

// 2% chance of pig starting muddy if in swamp
if (world.getBiome(((PigEntity)(Object)this).getBlockPos()).isIn(BiomeTags.RUINED_PORTAL_SWAMP_HAS_STRUCTURE) && world.getRandom().nextDouble() < 0.02) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/github/nyuppo/mixin/SheepVariantsMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.SHEEP, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.SHEEP, ((SheepEntity)(Object)this).getWorld().getRandom(), ((SheepEntity)(Object)this).getWorld().getBiome(((SheepEntity)(Object)this).getBlockPos()), null, ((SheepEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.SHEEP, ((SheepEntity)(Object)this).getWorld().getRandom().nextLong(), ((SheepEntity)(Object)this).getWorld().getBiome(((SheepEntity)(Object)this).getBlockPos()), null, ((SheepEntity)(Object)this).getWorld().getMoonSize());
}
hornColour = nbt.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY);

Expand All @@ -69,7 +69,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.SHEEP, world.getRandom(), world.getBiome(((SheepEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.SHEEP, world.getRandom().nextLong(), world.getBiome(((SheepEntity)(Object)this).getBlockPos()), null, world.getMoonSize());

SheepHornSettings.SheepHornColour colour = SheepHornSettings.getRandomSheepHornColour(world.getRandom(), world.getBiome(((SheepEntity)(Object)this).getBlockPos()));
if (colour != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.SKELETON, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.SKELETON, ((SkeletonEntity)(Object)this).getWorld().getRandom(), ((SkeletonEntity)(Object)this).getWorld().getBiome(((SkeletonEntity)(Object)this).getBlockPos()), null, ((SkeletonEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.SKELETON, ((SkeletonEntity)(Object)this).getWorld().getRandom().nextLong(), ((SkeletonEntity)(Object)this).getWorld().getBiome(((SkeletonEntity)(Object)this).getBlockPos()), null, ((SkeletonEntity)(Object)this).getWorld().getMoonSize());
}

// Update all players in the event that this is from modifying entity data with a command
Expand All @@ -60,6 +60,6 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.SKELETON, world.getRandom(), world.getBiome(((SkeletonEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.SKELETON, world.getRandom().nextLong(), world.getBiome(((SkeletonEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.SPIDER, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.SPIDER, ((SpiderEntity)(Object)this).getWorld().getRandom(), ((SpiderEntity)(Object)this).getWorld().getBiome(((SpiderEntity)(Object)this).getBlockPos()), null, ((SpiderEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.SPIDER, ((SpiderEntity)(Object)this).getWorld().getRandom().nextLong(), ((SpiderEntity)(Object)this).getWorld().getBiome(((SpiderEntity)(Object)this).getBlockPos()), null, ((SpiderEntity)(Object)this).getWorld().getMoonSize());
}

// Update all players in the event that this is from modifying entity data with a command
Expand All @@ -60,6 +60,6 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.SPIDER, world.getRandom(), world.getBiome(((SpiderEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.SPIDER, world.getRandom().nextLong(), world.getBiome(((SpiderEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/github/nyuppo/mixin/WolfVariantsMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.WOLF, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.WOLF, ((WolfEntity)(Object)this).getWorld().getRandom(), ((WolfEntity)(Object)this).getWorld().getBiome(((WolfEntity)(Object)this).getBlockPos()), null, ((WolfEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.WOLF, ((WolfEntity)(Object)this).getWorld().getRandom().nextLong(), ((WolfEntity)(Object)this).getWorld().getBiome(((WolfEntity)(Object)this).getBlockPos()), null, ((WolfEntity)(Object)this).getWorld().getMoonSize());
}

// Update all players in the event that this is from modifying entity data with a command
Expand All @@ -64,7 +64,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.WOLF, world.getRandom(), world.getBiome(((WolfEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.WOLF, world.getRandom().nextLong(), world.getBiome(((WolfEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
}

@Inject(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
variant = Variants.getVariant(EntityType.ZOMBIE, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY)));
}
} else {
variant = Variants.getRandomVariant(EntityType.ZOMBIE, ((ZombieEntity)(Object)this).getWorld().getRandom(), ((ZombieEntity)(Object)this).getWorld().getBiome(((ZombieEntity)(Object)this).getBlockPos()), null, ((ZombieEntity)(Object)this).getWorld().getMoonSize());
variant = Variants.getRandomVariant(EntityType.ZOMBIE, ((ZombieEntity)(Object)this).getWorld().getRandom().nextLong(), ((ZombieEntity)(Object)this).getWorld().getBiome(((ZombieEntity)(Object)this).getBlockPos()), null, ((ZombieEntity)(Object)this).getWorld().getMoonSize());
}

// Update all players in the event that this is from modifying entity data with a command
Expand All @@ -60,6 +60,6 @@ protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {

@Override
protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, @Nullable NbtCompound entityNbt, CallbackInfoReturnable<EntityData> ci) {
variant = Variants.getRandomVariant(EntityType.ZOMBIE, world.getRandom(), world.getBiome(((ZombieEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
variant = Variants.getRandomVariant(EntityType.ZOMBIE, world.getRandom().nextLong(), world.getBiome(((ZombieEntity)(Object)this).getBlockPos()), null, world.getMoonSize());
}
}

0 comments on commit 1090448

Please sign in to comment.