Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9c1f3e9aa |
43
.github/workflows/gradle.yml
vendored
43
.github/workflows/gradle.yml
vendored
|
|
@ -1,43 +0,0 @@
|
||||||
name: Build ModernFix using Gradle
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '**'
|
|
||||||
tags-ignore:
|
|
||||||
- '**'
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Set up JDK 17
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
distribution: 'temurin'
|
|
||||||
java-version: 17
|
|
||||||
check-latest: true
|
|
||||||
- name: Setup Gradle
|
|
||||||
uses: gradle/actions/setup-gradle@v3
|
|
||||||
with:
|
|
||||||
cache-read-only: ${{ !startsWith(github.ref, 'refs/heads/1.') }}
|
|
||||||
gradle-home-cache-cleanup: true
|
|
||||||
- name: Setup project Loom cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
.gradle/loom-cache
|
|
||||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/gradle.properties', '**/*.gradle*', '**/gradle-wrapper.properties') }}
|
|
||||||
restore-keys: ${{ runner.os }}-gradle-
|
|
||||||
- name: Build ModernFix using Gradle
|
|
||||||
run: ./gradlew build
|
|
||||||
- name: Upload Artifacts to GitHub
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: Package
|
|
||||||
path: bin
|
|
||||||
41
.github/workflows/release.yml
vendored
41
.github/workflows/release.yml
vendored
|
|
@ -1,41 +0,0 @@
|
||||||
name: Release ModernFix Artifacts
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
if: github.repository_owner == 'embeddedt'
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Set up JDK 17
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
distribution: 'temurin'
|
|
||||||
java-version: 17
|
|
||||||
check-latest: true
|
|
||||||
- name: Remove tags for release on other versions
|
|
||||||
run: ./scripts/tagcleaner.sh
|
|
||||||
- name: Build and publish mod to CurseForge & Modrinth
|
|
||||||
run: ./gradlew publishToModSites copyJarToBin
|
|
||||||
env:
|
|
||||||
CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }}
|
|
||||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
|
||||||
- name: Upload assets to GitHub
|
|
||||||
uses: AButler/upload-release-assets@v3.0
|
|
||||||
with:
|
|
||||||
files: 'bin/*'
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: Add changelog to release
|
|
||||||
uses: irongut/EditRelease@v1.2.0
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
id: ${{ github.event.release.id }}
|
|
||||||
replacebody: true
|
|
||||||
files: "CHANGELOG.md"
|
|
||||||
27
.github/workflows/wiki_update.yml
vendored
27
.github/workflows/wiki_update.yml
vendored
|
|
@ -1,27 +0,0 @@
|
||||||
name: Update wiki using WikiGen
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- '1.**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
wikigen:
|
|
||||||
if: github.repository_owner == 'embeddedt'
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Generate Markdown Patch-List
|
|
||||||
run: python3 scripts/gen-markdown-patchlist.py
|
|
||||||
- name: Very legitimate hack for wiki push race condition
|
|
||||||
run: sleep $((1 + (RANDOM % 30)))
|
|
||||||
shell: bash
|
|
||||||
- name: Upload generated file to wiki
|
|
||||||
uses: SwiftDocOrg/github-wiki-publish-action@v1
|
|
||||||
with:
|
|
||||||
path: "doc/generated"
|
|
||||||
env:
|
|
||||||
GH_PERSONAL_ACCESS_TOKEN: ${{ secrets.WIKI_TOKEN }}
|
|
||||||
|
|
@ -12,9 +12,7 @@ dependencies {
|
||||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||||
implementation(annotationProcessor("io.github.llamalad7:mixinextras-common:${rootProject.mixinextras_version}"))
|
implementation(annotationProcessor("io.github.llamalad7:mixinextras-common:${rootProject.mixinextras_version}"))
|
||||||
|
|
||||||
modCompileOnly("dev.latvian.mods:kubejs:${kubejs_version}") {
|
modCompileOnly("curse.maven:kubejs-238086:3103858")
|
||||||
transitive = false
|
|
||||||
}
|
|
||||||
// Remove the next line if you don't want to depend on the API
|
// Remove the next line if you don't want to depend on the API
|
||||||
// modApi "me.shedaniel:architectury:${rootProject.architectury_version}"
|
// modApi "me.shedaniel:architectury:${rootProject.architectury_version}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
package org.embeddedt.modernfix.blockstate;
|
package org.embeddedt.modernfix.blockstate;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.embeddedt.modernfix.duck.IBlockState;
|
import org.embeddedt.modernfix.duck.IBlockState;
|
||||||
|
|
||||||
public class BlockStateCacheHandler {
|
public class BlockStateCacheHandler {
|
||||||
public static void rebuildParallel(boolean force) {
|
public static void rebuildParallel(boolean force) {
|
||||||
synchronized (BlockBehaviour.BlockStateBase.class) {
|
synchronized (BlockState.class) {
|
||||||
for (BlockState blockState : Block.BLOCK_STATE_REGISTRY) {
|
for (BlockState blockState : Block.BLOCK_STATE_REGISTRY) {
|
||||||
((IBlockState)blockState).clearCache();
|
((IBlockState)blockState).clearCache();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ public class ModernFixCommands {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager manager = level.getServer().resources.getResourceManager();
|
ResourceManager manager = level.getServer().getResources();
|
||||||
Collection<ResourceLocation> structures = manager.listResources("structures", p -> p.endsWith(".nbt"));
|
Collection<ResourceLocation> structures = manager.listResources("structures", p -> p.endsWith(".nbt"));
|
||||||
int upgradedNum = 0;
|
int upgradedNum = 0;
|
||||||
Pattern pathPattern = Pattern.compile("^structures/(.*)\\.nbt$");
|
Pattern pathPattern = Pattern.compile("^structures/(.*)\\.nbt$");
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock;
|
package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock;
|
||||||
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.embeddedt.modernfix.chunk.SafeBlockGetter;
|
import org.embeddedt.modernfix.chunk.SafeBlockGetter;
|
||||||
import org.embeddedt.modernfix.duck.ISafeBlockGetter;
|
import org.embeddedt.modernfix.duck.ISafeBlockGetter;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
|
||||||
@Mixin(value = BlockBehaviour.BlockStateBase.class, priority = 100)
|
@Mixin(value = BlockState.class, priority = 100)
|
||||||
public class BlockStateBaseMixin {
|
public class BlockStateBaseMixin {
|
||||||
@ModifyVariable(method = "getOffset", at = @At("HEAD"), argsOnly = true, index = 1)
|
@ModifyVariable(method = "getOffset", at = @At("HEAD"), argsOnly = true, index = 1)
|
||||||
private BlockGetter useSafeGetter(BlockGetter g) {
|
private BlockGetter useSafeGetter(BlockGetter g) {
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.bugfix.concurrency;
|
|
||||||
|
|
||||||
import net.minecraft.tags.StaticTagHelper;
|
|
||||||
import net.minecraft.tags.TagCollection;
|
|
||||||
import net.minecraft.tags.TagContainer;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@Mixin(StaticTagHelper.class)
|
|
||||||
public class StaticTagHelperMixin<T> {
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
@Shadow @Mutable
|
|
||||||
@Final private List wrappers;
|
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
|
||||||
private void useCOWArrayList(Function<TagContainer, TagCollection<T>> function, CallbackInfo ci) {
|
|
||||||
this.wrappers = new CopyOnWriteArrayList<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.bugfix.paper_chunk_patches;
|
package org.embeddedt.modernfix.common.mixin.bugfix.paper_chunk_patches;
|
||||||
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.level.ChunkHolder;
|
import net.minecraft.server.level.ChunkHolder;
|
||||||
import net.minecraft.server.level.ChunkMap;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
|
@ -29,9 +28,8 @@ public class ChunkMapMixin {
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
private void setup(CallbackInfo ci) {
|
private void setup(CallbackInfo ci) {
|
||||||
MinecraftServer server = this.level.getServer();
|
|
||||||
this.mainInvokingExecutor = (runnable) -> {
|
this.mainInvokingExecutor = (runnable) -> {
|
||||||
if(server.isSameThread())
|
if(this.level.getServer().isSameThread())
|
||||||
runnable.run();
|
runnable.run();
|
||||||
else
|
else
|
||||||
this.mainThreadExecutor.execute(runnable);
|
this.mainThreadExecutor.execute(runnable);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public class MinecraftServerMixin implements ITimeTrackingServer {
|
||||||
return mfix$lastTickStartTime;
|
return mfix$lastTickStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "runServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;tickServer(Ljava/util/function/BooleanSupplier;)V"))
|
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;tickServer(Ljava/util/function/BooleanSupplier;)V"))
|
||||||
private void trackTickTime(CallbackInfo ci) {
|
private void trackTickTime(CallbackInfo ci) {
|
||||||
mfix$lastTickStartTime = Util.getMillis();
|
mfix$lastTickStartTime = Util.getMillis();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.devenv;
|
|
||||||
|
|
||||||
import com.mojang.authlib.minecraft.OfflineSocialInteractions;
|
|
||||||
import com.mojang.authlib.minecraft.SocialInteractionsService;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
@Mixin(Minecraft.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public class MinecraftMixin {
|
|
||||||
@Inject(method = "createSocialInteractions", at = @At("HEAD"), cancellable = true)
|
|
||||||
private void noSocialInteraction(CallbackInfoReturnable<SocialInteractionsService> cir) {
|
|
||||||
cir.setReturnValue(new OfflineSocialInteractions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.feature.measure_time;
|
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Function4;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.screens.Overlay;
|
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
|
||||||
import net.minecraft.world.level.DataPackConfig;
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
|
||||||
import net.minecraft.world.level.storage.WorldData;
|
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.ModernFixClient;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@Mixin(Minecraft.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public class MinecraftMixin {
|
|
||||||
@Shadow @Nullable public Overlay overlay;
|
|
||||||
private long datapackReloadStartTime;
|
|
||||||
|
|
||||||
@Inject(method = "makeServerStem", at = @At(value = "HEAD"))
|
|
||||||
private void recordReloadStart(RegistryAccess.RegistryHolder p_238189_1_, Function<LevelStorageSource.LevelStorageAccess, DataPackConfig> p_238189_2_, Function4<LevelStorageSource.LevelStorageAccess, RegistryAccess.RegistryHolder, ResourceManager, DataPackConfig, WorldData> p_238189_3_, boolean p_238189_4_, LevelStorageSource.LevelStorageAccess p_238189_5_, CallbackInfoReturnable<Minecraft.ServerStem> cir) {
|
|
||||||
datapackReloadStartTime = System.nanoTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "makeServerStem", at = @At(value = "RETURN"))
|
|
||||||
private void recordReloadEnd(RegistryAccess.RegistryHolder p_238189_1_, Function<LevelStorageSource.LevelStorageAccess, DataPackConfig> p_238189_2_, Function4<LevelStorageSource.LevelStorageAccess, RegistryAccess.RegistryHolder, ResourceManager, DataPackConfig, WorldData> p_238189_3_, boolean p_238189_4_, LevelStorageSource.LevelStorageAccess p_238189_5_, CallbackInfoReturnable<Minecraft.ServerStem> cir) {
|
|
||||||
float timeSpentReloading = ((float)(System.nanoTime() - datapackReloadStartTime) / 1000000000f);
|
|
||||||
ModernFix.LOGGER.warn("Datapack reload took " + timeSpentReloading + " seconds.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "tick", at = @At("HEAD"))
|
|
||||||
private void onClientTick(CallbackInfo ci) {
|
|
||||||
if(this.overlay == null && ModernFixClient.INSTANCE != null) {
|
|
||||||
ModernFixClient.INSTANCE.onGameLaunchFinish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.injection.ModifyConstant;
|
||||||
|
|
||||||
@Mixin(Util.class)
|
@Mixin(Util.class)
|
||||||
public class UtilMixin {
|
public class UtilMixin {
|
||||||
@ModifyConstant(method = "makeExecutor", constant = @Constant(intValue = 7))
|
@ModifyConstant(method = "makeBackgroundExecutor", constant = @Constant(intValue = 7))
|
||||||
private static int useHigherThreadCount(int old) {
|
private static int useHigherThreadCount(int old) {
|
||||||
String requestedMax = System.getProperty("max.bg.threads");
|
String requestedMax = System.getProperty("max.bg.threads");
|
||||||
if(requestedMax != null) {
|
if(requestedMax != null) {
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,15 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.cache_blockstate_cache_arrays;
|
package org.embeddedt.modernfix.common.mixin.perf.cache_blockstate_cache_arrays;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.SupportType;
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
@Mixin(BlockBehaviour.BlockStateBase.Cache.class)
|
@Mixin(BlockState.Cache.class)
|
||||||
public class AbstractBlockStateCacheMixin {
|
public class AbstractBlockStateCacheMixin {
|
||||||
private static final SupportType[] MF_BLOCK_VOXEL_SHAPES = SupportType.values();
|
|
||||||
private static final Direction.Axis[] DIRECTION_AXIS_VALUES = Direction.Axis.values();
|
private static final Direction.Axis[] DIRECTION_AXIS_VALUES = Direction.Axis.values();
|
||||||
|
|
||||||
@Redirect(method = "<init>(Lnet/minecraft/world/level/block/state/BlockState;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SupportType;values()[Lnet/minecraft/world/level/block/SupportType;"))
|
|
||||||
private SupportType[] getVoxelShapeValues() {
|
|
||||||
return MF_BLOCK_VOXEL_SHAPES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "<init>(Lnet/minecraft/world/level/block/state/BlockState;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/Direction$Axis;values()[Lnet/minecraft/core/Direction$Axis;"))
|
@Redirect(method = "<init>(Lnet/minecraft/world/level/block/state/BlockState;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/Direction$Axis;values()[Lnet/minecraft/core/Direction$Axis;"))
|
||||||
private Direction.Axis[] getDirectionAxisValues() {
|
private Direction.Axis[] getDirectionAxisValues() {
|
||||||
return DIRECTION_AXIS_VALUES;
|
return DIRECTION_AXIS_VALUES;
|
||||||
|
|
|
||||||
|
|
@ -4,26 +4,29 @@ import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
|
import net.minecraft.world.level.levelgen.feature.StrongholdFeature;
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
import org.embeddedt.modernfix.duck.IServerLevel;
|
import org.embeddedt.modernfix.duck.IServerLevel;
|
||||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||||
import org.embeddedt.modernfix.world.StrongholdLocationCache;
|
import org.embeddedt.modernfix.world.StrongholdLocationCache;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mixin(ChunkGenerator.class)
|
@Mixin(StrongholdFeature.class)
|
||||||
public class ChunkGeneratorMixin {
|
public class ChunkGeneratorMixin {
|
||||||
@Shadow @Final private List<ChunkPos> strongholdPositions;
|
@Shadow @Final @Mutable private ChunkPos[] strongholdPos;
|
||||||
|
|
||||||
@Inject(method = "generateStrongholds", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Lists;newArrayList()Ljava/util/ArrayList;", ordinal = 0, remap = false), cancellable = true)
|
@Inject(method = "generatePositions", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Lists;newArrayList()Ljava/util/ArrayList;", ordinal = 0, remap = false), cancellable = true)
|
||||||
private void useCachedDataIfAvailable(CallbackInfo ci) {
|
private void useCachedDataIfAvailable(ChunkGenerator<?> generator, CallbackInfo ci) {
|
||||||
ServerLevel level = searchLevel();
|
ServerLevel level = searchLevel(generator);
|
||||||
if(level == null) {
|
if(level == null) {
|
||||||
ModernFix.LOGGER.error("Can't find server level for " + this);
|
ModernFix.LOGGER.error("Can't find server level for " + this);
|
||||||
return;
|
return;
|
||||||
|
|
@ -32,17 +35,17 @@ public class ChunkGeneratorMixin {
|
||||||
List<ChunkPos> positions = cache.getChunkPosList();
|
List<ChunkPos> positions = cache.getChunkPosList();
|
||||||
if(positions.isEmpty())
|
if(positions.isEmpty())
|
||||||
return;
|
return;
|
||||||
ModernFix.LOGGER.debug("Loaded stronghold cache for dimension {} with {} positions", level.dimension().location(), positions.size());
|
ModernFix.LOGGER.debug("Loaded stronghold cache for dimension {} with {} positions", level.dimension.getType().toString(), positions.size());
|
||||||
this.strongholdPositions.addAll(positions);
|
this.strongholdPos = positions.toArray(new ChunkPos[0]);
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ServerLevel searchLevel() {
|
private ServerLevel searchLevel(ChunkGenerator<?> generator) {
|
||||||
MinecraftServer server = ModernFixPlatformHooks.INSTANCE.getCurrentServer();
|
MinecraftServer server = ModernFixPlatformHooks.INSTANCE.getCurrentServer();
|
||||||
if(server != null) {
|
if(server != null) {
|
||||||
ServerLevel ourLevel = null;
|
ServerLevel ourLevel = null;
|
||||||
for (ServerLevel level : server.getAllLevels()) {
|
for (ServerLevel level : server.getAllLevels()) {
|
||||||
if (level.getChunkSource().getGenerator() == ((ChunkGenerator) (Object) this)) {
|
if (level.getChunkSource().getGenerator() == generator) {
|
||||||
ourLevel = level;
|
ourLevel = level;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -52,14 +55,14 @@ public class ChunkGeneratorMixin {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "generateStrongholds", at = @At("TAIL"))
|
@Inject(method = "generatePositions", at = @At("TAIL"))
|
||||||
private void saveCachedData(CallbackInfo ci) {
|
private void saveCachedData(ChunkGenerator<?> generator, CallbackInfo ci) {
|
||||||
if(this.strongholdPositions.size() > 0) {
|
if(this.strongholdPos.length > 0) {
|
||||||
ServerLevel level = searchLevel();
|
ServerLevel level = searchLevel(generator);
|
||||||
if(level != null) {
|
if(level != null) {
|
||||||
StrongholdLocationCache cache = ((IServerLevel)level).mfix$getStrongholdCache();
|
StrongholdLocationCache cache = ((IServerLevel)level).mfix$getStrongholdCache();
|
||||||
cache.setChunkPosList(this.strongholdPositions);
|
cache.setChunkPosList(Arrays.asList(this.strongholdPos));
|
||||||
ModernFix.LOGGER.debug("Saved stronghold cache for dimension {}", level.dimension().location());
|
ModernFix.LOGGER.debug("Saved stronghold cache for dimension {}", level.dimension.getType().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,13 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.cache_strongholds;
|
package org.embeddedt.modernfix.common.mixin.perf.cache_strongholds;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
import net.minecraft.world.level.CustomSpawner;
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
|
import net.minecraft.world.level.dimension.Dimension;
|
||||||
import net.minecraft.world.level.dimension.DimensionType;
|
import net.minecraft.world.level.dimension.DimensionType;
|
||||||
import net.minecraft.world.level.storage.DimensionDataStorage;
|
import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
import net.minecraft.world.level.storage.LevelData;
|
||||||
import net.minecraft.world.level.storage.ServerLevelData;
|
|
||||||
import net.minecraft.world.level.storage.WritableLevelData;
|
|
||||||
import org.embeddedt.modernfix.duck.IServerLevel;
|
import org.embeddedt.modernfix.duck.IServerLevel;
|
||||||
import org.embeddedt.modernfix.world.StrongholdLocationCache;
|
import org.embeddedt.modernfix.world.StrongholdLocationCache;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -21,14 +16,13 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.function.BiFunction;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Mixin(ServerLevel.class)
|
@Mixin(ServerLevel.class)
|
||||||
public abstract class ServerLevelMixin extends Level implements IServerLevel {
|
public abstract class ServerLevelMixin extends Level implements IServerLevel {
|
||||||
protected ServerLevelMixin(WritableLevelData arg, ResourceKey<Level> arg2, DimensionType arg3, Supplier<ProfilerFiller> supplier, boolean bl, boolean bl2, long l) {
|
|
||||||
super(arg, arg2, arg3, supplier, bl, bl2, l);
|
protected ServerLevelMixin(LevelData levelData, DimensionType dimensionType, BiFunction<Level, Dimension, ChunkSource> biFunction, ProfilerFiller profilerFiller, boolean bl) {
|
||||||
|
super(levelData, dimensionType, biFunction, profilerFiller, bl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Shadow public abstract DimensionDataStorage getDataStorage();
|
@Shadow public abstract DimensionDataStorage getDataStorage();
|
||||||
|
|
@ -36,10 +30,8 @@ public abstract class ServerLevelMixin extends Level implements IServerLevel {
|
||||||
private StrongholdLocationCache mfix$strongholdCache;
|
private StrongholdLocationCache mfix$strongholdCache;
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
private void addStrongholdCache(MinecraftServer minecraftServer, Executor executor, LevelStorageSource.LevelStorageAccess arg,
|
private void addStrongholdCache(CallbackInfo ci) {
|
||||||
ServerLevelData arg2, ResourceKey<Level> arg3, DimensionType arg4, ChunkProgressListener arg5,
|
mfix$strongholdCache = this.getDataStorage().computeIfAbsent(() -> new StrongholdLocationCache((ServerLevel)(Object)this), StrongholdLocationCache.getFileId(this.dimension.getType()));
|
||||||
ChunkGenerator arg6, boolean bl, long l, List<CustomSpawner> list, boolean bl2, CallbackInfo ci) {
|
|
||||||
mfix$strongholdCache = this.getDataStorage().computeIfAbsent(() -> new StrongholdLocationCache((ServerLevel)(Object)this), StrongholdLocationCache.getFileId(this.dimensionType()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Lifecycle;
|
|
||||||
import net.minecraft.core.MappedRegistry;
|
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import org.embeddedt.modernfix.annotation.IgnoreOutsideDev;
|
|
||||||
import org.embeddedt.modernfix.registry.LifecycleMap;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Mixin(MappedRegistry.class)
|
|
||||||
@IgnoreOutsideDev
|
|
||||||
public abstract class MappedRegistryMixin<T> extends Registry<T> {
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
@Mutable
|
|
||||||
private Map<T, Lifecycle> lifecycles;
|
|
||||||
|
|
||||||
protected MappedRegistryMixin(ResourceKey<? extends Registry<T>> resourceKey, Lifecycle lifecycle) {
|
|
||||||
super(resourceKey, lifecycle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
|
||||||
private void replaceStorage(CallbackInfo ci) {
|
|
||||||
this.lifecycles = new LifecycleMap<>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,8 +2,8 @@ package org.embeddedt.modernfix.common.mixin.perf.compress_biome_container;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ShortMap;
|
import it.unimi.dsi.fastutil.objects.Reference2ShortMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ShortOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Reference2ShortOpenHashMap;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.util.BitStorage;
|
import net.minecraft.util.BitStorage;
|
||||||
import net.minecraft.core.IdMap;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
|
@ -21,10 +21,6 @@ public class MixinBiomeContainer {
|
||||||
@Final
|
@Final
|
||||||
private Biome[] biomes;
|
private Biome[] biomes;
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private IdMap<Biome> biomeRegistry;
|
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
@Final
|
@Final
|
||||||
private static int WIDTH_BITS;
|
private static int WIDTH_BITS;
|
||||||
|
|
@ -32,23 +28,23 @@ public class MixinBiomeContainer {
|
||||||
private Biome[] palette;
|
private Biome[] palette;
|
||||||
private BitStorage intArray;
|
private BitStorage intArray;
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/core/IdMap;[I)V", at = @At("RETURN"), require = 0)
|
@Inject(method = "<init>(Lnet/minecraft/network/FriendlyByteBuf;)V", at = @At("RETURN"))
|
||||||
private void reinit1(IdMap p_i241970_1_, int[] p_i241970_2_, CallbackInfo ci) {
|
private void reinit1(CallbackInfo ci) {
|
||||||
this.createCompact();
|
this.createCompact();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/core/IdMap;[Lnet/minecraft/world/level/biome/Biome;)V", at = @At("RETURN"))
|
@Inject(method = "<init>([Lnet/minecraft/world/level/biome/Biome;)V", at = @At("RETURN"))
|
||||||
private void reinit2(IdMap p_i241971_1_, Biome[] p_i241971_2_, CallbackInfo ci) {
|
private void reinit2(Biome[] p_i241971_2_, CallbackInfo ci) {
|
||||||
this.createCompact();
|
this.createCompact();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/core/IdMap;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/biome/BiomeSource;)V", at = @At("RETURN"))
|
@Inject(method = "<init>(Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/biome/BiomeSource;)V", at = @At("RETURN"))
|
||||||
private void reinit3(IdMap p_i241968_1_, ChunkPos p_i241968_2_, BiomeSource p_i241968_3_, CallbackInfo ci) {
|
private void reinit3(ChunkPos p_i241968_2_, BiomeSource p_i241968_3_, CallbackInfo ci) {
|
||||||
this.createCompact();
|
this.createCompact();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>(Lnet/minecraft/core/IdMap;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/biome/BiomeSource;[I)V", at = @At("RETURN"))
|
@Inject(method = "<init>(Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/world/level/biome/BiomeSource;[I)V", at = @At("RETURN"))
|
||||||
private void reinit4(IdMap p_i241969_1_, ChunkPos p_i241969_2_, BiomeSource p_i241969_3_, int[] p_i241969_4_, CallbackInfo ci) {
|
private void reinit4(ChunkPos p_i241969_2_, BiomeSource p_i241969_3_, int[] p_i241969_4_, CallbackInfo ci) {
|
||||||
this.createCompact();
|
this.createCompact();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,7 +123,7 @@ public class MixinBiomeContainer {
|
||||||
int[] array = new int[size];
|
int[] array = new int[size];
|
||||||
|
|
||||||
for(int i = 0; i < size; ++i) {
|
for(int i = 0; i < size; ++i) {
|
||||||
array[i] = this.biomeRegistry.getId(this.palette[this.intArray.get(i)]);
|
array[i] = Registry.BIOME.getId(this.palette[this.intArray.get(i)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
|
|
@ -145,4 +141,18 @@ public class MixinBiomeContainer {
|
||||||
|
|
||||||
return this.palette[this.intArray.get(y << WIDTH_BITS + WIDTH_BITS | z << WIDTH_BITS | x)];
|
return this.palette[this.intArray.get(y << WIDTH_BITS + WIDTH_BITS | z << WIDTH_BITS | x)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author embeddedt
|
||||||
|
* @reason Reimplement
|
||||||
|
*/
|
||||||
|
@Overwrite
|
||||||
|
public ChunkBiomeContainer copy() {
|
||||||
|
int size = this.intArray.getSize();
|
||||||
|
Biome[] biomes = new Biome[size];
|
||||||
|
for(int i = 0; i < size; ++i) {
|
||||||
|
biomes[i] = this.palette[this.intArray.get(i)];
|
||||||
|
}
|
||||||
|
return new ChunkBiomeContainer(biomes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import java.util.concurrent.Executor;
|
||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
@ClientOnlyMixin
|
@ClientOnlyMixin
|
||||||
public class MinecraftMixin {
|
public class MinecraftMixin {
|
||||||
@Redirect(method = { "<init>", "makeServerStem", "reloadResourcePacks" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;backgroundExecutor()Ljava/util/concurrent/Executor;", ordinal = 0))
|
@Redirect(method = { "<init>", "reloadResourcePacks" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;backgroundExecutor()Ljava/util/concurrent/Executor;", ordinal = 0))
|
||||||
private Executor getResourceReloadExecutor() {
|
private Executor getResourceReloadExecutor() {
|
||||||
return ModernFix.resourceReloadExecutor();
|
return ModernFix.resourceReloadExecutor();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@Mixin(MinecraftServer.class)
|
@Mixin(MinecraftServer.class)
|
||||||
public class MinecraftServerMixin {
|
public class MinecraftServerMixin {
|
||||||
@ModifyArg(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/ServerResources;loadResources(Ljava/util/List;Lnet/minecraft/commands/Commands$CommandSelection;ILjava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 3)
|
@ModifyArg(method = "updateSelectedPacks", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/resources/ReloadableResourceManager;reload(Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/List;Ljava/util/concurrent/CompletableFuture;)Ljava/util/concurrent/CompletableFuture;"), index = 1)
|
||||||
private Executor getReloadExecutor(Executor asyncExecutor) {
|
private Executor getReloadExecutor(Executor asyncExecutor) {
|
||||||
return ModernFix.resourceReloadExecutor();
|
return ModernFix.resourceReloadExecutor();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.deduplicate_wall_shapes;
|
package org.embeddedt.modernfix.common.mixin.perf.deduplicate_wall_shapes;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.WallBlock;
|
import net.minecraft.world.level.block.CrossCollisionBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.StateDefinition;
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
@ -23,44 +21,33 @@ import java.util.Map;
|
||||||
* same shape instances. To do this we can cache a mapping between a state (represented only as its prop->value map)
|
* same shape instances. To do this we can cache a mapping between a state (represented only as its prop->value map)
|
||||||
* and the desired shape, and generate the BlockState->VoxelShape map from this for each block.
|
* and the desired shape, and generate the BlockState->VoxelShape map from this for each block.
|
||||||
*/
|
*/
|
||||||
@Mixin(WallBlock.class)
|
@Mixin(CrossCollisionBlock.class)
|
||||||
public abstract class WallBlockMixin extends Block {
|
public abstract class WallBlockMixin extends Block {
|
||||||
private static Map<ImmutableList<Float>, Pair<Map<ImmutableMap<Property<?>, Comparable<?>>, VoxelShape>, StateDefinition<Block, BlockState>>> CACHE_BY_SHAPE_VALS = new HashMap<>();
|
private static Map<ImmutableList<Float>, Pair<VoxelShape[], StateDefinition<Block, BlockState>>> CACHE_BY_SHAPE_VALS = new HashMap<>();
|
||||||
|
|
||||||
public WallBlockMixin(Properties properties) {
|
public WallBlockMixin(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "makeShapes", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "makeShapes", at = @At("HEAD"), cancellable = true)
|
||||||
private synchronized void useCachedShapeMap(float f1, float f2, float f3, float f4, float f5, float f6, CallbackInfoReturnable<Map<BlockState, VoxelShape>> cir) {
|
private synchronized void useCachedShapeMap(float f1, float f2, float f3, float f4, float f5, CallbackInfoReturnable<VoxelShape[]> cir) {
|
||||||
ImmutableList<Float> key = ImmutableList.of(f1, f2, f3, f4, f5, f6);
|
ImmutableList<Float> key = ImmutableList.of(f1, f2, f3, f4, f5);
|
||||||
Pair<Map<ImmutableMap<Property<?>, Comparable<?>>, VoxelShape>, StateDefinition<Block, BlockState>> cache = CACHE_BY_SHAPE_VALS.get(key);
|
Pair<VoxelShape[], StateDefinition<Block, BlockState>> cache = CACHE_BY_SHAPE_VALS.get(key);
|
||||||
// require the properties to be identical
|
// require the properties to be identical
|
||||||
if(cache == null || !cache.getSecond().getProperties().equals(this.stateDefinition.getProperties()))
|
if(cache == null || !cache.getSecond().getProperties().equals(this.stateDefinition.getProperties()))
|
||||||
return;
|
return;
|
||||||
ImmutableMap.Builder<BlockState, VoxelShape> builder = ImmutableMap.builder();
|
cir.setReturnValue(cache.getFirst());
|
||||||
for(BlockState state : this.stateDefinition.getPossibleStates()) {
|
|
||||||
VoxelShape shape = cache.getFirst().get(state.getValues());
|
|
||||||
if(shape == null)
|
|
||||||
return; // fallback to vanilla logic
|
|
||||||
builder.put(state, shape);
|
|
||||||
}
|
|
||||||
cir.setReturnValue(builder.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "makeShapes", at = @At("RETURN"))
|
@Inject(method = "makeShapes", at = @At("RETURN"))
|
||||||
private synchronized void storeCachedShapesByProperty(float f1, float f2, float f3, float f4, float f5, float f6, CallbackInfoReturnable<Map<BlockState, VoxelShape>> cir) {
|
private synchronized void storeCachedShapesByProperty(float f1, float f2, float f3, float f4, float f5, CallbackInfoReturnable<VoxelShape[]> cir) {
|
||||||
// never populate cache as a non-vanilla block
|
// never populate cache as a non-vanilla block
|
||||||
if((Class<?>)this.getClass() != WallBlock.class)
|
//if((Class<?>)this.getClass() != WallBlock.class)
|
||||||
return;
|
// return;
|
||||||
ImmutableList<Float> key = ImmutableList.of(f1, f2, f3, f4, f5, f6);
|
ImmutableList<Float> key = ImmutableList.of(f1, f2, f3, f4, f5);
|
||||||
if(!CACHE_BY_SHAPE_VALS.containsKey(key)) {
|
if(!CACHE_BY_SHAPE_VALS.containsKey(key)) {
|
||||||
Map<ImmutableMap<Property<?>, Comparable<?>>, VoxelShape> cacheByProperties = new HashMap<>();
|
VoxelShape[] shapes = cir.getReturnValue();
|
||||||
Map<BlockState, VoxelShape> shapeMap = cir.getReturnValue();
|
CACHE_BY_SHAPE_VALS.put(key, Pair.of(shapes, this.stateDefinition));
|
||||||
for(Map.Entry<BlockState, VoxelShape> entry : shapeMap.entrySet()) {
|
|
||||||
cacheByProperties.put(entry.getKey().getValues(), entry.getValue());
|
|
||||||
}
|
|
||||||
CACHE_BY_SHAPE_VALS.put(key, Pair.of(cacheByProperties, this.stateDefinition));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_dfu;
|
|
||||||
|
|
||||||
import com.mojang.datafixers.DSL;
|
|
||||||
import com.mojang.datafixers.types.Type;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent fetchChoiceType calls from loading DFU early. Vanilla doesn't need the return values here.
|
|
||||||
*/
|
|
||||||
@Mixin(BlockEntityType.class)
|
|
||||||
public class BlockEntityTypeMixin {
|
|
||||||
@Redirect(method = "register", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;fetchChoiceType(Lcom/mojang/datafixers/DSL$TypeReference;Ljava/lang/String;)Lcom/mojang/datafixers/types/Type;"))
|
|
||||||
private static Type<?> skipSchemaCheck(DSL.TypeReference ref, String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_dfu;
|
|
||||||
|
|
||||||
import com.mojang.datafixers.DataFixer;
|
|
||||||
import net.minecraft.util.datafix.DataFixers;
|
|
||||||
import org.embeddedt.modernfix.dfu.LazyDataFixer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
@Mixin(DataFixers.class)
|
|
||||||
public abstract class DataFixersMixin {
|
|
||||||
@Shadow protected static DataFixer createFixerUpper() {
|
|
||||||
throw new AssertionError();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static LazyDataFixer lazyDataFixer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Avoid classloading the DFU logic until we actually need it.
|
|
||||||
*/
|
|
||||||
@Inject(method = "createFixerUpper", at = @At("HEAD"), cancellable = true)
|
|
||||||
private static void createLazyFixerUpper(CallbackInfoReturnable<DataFixer> cir) {
|
|
||||||
if(lazyDataFixer == null) {
|
|
||||||
lazyDataFixer = new LazyDataFixer(DataFixersMixin::createFixerUpper);
|
|
||||||
cir.setReturnValue(lazyDataFixer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_dfu;
|
|
||||||
|
|
||||||
import com.mojang.datafixers.DSL;
|
|
||||||
import com.mojang.datafixers.types.Type;
|
|
||||||
import net.minecraft.world.entity.EntityType;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent fetchChoiceType calls from loading DFU early. Vanilla doesn't need the return values here.
|
|
||||||
*/
|
|
||||||
@Mixin(EntityType.Builder.class)
|
|
||||||
public class EntityTypeBuilderMixin {
|
|
||||||
@Redirect(method = "build", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;fetchChoiceType(Lcom/mojang/datafixers/DSL$TypeReference;Ljava/lang/String;)Lcom/mojang/datafixers/types/Type;"))
|
|
||||||
private Type<?> skipSchemaCheck(DSL.TypeReference ref, String s) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,12 +2,9 @@ package org.embeddedt.modernfix.common.mixin.perf.dynamic_structure_manager;
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.mojang.datafixers.DataFixer;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
|
|
@ -24,7 +21,7 @@ public class StructureManagerMixin {
|
||||||
private Map<ResourceLocation, StructureTemplate> structureRepository;
|
private Map<ResourceLocation, StructureTemplate> structureRepository;
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
private void makeStructuresSafe(ResourceManager arg, LevelStorageSource.LevelStorageAccess arg2, DataFixer dataFixer, CallbackInfo ci) {
|
private void makeStructuresSafe(CallbackInfo ci) {
|
||||||
/* Structures needing to be reloaded is not a huge issue since we optimize loading them already */
|
/* Structures needing to be reloaded is not a huge issue since we optimize loading them already */
|
||||||
Cache<ResourceLocation, StructureTemplate> structureCache = CacheBuilder.newBuilder()
|
Cache<ResourceLocation, StructureTemplate> structureCache = CacheBuilder.newBuilder()
|
||||||
.softValues()
|
.softValues()
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,15 @@ import java.util.Map;
|
||||||
@Mixin(LegacyUnicodeBitmapsProvider.class)
|
@Mixin(LegacyUnicodeBitmapsProvider.class)
|
||||||
@ClientOnlyMixin
|
@ClientOnlyMixin
|
||||||
public abstract class LegacyUnicodeBitmapsProviderMixin {
|
public abstract class LegacyUnicodeBitmapsProviderMixin {
|
||||||
@Shadow protected abstract ResourceLocation getSheetLocation(int i);
|
@Shadow protected abstract ResourceLocation getSheetLocation(char i);
|
||||||
|
|
||||||
@Shadow @Final private Map<ResourceLocation, NativeImage> textures;
|
@Shadow @Final private Map<ResourceLocation, NativeImage> textures;
|
||||||
private final ResourceLocation[] glyphLocations = new ResourceLocation[256];
|
private final ResourceLocation[] glyphLocations = new ResourceLocation[256];
|
||||||
|
|
||||||
private ResourceLocation currentCharIdx;
|
private ResourceLocation currentCharIdx;
|
||||||
|
|
||||||
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/font/providers/LegacyUnicodeBitmapsProvider;getSheetLocation(I)Lnet/minecraft/resources/ResourceLocation;"))
|
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/font/providers/LegacyUnicodeBitmapsProvider;getSheetLocation(C)Lnet/minecraft/resources/ResourceLocation;"))
|
||||||
private ResourceLocation storeCurrentCharIdx(LegacyUnicodeBitmapsProvider provider, int i) {
|
private ResourceLocation storeCurrentCharIdx(LegacyUnicodeBitmapsProvider provider, char i) {
|
||||||
ResourceLocation location = getSheetLocation(i);
|
ResourceLocation location = getSheetLocation(i);
|
||||||
currentCharIdx = location;
|
currentCharIdx = location;
|
||||||
return location;
|
return location;
|
||||||
|
|
@ -56,15 +56,15 @@ public abstract class LegacyUnicodeBitmapsProviderMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "getSheetLocation", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "getSheetLocation", at = @At("HEAD"), cancellable = true)
|
||||||
private void useCachedLocation(int idx, CallbackInfoReturnable<ResourceLocation> cir) {
|
private void useCachedLocation(char idx, CallbackInfoReturnable<ResourceLocation> cir) {
|
||||||
int cachedIdx = idx / 256;
|
char cachedIdx = (char)(idx / 256);
|
||||||
if(cachedIdx >= 0 && cachedIdx < glyphLocations.length && glyphLocations[cachedIdx] != null)
|
if(cachedIdx >= 0 && cachedIdx < glyphLocations.length && glyphLocations[cachedIdx] != null)
|
||||||
cir.setReturnValue(glyphLocations[cachedIdx]);
|
cir.setReturnValue(glyphLocations[cachedIdx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "getSheetLocation", at = @At("RETURN"))
|
@Inject(method = "getSheetLocation", at = @At("RETURN"))
|
||||||
private void saveCachedLocation(int idx, CallbackInfoReturnable<ResourceLocation> cir) {
|
private void saveCachedLocation(char idx, CallbackInfoReturnable<ResourceLocation> cir) {
|
||||||
int cachedIdx = idx / 256;
|
char cachedIdx = (char)(idx / 256);
|
||||||
if(cachedIdx >= 0 && cachedIdx < glyphLocations.length)
|
if(cachedIdx >= 0 && cachedIdx < glyphLocations.length)
|
||||||
glyphLocations[cachedIdx] = cir.getReturnValue();
|
glyphLocations[cachedIdx] = cir.getReturnValue();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.model_optimizations;
|
package org.embeddedt.modernfix.common.mixin.perf.model_optimizations;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
import net.minecraft.world.level.block.state.properties.AbstractProperty;
|
||||||
import org.embeddedt.modernfix.dedup.IdentifierCaches;
|
import org.embeddedt.modernfix.dedup.IdentifierCaches;
|
||||||
import org.spongepowered.asm.mixin.*;
|
import org.spongepowered.asm.mixin.*;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
@Mixin(Property.class)
|
@Mixin(AbstractProperty.class)
|
||||||
public class PropertyMixin {
|
public class PropertyMixin {
|
||||||
|
|
||||||
@Shadow @Mutable
|
@Shadow @Mutable
|
||||||
|
|
@ -16,8 +16,8 @@ public class PropertyMixin {
|
||||||
|
|
||||||
@Shadow @Final private Class clazz;
|
@Shadow @Final private Class clazz;
|
||||||
|
|
||||||
@Redirect(method = "<init>", at = @At(value = "FIELD", target = "Lnet/minecraft/world/level/block/state/properties/Property;name:Ljava/lang/String;"))
|
@Redirect(method = "<init>", at = @At(value = "FIELD", target = "Lnet/minecraft/world/level/block/state/properties/AbstractProperty;name:Ljava/lang/String;"))
|
||||||
private void internName(Property instance, String name) {
|
private void internName(AbstractProperty<?> instance, String name) {
|
||||||
this.name = IdentifierCaches.PROPERTY.deduplicate(name);
|
this.name = IdentifierCaches.PROPERTY.deduplicate(name);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
@ -28,10 +28,10 @@ public class PropertyMixin {
|
||||||
public boolean equals(Object p_equals_1_) {
|
public boolean equals(Object p_equals_1_) {
|
||||||
if (this == p_equals_1_) {
|
if (this == p_equals_1_) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!(p_equals_1_ instanceof Property)) {
|
} else if (!(p_equals_1_ instanceof AbstractProperty<?>)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
Property<?> property = (Property)p_equals_1_;
|
AbstractProperty<?> property = (AbstractProperty<?>)p_equals_1_;
|
||||||
/* reference equality is safe here because of deduplication */
|
/* reference equality is safe here because of deduplication */
|
||||||
return this.clazz == property.getValueClass() && this.name == property.getName();
|
return this.clazz == property.getValueClass() && this.name == property.getName();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectList;
|
|
||||||
import net.minecraft.core.MappedRegistry;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(MappedRegistry.class)
|
|
||||||
public class MappedRegistryMixin {
|
|
||||||
/**
|
|
||||||
* Avoid copying the ID list to a slightly larger one every time an entry is added to the registry.
|
|
||||||
* The original behavior causes O(n) time complexity for registration.
|
|
||||||
*/
|
|
||||||
@Redirect(
|
|
||||||
method = "registerMapping(ILnet/minecraft/resources/ResourceKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Ljava/lang/Object;",
|
|
||||||
at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectList;size(I)V", remap = false)
|
|
||||||
)
|
|
||||||
private void setSizeSmart(ObjectList<?> list, int size) {
|
|
||||||
if(list instanceof ObjectArrayList && size > list.size()) {
|
|
||||||
int requestedSize = size;
|
|
||||||
/* choose next power of two, or this value if it is a power of two */
|
|
||||||
int p2Size = Integer.highestOneBit(size);
|
|
||||||
if(p2Size != size)
|
|
||||||
size = p2Size << 1;
|
|
||||||
// grow backing array to power-of-two size, this will return instantly in most cases
|
|
||||||
((ObjectArrayList<?>)list).ensureCapacity(size);
|
|
||||||
// write null entries to fill size, to match the behavior of list.size(int)
|
|
||||||
while(list.size() < requestedSize)
|
|
||||||
list.add(null);
|
|
||||||
} else {
|
|
||||||
list.size(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Mixin(ResourceKey.class)
|
|
||||||
public class ResourceKeyMixin<T> {
|
|
||||||
private static final Map<ResourceLocation, Map<ResourceLocation, ResourceKey<?>>> INTERNING_MAP = new Object2ObjectOpenHashMap<>();
|
|
||||||
@Inject(method = "create(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/resources/ResourceKey;", at = @At("HEAD"), cancellable = true)
|
|
||||||
private static <T> void createEfficient(ResourceLocation parent, ResourceLocation location, CallbackInfoReturnable<ResourceKey<T>> cir) {
|
|
||||||
synchronized (ResourceKey.class) {
|
|
||||||
Map<ResourceLocation, ResourceKey<?>> keys = INTERNING_MAP.computeIfAbsent(parent, k -> new Object2ObjectOpenHashMap<>());
|
|
||||||
ResourceKey<?> key = keys.get(location);
|
|
||||||
if(key == null) {
|
|
||||||
key = new ResourceKey<>(parent, location);
|
|
||||||
keys.put(location, key);
|
|
||||||
}
|
|
||||||
cir.setReturnValue((ResourceKey<T>)key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@ import com.google.common.collect.ArrayTable;
|
||||||
import com.google.common.collect.HashBasedTable;
|
import com.google.common.collect.HashBasedTable;
|
||||||
import com.google.common.collect.ImmutableTable;
|
import com.google.common.collect.ImmutableTable;
|
||||||
import com.google.common.collect.Table;
|
import com.google.common.collect.Table;
|
||||||
import net.minecraft.world.level.block.state.StateHolder;
|
import net.minecraft.world.level.block.state.AbstractStateHolder;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
import org.embeddedt.modernfix.annotation.RequiresMod;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -17,7 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
* Minor mixin to avoid duplicate empty neighbor tables, used when FerriteCore is not present. Won't be enabled in 99% of
|
* Minor mixin to avoid duplicate empty neighbor tables, used when FerriteCore is not present. Won't be enabled in 99% of
|
||||||
* modded environments but is useful for testing in dev without dragging in Fabric API.
|
* modded environments but is useful for testing in dev without dragging in Fabric API.
|
||||||
*/
|
*/
|
||||||
@Mixin(StateHolder.class)
|
@Mixin(AbstractStateHolder.class)
|
||||||
@RequiresMod("!ferritecore")
|
@RequiresMod("!ferritecore")
|
||||||
public class StateHolderMixin {
|
public class StateHolderMixin {
|
||||||
@Shadow private Table<Property<?>, Comparable<?>, ?> neighbours;
|
@Shadow private Table<Property<?>, Comparable<?>, ?> neighbours;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuilds;
|
package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuilds;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.embeddedt.modernfix.duck.IBlockState;
|
import org.embeddedt.modernfix.duck.IBlockState;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -9,11 +9,11 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
|
||||||
@Mixin(BlockBehaviour.BlockStateBase.class)
|
@Mixin(BlockState.class)
|
||||||
public abstract class BlockStateBaseMixin implements IBlockState {
|
public abstract class BlockStateBaseMixin implements IBlockState {
|
||||||
@Shadow public abstract void initCache();
|
@Shadow public abstract void initCache();
|
||||||
|
|
||||||
@Shadow private BlockBehaviour.BlockStateBase.Cache cache;
|
@Shadow private BlockState.Cache cache;
|
||||||
|
|
||||||
private volatile boolean cacheInvalid = false;
|
private volatile boolean cacheInvalid = false;
|
||||||
private static boolean buildingCache = false;
|
private static boolean buildingCache = false;
|
||||||
|
|
@ -30,7 +30,7 @@ public abstract class BlockStateBaseMixin implements IBlockState {
|
||||||
private void mfix$generateCache() {
|
private void mfix$generateCache() {
|
||||||
if(cacheInvalid) {
|
if(cacheInvalid) {
|
||||||
// Ensure that only one block's cache is built at a time
|
// Ensure that only one block's cache is built at a time
|
||||||
synchronized (BlockBehaviour.BlockStateBase.class) {
|
synchronized (BlockState.class) {
|
||||||
if(cacheInvalid) {
|
if(cacheInvalid) {
|
||||||
// Ensure that if we end up in here recursively, we just use the original cache
|
// Ensure that if we end up in here recursively, we just use the original cache
|
||||||
if(!buildingCache) {
|
if(!buildingCache) {
|
||||||
|
|
@ -51,10 +51,10 @@ public abstract class BlockStateBaseMixin implements IBlockState {
|
||||||
@Redirect(method = "*", at = @At(
|
@Redirect(method = "*", at = @At(
|
||||||
value = "FIELD",
|
value = "FIELD",
|
||||||
opcode = Opcodes.GETFIELD,
|
opcode = Opcodes.GETFIELD,
|
||||||
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;cache:Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase$Cache;",
|
target = "Lnet/minecraft/world/level/block/state/BlockState;cache:Lnet/minecraft/world/level/block/state/BlockState$Cache;",
|
||||||
ordinal = 0
|
ordinal = 0
|
||||||
))
|
))
|
||||||
private BlockBehaviour.BlockStateBase.Cache dynamicCacheGen(BlockBehaviour.BlockStateBase base) {
|
private BlockState.Cache dynamicCacheGen(BlockState base) {
|
||||||
mfix$generateCache();
|
mfix$generateCache();
|
||||||
return this.cache;
|
return this.cache;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuilds;
|
package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuilds;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.embeddedt.modernfix.blockstate.BlockStateCacheHandler;
|
import org.embeddedt.modernfix.blockstate.BlockStateCacheHandler;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
|
@ -8,10 +8,10 @@ import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
@Mixin(value = Blocks.class, priority = 1100)
|
@Mixin(value = MinecraftServer.class, priority = 1100)
|
||||||
public class BlocksMixin {
|
public class BlocksMixin {
|
||||||
@ModifyArg(method = "rebuildCache", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/IdMapper;forEach(Ljava/util/function/Consumer;)V"), index = 0)
|
@ModifyArg(method = "refreshRegistries", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/IdMapper;forEach(Ljava/util/function/Consumer;)V"), index = 0)
|
||||||
private static Consumer getEmptyConsumer(Consumer original) {
|
private Consumer getEmptyConsumer(Consumer original) {
|
||||||
BlockStateCacheHandler.rebuildParallel(true);
|
BlockStateCacheHandler.rebuildParallel(true);
|
||||||
return o -> {};
|
return o -> {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||||
/* Idea from Lithium for 1.19.3 */
|
/* Idea from Lithium for 1.19.3 */
|
||||||
@Mixin(Biome.class)
|
@Mixin(Biome.class)
|
||||||
public abstract class BiomeMixin {
|
public abstract class BiomeMixin {
|
||||||
@Shadow protected abstract float getHeightAdjustedTemperature(BlockPos pos);
|
@Shadow protected abstract float getTemperatureNoCache(BlockPos pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author 2No2Name
|
* @author 2No2Name
|
||||||
|
|
@ -19,6 +19,6 @@ public abstract class BiomeMixin {
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public final float getTemperature(BlockPos pos) {
|
public final float getTemperature(BlockPos pos) {
|
||||||
return this.getHeightAdjustedTemperature(pos);
|
return this.getTemperatureNoCache(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.TicketType;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
|
||||||
public class EntityMixin {
|
|
||||||
/**
|
|
||||||
* @author embeddedt
|
|
||||||
* @reason If the spawn chunks are not loaded, end portals linking to the overworld will teleport entities into
|
|
||||||
* the void at the spawn position, which is not ideal. To solve this, we create a PORTAL ticket if the expected
|
|
||||||
* overworld chunk is missing.
|
|
||||||
*/
|
|
||||||
@ModifyExpressionValue(method = "findDimensionEntryPoint", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getSharedSpawnPos()Lnet/minecraft/core/BlockPos;"), require = 0)
|
|
||||||
private BlockPos mfix$triggerChunkloadAtSpawnPos(BlockPos spawnPos, ServerLevel destination) {
|
|
||||||
// Only apply this change if the overworld is the destination
|
|
||||||
if (destination.dimension() == ServerLevel.OVERWORLD) {
|
|
||||||
// No ticket is required if the chunk happens to already be loaded
|
|
||||||
if(!destination.hasChunk(spawnPos.getX() >> 4, spawnPos.getZ() >> 4)) {
|
|
||||||
// Create a portal ticket. While we could just load the chunk once, it would immediately unload on the
|
|
||||||
// next tick, causing churn. The ticket will keep it loaded for a few seconds which should give high
|
|
||||||
// performance for farms pumping things through portals frequently.
|
|
||||||
BlockPos key = spawnPos.immutable();
|
|
||||||
destination.getChunkSource().addRegionTicket(TicketType.PORTAL, new ChunkPos(key), 3, key);
|
|
||||||
// Wait for the chunk to be loaded, as adding the ticket is asynchronous
|
|
||||||
destination.getChunk(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return spawnPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
|
||||||
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
|
||||||
import net.minecraft.server.level.TicketType;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(value = MinecraftServer.class, priority = 1100)
|
|
||||||
public class MinecraftServerMixin {
|
|
||||||
@Redirect(method = "prepareLevels", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;addRegionTicket(Lnet/minecraft/server/level/TicketType;Lnet/minecraft/world/level/ChunkPos;ILjava/lang/Object;)V"))
|
|
||||||
private void addSpawnChunkTicket(ServerChunkCache cache, TicketType<?> type, ChunkPos pos, int distance, Object o) {
|
|
||||||
// load first chunk
|
|
||||||
cache.getChunk(pos.x, pos.z, ChunkStatus.FULL, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "prepareLevels", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;getTickingGenerated()I"), require = 0)
|
|
||||||
private int getGenerated(ServerChunkCache cache) {
|
|
||||||
return 441;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
|
||||||
|
|
||||||
import net.minecraft.server.level.DistanceManager;
|
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
@Mixin(ServerChunkCache.class)
|
|
||||||
public interface ServerChunkCacheAccessor {
|
|
||||||
@Accessor("distanceManager")
|
|
||||||
DistanceManager getDistanceManager();
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
|
||||||
|
|
||||||
import net.minecraft.server.level.ServerChunkCache;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.TicketType;
|
|
||||||
import net.minecraft.world.level.ChunkPos;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(ServerLevel.class)
|
|
||||||
public class ServerLevelMixin {
|
|
||||||
@Redirect(method = "setDefaultSpawnPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;removeRegionTicket(Lnet/minecraft/server/level/TicketType;Lnet/minecraft/world/level/ChunkPos;ILjava/lang/Object;)V"))
|
|
||||||
private void removeTicket(ServerChunkCache cache, TicketType<?> type, ChunkPos pos, int distance, Object o) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "setDefaultSpawnPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;addRegionTicket(Lnet/minecraft/server/level/TicketType;Lnet/minecraft/world/level/ChunkPos;ILjava/lang/Object;)V"))
|
|
||||||
private void addTicket(ServerChunkCache cache, TicketType<?> type, ChunkPos pos, int distance, Object o) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
|
||||||
import net.minecraft.util.SortedArraySet;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
|
|
||||||
@Mixin(SortedArraySet.class)
|
|
||||||
public class SortedArraySetMixin<T> {
|
|
||||||
/**
|
|
||||||
* @author embeddedt
|
|
||||||
* @reason Make add() not crash with a null key, since some mods (Carpet) assume there will always be a spawn ticket,
|
|
||||||
* and then assume the reference they have is non-null (it can be null with this option enabled).
|
|
||||||
*/
|
|
||||||
@WrapOperation(method = "add", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/SortedArraySet;findIndex(Ljava/lang/Object;)I"), require = 0)
|
|
||||||
private int checkStatus(SortedArraySet<T> instance, T object, Operation<Integer> original) {
|
|
||||||
if(object == null) {
|
|
||||||
ModernFix.LOGGER.error("Attempted to insert a null key into SortedArraySet, ignoring");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return original.call(instance, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.reuse_datapacks;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.commands.Commands;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.ServerResources;
|
|
||||||
import net.minecraft.server.packs.PackResources;
|
|
||||||
import net.minecraft.server.packs.repository.Pack;
|
|
||||||
import net.minecraft.server.packs.repository.PackRepository;
|
|
||||||
import net.minecraft.world.level.DataPackConfig;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.embeddedt.modernfix.duck.reuse_datapacks.ICachingResourceClient;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
@Mixin(Minecraft.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public abstract class MinecraftMixin implements ICachingResourceClient {
|
|
||||||
@Shadow public abstract boolean isLocalServer();
|
|
||||||
|
|
||||||
private ServerResources cachedResources;
|
|
||||||
private List<String> cachedDataPackConfig;
|
|
||||||
|
|
||||||
private List<String> loadingDataPackConfig;
|
|
||||||
|
|
||||||
@Redirect(method = "makeServerStem", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;configurePackRepository(Lnet/minecraft/server/packs/repository/PackRepository;Lnet/minecraft/world/level/DataPackConfig;Z)Lnet/minecraft/world/level/DataPackConfig;"))
|
|
||||||
private DataPackConfig saveLoadingConfig(PackRepository repo, DataPackConfig inCodec, boolean vanillaOnly) {
|
|
||||||
DataPackConfig config = MinecraftServer.configurePackRepository(repo, inCodec, vanillaOnly);
|
|
||||||
loadingDataPackConfig = repo.getSelectedPacks().stream().map(Pack::getId).collect(ImmutableList.toImmutableList());
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "makeServerStem", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/ServerResources;loadResources(Ljava/util/List;Lnet/minecraft/commands/Commands$CommandSelection;ILjava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"))
|
|
||||||
private CompletableFuture<ServerResources> useCachedResources(List<PackResources> list, Commands.CommandSelection arg, int i, Executor executor, Executor executor2) {
|
|
||||||
if(cachedResources != null) {
|
|
||||||
if(cachedResources.getResourceManager().getNamespaces().size() > 0) {
|
|
||||||
if (cachedDataPackConfig.equals(loadingDataPackConfig)) {
|
|
||||||
ModernFix.LOGGER.warn("Reusing loaded server resources from previous world");
|
|
||||||
return CompletableFuture.completedFuture(cachedResources);
|
|
||||||
} else {
|
|
||||||
ModernFix.LOGGER.warn("Discarding cached server resources, datapack configs have changed");
|
|
||||||
ModernFix.LOGGER.warn("Old: {}", "[" + String.join(", ", cachedDataPackConfig) + "]");
|
|
||||||
ModernFix.LOGGER.warn("New: {}", "[" + String.join(", ", loadingDataPackConfig) + "]");
|
|
||||||
cachedResources.close();
|
|
||||||
cachedResources = null;
|
|
||||||
cachedDataPackConfig = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ModernFix.LOGGER.error("Cached server resources were closed somehow, that shouldn't happen");
|
|
||||||
cachedResources = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ServerResources.loadResources(list, arg, i, executor, executor2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCachedResources(ServerResources r) {
|
|
||||||
cachedResources = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCachedDataPackConfig(Collection<String> c) {
|
|
||||||
cachedDataPackConfig = ImmutableList.copyOf(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "setLevel", at = @At("HEAD"))
|
|
||||||
private void clearResourcesIfNotLocal(CallbackInfo ci) {
|
|
||||||
if(!this.isLocalServer())
|
|
||||||
cachedResources = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.reuse_datapacks;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.ServerResources;
|
|
||||||
import net.minecraft.server.packs.repository.Pack;
|
|
||||||
import net.minecraft.server.packs.repository.PackRepository;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.embeddedt.modernfix.duck.reuse_datapacks.ICachingResourceClient;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(MinecraftServer.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public class MinecraftServerMixin {
|
|
||||||
|
|
||||||
@Shadow @Final private PackRepository packRepository;
|
|
||||||
|
|
||||||
@Redirect(method = "stopServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/ServerResources;close()V"))
|
|
||||||
private void saveResources(ServerResources resources) {
|
|
||||||
ICachingResourceClient client = ((ICachingResourceClient) Minecraft.getInstance());
|
|
||||||
client.setCachedDataPackConfig(this.packRepository.getSelectedPacks().stream().map(Pack::getId).collect(ImmutableList.toImmutableList()));
|
|
||||||
client.setCachedResources(resources);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -16,7 +16,7 @@ import java.util.Map;
|
||||||
|
|
||||||
@Mixin(StateDefinition.class)
|
@Mixin(StateDefinition.class)
|
||||||
@RequiresMod("ferritecore")
|
@RequiresMod("ferritecore")
|
||||||
public class StateDefinitionMixin<O, S extends StateHolder<O, S>> {
|
public class StateDefinitionMixin<O, S extends StateHolder<S>> {
|
||||||
@Shadow @Final private ImmutableSortedMap<String, Property<?>> propertiesByName;
|
@Shadow @Final private ImmutableSortedMap<String, Property<?>> propertiesByName;
|
||||||
|
|
||||||
@ModifyVariable(method = "<init>", at = @At(value = "STORE", ordinal = 0), ordinal = 1, index = 8)
|
@ModifyVariable(method = "<init>", at = @At(value = "STORE", ordinal = 0), ordinal = 1, index = 8)
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,32 @@ package org.embeddedt.modernfix.common.mixin.perf.thread_priorities;
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfileRepository;
|
import com.mojang.authlib.GameProfileRepository;
|
||||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||||
import net.minecraft.client.Minecraft;
|
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||||
import net.minecraft.server.ServerResources;
|
import com.mojang.datafixers.DataFixer;
|
||||||
import net.minecraft.server.packs.repository.PackRepository;
|
|
||||||
import net.minecraft.client.server.IntegratedServer;
|
import net.minecraft.client.server.IntegratedServer;
|
||||||
import net.minecraft.server.players.GameProfileCache;
|
import net.minecraft.commands.Commands;
|
||||||
import net.minecraft.core.RegistryAccess;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
|
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
|
||||||
import net.minecraft.world.level.storage.WorldData;
|
import net.minecraft.server.players.GameProfileCache;
|
||||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.Proxy;
|
||||||
|
|
||||||
@Mixin(IntegratedServer.class)
|
@Mixin(IntegratedServer.class)
|
||||||
@ClientOnlyMixin
|
@ClientOnlyMixin
|
||||||
public class IntegratedServerMixin {
|
public abstract class IntegratedServerMixin extends MinecraftServer {
|
||||||
|
public IntegratedServerMixin(File file, Proxy proxy, DataFixer dataFixer, Commands commands, YggdrasilAuthenticationService yggdrasilAuthenticationService, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache gameProfileCache, ChunkProgressListenerFactory chunkProgressListenerFactory, String string) {
|
||||||
|
super(file, proxy, dataFixer, commands, yggdrasilAuthenticationService, minecraftSessionService, gameProfileRepository, gameProfileCache, chunkProgressListenerFactory, string);
|
||||||
|
}
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
private void adjustServerPriority(Thread pServerThread, Minecraft pMinecraft, RegistryAccess.RegistryHolder pRegistryHolder, LevelStorageSource.LevelStorageAccess pStorageSource, PackRepository pPackRepository, ServerResources pResources, WorldData pWorldData, MinecraftSessionService pSessionService, GameProfileRepository pProfileRepository, GameProfileCache pProfileCache, ChunkProgressListenerFactory pProgressListenerfactory, CallbackInfo ci) {
|
private void adjustServerPriority(CallbackInfo ci) {
|
||||||
int pri = 4; //ModernFixConfig.INTEGRATED_SERVER_PRIORITY.get();
|
int pri = 4; //ModernFixConfig.INTEGRATED_SERVER_PRIORITY.get();
|
||||||
pServerThread.setPriority(pri);
|
this.serverThread.setPriority(pri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import java.util.concurrent.ForkJoinWorkerThread;
|
||||||
|
|
||||||
@Mixin(Util.class)
|
@Mixin(Util.class)
|
||||||
public class UtilMixin {
|
public class UtilMixin {
|
||||||
@ModifyArg(method = "makeExecutor", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/ForkJoinPool;<init>(ILjava/util/concurrent/ForkJoinPool$ForkJoinWorkerThreadFactory;Ljava/lang/Thread$UncaughtExceptionHandler;Z)V"), index = 1)
|
@ModifyArg(method = "makeBackgroundExecutor", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/ForkJoinPool;<init>(ILjava/util/concurrent/ForkJoinPool$ForkJoinWorkerThreadFactory;Ljava/lang/Thread$UncaughtExceptionHandler;Z)V"), index = 1)
|
||||||
private static ForkJoinPool.ForkJoinWorkerThreadFactory adjustPriorityOfThreadFactory(ForkJoinPool.ForkJoinWorkerThreadFactory factory) {
|
private static ForkJoinPool.ForkJoinWorkerThreadFactory adjustPriorityOfThreadFactory(ForkJoinPool.ForkJoinWorkerThreadFactory factory) {
|
||||||
return pool -> {
|
return pool -> {
|
||||||
ForkJoinWorkerThread thread = factory.newThread(pool);
|
ForkJoinWorkerThread thread = factory.newThread(pool);
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.safety;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.item.ItemProperties;
|
|
||||||
import net.minecraft.client.renderer.item.ItemPropertyFunction;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.Item;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Mixin(value = ItemProperties.class, priority = 700)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public class ItemPropertiesMixin {
|
|
||||||
@Shadow @Final @Mutable private static Map<ResourceLocation, ItemPropertyFunction> GENERIC_PROPERTIES;
|
|
||||||
@Shadow @Final @Mutable private static Map<Item, Map<ResourceLocation, ItemPropertyFunction>> PROPERTIES;
|
|
||||||
|
|
||||||
@Inject(method = "<clinit>", at = @At("RETURN"))
|
|
||||||
private static void useConcurrentMaps(CallbackInfo ci) {
|
|
||||||
GENERIC_PROPERTIES = Collections.synchronizedMap(GENERIC_PROPERTIES);
|
|
||||||
PROPERTIES = Collections.synchronizedMap(PROPERTIES);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -182,7 +182,7 @@ public class ModernFixEarlyConfig {
|
||||||
.put("mixin.feature.spark_profile_launch", false)
|
.put("mixin.feature.spark_profile_launch", false)
|
||||||
.put("mixin.perf.blast_search_trees", shouldReplaceSearchTrees)
|
.put("mixin.perf.blast_search_trees", shouldReplaceSearchTrees)
|
||||||
.put("mixin.devenv", isDevEnv)
|
.put("mixin.devenv", isDevEnv)
|
||||||
.put("mixin.perf.remove_spawn_chunks", isDevEnv)
|
.put("mixin.perf.remove_spawn_chunks", false)
|
||||||
.putConditionally(() -> !isFabric, "mixin.bugfix.fix_config_crashes", true)
|
.putConditionally(() -> !isFabric, "mixin.bugfix.fix_config_crashes", true)
|
||||||
.putConditionally(() -> isFabric, "mixin.perf.clear_fabric_mapping_tables", false)
|
.putConditionally(() -> isFabric, "mixin.perf.clear_fabric_mapping_tables", false)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package org.embeddedt.modernfix.dfu;
|
||||||
|
|
||||||
import com.mojang.datafixers.DSL;
|
import com.mojang.datafixers.DSL;
|
||||||
import com.mojang.datafixers.DataFixer;
|
import com.mojang.datafixers.DataFixer;
|
||||||
|
import com.mojang.datafixers.Dynamic;
|
||||||
import com.mojang.datafixers.schemas.Schema;
|
import com.mojang.datafixers.schemas.Schema;
|
||||||
import com.mojang.serialization.Dynamic;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
package org.embeddedt.modernfix.duck.reuse_datapacks;
|
|
||||||
|
|
||||||
import net.minecraft.server.ServerResources;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public interface ICachingResourceClient {
|
|
||||||
void setCachedResources(ServerResources r);
|
|
||||||
void setCachedDataPackConfig(Collection<String> c);
|
|
||||||
}
|
|
||||||
|
|
@ -14,7 +14,7 @@ import it.unimi.dsi.fastutil.objects.ReferenceSet;
|
||||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
import net.minecraft.client.resources.model.*;
|
import net.minecraft.client.resources.model.*;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.packs.PackResources;
|
import net.minecraft.server.packs.Pack;
|
||||||
import net.minecraft.server.packs.PackType;
|
import net.minecraft.server.packs.PackType;
|
||||||
import net.minecraft.server.packs.resources.FallbackResourceManager;
|
import net.minecraft.server.packs.resources.FallbackResourceManager;
|
||||||
import net.minecraft.server.packs.resources.Resource;
|
import net.minecraft.server.packs.resources.Resource;
|
||||||
|
|
@ -90,8 +90,8 @@ public class ModelBakeryHelpers {
|
||||||
return parser.parse(jsonReader);
|
return parser.parse(jsonReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void gatherAdditionalViaManualScan(List<PackResources> untrustedPacks, Set<ResourceLocation> knownLocations,
|
private static void gatherAdditionalViaManualScan(List<Pack> untrustedPacks, Set<ResourceLocation> knownLocations,
|
||||||
Collection<ResourceLocation> uncertainLocations, String filePrefix) {
|
Collection<ResourceLocation> uncertainLocations, String filePrefix) {
|
||||||
if(untrustedPacks.size() > 0) {
|
if(untrustedPacks.size() > 0) {
|
||||||
/* Now make a fallback resource manager and use it on the remaining packs to see if they actually contain these files */
|
/* Now make a fallback resource manager and use it on the remaining packs to see if they actually contain these files */
|
||||||
FallbackResourceManager frm = new FallbackResourceManager(PackType.CLIENT_RESOURCES, "dummy");
|
FallbackResourceManager frm = new FallbackResourceManager(PackType.CLIENT_RESOURCES, "dummy");
|
||||||
|
|
@ -126,10 +126,10 @@ public class ModelBakeryHelpers {
|
||||||
* main list contained inside the parent resource manager, so we need to scan each of the namespaced managers as
|
* main list contained inside the parent resource manager, so we need to scan each of the namespaced managers as
|
||||||
* well.
|
* well.
|
||||||
*/
|
*/
|
||||||
private static void checkFallbacks(SimpleReloadableResourceManager manager, List<PackResources> resourcePackList) {
|
private static void checkFallbacks(SimpleReloadableResourceManager manager, List<Pack> resourcePackList) {
|
||||||
ReferenceSet<PackResources> knownPacks = new ReferenceOpenHashSet<>(resourcePackList);
|
ReferenceSet<Pack> knownPacks = new ReferenceOpenHashSet<>(resourcePackList);
|
||||||
Map<String, FallbackResourceManager> namespacedMap = manager.namespacedPacks;
|
Map<String, FallbackResourceManager> namespacedMap = manager.namespacedPacks;
|
||||||
namespacedMap.values().stream().flatMap(FallbackResourceManager::listPacks).forEach(pack -> {
|
namespacedMap.values().stream().flatMap(m -> getAllPacks(m).stream()).forEach(pack -> {
|
||||||
if(knownPacks.add(pack)) {
|
if(knownPacks.add(pack)) {
|
||||||
/* the pack was not previously known, add to our list */
|
/* the pack was not previously known, add to our list */
|
||||||
ModernFix.LOGGER.debug("Injecting unlisted pack '{}': {}", pack.getName(), pack.getClass().getName());
|
ModernFix.LOGGER.debug("Injecting unlisted pack '{}': {}", pack.getName(), pack.getClass().getName());
|
||||||
|
|
@ -138,7 +138,17 @@ public class ModelBakeryHelpers {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void gatherModelMaterials(ResourceManager manager, Predicate<PackResources> isTrustedPack,
|
private static List<Pack> getAllPacks(ResourceManager manager) {
|
||||||
|
if (manager instanceof FallbackResourceManager) {
|
||||||
|
return ((FallbackResourceManager)manager).fallbacks;
|
||||||
|
} else if (manager instanceof SimpleReloadableResourceManager) {
|
||||||
|
return ((SimpleReloadableResourceManager)manager).namespacedPacks.values().stream().flatMap(m -> m.fallbacks.stream()).distinct().collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
return ImmutableList.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void gatherModelMaterials(ResourceManager manager, Predicate<Pack> isTrustedPack,
|
||||||
Set<Material> materialSet, Set<ResourceLocation> blockStateFiles,
|
Set<Material> materialSet, Set<ResourceLocation> blockStateFiles,
|
||||||
Set<ResourceLocation> modelFiles, UnbakedModel missingModel,
|
Set<ResourceLocation> modelFiles, UnbakedModel missingModel,
|
||||||
Function<JsonElement, BlockModel> modelDeserializer,
|
Function<JsonElement, BlockModel> modelDeserializer,
|
||||||
|
|
@ -151,19 +161,19 @@ public class ModelBakeryHelpers {
|
||||||
* First, gather all vanilla packs, and use listResources on them. This will allow us to (hopefully) avoid
|
* First, gather all vanilla packs, and use listResources on them. This will allow us to (hopefully) avoid
|
||||||
* scanning most packs a lot.
|
* scanning most packs a lot.
|
||||||
*/
|
*/
|
||||||
List<PackResources> allPackResources = new ArrayList<>(manager.listPacks().collect(Collectors.toList()));
|
List<Pack> allPack = new ArrayList<>(getAllPacks(manager));
|
||||||
if(manager instanceof SimpleReloadableResourceManager) {
|
if(manager instanceof SimpleReloadableResourceManager) {
|
||||||
checkFallbacks((SimpleReloadableResourceManager)manager, allPackResources);
|
checkFallbacks((SimpleReloadableResourceManager)manager, allPack);
|
||||||
}
|
}
|
||||||
Collections.reverse(allPackResources);
|
Collections.reverse(allPack);
|
||||||
ObjectOpenHashSet<ResourceLocation> allAvailableModels = new ObjectOpenHashSet<>(), allAvailableStates = new ObjectOpenHashSet<>();
|
ObjectOpenHashSet<ResourceLocation> allAvailableModels = new ObjectOpenHashSet<>(), allAvailableStates = new ObjectOpenHashSet<>();
|
||||||
/* try to fix CME in some runtime packs by forcing generation */
|
/* try to fix CME in some runtime packs by forcing generation */
|
||||||
for(PackResources pack : allPackResources) {
|
for(Pack pack : allPack) {
|
||||||
try(InputStream stream = pack.getResource(PackType.CLIENT_RESOURCES, new ResourceLocation("modernfix", "dummy.json"))) {
|
try(InputStream stream = pack.getResource(PackType.CLIENT_RESOURCES, new ResourceLocation("modernfix", "dummy.json"))) {
|
||||||
} catch(Exception ignored) {
|
} catch(Exception ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allPackResources.removeIf(pack -> {
|
allPack.removeIf(pack -> {
|
||||||
for(String namespace : pack.getNamespaces(PackType.CLIENT_RESOURCES)) {
|
for(String namespace : pack.getNamespaces(PackType.CLIENT_RESOURCES)) {
|
||||||
Collection<ResourceLocation> allBlockstates = pack.getResources(PackType.CLIENT_RESOURCES, namespace, "blockstates", Integer.MAX_VALUE, p -> p.endsWith(".json"));
|
Collection<ResourceLocation> allBlockstates = pack.getResources(PackType.CLIENT_RESOURCES, namespace, "blockstates", Integer.MAX_VALUE, p -> p.endsWith(".json"));
|
||||||
for(ResourceLocation blockstate : allBlockstates) {
|
for(ResourceLocation blockstate : allBlockstates) {
|
||||||
|
|
@ -181,7 +191,7 @@ public class ModelBakeryHelpers {
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
gatherAdditionalViaManualScan(allPackResources, allAvailableStates, blockStateFiles, "blockstates/");
|
gatherAdditionalViaManualScan(allPack, allAvailableStates, blockStateFiles, "blockstates/");
|
||||||
// We now have a list of all blockstates known to exist. Delete anything that we don't have
|
// We now have a list of all blockstates known to exist. Delete anything that we don't have
|
||||||
blockStateFiles.retainAll(allAvailableStates);
|
blockStateFiles.retainAll(allAvailableStates);
|
||||||
allAvailableStates.clear();
|
allAvailableStates.clear();
|
||||||
|
|
@ -275,7 +285,7 @@ public class ModelBakeryHelpers {
|
||||||
|
|
||||||
modelFiles.addAll(allAvailableModels);
|
modelFiles.addAll(allAvailableModels);
|
||||||
/* figure out which models we should actually load */
|
/* figure out which models we should actually load */
|
||||||
gatherAdditionalViaManualScan(allPackResources, allAvailableModels, modelFiles, "models/");
|
gatherAdditionalViaManualScan(allPack, allAvailableModels, modelFiles, "models/");
|
||||||
modelFiles.retainAll(allAvailableModels);
|
modelFiles.retainAll(allAvailableModels);
|
||||||
allAvailableModels.clear();
|
allAvailableModels.clear();
|
||||||
allAvailableModels.trim();
|
allAvailableModels.trim();
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package org.embeddedt.modernfix.registry;
|
|
||||||
|
|
||||||
import com.mojang.serialization.Lifecycle;
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
|
|
||||||
|
|
||||||
public class LifecycleMap<T> extends Reference2ReferenceOpenHashMap<T, Lifecycle> {
|
|
||||||
public LifecycleMap() {
|
|
||||||
this.defaultReturnValue(Lifecycle.stable());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Lifecycle put(T t, Lifecycle lifecycle) {
|
|
||||||
if(lifecycle != defRetValue)
|
|
||||||
return super.put(t, lifecycle);
|
|
||||||
else {
|
|
||||||
// need the duplicate containsKey/get logic here to override the default return value
|
|
||||||
return super.containsKey(t) ? super.get(t) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -95,7 +95,7 @@ public class PackResourcesCacheEngine {
|
||||||
if(str.length() == 0)
|
if(str.length() == 0)
|
||||||
return false;
|
return false;
|
||||||
for(int i = 0; i < str.length(); i++) {
|
for(int i = 0; i < str.length(); i++) {
|
||||||
if(!ResourceLocation.validPathChar(str.charAt(i))) {
|
if(!ResourceLocation.isAllowedInResourceLocation(str.charAt(i))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
package org.embeddedt.modernfix.screen;
|
package org.embeddedt.modernfix.screen;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.gui.components.Button;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.*;
|
import net.minecraft.network.chat.*;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
public class ModernFixConfigScreen extends Screen {
|
public class ModernFixConfigScreen extends Screen {
|
||||||
private OptionList optionList;
|
private OptionList optionList;
|
||||||
|
|
@ -25,10 +23,10 @@ public class ModernFixConfigScreen extends Screen {
|
||||||
this.optionList = new OptionList(this, this.minecraft);
|
this.optionList = new OptionList(this, this.minecraft);
|
||||||
this.optionList.setScrollAmount(lastScrollAmount);
|
this.optionList.setScrollAmount(lastScrollAmount);
|
||||||
this.children.add(this.optionList);
|
this.children.add(this.optionList);
|
||||||
this.wikiButton = new Button(this.width / 2 - 155, this.height - 29, 150, 20, new TranslatableComponent("modernfix.config.wiki"), (arg) -> {
|
this.wikiButton = new Button(this.width / 2 - 155, this.height - 29, 150, 20, new TranslatableComponent("modernfix.config.wiki").getString(), (arg) -> {
|
||||||
Util.getPlatform().openUri("https://github.com/embeddedt/ModernFix/wiki/Summary-of-Patches");
|
Util.getPlatform().openUri("https://github.com/embeddedt/ModernFix/wiki/Summary-of-Patches");
|
||||||
});
|
});
|
||||||
this.doneButton = new Button(this.width / 2 - 155 + 160, this.height - 29, 150, 20, CommonComponents.GUI_DONE, (arg) -> {
|
this.doneButton = new Button(this.width / 2 - 155 + 160, this.height - 29, 150, 20, "Done", (arg) -> {
|
||||||
this.onClose();
|
this.onClose();
|
||||||
});
|
});
|
||||||
this.addButton(this.wikiButton);
|
this.addButton(this.wikiButton);
|
||||||
|
|
@ -41,17 +39,12 @@ public class ModernFixConfigScreen extends Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) {
|
public void render(int mouseX, int mouseY, float partialTicks) {
|
||||||
this.renderBackground(poseStack);
|
this.renderBackground();
|
||||||
this.optionList.render(poseStack, mouseX, mouseY, partialTicks);
|
this.optionList.render(mouseX, mouseY, partialTicks);
|
||||||
drawCenteredString(poseStack, this.font, this.title, this.width / 2, 8, 16777215);
|
drawCenteredString(this.font, this.title.getString(), this.width / 2, 8, 16777215);
|
||||||
this.doneButton.setMessage(madeChanges ? new TranslatableComponent("modernfix.config.done_restart") : CommonComponents.GUI_DONE);
|
this.doneButton.setMessage(madeChanges ? new TranslatableComponent("modernfix.config.done_restart").getString() : "Done");
|
||||||
super.render(poseStack, mouseX, mouseY, partialTicks);
|
super.render(mouseX, mouseY, partialTicks);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void renderComponentHoverEffect(PoseStack matrixStack, @Nullable Style style, int mouseX, int mouseY) {
|
|
||||||
super.renderComponentHoverEffect(matrixStack, style, mouseX, mouseY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastScrollAmount(double d) {
|
public void setLastScrollAmount(double d) {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
package org.embeddedt.modernfix.screen;
|
package org.embeddedt.modernfix.screen;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import net.minecraft.client.gui.Font;
|
import net.minecraft.client.gui.Font;
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.gui.components.Button;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.network.chat.CommonComponents;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
import net.minecraft.util.FormattedCharSequence;
|
|
||||||
|
|
||||||
public class ModernFixOptionInfoScreen extends Screen {
|
public class ModernFixOptionInfoScreen extends Screen {
|
||||||
private final Screen lastScreen;
|
private final Screen lastScreen;
|
||||||
|
|
@ -24,7 +21,7 @@ public class ModernFixOptionInfoScreen extends Screen {
|
||||||
@Override
|
@Override
|
||||||
protected void init() {
|
protected void init() {
|
||||||
super.init();
|
super.init();
|
||||||
this.addButton(new Button(this.width / 2 - 100, this.height - 29, 200, 20, CommonComponents.GUI_DONE, (button) -> {
|
this.addButton(new Button(this.width / 2 - 100, this.height - 29, 200, 20, "Done", (button) -> {
|
||||||
this.onClose();
|
this.onClose();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
@ -34,18 +31,18 @@ public class ModernFixOptionInfoScreen extends Screen {
|
||||||
this.minecraft.setScreen(lastScreen);
|
this.minecraft.setScreen(lastScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawMultilineString(PoseStack mStack, Font fr, Component str, int x, int y) {
|
private void drawMultilineString(Font fr, Component str, int x, int y) {
|
||||||
for(FormattedCharSequence s : fr.split(str, this.width - 50)) {
|
for(String s : fr.split(str.getString(), this.width - 50)) {
|
||||||
fr.drawShadow(mStack, s, (float)x, (float)y, 16777215);
|
fr.drawShadow(s, (float)x, (float)y, 16777215);
|
||||||
y += fr.lineHeight;
|
y += fr.lineHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) {
|
public void render(int mouseX, int mouseY, float partialTicks) {
|
||||||
this.renderBackground(poseStack);
|
this.renderBackground();
|
||||||
drawCenteredString(poseStack, this.font, this.title, this.width / 2, 8, 16777215);
|
drawCenteredString(this.font, this.title.getString(), this.width / 2, 8, 16777215);
|
||||||
this.drawMultilineString(poseStack, this.minecraft.font, description, 10, 50);
|
this.drawMultilineString(this.minecraft.font, description, 10, 50);
|
||||||
super.render(poseStack, mouseX, mouseY, partialTicks);
|
super.render(mouseX, mouseY, partialTicks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package org.embeddedt.modernfix.screen;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.Font;
|
import net.minecraft.client.gui.Font;
|
||||||
|
|
@ -25,18 +24,18 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
|
|
||||||
private static final int DEPTH_OFFSET = 20;
|
private static final int DEPTH_OFFSET = 20;
|
||||||
|
|
||||||
private static final Component OPTION_ON = new TranslatableComponent("modernfix.option.on").withStyle(style -> style.withColor(ChatFormatting.GREEN));
|
private static final Component OPTION_ON = new TranslatableComponent("modernfix.option.on").withStyle(style -> style.setColor(ChatFormatting.GREEN));
|
||||||
private static final Component OPTION_OFF = new TranslatableComponent("modernfix.option.off").withStyle(style -> style.withColor(ChatFormatting.RED));
|
private static final Component OPTION_OFF = new TranslatableComponent("modernfix.option.off").withStyle(style -> style.setColor(ChatFormatting.RED));
|
||||||
|
|
||||||
private static final Set<String> OPTIONS_MISSING_HELP = new HashSet<>();
|
private static final Set<String> OPTIONS_MISSING_HELP = new HashSet<>();
|
||||||
|
|
||||||
private ModernFixConfigScreen mainScreen;
|
private ModernFixConfigScreen mainScreen;
|
||||||
|
|
||||||
private static MutableComponent getOptionComponent(Option option) {
|
private static BaseComponent getOptionComponent(Option option) {
|
||||||
String friendlyKey = "modernfix.option.name." + option.getName();
|
String friendlyKey = "modernfix.option.name." + option.getName();
|
||||||
TextComponent baseComponent = new TextComponent(option.getSelfName());
|
TextComponent baseComponent = new TextComponent(option.getSelfName());
|
||||||
if(I18n.exists(friendlyKey))
|
if(I18n.exists(friendlyKey))
|
||||||
return new TranslatableComponent(friendlyKey).withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, baseComponent)));
|
return new TranslatableComponent(friendlyKey);
|
||||||
else
|
else
|
||||||
return baseComponent;
|
return baseComponent;
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +52,7 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
|
|
||||||
private void addOption(Option option) {
|
private void addOption(Option option) {
|
||||||
if(addedOptions.add(option)) {
|
if(addedOptions.add(option)) {
|
||||||
int w = this.minecraft.font.width(getOptionComponent(option)) + DEPTH_OFFSET * option.getDepth();
|
int w = this.minecraft.font.width(getOptionComponent(option).getString()) + DEPTH_OFFSET * option.getDepth();
|
||||||
this.maxNameWidth = Math.max(w, this.maxNameWidth);
|
this.maxNameWidth = Math.max(w, this.maxNameWidth);
|
||||||
this.addEntry(new OptionEntry(option.getName(), option));
|
this.addEntry(new OptionEntry(option.getName(), option));
|
||||||
ModernFixMixinPlugin.instance.config.getOptionMap().values().stream()
|
ModernFixMixinPlugin.instance.config.getOptionMap().values().stream()
|
||||||
|
|
@ -73,7 +72,6 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
for(String category : theCategories) {
|
for(String category : theCategories) {
|
||||||
String categoryTranslationKey = "modernfix.option.category." + category;
|
String categoryTranslationKey = "modernfix.option.category." + category;
|
||||||
this.addEntry(new CategoryEntry(new TranslatableComponent(categoryTranslationKey)
|
this.addEntry(new CategoryEntry(new TranslatableComponent(categoryTranslationKey)
|
||||||
.withStyle(Style.EMPTY.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TranslatableComponent(categoryTranslationKey + ".description"))))
|
|
||||||
));
|
));
|
||||||
optionsByCategory.get(category).stream().filter(key -> {
|
optionsByCategory.get(category).stream().filter(key -> {
|
||||||
int dotCount = 0;
|
int dotCount = 0;
|
||||||
|
|
@ -100,16 +98,14 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
|
|
||||||
public CategoryEntry(Component component) {
|
public CategoryEntry(Component component) {
|
||||||
this.name = component;
|
this.name = component;
|
||||||
this.width = OptionList.this.minecraft.font.width(this.name);
|
this.width = OptionList.this.minecraft.font.width(this.name.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(PoseStack matrixStack, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean isMouseOver, float partialTicks) {
|
public void render(int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean isMouseOver, float partialTicks) {
|
||||||
Font var10000 = OptionList.this.minecraft.font;
|
Font var10000 = OptionList.this.minecraft.font;
|
||||||
float x = (float)(OptionList.this.minecraft.screen.width / 2 - this.width / 2);
|
float x = (float)(OptionList.this.minecraft.screen.width / 2 - this.width / 2);
|
||||||
int y = top + height - 10;
|
int y = top + height - 10;
|
||||||
var10000.draw(matrixStack, this.name, x, y, 16777215);
|
var10000.draw(this.name.getString(), x, y, 16777215);
|
||||||
if(mouseX >= x && mouseY >= y && mouseX <= (x + this.width) && mouseY <= (y + OptionList.this.minecraft.font.lineHeight))
|
|
||||||
OptionList.this.mainScreen.renderComponentHoverEffect(matrixStack, this.name.getStyle(), mouseX, mouseY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean changeFocus(boolean focus) {
|
public boolean changeFocus(boolean focus) {
|
||||||
|
|
@ -131,7 +127,7 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
public OptionEntry(String optionName, Option option) {
|
public OptionEntry(String optionName, Option option) {
|
||||||
this.name = optionName;
|
this.name = optionName;
|
||||||
this.option = option;
|
this.option = option;
|
||||||
this.toggleButton = new Button(0, 0, 55, 20, new TextComponent(""), (arg) -> {
|
this.toggleButton = new Button(0, 0, 55, 20, new TextComponent("").toString(), (arg) -> {
|
||||||
this.option.setEnabled(!this.option.isEnabled(), !this.option.isUserDefined());
|
this.option.setEnabled(!this.option.isEnabled(), !this.option.isUserDefined());
|
||||||
try {
|
try {
|
||||||
ModernFixMixinPlugin.instance.config.save();
|
ModernFixMixinPlugin.instance.config.save();
|
||||||
|
|
@ -144,20 +140,9 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
ModernFix.LOGGER.error("Unable to save config", e);
|
ModernFix.LOGGER.error("Unable to save config", e);
|
||||||
}
|
}
|
||||||
OptionList.this.updateOptionEntryStatuses();
|
OptionList.this.updateOptionEntryStatuses();
|
||||||
}, (btn, gfx, x, y) -> {
|
|
||||||
if(this.option.isModDefined()) {
|
|
||||||
String disablingMods = String.join(", ", this.option.getDefiningMods());
|
|
||||||
OptionList.this.mainScreen.renderTooltip(
|
|
||||||
gfx,
|
|
||||||
new TranslatableComponent("modernfix.option." + (this.option.isEnabled() ? "enabled" : "disabled"))
|
|
||||||
.append(new TranslatableComponent("modernfix.option.mod_override", disablingMods)),
|
|
||||||
x,
|
|
||||||
y
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
updateStatus();
|
updateStatus();
|
||||||
this.helpButton = new Button(75, 0, 20, 20, new TextComponent("?"), (arg) -> {
|
this.helpButton = new Button(75, 0, 20, 20, new TextComponent("?").getString(), (arg) -> {
|
||||||
mainScreen.setLastScrollAmount(getScrollAmount());
|
mainScreen.setLastScrollAmount(getScrollAmount());
|
||||||
Minecraft.getInstance().setScreen(new ModernFixOptionInfoScreen(mainScreen, optionName));
|
Minecraft.getInstance().setScreen(new ModernFixOptionInfoScreen(mainScreen, optionName));
|
||||||
});
|
});
|
||||||
|
|
@ -173,22 +158,20 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(PoseStack matrixStack, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean isMouseOver, float partialTicks) {
|
public void render(int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean isMouseOver, float partialTicks) {
|
||||||
MutableComponent nameComponent = getOptionComponent(option);
|
BaseComponent nameComponent = getOptionComponent(option);
|
||||||
if(this.option.isUserDefined())
|
if(this.option.isUserDefined())
|
||||||
nameComponent = nameComponent.withStyle(style -> style.withItalic(true)).append(new TranslatableComponent("modernfix.config.not_default"));
|
nameComponent = (BaseComponent) nameComponent.withStyle(style -> style.setItalic(true)).append(new TranslatableComponent("modernfix.config.not_default"));
|
||||||
float textX = (float)(left + DEPTH_OFFSET * option.getDepth() + 160 - OptionList.this.maxNameWidth);
|
float textX = (float)(left + DEPTH_OFFSET * option.getDepth() + 160 - OptionList.this.maxNameWidth);
|
||||||
float textY = (float)(top + height / 2 - 4);
|
float textY = (float)(top + height / 2 - 4);
|
||||||
OptionList.this.minecraft.font.draw(matrixStack, nameComponent, textX, textY, 16777215);
|
OptionList.this.minecraft.font.draw(nameComponent.getString(), textX, textY, 16777215);
|
||||||
this.toggleButton.x = left + 175;
|
this.toggleButton.x = left + 175;
|
||||||
this.toggleButton.y = top;
|
this.toggleButton.y = top;
|
||||||
this.toggleButton.setMessage(getOptionMessage(this.option));
|
this.toggleButton.setMessage(getOptionMessage(this.option).getString());
|
||||||
this.toggleButton.render(matrixStack, mouseX, mouseY, partialTicks);
|
this.toggleButton.render(mouseX, mouseY, partialTicks);
|
||||||
this.helpButton.x = left + 175 + 55;
|
this.helpButton.x = left + 175 + 55;
|
||||||
this.helpButton.y = top;
|
this.helpButton.y = top;
|
||||||
this.helpButton.render(matrixStack, mouseX, mouseY, partialTicks);
|
this.helpButton.render(mouseX, mouseY, partialTicks);
|
||||||
if(mouseX >= textX && mouseY >= textY && mouseX <= (textX + OptionList.this.maxNameWidth) && mouseY <= (textY + OptionList.this.minecraft.font.lineHeight))
|
|
||||||
OptionList.this.mainScreen.renderComponentHoverEffect(matrixStack, nameComponent.getStyle(), mouseX, mouseY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component getOptionMessage(Option option) {
|
private Component getOptionMessage(Option option) {
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ public class CachingStructureManager {
|
||||||
private static synchronized CompoundTag getCachedUpgraded(ResourceLocation location, String hash) {
|
private static synchronized CompoundTag getCachedUpgraded(ResourceLocation location, String hash) {
|
||||||
File theFile = getCachePath(location, hash);
|
File theFile = getCachePath(location, hash);
|
||||||
try {
|
try {
|
||||||
return NbtIo.readCompressed(theFile);
|
return NbtIo.readCompressed(new FileInputStream(theFile));
|
||||||
} catch(FileNotFoundException e) {
|
} catch(FileNotFoundException e) {
|
||||||
return null;
|
return null;
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
|
|
@ -110,7 +110,7 @@ public class CachingStructureManager {
|
||||||
private static synchronized void saveCachedUpgraded(ResourceLocation location, String hash, CompoundTag tagToSave) {
|
private static synchronized void saveCachedUpgraded(ResourceLocation location, String hash, CompoundTag tagToSave) {
|
||||||
File theFile = getCachePath(location, truncateHash(hash));
|
File theFile = getCachePath(location, truncateHash(hash));
|
||||||
try {
|
try {
|
||||||
NbtIo.writeCompressed(tagToSave, theFile);
|
NbtIo.writeCompressed(tagToSave, new FileOutputStream(theFile));
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,148 +1,6 @@
|
||||||
package org.embeddedt.modernfix.util;
|
package org.embeddedt.modernfix.util;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.mojang.serialization.Lifecycle;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.world.level.DataPackConfig;
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
|
||||||
import net.minecraft.world.Difficulty;
|
|
||||||
import net.minecraft.world.level.GameRules;
|
|
||||||
import net.minecraft.world.level.GameType;
|
|
||||||
import net.minecraft.world.level.LevelSettings;
|
|
||||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
|
||||||
import net.minecraft.world.level.storage.WorldData;
|
|
||||||
import net.minecraft.world.level.storage.ServerLevelData;
|
|
||||||
|
|
||||||
import java.util.Set;
|
public class DummyServerConfiguration {
|
||||||
|
|
||||||
public class DummyServerConfiguration implements WorldData {
|
|
||||||
@Override
|
|
||||||
public DataPackConfig getDataPackConfig() {
|
|
||||||
return DataPackConfig.DEFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDataPackConfig(DataPackConfig codec) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean wasModded() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getKnownServerBrands() {
|
|
||||||
return ImmutableSet.of("forge");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setModdedInfo(String name, boolean isModded) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompoundTag getCustomBossEvents() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCustomBossEvents(CompoundTag nbt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ServerLevelData overworldData() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LevelSettings getLevelSettings() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompoundTag createTag(RegistryAccess registries, CompoundTag hostPlayerNBT) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isHardcore() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getVersion() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLevelName() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GameType getGameType() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameType(GameType type) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getAllowCommands() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Difficulty getDifficulty() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDifficulty(Difficulty difficulty) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDifficultyLocked() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDifficultyLocked(boolean locked) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GameRules getGameRules() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompoundTag getLoadedPlayerTag() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CompoundTag endDragonFightData() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEndDragonFightData(CompoundTag nbt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public WorldGenSettings worldGenSettings() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Lifecycle worldGenSettingsLifecycle() {
|
|
||||||
return Lifecycle.stable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import java.util.List;
|
||||||
public class StrongholdLocationCache extends SavedData {
|
public class StrongholdLocationCache extends SavedData {
|
||||||
private List<ChunkPos> chunkPosList;
|
private List<ChunkPos> chunkPosList;
|
||||||
public StrongholdLocationCache(ServerLevel level) {
|
public StrongholdLocationCache(ServerLevel level) {
|
||||||
super(getFileId(level.dimensionType()));
|
super(getFileId(level.dimension.getType()));
|
||||||
chunkPosList = new ArrayList<>();
|
chunkPosList = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,8 @@ accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType
|
||||||
accessible method net/minecraft/client/renderer/RenderType$CompositeRenderType <init> (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$CompositeState;)V
|
accessible method net/minecraft/client/renderer/RenderType$CompositeRenderType <init> (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$CompositeState;)V
|
||||||
accessible method net/minecraft/nbt/CompoundTag <init> (Ljava/util/Map;)V
|
accessible method net/minecraft/nbt/CompoundTag <init> (Ljava/util/Map;)V
|
||||||
|
|
||||||
accessible class net/minecraft/client/Minecraft$ExperimentalDialogType
|
accessible class net/minecraft/world/level/block/state/BlockState$Cache
|
||||||
accessible class net/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase$Cache
|
|
||||||
accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor
|
accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor
|
||||||
accessible field net/minecraft/world/level/block/state/BlockBehaviour properties Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;
|
|
||||||
accessible class net/minecraft/client/renderer/block/model/BlockElementFace$Deserializer
|
accessible class net/minecraft/client/renderer/block/model/BlockElementFace$Deserializer
|
||||||
accessible class net/minecraft/client/renderer/texture/Stitcher$Holder
|
accessible class net/minecraft/client/renderer/texture/Stitcher$Holder
|
||||||
accessible field net/minecraft/client/renderer/texture/Stitcher$Holder width I
|
accessible field net/minecraft/client/renderer/texture/Stitcher$Holder width I
|
||||||
|
|
@ -24,17 +22,15 @@ accessible class net/minecraft/client/resources/model/ModelBakery$BlockStateDefi
|
||||||
accessible field net/minecraft/network/syncher/SynchedEntityData itemsById Ljava/util/Map;
|
accessible field net/minecraft/network/syncher/SynchedEntityData itemsById Ljava/util/Map;
|
||||||
accessible field net/minecraft/network/syncher/SynchedEntityData ENTITY_ID_POOL Ljava/util/Map;
|
accessible field net/minecraft/network/syncher/SynchedEntityData ENTITY_ID_POOL Ljava/util/Map;
|
||||||
accessible field net/minecraft/network/syncher/SynchedEntityData lock Ljava/util/concurrent/locks/ReadWriteLock;
|
accessible field net/minecraft/network/syncher/SynchedEntityData lock Ljava/util/concurrent/locks/ReadWriteLock;
|
||||||
accessible method net/minecraft/Util makeExecutor (Ljava/lang/String;)Ljava/util/concurrent/ExecutorService;
|
|
||||||
accessible field net/minecraft/server/level/ChunkMap updatingChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
accessible field net/minecraft/server/level/ChunkMap updatingChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
||||||
accessible field net/minecraft/server/level/ChunkMap visibleChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
accessible field net/minecraft/server/level/ChunkMap visibleChunkMap Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
||||||
accessible field net/minecraft/server/level/ChunkMap pendingUnloads Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
accessible field net/minecraft/server/level/ChunkMap pendingUnloads Lit/unimi/dsi/fastutil/longs/Long2ObjectLinkedOpenHashMap;
|
||||||
accessible field net/minecraft/client/Minecraft reserve [B
|
accessible field net/minecraft/client/Minecraft reserve [B
|
||||||
accessible method net/minecraft/resources/ResourceKey <init> (Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V
|
|
||||||
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite <init> (Lnet/minecraft/client/renderer/texture/TextureAtlas;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIIILcom/mojang/blaze3d/platform/NativeImage;)V
|
accessible method net/minecraft/client/renderer/texture/TextureAtlasSprite <init> (Lnet/minecraft/client/renderer/texture/TextureAtlas;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIIILcom/mojang/blaze3d/platform/NativeImage;)V
|
||||||
accessible field net/minecraft/client/renderer/block/model/BlockModel GSON Lcom/google/gson/Gson;
|
accessible field net/minecraft/client/renderer/block/model/BlockModel GSON Lcom/google/gson/Gson;
|
||||||
accessible field net/minecraft/server/MinecraftServer resources Lnet/minecraft/server/ServerResources;
|
|
||||||
accessible field net/minecraft/client/renderer/RenderStateShard name Ljava/lang/String;
|
accessible field net/minecraft/client/renderer/RenderStateShard name Ljava/lang/String;
|
||||||
accessible method net/minecraft/client/gui/screens/Screen addButton (Lnet/minecraft/client/gui/components/AbstractWidget;)Lnet/minecraft/client/gui/components/AbstractWidget;
|
accessible method net/minecraft/client/gui/screens/Screen addButton (Lnet/minecraft/client/gui/components/AbstractWidget;)Lnet/minecraft/client/gui/components/AbstractWidget;
|
||||||
accessible field net/minecraft/server/packs/resources/SimpleReloadableResourceManager namespacedPacks Ljava/util/Map;
|
accessible field net/minecraft/server/packs/resources/SimpleReloadableResourceManager namespacedPacks Ljava/util/Map;
|
||||||
accessible field net/minecraft/client/renderer/entity/EnderDragonRenderer$DragonModel entity Lnet/minecraft/world/entity/boss/enderdragon/EnderDragon;
|
accessible field net/minecraft/client/renderer/entity/EnderDragonRenderer$DragonModel entity Lnet/minecraft/world/entity/boss/enderdragon/EnderDragon;
|
||||||
accessible method net/minecraft/world/level/block/state/StateDefinition appendPropertyCodec (Lcom/mojang/serialization/MapCodec;Ljava/util/function/Supplier;Ljava/lang/String;Lnet/minecraft/world/level/block/state/properties/Property;)Lcom/mojang/serialization/MapCodec;
|
|
||||||
|
accessible field net/minecraft/server/packs/resources/FallbackResourceManager fallbacks Ljava/util/List;
|
||||||
|
|
@ -32,7 +32,7 @@ dependencies {
|
||||||
include(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:${rootProject.mixinextras_version}")))
|
include(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:${rootProject.mixinextras_version}")))
|
||||||
|
|
||||||
modCompileOnly(fabricApi.module("fabric-api-base", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
modCompileOnly(fabricApi.module("fabric-api-base", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||||
modCompileOnly(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
//modCompileOnly(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||||
modCompileOnly(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
modCompileOnly(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||||
modCompileOnly(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
modCompileOnly(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||||
modCompileOnly(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
modCompileOnly(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ package org.embeddedt.modernfix.fabric.bridge;
|
||||||
|
|
||||||
import net.fabricmc.fabric.impl.client.model.ModelLoadingRegistryImpl;
|
import net.fabricmc.fabric.impl.client.model.ModelLoadingRegistryImpl;
|
||||||
import net.minecraft.client.resources.model.ModelBakery;
|
import net.minecraft.client.resources.model.ModelBakery;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class ModelV0Bridge {
|
public class ModelV0Bridge {
|
||||||
public static void populate(Consumer<ResourceLocation> modelConsumer, ModelBakery bakery, ResourceManager manager) {
|
public static void populate(Consumer<ModelResourceLocation> modelConsumer, ModelBakery bakery, ResourceManager manager) {
|
||||||
ModelLoadingRegistryImpl.LoaderInstance instance = ModelLoadingRegistryImpl.begin(bakery, manager);
|
ModelLoadingRegistryImpl.LoaderInstance instance = ModelLoadingRegistryImpl.begin(bakery, manager);
|
||||||
instance.onModelPopulation(modelConsumer);
|
instance.onModelPopulation(modelConsumer);
|
||||||
instance.finish();
|
instance.finish();
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@Mixin(MinecraftServer.class)
|
@Mixin(MinecraftServer.class)
|
||||||
@ClientOnlyMixin
|
@ClientOnlyMixin
|
||||||
public class ClientMinecraftServerMixin {
|
public class ClientMinecraftServerMixin {
|
||||||
@Inject(method = "runServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;getMillis()J", ordinal = 0))
|
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;getMillis()J", ordinal = 0))
|
||||||
private void markServerStarted(CallbackInfo ci) {
|
private void markServerStarted(CallbackInfo ci) {
|
||||||
ModernFixClient.INSTANCE.onServerStarted((MinecraftServer)(Object)this);
|
ModernFixClient.INSTANCE.onServerStarted((MinecraftServer)(Object)this);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@ import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
@Mixin(MinecraftServer.class)
|
@Mixin(MinecraftServer.class)
|
||||||
public class MinecraftServerMixin {
|
public class MinecraftServerMixin {
|
||||||
@Inject(method = "runServer", at = @At("HEAD"))
|
@Inject(method = "run", at = @At("HEAD"))
|
||||||
private void changeServerReference(CallbackInfo ci) {
|
private void changeServerReference(CallbackInfo ci) {
|
||||||
ModernFixFabric.theServer = new WeakReference<>((MinecraftServer)(Object)this);
|
ModernFixFabric.theServer = new WeakReference<>((MinecraftServer)(Object)this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "runServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;getMillis()J", ordinal = 0))
|
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;getMillis()J", ordinal = 0))
|
||||||
private void hookServerStarted(CallbackInfo ci) {
|
private void hookServerStarted(CallbackInfo ci) {
|
||||||
ModernFix.INSTANCE.onServerStarted();
|
ModernFix.INSTANCE.onServerStarted();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
@ClientOnlyMixin
|
@ClientOnlyMixin
|
||||||
public class MinecraftMixin_Fabric {
|
public class MinecraftMixin_Fabric {
|
||||||
@Inject(method = "doLoadLevel", at = @At("HEAD"))
|
@Inject(method = "selectLevel", at = @At("HEAD"))
|
||||||
private void recordWorldLoadStart(CallbackInfo ci) {
|
private void recordWorldLoadStart(CallbackInfo ci) {
|
||||||
ModernFixClient.worldLoadStartTime = System.nanoTime();
|
ModernFixClient.worldLoadStartTime = System.nanoTime();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ import net.minecraft.client.resources.ClientPackSource;
|
||||||
import net.minecraft.client.resources.model.*;
|
import net.minecraft.client.resources.model.*;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.packs.FilePackResources;
|
import net.minecraft.server.packs.FileResourcePack;
|
||||||
import net.minecraft.server.packs.FolderPackResources;
|
import net.minecraft.server.packs.FolderResourcePack;
|
||||||
import net.minecraft.server.packs.PackResources;
|
import net.minecraft.server.packs.Pack;
|
||||||
import net.minecraft.server.packs.VanillaPackResources;
|
import net.minecraft.server.packs.VanillaPack;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
|
@ -231,11 +231,11 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean trustedResourcePack(PackResources pack) {
|
private boolean trustedResourcePack(Pack pack) {
|
||||||
return pack instanceof VanillaPackResources ||
|
return pack instanceof VanillaPack ||
|
||||||
pack instanceof ClientPackSource ||
|
pack instanceof ClientPackSource ||
|
||||||
pack instanceof FolderPackResources ||
|
pack instanceof FolderResourcePack ||
|
||||||
pack instanceof FilePackResources;
|
pack instanceof FileResourcePack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package org.embeddedt.modernfix.fabric.modmenu;
|
package org.embeddedt.modernfix.fabric.modmenu;
|
||||||
|
|
||||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
import io.github.prospector.modmenu.api.ConfigScreenFactory;
|
||||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
import io.github.prospector.modmenu.api.ModMenuApi;
|
||||||
import org.embeddedt.modernfix.screen.ModernFixConfigScreen;
|
import org.embeddedt.modernfix.screen.ModernFixConfigScreen;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
"modernfix-common.mixins.json"
|
"modernfix-common.mixins.json"
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"minecraft": ">=1.16.2"
|
"minecraft": "1.15.2"
|
||||||
},
|
},
|
||||||
"breaks": {
|
"breaks": {
|
||||||
"dashloader": "*"
|
"dashloader": "*"
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ dependencies {
|
||||||
|
|
||||||
modCompileOnly("curse.maven:refinedstorage-243076:${refined_storage_version}")
|
modCompileOnly("curse.maven:refinedstorage-243076:${refined_storage_version}")
|
||||||
|
|
||||||
modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}")
|
modCompileOnly("curse.maven:kubejs-238086:3103858")
|
||||||
modCompileOnly("curse.maven:jeresources-240630:3545538")
|
modCompileOnly("curse.maven:jeresources-240630:3545538")
|
||||||
modCompileOnly("curse.maven:jepb-437558:3172880")
|
modCompileOnly("curse.maven:jepb-437558:3172880")
|
||||||
modCompileOnly("curse.maven:babel-436964:3196072")
|
modCompileOnly("curse.maven:babel-436964:3196072")
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package org.embeddedt.modernfix.forge.classloading;
|
package org.embeddedt.modernfix.forge.classloading;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.Iterators;
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import net.minecraftforge.fml.loading.FMLLoader;
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
import net.minecraftforge.fml.loading.LoadingModList;
|
import net.minecraftforge.fml.loading.LoadingModList;
|
||||||
|
|
@ -19,8 +18,6 @@ import org.embeddedt.modernfix.util.FileUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.FileSystem;
|
import java.nio.file.FileSystem;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
@ -90,26 +87,4 @@ public class ModernFixResourceFinder {
|
||||||
} else
|
} else
|
||||||
throw new UnsupportedOperationException("Unknown ModLocator type: " + locator.getClass().getName());
|
throw new UnsupportedOperationException("Unknown ModLocator type: " + locator.getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Enumeration<URL> findAllURLsForResource(String input) {
|
|
||||||
// fallback to Forge impl for any paths ending in a slash
|
|
||||||
char endChar = input.length() > 0 ? input.charAt(input.length() - 1) : '/';
|
|
||||||
if(endChar == '/' || endChar == '\\') {
|
|
||||||
return LoadingModList.get().findAllURLsForResource(input);
|
|
||||||
}
|
|
||||||
// CachedResourcePath normalizes already
|
|
||||||
Collection<String> urlList = urlsForClass.get(new CachedResourcePath(input));
|
|
||||||
if(!urlList.isEmpty()) {
|
|
||||||
String pathInput = FileUtil.normalize(input);
|
|
||||||
return Iterators.asEnumeration(urlList.stream().map(modId -> {
|
|
||||||
try {
|
|
||||||
return new URL("modjar://" + modId + "/" + pathInput);
|
|
||||||
} catch(MalformedURLException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}).iterator());
|
|
||||||
} else {
|
|
||||||
return Collections.emptyEnumeration();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.datagen;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.components.Button;
|
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
|
||||||
import net.minecraft.network.chat.TextComponent;
|
|
||||||
import net.minecraft.server.packs.resources.SimpleReloadableResourceManager;
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.client.event.GuiScreenEvent;
|
|
||||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
||||||
import net.minecraftforge.fml.DatagenModLoader;
|
|
||||||
import net.minecraftforge.fml.ModLoader;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
|
||||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber(value = Dist.CLIENT)
|
|
||||||
public class RuntimeDatagen {
|
|
||||||
private static final String RESOURCES_OUT_DIR = getPropertyOrBlank("modernfix.datagen.output");
|
|
||||||
private static final String RESOURCES_IN_DIR = getPropertyOrBlank("modernfix.datagen.existing");
|
|
||||||
private static final String MODS_LIST = getPropertyOrBlank("modernfix.datagen.mods");
|
|
||||||
private static final String EXISTING_MODS_LIST = getPropertyOrBlank("modernfix.datagen.existing_mods");
|
|
||||||
private static final boolean IS_FLAT = Boolean.getBoolean("modernfix.datagen.flat");
|
|
||||||
|
|
||||||
private static String getPropertyOrBlank(String name) {
|
|
||||||
String val = System.getProperty(name);
|
|
||||||
if(val == null || val.length() == 0)
|
|
||||||
return "";
|
|
||||||
else
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isDatagenAvailable() {
|
|
||||||
return RESOURCES_OUT_DIR.length() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void runRuntimeDatagen() {
|
|
||||||
ObfuscationReflectionHelper.setPrivateValue(DatagenModLoader.class, null, true, "runningDataGen");
|
|
||||||
Set<String> mods = new HashSet<>(Arrays.stream(MODS_LIST.split(",")).collect(Collectors.toSet()));
|
|
||||||
ModernFix.LOGGER.info("Beginning runtime datagen for " + mods.size() + " mods...");
|
|
||||||
Set<String> existingMods = new HashSet<>(Arrays.stream(EXISTING_MODS_LIST.split(",")).collect(Collectors.toSet()));
|
|
||||||
Set<Path> existingPacks = new HashSet<>(Arrays.stream(RESOURCES_IN_DIR.split(",")).map(Paths::get).collect(Collectors.toSet()));
|
|
||||||
Path path = Paths.get(RESOURCES_OUT_DIR);
|
|
||||||
GatherDataEvent.DataGeneratorConfig dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, Collections.emptyList(),
|
|
||||||
true, true, true, true, true, mods.isEmpty() || IS_FLAT);
|
|
||||||
if (!mods.contains("forge")) {
|
|
||||||
//If we aren't generating data for forge, automatically add forge as an existing so mods can access forge's data
|
|
||||||
existingMods.add("forge");
|
|
||||||
}
|
|
||||||
ExistingFileHelper existingFileHelper = new ExistingFileHelper(existingPacks, existingMods, true, null, null);
|
|
||||||
/* Inject the client pack resources from us */
|
|
||||||
((SimpleReloadableResourceManager)ObfuscationReflectionHelper.getPrivateValue(ExistingFileHelper.class, existingFileHelper, "clientResources")).add(Minecraft.getInstance().getClientPackSource().getVanillaPack());
|
|
||||||
ModLoader.get().runEventGenerator(mc->new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p->dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig, existingFileHelper));
|
|
||||||
dataGeneratorConfig.runAll();
|
|
||||||
ObfuscationReflectionHelper.setPrivateValue(DatagenModLoader.class, null, false, "runningDataGen");
|
|
||||||
ModernFix.LOGGER.info("Finished runtime datagen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onInitTitleScreen(GuiScreenEvent.InitGuiEvent.Post event) {
|
|
||||||
if(isDatagenAvailable() && event.getGui() instanceof TitleScreen) {
|
|
||||||
TitleScreen screen = (TitleScreen)event.getGui();
|
|
||||||
screen.addButton(new Button(screen.width / 2 - 100 - 50, screen.height / 4 + 48, 50, 20, new TextComponent("DG"), (arg) -> {
|
|
||||||
runRuntimeDatagen();
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -47,7 +47,7 @@ public class ModernFixClientForge {
|
||||||
ClientRegistry.registerKeyBinding(configKey);
|
ClientRegistry.registerKeyBinding(configKey);
|
||||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dynamic_resources.ConnectednessCheck")
|
if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dynamic_resources.ConnectednessCheck")
|
||||||
&& ModList.get().isLoaded("connectedness")) {
|
&& ModList.get().isLoaded("connectedness")) {
|
||||||
event.enqueueWork(() -> {
|
DeferredWorkQueue.runLater(() -> {
|
||||||
ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.SIDED_SETUP, "modernfix.connectedness_dynresoruces"));
|
ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.SIDED_SETUP, "modernfix.connectedness_dynresoruces"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ import net.minecraft.commands.CommandSourceStack;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.OnDatapackSyncEvent;
|
|
||||||
import net.minecraftforge.event.RegisterCommandsEvent;
|
|
||||||
import net.minecraftforge.event.RegistryEvent;
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
import net.minecraftforge.eventbus.api.EventPriority;
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
|
@ -16,16 +14,15 @@ import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.config.ModConfig;
|
import net.minecraftforge.fml.config.ModConfig;
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
||||||
|
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||||
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import net.minecraftforge.fml.loading.FMLLoader;
|
import net.minecraftforge.fml.loading.FMLLoader;
|
||||||
import net.minecraftforge.fml.network.FMLNetworkConstants;
|
import net.minecraftforge.fml.network.FMLNetworkConstants;
|
||||||
import net.minecraftforge.fml.server.ServerLifecycleHooks;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||||
import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler;
|
|
||||||
import org.embeddedt.modernfix.forge.ModernFixConfig;
|
import org.embeddedt.modernfix.forge.ModernFixConfig;
|
||||||
import org.embeddedt.modernfix.forge.classloading.ClassLoadHack;
|
import org.embeddedt.modernfix.forge.classloading.ClassLoadHack;
|
||||||
import org.embeddedt.modernfix.forge.classloading.ModFileScanDataDeduplicator;
|
import org.embeddedt.modernfix.forge.classloading.ModFileScanDataDeduplicator;
|
||||||
|
|
@ -46,24 +43,24 @@ public class ModernFixForge {
|
||||||
commonMod = new ModernFix();
|
commonMod = new ModernFix();
|
||||||
// Register ourselves for server and other game events we are interested in
|
// Register ourselves for server and other game events we are interested in
|
||||||
MinecraftForge.EVENT_BUS.register(this);
|
MinecraftForge.EVENT_BUS.register(this);
|
||||||
|
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onCommandRegister);
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup);
|
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::commonSetup);
|
||||||
FMLJavaModLoadingContext.get().getModEventBus().addGenericListener(Item.class, this::registerItems);
|
FMLJavaModLoadingContext.get().getModEventBus().addGenericListener(Item.class, this::registerItems);
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClientForge()));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> MinecraftForge.EVENT_BUS.register(new ModernFixClientForge()));
|
||||||
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true));
|
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (a, b) -> true));
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModernFixConfig.COMMON_CONFIG);
|
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModernFixConfig.COMMON_CONFIG);
|
||||||
if(ModList.get().isLoaded("kubejs"))
|
if(ModList.get().isLoaded("kubejs"))
|
||||||
MinecraftForge.EVENT_BUS.register(KubeUtil.class);
|
FMLJavaModLoadingContext.get().getModEventBus().register(KubeUtil.class);
|
||||||
PacketHandler.register();
|
PacketHandler.register();
|
||||||
ModFileScanDataDeduplicator.deduplicate();
|
ModFileScanDataDeduplicator.deduplicate();
|
||||||
ClassLoadHack.loadModClasses();
|
ClassLoadHack.loadModClasses();
|
||||||
ConfigFixer.replaceConfigHandlers();
|
ConfigFixer.replaceConfigHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
public void onCommandRegister(FMLServerStartingEvent event) {
|
||||||
public void onCommandRegister(RegisterCommandsEvent event) {
|
|
||||||
// Register separate commands since redirecting doesn't work without arguments
|
// Register separate commands since redirecting doesn't work without arguments
|
||||||
for(String name : new String[] { "mfrc", "mfsrc"}) {
|
for(String name : new String[] { "mfrc", "mfsrc"}) {
|
||||||
event.getDispatcher().register(LiteralArgumentBuilder.<CommandSourceStack>literal(name)
|
event.getCommandDispatcher().register(LiteralArgumentBuilder.<CommandSourceStack>literal(name)
|
||||||
.requires(source -> source.hasPermission(3))
|
.requires(source -> source.hasPermission(3))
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
NightConfigFixer.runReloads();
|
NightConfigFixer.runReloads();
|
||||||
|
|
@ -72,15 +69,6 @@ public class ModernFixForge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void onDatapackSync(OnDatapackSyncEvent event) {
|
|
||||||
if(event.getPlayer() != null) {
|
|
||||||
if(!ServerLifecycleHooks.getCurrentServer().isDedicatedServer() && event.getPlayerList().getPlayerCount() == 0)
|
|
||||||
return;
|
|
||||||
EntityDataIDSyncHandler.onDatapackSyncEvent(event.getPlayer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerItems(RegistryEvent<Item> event) {
|
private void registerItems(RegistryEvent<Item> event) {
|
||||||
if(Boolean.getBoolean("modernfix.largeRegistryTest")) {
|
if(Boolean.getBoolean("modernfix.largeRegistryTest")) {
|
||||||
Item.Properties props = new Item.Properties();
|
Item.Properties props = new Item.Properties();
|
||||||
|
|
@ -98,7 +86,7 @@ public class ModernFixForge {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void commonSetup(FMLCommonSetupEvent event) {
|
public void commonSetup(FMLCommonSetupEvent event) {
|
||||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.warn_missing_perf_mods.Warnings")) {
|
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.warn_missing_perf_mods.Warnings")) {
|
||||||
event.enqueueWork(() -> {
|
DeferredWorkQueue.runLater(() -> {
|
||||||
boolean atLeastOneWarning = false;
|
boolean atLeastOneWarning = false;
|
||||||
for(Pair<List<String>, String> warning : MOD_WARNINGS) {
|
for(Pair<List<String>, String> warning : MOD_WARNINGS) {
|
||||||
boolean isPresent = !FMLLoader.isProduction() || warning.getLeft().stream().anyMatch(name -> ModList.get().isLoaded(name));
|
boolean isPresent = !FMLLoader.isProduction() || warning.getLeft().stream().anyMatch(name -> ModList.get().isLoaded(name));
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package org.embeddedt.modernfix.forge.load;
|
package org.embeddedt.modernfix.forge.load;
|
||||||
|
|
||||||
import net.minecraftforge.fml.ModWorkManager;
|
|
||||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
@ -40,6 +38,7 @@ public class ModWorkManagerQueue extends ConcurrentLinkedDeque<Runnable> {
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public static void replace() {
|
public static void replace() {
|
||||||
|
/*
|
||||||
try {
|
try {
|
||||||
Class<?> syncExecutorClass = Class.forName("net.minecraftforge.fml.ModWorkManager$SyncExecutor");
|
Class<?> syncExecutorClass = Class.forName("net.minecraftforge.fml.ModWorkManager$SyncExecutor");
|
||||||
ConcurrentLinkedDeque<Runnable> taskQueue = (ConcurrentLinkedDeque<Runnable>)ObfuscationReflectionHelper.getPrivateValue((Class)syncExecutorClass, (Object)ModWorkManager.syncExecutor(), "tasks");
|
ConcurrentLinkedDeque<Runnable> taskQueue = (ConcurrentLinkedDeque<Runnable>)ObfuscationReflectionHelper.getPrivateValue((Class)syncExecutorClass, (Object)ModWorkManager.syncExecutor(), "tasks");
|
||||||
|
|
@ -54,5 +53,7 @@ public class ModWorkManagerQueue extends ConcurrentLinkedDeque<Runnable> {
|
||||||
} catch(ReflectiveOperationException e) {
|
} catch(ReflectiveOperationException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import com.stal111.valhelsia_structures.init.ModBlocks;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
import org.embeddedt.modernfix.annotation.RequiresMod;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
@Mixin(value = BlockBehaviour.BlockStateBase.class, priority = 900)
|
@Mixin(value = BlockState.class, priority = 900)
|
||||||
@RequiresMod("valhelsia_structures")
|
@RequiresMod("valhelsia_structures")
|
||||||
public abstract class BlockStateBaseMixin {
|
public abstract class BlockStateBaseMixin {
|
||||||
@Shadow public abstract Block getBlock();
|
@Shadow public abstract Block getBlock();
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ public class ChunkMapMixin {
|
||||||
for (ClassInstanceMultiMap<Entity> entitySection : entitySections) {
|
for (ClassInstanceMultiMap<Entity> entitySection : entitySections) {
|
||||||
if(entitySection == null)
|
if(entitySection == null)
|
||||||
continue;
|
continue;
|
||||||
for (Entity entity : entitySection.getAllInstances()) {
|
for (Entity entity : entitySection) {
|
||||||
if (!(entity instanceof Player) && !this.level.loadFromChunk(entity)) {
|
if (!(entity instanceof Player) && !this.level.loadFromChunk(entity)) {
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
list = Lists.newArrayList(entity);
|
list = Lists.newArrayList(entity);
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.bugfix.file_dialog_title;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.screens.worldselection.WorldGenSettingsComponent;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
|
|
||||||
@Mixin(WorldGenSettingsComponent.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public class WorldGenSettingsComponentMixin {
|
|
||||||
/**
|
|
||||||
* @author embeddedt
|
|
||||||
* @reason Do not provide resource pack-controlled string to TinyFD
|
|
||||||
*/
|
|
||||||
@ModifyArg(method = "*", at = @At(value = "INVOKE", target = "Lorg/lwjgl/util/tinyfd/TinyFileDialogs;tinyfd_openFileDialog(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Lorg/lwjgl/PointerBuffer;Ljava/lang/CharSequence;Z)Ljava/lang/String;", remap = false), index = 0)
|
|
||||||
private CharSequence sanitizeTitleString(CharSequence original) {
|
|
||||||
return "Select settings file (.json)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.bugfix.recipe_book_type_desync;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
|
||||||
import net.minecraft.stats.RecipeBookSettings;
|
|
||||||
import net.minecraft.world.inventory.RecipeBookType;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.embeddedt.modernfix.forge.packet.NetworkUtils;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
|
|
||||||
@Mixin(RecipeBookSettings.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public class RecipeBookSettingsMixin {
|
|
||||||
private static int mfix$maxVanillaOrdinal;
|
|
||||||
|
|
||||||
static {
|
|
||||||
int ord = 0;
|
|
||||||
for(Field f : RecipeBookType.class.getDeclaredFields()) {
|
|
||||||
if(RecipeBookType.class.isAssignableFrom(f.getType()) && Modifier.isStatic(f.getModifiers()) && Modifier.isPublic(f.getModifiers())) {
|
|
||||||
try {
|
|
||||||
f.setAccessible(true);
|
|
||||||
RecipeBookType type = (RecipeBookType)f.get(null);
|
|
||||||
ord = Math.max(type.ordinal(), ord);
|
|
||||||
} catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
ord = Integer.MAX_VALUE - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mfix$maxVanillaOrdinal = ord;
|
|
||||||
}
|
|
||||||
@Redirect(method = "read(Lnet/minecraft/network/FriendlyByteBuf;)Lnet/minecraft/stats/RecipeBookSettings;", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/FriendlyByteBuf;readBoolean()Z"))
|
|
||||||
private static boolean useDefaultBooleanIfVanilla(FriendlyByteBuf buf, @Local(ordinal = 0) RecipeBookType type) {
|
|
||||||
if(type.ordinal() >= (mfix$maxVanillaOrdinal + 1) && NetworkUtils.isCurrentlyVanilla) {
|
|
||||||
ModernFix.LOGGER.warn("Not reading recipe book data for type '{}' as we are using vanilla connection", type.name());
|
|
||||||
return false; // skip actually reading buffer
|
|
||||||
}
|
|
||||||
return buf.readBoolean();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.bugfix.remove_block_chunkloading;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
import net.minecraft.world.entity.Mob;
|
|
||||||
import net.minecraft.world.entity.ai.goal.RemoveBlockGoal;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraftforge.event.ForgeEventFactory;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(RemoveBlockGoal.class)
|
|
||||||
public class RemoveBlockGoalMixin {
|
|
||||||
@Shadow @Final private Mob removerMob;
|
|
||||||
|
|
||||||
@Redirect(method = "canUse", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/common/ForgeHooks;canEntityDestroy(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/LivingEntity;)Z"))
|
|
||||||
private boolean fireGriefingEvent(Level level, BlockPos pos, LivingEntity entity) {
|
|
||||||
return ForgeEventFactory.getMobGriefingEvent(level, entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "isValidTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/world/level/block/Block;)Z"))
|
|
||||||
private boolean checkBlockValidDestroyTarget(BlockState state, Block desiredBlock, LevelReader level, BlockPos pos) {
|
|
||||||
if(!(state.canEntityDestroy(level, pos, this.removerMob) && ForgeEventFactory.onEntityDestroyBlock(this.removerMob, pos, state)))
|
|
||||||
return false;
|
|
||||||
return state.is(desiredBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
@Mixin(Minecraft.class)
|
@Mixin(Minecraft.class)
|
||||||
@ClientOnlyMixin
|
@ClientOnlyMixin
|
||||||
public class MinecraftMixin_Forge {
|
public class MinecraftMixin_Forge {
|
||||||
@Inject(method = "loadWorld", at = @At("HEAD"), remap = false)
|
@Inject(method = "selectLevel", at = @At("HEAD"))
|
||||||
private void recordWorldLoadStart(CallbackInfo ci) {
|
private void recordWorldLoadStart(CallbackInfo ci) {
|
||||||
ModernFixClient.worldLoadStartTime = System.nanoTime();
|
ModernFixClient.worldLoadStartTime = System.nanoTime();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_jei;
|
|
||||||
|
|
||||||
import mezz.jei.api.IModPlugin;
|
|
||||||
import mezz.jei.api.helpers.IModIdHelper;
|
|
||||||
import mezz.jei.config.*;
|
|
||||||
import mezz.jei.config.sorting.RecipeCategorySortingConfig;
|
|
||||||
import mezz.jei.events.EventBusHelper;
|
|
||||||
import mezz.jei.events.PlayerJoinedWorldEvent;
|
|
||||||
import mezz.jei.gui.textures.Textures;
|
|
||||||
import mezz.jei.ingredients.IIngredientSorter;
|
|
||||||
import mezz.jei.startup.ClientLifecycleHandler;
|
|
||||||
import mezz.jei.startup.JeiStarter;
|
|
||||||
import mezz.jei.startup.NetworkHandler;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
|
||||||
import org.embeddedt.modernfix.jei.async.JEILoadingInterruptedException;
|
|
||||||
import org.embeddedt.modernfix.jei.async.JEIReloadThread;
|
|
||||||
import org.embeddedt.modernfix.forge.util.JEIUtil;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mixin(ClientLifecycleHandler.class)
|
|
||||||
@RequiresMod("jei")
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public class ClientLifecycleHandlerMixin {
|
|
||||||
@Shadow(remap = false) @Final private JeiStarter starter;
|
|
||||||
@Shadow(remap = false) @Final private List<IModPlugin> plugins;
|
|
||||||
@Shadow(remap = false) @Final private Textures textures;
|
|
||||||
@Shadow(remap = false) @Final private IClientConfig clientConfig;
|
|
||||||
@Shadow(remap = false) @Final private IEditModeConfig editModeConfig;
|
|
||||||
@Shadow(remap = false) @Final private IngredientFilterConfig ingredientFilterConfig;
|
|
||||||
@Shadow(remap = false) @Final private WorldConfig worldConfig;
|
|
||||||
@Shadow(remap = false) @Final private BookmarkConfig bookmarkConfig;
|
|
||||||
@Shadow(remap = false) @Final private IModIdHelper modIdHelper;
|
|
||||||
@Shadow(remap = false) @Final private RecipeCategorySortingConfig recipeCategorySortingConfig;
|
|
||||||
@Shadow(remap = false) @Final private IIngredientSorter ingredientSorter;
|
|
||||||
private volatile JEIReloadThread reloadThread = null;
|
|
||||||
@Inject(method = "setupJEI", at = @At(value = "INVOKE", target = "Lmezz/jei/startup/ClientLifecycleHandler;startJEI()V"), cancellable = true, remap = false)
|
|
||||||
private void startAsync(CallbackInfo ci) {
|
|
||||||
ci.cancel();
|
|
||||||
startJEIAsync(() -> Minecraft.getInstance().execute(() -> EventBusHelper.post(new PlayerJoinedWorldEvent())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author embeddedt
|
|
||||||
* @reason force JEI starts to be asynchronous
|
|
||||||
*/
|
|
||||||
@Overwrite(remap = false)
|
|
||||||
public void startJEI() {
|
|
||||||
startJEIAsync(() -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("TAIL"))
|
|
||||||
private void setupCancellationHandler(NetworkHandler networkHandler, Textures textures, CallbackInfo ci) {
|
|
||||||
EventBusHelper.addListener(this, ClientPlayerNetworkEvent.LoggedOutEvent.class, event -> cancelPreviousStart());
|
|
||||||
JEIUtil.registerLoadingRenderer(() -> reloadThread != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelPreviousStart() {
|
|
||||||
JEIReloadThread currentReloadThread = reloadThread;
|
|
||||||
if(currentReloadThread != null) {
|
|
||||||
currentReloadThread.requestStop();
|
|
||||||
if(currentReloadThread.isAlive()) {
|
|
||||||
ModernFix.LOGGER.warn("Blocking until JEI thread terminates");
|
|
||||||
Minecraft.getInstance().managedBlock(() -> !currentReloadThread.isAlive());
|
|
||||||
}
|
|
||||||
reloadThread = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int numReloads = 1;
|
|
||||||
|
|
||||||
private void startJEIAsync(Runnable whenFinishedCb) {
|
|
||||||
cancelPreviousStart();
|
|
||||||
if(Minecraft.getInstance().level == null)
|
|
||||||
return;
|
|
||||||
ModernFix.LOGGER.info("Starting new JEI thread.");
|
|
||||||
JEIReloadThread newThread = new JEIReloadThread(() -> {
|
|
||||||
if(((JEIReloadThread)Thread.currentThread()).isStopRequested())
|
|
||||||
return;
|
|
||||||
try {
|
|
||||||
starter.start(
|
|
||||||
plugins,
|
|
||||||
textures,
|
|
||||||
clientConfig,
|
|
||||||
editModeConfig,
|
|
||||||
ingredientFilterConfig,
|
|
||||||
worldConfig,
|
|
||||||
bookmarkConfig,
|
|
||||||
modIdHelper,
|
|
||||||
recipeCategorySortingConfig,
|
|
||||||
ingredientSorter);
|
|
||||||
} catch(JEILoadingInterruptedException e) {
|
|
||||||
ModernFix.LOGGER.warn("JEI loading interrupted prematurely (this is normal)");
|
|
||||||
}
|
|
||||||
whenFinishedCb.run();
|
|
||||||
reloadThread = null;
|
|
||||||
}, "ModernFix JEI Reload Thread " + numReloads++);
|
|
||||||
newThread.setPriority(Thread.MIN_PRIORITY);
|
|
||||||
reloadThread = newThread;
|
|
||||||
newThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_jei;
|
|
||||||
|
|
||||||
import mezz.jei.api.ingredients.IIngredientType;
|
|
||||||
import mezz.jei.api.runtime.IIngredientManager;
|
|
||||||
import mezz.jei.gui.ingredients.IIngredientListElement;
|
|
||||||
import mezz.jei.ingredients.IngredientListElementFactory;
|
|
||||||
import net.minecraft.core.NonNullList;
|
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
|
||||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(IngredientListElementFactory.class)
|
|
||||||
@RequiresMod("jei")
|
|
||||||
public class IngredientListElementFactoryMixin {
|
|
||||||
private static int ingredientNum = 0;
|
|
||||||
@Inject(method = "addToBaseList", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/NonNullList;add(Ljava/lang/Object;)Z"))
|
|
||||||
private static void checkForInterrupt(NonNullList<IIngredientListElement<?>> baseList, IIngredientManager ingredientManager, IIngredientType ingredientType, CallbackInfo ci) {
|
|
||||||
if((ingredientNum++ % 100) == 0)
|
|
||||||
IAsyncJeiStarter.checkForLoadInterruption();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_jei;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(InputConstants.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
@RequiresMod("jei")
|
|
||||||
public class InputConstantsMixin {
|
|
||||||
@Redirect(method = "isKeyDown", at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwGetKey(JI)I", remap = false))
|
|
||||||
private static int offThreadKeyFetch(long win, int k) {
|
|
||||||
if(RenderSystem.isOnRenderThreadOrInit())
|
|
||||||
return GLFW.glfwGetKey(win, k);
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_jei;
|
|
||||||
|
|
||||||
import mezz.jei.api.IModPlugin;
|
|
||||||
import mezz.jei.api.helpers.IModIdHelper;
|
|
||||||
import mezz.jei.config.*;
|
|
||||||
import mezz.jei.config.sorting.RecipeCategorySortingConfig;
|
|
||||||
import mezz.jei.gui.textures.Textures;
|
|
||||||
import mezz.jei.ingredients.IIngredientSorter;
|
|
||||||
import mezz.jei.load.PluginCaller;
|
|
||||||
import mezz.jei.startup.JeiStarter;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CancellationException;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletionException;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Mixin(JeiStarter.class)
|
|
||||||
@RequiresMod("jei")
|
|
||||||
public class JeiStarterMixin {
|
|
||||||
@Shadow(remap = false) private boolean started;
|
|
||||||
|
|
||||||
@Inject(method = "start", at = @At(value = "INVOKE", target = "Lmezz/jei/util/ErrorUtil;checkNotEmpty(Ljava/util/Collection;Ljava/lang/String;)V", ordinal = 0, shift = At.Shift.AFTER), remap = false)
|
|
||||||
private void setStartedFlag(List<IModPlugin> plugins, Textures textures, IClientConfig clientConfig, IEditModeConfig editModeConfig, IIngredientFilterConfig ingredientFilterConfig, IWorldConfig worldConfig, BookmarkConfig bookmarkConfig, IModIdHelper modIdHelper, RecipeCategorySortingConfig recipeCategorySortingConfig, IIngredientSorter ingredientSorter, CallbackInfo ci) {
|
|
||||||
/* We need to set this ASAP so the reload system will restart the async load if needed */
|
|
||||||
started = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(method = "start", at = @At(value = "INVOKE", target = "Lmezz/jei/load/PluginCaller;callOnPlugins(Ljava/lang/String;Ljava/util/List;Ljava/util/function/Consumer;)V"), remap = false)
|
|
||||||
private void callOnPluginsViaMainThread(String title, List<IModPlugin> plugins, Consumer<IModPlugin> func) {
|
|
||||||
PluginCaller.callOnPlugins(title, plugins, plugin -> {
|
|
||||||
try {
|
|
||||||
Minecraft.getInstance().executeBlocking(() -> func.accept(plugin));
|
|
||||||
} catch(CancellationException | CompletionException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_jei;
|
|
||||||
|
|
||||||
import mezz.jei.api.IModPlugin;
|
|
||||||
import mezz.jei.load.PluginCaller;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
|
||||||
import org.embeddedt.modernfix.forge.ModernFixConfig;
|
|
||||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
@Mixin(PluginCaller.class)
|
|
||||||
@RequiresMod("jei")
|
|
||||||
public class PluginCallerMixin {
|
|
||||||
@Inject(method = "callOnPlugins", at = @At(value = "INVOKE", target = "Ljava/util/Iterator;hasNext()Z"), remap = false)
|
|
||||||
private static void checkForInterrupt(String title, List<IModPlugin> plugins, Consumer<IModPlugin> func, CallbackInfo ci) {
|
|
||||||
IAsyncJeiStarter.checkForLoadInterruption();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked","rawtypes"})
|
|
||||||
@Redirect(method = "callOnPlugins", at = @At(value = "INVOKE", target = "Ljava/util/function/Consumer;accept(Ljava/lang/Object;)V"), remap = false)
|
|
||||||
private static void runOnMainThreadIfNeeded(Consumer instance, Object pluginObj) {
|
|
||||||
IModPlugin plugin = (IModPlugin)pluginObj;
|
|
||||||
if(ModernFixConfig.getJeiPluginBlacklist().contains(plugin.getPluginUid())) {
|
|
||||||
ModernFix.LOGGER.warn("Going to main thread for " + plugin.getPluginUid());
|
|
||||||
Minecraft.getInstance().executeBlocking(() -> instance.accept(plugin));
|
|
||||||
} else {
|
|
||||||
instance.accept(plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_jei;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableListMultimap;
|
|
||||||
import mezz.jei.recipes.RecipeManagerInternal;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
|
||||||
import org.embeddedt.modernfix.jei.async.IAsyncJeiStarter;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(RecipeManagerInternal.class)
|
|
||||||
@RequiresMod("jei")
|
|
||||||
public class RecipeManagerInternalMixin {
|
|
||||||
@Inject(method = "addRecipes", at = @At(value = "INVOKE", target = "Lmezz/jei/recipes/RecipeManagerInternal;addRecipeTyped(Ljava/lang/Object;Lnet/minecraft/resources/ResourceLocation;)V"))
|
|
||||||
private void checkForInterrupt(ImmutableListMultimap<ResourceLocation, Object> recipes, CallbackInfo ci) {
|
|
||||||
IAsyncJeiStarter.checkForLoadInterruption();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.commands.CommandSource;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
@Mixin(CommandSourceStack.class)
|
|
||||||
public interface CommandSourceStackAccess {
|
|
||||||
@Accessor
|
|
||||||
CommandSource getSource();
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.entity.animal.Dolphin;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.AsyncLocator;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
@Mixin(targets = "net.minecraft.world.entity.animal.Dolphin$DolphinSwimToTreasureGoal")
|
|
||||||
public class DolphinSwimToTreasureGoalMixin {
|
|
||||||
@Final
|
|
||||||
@Shadow
|
|
||||||
private Dolphin dolphin;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private boolean stuck;
|
|
||||||
|
|
||||||
private AsyncLocator.LocateTask<BlockPos> locateTask = null;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Intercept DolphinSwimToTreasureGoal#start call right before it calls ServerLevel#findNearestMapFeature to pass
|
|
||||||
the logic over to an async task.
|
|
||||||
*/
|
|
||||||
@Inject(
|
|
||||||
method = "start",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;"
|
|
||||||
),
|
|
||||||
cancellable = true,
|
|
||||||
locals = LocalCapture.CAPTURE_FAILSOFT
|
|
||||||
)
|
|
||||||
public void findTreasureAsync(CallbackInfo ci, ServerLevel level, BlockPos blockpos) {
|
|
||||||
ModernFix.LOGGER.debug("Intercepted DolphinSwimToTreasureGoal#start call");
|
|
||||||
handleFindTreasureAsync(level, blockpos);
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Intercept DolphinSwimToTreasureGoal#canContinueToUse to return true if an async locating task is ongoing so that
|
|
||||||
the goal isn't ended early due to no treasure pos being set yet.
|
|
||||||
*/
|
|
||||||
@Inject(
|
|
||||||
method = "canContinueToUse",
|
|
||||||
at = @At(value = "HEAD"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
public void continueToUseIfLocatingTreasure(CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
if (locateTask != null) {
|
|
||||||
ModernFix.LOGGER.debug("Locating task ongoing - returning true for continueToUse()");
|
|
||||||
cir.setReturnValue(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "stop",
|
|
||||||
at = @At(value = "HEAD")
|
|
||||||
)
|
|
||||||
public void stopLocatingTreasure(CallbackInfo ci) {
|
|
||||||
if (locateTask != null) {
|
|
||||||
ModernFix.LOGGER.debug("Locating task ongoing - cancelling during stop()");
|
|
||||||
locateTask.cancel();
|
|
||||||
locateTask = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Intercept DolphinSwimToTreasureGoal#tick to return early if an async locating task is ongoing so that the
|
|
||||||
dolphin doesn't try to go towards an old treasure position.
|
|
||||||
*/
|
|
||||||
@Inject(
|
|
||||||
method = "tick",
|
|
||||||
at = @At(value = "HEAD"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
public void skipTickingIfLocatingTreasure(CallbackInfo ci) {
|
|
||||||
if (locateTask != null) {
|
|
||||||
ModernFix.LOGGER.debug("Locating task ongoing - skipping tick()");
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleFindTreasureAsync(ServerLevel level, BlockPos blockPos) {
|
|
||||||
locateTask = AsyncLocator.locateLevel(level, ImmutableSet.of(StructureFeature.OCEAN_RUIN, StructureFeature.SHIPWRECK), blockPos, 50, false)
|
|
||||||
.thenOnServerThread(pos -> handleLocationFound(level, pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleLocationFound(ServerLevel level, BlockPos pos) {
|
|
||||||
locateTask = null;
|
|
||||||
if (pos != null) {
|
|
||||||
ModernFix.LOGGER.debug("Location found - updating dolphin treasure pos");
|
|
||||||
dolphin.setTreasurePos(pos);
|
|
||||||
level.broadcastEntityEvent(dolphin, (byte) 38);
|
|
||||||
} else {
|
|
||||||
ModernFix.LOGGER.debug("No location found - marking dolphin as stuck");
|
|
||||||
stuck = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.advancements.critereon.UsedEnderEyeTrigger;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.stats.Stat;
|
|
||||||
import net.minecraft.world.InteractionHand;
|
|
||||||
import net.minecraft.world.InteractionResultHolder;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.entity.projectile.EyeOfEnder;
|
|
||||||
import net.minecraft.world.item.EnderEyeItem;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
|
||||||
import net.minecraft.world.phys.HitResult;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.EnderEyeItemLogic;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
@Mixin(EnderEyeItem.class)
|
|
||||||
public class EnderEyeItemMixin {
|
|
||||||
/*
|
|
||||||
Intercept EnderEyeItem#use call and return BlockPos.ZERO instead. It won't be used in the EyeOfEnder entity
|
|
||||||
created later either, as we need to set the actual location ourselves.
|
|
||||||
*/
|
|
||||||
@Redirect(
|
|
||||||
method = "use",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/world/level/chunk/ChunkGenerator;findNearestMapFeature(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
public BlockPos levelFindNearestMapFeature(
|
|
||||||
ChunkGenerator generator,
|
|
||||||
ServerLevel level,
|
|
||||||
StructureFeature<?> structureFeature,
|
|
||||||
BlockPos pPos,
|
|
||||||
int pRadius,
|
|
||||||
boolean pSkipExistingChunks
|
|
||||||
) {
|
|
||||||
return BlockPos.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the async locate task here so we have the eye of ender entity for context
|
|
||||||
@Inject(
|
|
||||||
method = "use",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/world/entity/projectile/EyeOfEnder;setItem(Lnet/minecraft/world/item/ItemStack;)V"
|
|
||||||
),
|
|
||||||
locals = LocalCapture.CAPTURE_FAILEXCEPTION
|
|
||||||
)
|
|
||||||
public void startAsyncLocateTask(
|
|
||||||
Level pLevel,
|
|
||||||
Player pPlayer,
|
|
||||||
InteractionHand pHand,
|
|
||||||
CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir,
|
|
||||||
ItemStack itemstack,
|
|
||||||
HitResult hitresult,
|
|
||||||
BlockPos blockpos,
|
|
||||||
EyeOfEnder eyeofender
|
|
||||||
) {
|
|
||||||
EnderEyeItemLogic.locateAsync((ServerLevel)pLevel, pPlayer, eyeofender, (EnderEyeItem) (Object) this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(
|
|
||||||
method = "use",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/world/entity/projectile/EyeOfEnder;signalTo(Lnet/minecraft/core/BlockPos;)V"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
public void eyeOfEnderSignalTo(EyeOfEnder eyeOfEnder, BlockPos blockpos) {
|
|
||||||
// Do nothing - we'll do this later if a location is found
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(
|
|
||||||
method = "use",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/advancements/critereon/UsedEnderEyeTrigger;trigger(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/core/BlockPos;)V"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
public void triggerUsedEnderEyeCriteria(UsedEnderEyeTrigger trigger, ServerPlayer player, BlockPos pos) {
|
|
||||||
// Do nothing - we'll do this later if a location is found
|
|
||||||
}
|
|
||||||
|
|
||||||
@Redirect(
|
|
||||||
method = "use",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/world/entity/player/Player;awardStat(Lnet/minecraft/stats/Stat;)V"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
public void playerAwardStat(Player instance, Stat<?> pStat) {
|
|
||||||
// Do nothing - we'll do this later if a location is found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
|
||||||
import net.minecraft.world.level.saveddata.maps.MapDecoration;
|
|
||||||
import net.minecraft.world.level.storage.loot.LootContext;
|
|
||||||
import net.minecraft.world.level.storage.loot.functions.ExplorationMapFunction;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.ExplorationMapFunctionLogic;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
@Mixin(ExplorationMapFunction.class)
|
|
||||||
public class ExplorationMapFunctionMixin {
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
StructureFeature<?> destination;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
MapDecoration.Type mapDecoration;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
byte zoom;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
int searchRadius;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
boolean skipKnownStructures;
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "run",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;"
|
|
||||||
),
|
|
||||||
locals = LocalCapture.CAPTURE_FAILSOFT,
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
public void updateMapAsync(
|
|
||||||
ItemStack pStack,
|
|
||||||
LootContext pContext,
|
|
||||||
CallbackInfoReturnable<ItemStack> cir,
|
|
||||||
Vec3 vec3,
|
|
||||||
ServerLevel serverlevel
|
|
||||||
) {
|
|
||||||
ItemStack mapStack = ExplorationMapFunctionLogic.updateMapAsync(
|
|
||||||
serverlevel, new BlockPos(vec3), zoom, searchRadius, skipKnownStructures, mapDecoration, destination
|
|
||||||
);
|
|
||||||
cir.setReturnValue(mapStack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.world.entity.projectile.EyeOfEnder;
|
|
||||||
import org.embeddedt.modernfix.annotation.IgnoreMixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
@Mixin(EyeOfEnder.class)
|
|
||||||
@IgnoreMixin
|
|
||||||
public interface EyeOfEnderAccess {
|
|
||||||
@Accessor
|
|
||||||
void setLife(int life);
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.world.entity.projectile.EyeOfEnder;
|
|
||||||
import org.embeddedt.modernfix.annotation.IgnoreMixin;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.EyeOfEnderData;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
@Mixin(EyeOfEnder.class)
|
|
||||||
@IgnoreMixin
|
|
||||||
public class EyeOfEnderMixin implements EyeOfEnderData {
|
|
||||||
private boolean locateTaskOngoing = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLocateTaskOngoing(boolean locateTaskOngoing) {
|
|
||||||
this.locateTaskOngoing = locateTaskOngoing;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Intercept EyeOfEnder#tick call and return after the super call if there's an ongoing locate task. This is to
|
|
||||||
prevent the entity from moving or dying until we have a location result.
|
|
||||||
*/
|
|
||||||
@Inject(
|
|
||||||
method = "tick",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/world/entity/Entity;tick()V",
|
|
||||||
shift = At.Shift.AFTER
|
|
||||||
),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
public void skipTick(CallbackInfo ci) {
|
|
||||||
if (locateTaskOngoing) {
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
|
||||||
import net.minecraft.server.commands.LocateCommand;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
@Mixin(LocateCommand.class)
|
|
||||||
public interface LocateCommandAccess {
|
|
||||||
@Accessor("ERROR_FAILED")
|
|
||||||
static SimpleCommandExceptionType getErrorFailed() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.commands.CommandSource;
|
|
||||||
import net.minecraft.commands.CommandSourceStack;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.commands.LocateCommand;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.LocateCommandLogic;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
|
||||||
|
|
||||||
@Mixin(LocateCommand.class)
|
|
||||||
public class LocateCommandMixin {
|
|
||||||
@Inject(
|
|
||||||
method = "locate",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;"
|
|
||||||
),
|
|
||||||
cancellable = true,
|
|
||||||
locals = LocalCapture.CAPTURE_FAILSOFT
|
|
||||||
)
|
|
||||||
private static void findLocationAsync(CommandSourceStack sourceStack, StructureFeature<?> feature, CallbackInfoReturnable<Integer> cir) {
|
|
||||||
CommandSource source = ((CommandSourceStackAccess) sourceStack).getSource();
|
|
||||||
if (source instanceof ServerPlayer || source instanceof MinecraftServer) {
|
|
||||||
LocateCommandLogic.locateAsync(sourceStack, feature);
|
|
||||||
cir.setReturnValue(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceKey;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.MapItem;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.saveddata.maps.MapItemSavedData;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
|
||||||
|
|
||||||
@Mixin(MapItem.class)
|
|
||||||
public interface MapItemAccess {
|
|
||||||
@Invoker
|
|
||||||
static MapItemSavedData callCreateAndStoreSavedData(ItemStack pStack, Level pLevel, int pX, int pZ, int pScale, boolean pTrackingPosition, boolean pUnlimitedTracking, ResourceKey<Level> pDimension) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.world.item.trading.MerchantOffer;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
@Mixin(MerchantOffer.class)
|
|
||||||
public interface MerchantOfferAccess {
|
|
||||||
@Mutable
|
|
||||||
@Accessor
|
|
||||||
void setMaxUses(int maxUses);
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.storage.loot.functions.SetNameFunction;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.ExplorationMapFunctionLogic;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
|
||||||
|
|
||||||
@Mixin(SetNameFunction.class)
|
|
||||||
public class SetNameFunctionMixin {
|
|
||||||
@Redirect(
|
|
||||||
method = "run",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/world/item/ItemStack;setHoverName(Lnet/minecraft/network/chat/Component;)Lnet/minecraft/world/item/ItemStack;"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
public ItemStack deferSetName(ItemStack stack, Component name) {
|
|
||||||
if (CommonLogic.isEmptyPendingMap(stack))
|
|
||||||
ExplorationMapFunctionLogic.cacheName(stack, name);
|
|
||||||
else
|
|
||||||
stack.setHoverName(name);
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.inventory.Slot;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.CommonLogic;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
@Mixin(Slot.class)
|
|
||||||
public abstract class SlotMixin {
|
|
||||||
@Shadow
|
|
||||||
public abstract ItemStack getItem();
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "mayPickup",
|
|
||||||
at = @At(value = "HEAD"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
public void preventPickupOfPendingExplorationMap(Player player, CallbackInfoReturnable<Boolean> cir) {
|
|
||||||
if (CommonLogic.isEmptyPendingMap(getItem())) {
|
|
||||||
cir.setReturnValue(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.async_locator;
|
|
||||||
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.item.trading.MerchantOffer;
|
|
||||||
import net.minecraft.world.level.levelgen.feature.StructureFeature;
|
|
||||||
import net.minecraft.world.level.saveddata.maps.MapDecoration;
|
|
||||||
import org.embeddedt.modernfix.forge.structure.logic.MerchantLogic;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
@Mixin(targets = "net.minecraft.world.entity.npc.VillagerTrades$TreasureMapForEmeralds")
|
|
||||||
public class TreasureMapForEmeraldsMixin {
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private int emeraldCost;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private MapDecoration.Type destinationType;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private int maxUses;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private int villagerXp;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private StructureFeature<?> destination;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Intercept TreasureMapForEmeralds#getOffer call right before it calls ServerLevel#findNearestMapFeature to pass
|
|
||||||
the logic over to an async task. Instead of returning the complete map or null, we'll have to always return an
|
|
||||||
incomplete filled map and later update it with the details when we have them.
|
|
||||||
*/
|
|
||||||
@Inject(
|
|
||||||
method = "getOffer",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/server/level/ServerLevel;findNearestMapFeature(Lnet/minecraft/world/level/levelgen/feature/StructureFeature;Lnet/minecraft/core/BlockPos;IZ)Lnet/minecraft/core/BlockPos;"
|
|
||||||
),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
public void updateMapAsync(Entity pTrader, Random pRand, CallbackInfoReturnable<MerchantOffer> callbackInfo) {
|
|
||||||
String displayName = "filled_map." + this.destination.getFeatureName().toLowerCase(Locale.ROOT);
|
|
||||||
MerchantOffer offer = MerchantLogic.updateMapAsync(
|
|
||||||
pTrader, emeraldCost, displayName, destinationType, maxUses, villagerXp, destination
|
|
||||||
);
|
|
||||||
if (offer != null) {
|
|
||||||
callbackInfo.setReturnValue(offer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.blast_search_trees;
|
package org.embeddedt.modernfix.forge.mixin.perf.blast_search_trees;
|
||||||
|
|
||||||
import mezz.jei.ingredients.IIngredientListElementInfo;
|
import mezz.jei.gui.ingredients.IIngredientListElement;
|
||||||
import mezz.jei.ingredients.IngredientFilter;
|
import mezz.jei.ingredients.IngredientFilter;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
@ -10,5 +10,5 @@ import java.util.List;
|
||||||
@Mixin(IngredientFilter.class)
|
@Mixin(IngredientFilter.class)
|
||||||
public interface IngredientFilterInvoker {
|
public interface IngredientFilterInvoker {
|
||||||
@Invoker(remap = false)
|
@Invoker(remap = false)
|
||||||
List<IIngredientListElementInfo<?>> invokeGetIngredientListUncached(String filterText);
|
List<IIngredientListElement<?>> invokeGetIngredientListUncached(String filterText);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ public class ForgeHooksClientMixin {
|
||||||
*/
|
*/
|
||||||
@Redirect(method = "onModelBake", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/ModLoader;postEvent(Lnet/minecraftforge/eventbus/api/Event;)V"), remap = false)
|
@Redirect(method = "onModelBake", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/ModLoader;postEvent(Lnet/minecraftforge/eventbus/api/Event;)V"), remap = false)
|
||||||
private static void postNamespacedKeySetEvent(ModLoader loader, Event event) {
|
private static void postNamespacedKeySetEvent(ModLoader loader, Event event) {
|
||||||
if(!ModLoader.isLoadingStateValid())
|
|
||||||
return;
|
|
||||||
ModelBakeEvent bakeEvent = ((ModelBakeEvent)event);
|
ModelBakeEvent bakeEvent = ((ModelBakeEvent)event);
|
||||||
ModelBakeEventHelper helper = new ModelBakeEventHelper(bakeEvent.getModelRegistry());
|
ModelBakeEventHelper helper = new ModelBakeEventHelper(bakeEvent.getModelRegistry());
|
||||||
Method acceptEv = ObfuscationReflectionHelper.findMethod(ModContainer.class, "acceptEvent", Event.class);
|
Method acceptEv = ObfuscationReflectionHelper.findMethod(ModContainer.class, "acceptEvent", Event.class);
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ import net.minecraft.client.renderer.texture.TextureManager;
|
||||||
import net.minecraft.client.resources.ClientPackSource;
|
import net.minecraft.client.resources.ClientPackSource;
|
||||||
import net.minecraft.client.resources.model.*;
|
import net.minecraft.client.resources.model.*;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.packs.FilePackResources;
|
import net.minecraft.server.packs.FileResourcePack;
|
||||||
import net.minecraft.server.packs.FolderPackResources;
|
import net.minecraft.server.packs.FolderResourcePack;
|
||||||
import net.minecraft.server.packs.PackResources;
|
import net.minecraft.server.packs.Pack;
|
||||||
import net.minecraft.server.packs.VanillaPackResources;
|
import net.minecraft.server.packs.VanillaPack;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
|
@ -190,13 +190,13 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean trustedResourcePack(PackResources pack) {
|
private boolean trustedResourcePack(Pack pack) {
|
||||||
return pack instanceof VanillaPackResources ||
|
return pack instanceof VanillaPack ||
|
||||||
pack instanceof ModFileResourcePack ||
|
pack instanceof ModFileResourcePack ||
|
||||||
pack instanceof ClientPackSource ||
|
pack instanceof ClientPackSource ||
|
||||||
pack instanceof DelegatingResourcePack ||
|
pack instanceof DelegatingResourcePack ||
|
||||||
pack instanceof FolderPackResources ||
|
pack instanceof FolderResourcePack ||
|
||||||
pack instanceof FilePackResources;
|
pack instanceof FileResourcePack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.kubejs;
|
|
||||||
|
|
||||||
import dev.latvian.kubejs.recipe.RecipeJS;
|
|
||||||
import dev.latvian.kubejs.recipe.filter.IDFilter;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
|
||||||
import org.embeddedt.modernfix.forge.util.KubeUtil;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Overwrite;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
|
|
||||||
@Mixin(IDFilter.class)
|
|
||||||
@RequiresMod("kubejs")
|
|
||||||
public class IDFilterMixin {
|
|
||||||
@Shadow @Final private ResourceLocation id;
|
|
||||||
private RecipeJS _target;
|
|
||||||
private boolean _targetSearched = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author embeddedt
|
|
||||||
* @reason avoid scanning every recipe
|
|
||||||
*/
|
|
||||||
@Overwrite(remap = false)
|
|
||||||
public boolean test(RecipeJS recipe) {
|
|
||||||
if(!_targetSearched) {
|
|
||||||
if(KubeUtil.originalRecipesByHash.size() > 0) {
|
|
||||||
_target = KubeUtil.originalRecipesByHash.get(this.id);
|
|
||||||
_targetSearched = true;
|
|
||||||
} else
|
|
||||||
return recipe.getOrCreateId().equals(this.id); // fallback
|
|
||||||
}
|
|
||||||
return recipe == _target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user