Merge remote-tracking branch 'origin/1.19.2' into 1.19.4
This commit is contained in:
commit
ea25f2e854
8
.github/workflows/gradle.yml
vendored
8
.github/workflows/gradle.yml
vendored
|
|
@ -22,5 +22,9 @@ jobs:
|
|||
run: ./gradlew --no-daemon build
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Package
|
||||
path: build/libs
|
||||
name: Forge
|
||||
path: forge/build/libs
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Fabric
|
||||
path: fabric/build/libs
|
||||
242
build.gradle
242
build.gradle
|
|
@ -1,109 +1,140 @@
|
|||
plugins {
|
||||
id "dev.architectury.loom" version "1.1-SNAPSHOT"
|
||||
id "architectury-plugin" version "3.4-SNAPSHOT"
|
||||
id "dev.architectury.loom" version "1.1-SNAPSHOT" apply false
|
||||
id "maven-publish"
|
||||
id 'com.matthewprenger.cursegradle' version '1.4.0'
|
||||
id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
|
||||
id 'com.palantir.git-version' version '1.0.0'
|
||||
id 'se.bjurr.gitchangelog.git-changelog-gradle-plugin' version '1.79.0'
|
||||
id "com.modrinth.minotaur" version "2.+"
|
||||
id "com.modrinth.minotaur" version "2.+" apply false
|
||||
id("com.diffplug.spotless") version "6.18.0" apply false
|
||||
}
|
||||
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
group = 'org.embeddedt'
|
||||
version = gitVersion()
|
||||
|
||||
java {
|
||||
archivesBaseName = 'modernfix-mc' + minecraft_version
|
||||
architectury {
|
||||
minecraft = rootProject.minecraft_version
|
||||
}
|
||||
|
||||
loom {
|
||||
// use this if you are using the official mojang mappings
|
||||
// and want loom to stop warning you about their license
|
||||
silentMojangMappingsLicense()
|
||||
ext.archives_base_name = 'modernfix-mc' + minecraft_version
|
||||
|
||||
// since loom 0.10, you are **required** to use the
|
||||
// "forge" block to configure forge-specific features,
|
||||
// such as the mixinConfigs array or datagen
|
||||
forge {
|
||||
// specify the mixin configs used in this mod
|
||||
// this will be added to the jar manifest as well!
|
||||
mixinConfigs = [
|
||||
"modernfix.mixins.json"
|
||||
allprojects {
|
||||
apply plugin: "java"
|
||||
apply plugin: "architectury-plugin"
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: "com.diffplug.spotless"
|
||||
|
||||
spotless {
|
||||
java {
|
||||
removeUnusedImports()
|
||||
}
|
||||
}
|
||||
|
||||
group = 'org.embeddedt'
|
||||
version = gitVersion()
|
||||
archivesBaseName = rootProject.archives_base_name + '-' + project.name
|
||||
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
repositories {
|
||||
maven { url 'https://modmaven.dev/' }
|
||||
maven {
|
||||
url "https://cursemaven.com"
|
||||
content {
|
||||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = 'ParchmentMC'
|
||||
url = 'https://maven.parchmentmc.org'
|
||||
}
|
||||
maven {
|
||||
// Shedaniel's maven (Architectury API)
|
||||
url = "https://maven.architectury.dev"
|
||||
content {
|
||||
includeGroup "me.shedaniel"
|
||||
}
|
||||
}
|
||||
|
||||
maven {
|
||||
// saps.dev Maven (KubeJS and Rhino)
|
||||
url = "https://maven.saps.dev/minecraft"
|
||||
content {
|
||||
includeGroup "dev.latvian.mods"
|
||||
}
|
||||
}
|
||||
maven { // CTM
|
||||
url "https://maven.tterrag.com/"
|
||||
}
|
||||
maven { url 'https://maven.blamejared.com' }
|
||||
repositories {
|
||||
maven {
|
||||
name = "Fuzs Mod Resources"
|
||||
url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: "dev.architectury.loom"
|
||||
|
||||
loom {
|
||||
silentMojangMappingsLicense()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
|
||||
mappings loom.officialMojangMappings()
|
||||
}
|
||||
|
||||
processResources {
|
||||
def mixinFileList = []
|
||||
def mixinDirectory = file("src/main/java/org/embeddedt/modernfix/" + project.name + "/mixin")
|
||||
fileTree(mixinDirectory).visit { FileVisitDetails details ->
|
||||
if(details.file.isFile()) {
|
||||
def fileName = mixinDirectory.relativePath(details.file).toString().replaceFirst(/\.java$/, "").replace('/', '.')
|
||||
mixinFileList << fileName
|
||||
}
|
||||
}
|
||||
|
||||
def mixinClassesStringB = new StringBuilder()
|
||||
for(int i = 0; i < mixinFileList.size(); i++) {
|
||||
mixinClassesStringB.append(" \"")
|
||||
mixinClassesStringB.append(mixinFileList.get(i))
|
||||
mixinClassesStringB.append('"')
|
||||
if(i < (mixinFileList.size() - 1))
|
||||
mixinClassesStringB.append(',')
|
||||
mixinClassesStringB.append('\n')
|
||||
}
|
||||
|
||||
def replacements = [
|
||||
mixin_classes: mixinClassesStringB.toString()
|
||||
]
|
||||
|
||||
inputs.properties replacements
|
||||
def filePattern = "modernfix-" + project.name + ".mixins.json"
|
||||
filesMatching(filePattern) {
|
||||
expand replacements
|
||||
}
|
||||
}
|
||||
mixin.defaultRefmapName = "modernfix.refmap.json"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url 'https://modmaven.dev/' }
|
||||
maven {
|
||||
url "https://cursemaven.com"
|
||||
content {
|
||||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = 'ParchmentMC'
|
||||
url = 'https://maven.parchmentmc.org'
|
||||
}
|
||||
maven {
|
||||
// Shedaniel's maven (Architectury API)
|
||||
url = "https://maven.architectury.dev"
|
||||
content {
|
||||
includeGroup "me.shedaniel"
|
||||
}
|
||||
}
|
||||
|
||||
maven {
|
||||
// saps.dev Maven (KubeJS and Rhino)
|
||||
url = "https://maven.saps.dev/minecraft"
|
||||
content {
|
||||
includeGroup "dev.latvian.mods"
|
||||
}
|
||||
}
|
||||
maven { // CTM
|
||||
url "https://maven.tterrag.com/"
|
||||
}
|
||||
maven { url "https://maven.shedaniel.me" }
|
||||
maven { url 'https://maven.blamejared.com' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// to change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
|
||||
// choose what mappings you want to use here
|
||||
// leave this uncommented if you want to use
|
||||
// mojang's official mappings, or feel free
|
||||
// to add your own mappings here (how about
|
||||
// mojmap layered with parchment, for example?)
|
||||
mappings loom.officialMojangMappings()
|
||||
/*
|
||||
mappings loom.layered() {
|
||||
officialMojangMappings()
|
||||
parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip")
|
||||
}
|
||||
*/
|
||||
|
||||
// uncomment this if you want to use yarn mappings
|
||||
// mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
|
||||
// your forge dependency, this is **required** when using Forge Loom in forge mode!
|
||||
forge "net.minecraftforge:forge:${project.forge_version}"
|
||||
/*
|
||||
modCompileOnly("mezz.jei:jei-${minecraft_version}:${jei_version}")
|
||||
//modRuntimeOnly("mezz.jei:jei-${minecraft_version}:${jei_version}")
|
||||
|
||||
modCompileOnly("curse.maven:refinedstorage-243076:${refined_storage_version}")
|
||||
|
||||
// compile against the JEI API but do not include it at runtime
|
||||
modCompileOnly("mezz.jei:jei-${minecraft_version}-forge:${jei_version}")
|
||||
|
||||
modCompileOnly("curse.maven:jeresources-240630:3951643")
|
||||
modCompileOnly "me.shedaniel:RoughlyEnoughItems-forge:${rei_version}"
|
||||
modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}")
|
||||
modRuntimeOnly("curse.maven:ferritecore-429235:4441949")
|
||||
modRuntimeOnly("curse.maven:ferritecore-429235:4117906")
|
||||
modCompileOnly("team.chisel.ctm:CTM:${ctm_version}")
|
||||
modCompileOnly("curse.maven:supermartijncore-454372:4484241")
|
||||
modCompileOnly("curse.maven:supermartijncore-454372:4455391")
|
||||
modCompileOnly("appeng:appliedenergistics2-forge:12.9.4")
|
||||
modCompileOnly("vazkii.patchouli:Patchouli:1.19.2-77")
|
||||
}
|
||||
*/
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||||
|
|
@ -112,7 +143,10 @@ tasks.withType(JavaCompile) {
|
|||
// If Javadoc is generated, this must be specified in that task too.
|
||||
options.encoding = "UTF-8"
|
||||
|
||||
def targetVersion = 17
|
||||
// The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too
|
||||
// JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used.
|
||||
// We'll use that if it's available, but otherwise we'll use the older option.
|
||||
def targetVersion = 8
|
||||
/*
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
options.release = targetVersion
|
||||
|
|
@ -136,46 +170,7 @@ task generateChangelog(type: se.bjurr.gitchangelog.plugin.gradle.GitChangelogTas
|
|||
toCommit = "HEAD";
|
||||
}
|
||||
|
||||
java {
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this line, sources will not be generated.
|
||||
// withSourcesJar()
|
||||
}
|
||||
|
||||
// Example for how to get properties into the manifest for reading at runtime.
|
||||
jar {
|
||||
manifest {
|
||||
attributes([
|
||||
"Specification-Title" : "modernfix",
|
||||
"Operative-Class" : "org.embeddedt.modernfix.agent.Agent",
|
||||
//"Specification-Vendor": "modernfix authors",
|
||||
"Specification-Version" : "1", // We are version 1 of ourselves
|
||||
"Implementation-Title" : project.name,
|
||||
"Implementation-Version" : project.jar.archiveVersion,
|
||||
//"Implementation-Vendor": "modernfix authors",
|
||||
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
// Notice: This block does NOT have the same function as the block in the top level.
|
||||
// The repositories here will be used for publishing your artifact, not for
|
||||
// retrieving dependencies.
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
curseforge {
|
||||
if (System.getenv("CURSEFORGE_TOKEN") != null) {
|
||||
apiKey = System.getenv("CURSEFORGE_TOKEN")
|
||||
|
|
@ -219,3 +214,4 @@ tasks.register('publishToModSites') {
|
|||
publishToModSites.dependsOn(tasks.modrinth)
|
||||
publishToModSites.dependsOn(tasks.curseforge)
|
||||
}
|
||||
*/
|
||||
42
common/build.gradle
Normal file
42
common/build.gradle
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
architectury {
|
||||
common(rootProject.enabled_platforms.split(","))
|
||||
}
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/modernfix.accesswidener")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
|
||||
// Do NOT use other classes from fabric loader
|
||||
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
|
||||
|
||||
modApi("dev.latvian.mods:kubejs:${kubejs_version}") {
|
||||
transitive = false
|
||||
}
|
||||
modApi("dev.latvian.mods:rhino:${rhino_version}") {
|
||||
transitive = false
|
||||
}
|
||||
modApi("me.shedaniel:RoughlyEnoughItems-api:${rei_version}") {
|
||||
transitive = false
|
||||
}
|
||||
modCompileOnly("me.shedaniel:RoughlyEnoughItems-fabric:${rei_version}") {
|
||||
transitive = false
|
||||
}
|
||||
// Remove the next line if you don't want to depend on the API
|
||||
// modApi "me.shedaniel:architectury:${rootProject.architectury_version}"
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenCommon(MavenPublication) {
|
||||
artifactId = rootProject.archives_base_name
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
}
|
||||
}
|
||||
73
common/src/main/java/org/embeddedt/modernfix/ModernFix.java
Normal file
73
common/src/main/java/org/embeddedt/modernfix/ModernFix.java
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
package org.embeddedt.modernfix;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.embeddedt.modernfix.util.ClassInfoManager;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
// The value here should match an entry in the META-INF/mods.toml file
|
||||
public class ModernFix {
|
||||
|
||||
// Directly reference a log4j logger.
|
||||
public static final Logger LOGGER = LogManager.getLogger("ModernFix");
|
||||
|
||||
public static final String MODID = "modernfix";
|
||||
|
||||
public static ModernFix INSTANCE;
|
||||
|
||||
// Used to skip computing the blockstate caches twice
|
||||
public static boolean runningFirstInjection = false;
|
||||
|
||||
private static ExecutorService resourceReloadService = null;
|
||||
|
||||
static {
|
||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dedicated_reload_executor.ReloadExecutor")) {
|
||||
resourceReloadService = Util.makeExecutor("ResourceReload");
|
||||
} else {
|
||||
resourceReloadService = Util.backgroundExecutor();
|
||||
}
|
||||
}
|
||||
|
||||
public static ExecutorService resourceReloadExecutor() {
|
||||
return resourceReloadService;
|
||||
}
|
||||
|
||||
|
||||
public ModernFix() {
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public void onServerStarted() {
|
||||
if(ModernFixPlatformHooks.isDedicatedServer()) {
|
||||
float gameStartTime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f;
|
||||
ModernFix.LOGGER.warn("Dedicated server took " + gameStartTime + " seconds to load");
|
||||
}
|
||||
ClassInfoManager.clear();
|
||||
}
|
||||
|
||||
public void onLoadComplete() {
|
||||
ClassInfoManager.clear();
|
||||
}
|
||||
|
||||
public void onServerDead(MinecraftServer server) {
|
||||
/* Clear as much data from the integrated server as possible, in case a mod holds on to it */
|
||||
try {
|
||||
for(ServerLevel level : server.getAllLevels()) {
|
||||
ChunkMap chunkMap = level.getChunkSource().chunkMap;
|
||||
chunkMap.updatingChunkMap.clear();
|
||||
chunkMap.visibleChunkMap.clear();
|
||||
chunkMap.pendingUnloads.clear();
|
||||
}
|
||||
} catch(RuntimeException e) {
|
||||
ModernFix.LOGGER.error("Couldn't clear chunk data", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
package org.embeddedt.modernfix;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.ConnectScreen;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.MemoryReserve;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.embeddedt.modernfix.world.IntegratedWatchdog;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
public class ModernFixClient {
|
||||
public static long worldLoadStartTime;
|
||||
private static int numRenderTicks;
|
||||
|
||||
public static float gameStartTimeSeconds = -1;
|
||||
|
||||
private static boolean recipesUpdated, tagsUpdated = false;
|
||||
|
||||
public String brandingString = null;
|
||||
|
||||
public ModernFixClient() {
|
||||
// clear reserve as it's not needed
|
||||
MemoryReserve.release();
|
||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.branding.F3Screen")) {
|
||||
brandingString = "ModernFix " + ModernFixPlatformHooks.getVersionString();
|
||||
}
|
||||
}
|
||||
|
||||
public void resetWorldLoadStateMachine() {
|
||||
numRenderTicks = 0;
|
||||
worldLoadStartTime = -1;
|
||||
recipesUpdated = false;
|
||||
tagsUpdated = false;
|
||||
}
|
||||
|
||||
public void onScreenOpening(Screen openingScreen) {
|
||||
if(openingScreen instanceof ConnectScreen) {
|
||||
worldLoadStartTime = System.nanoTime();
|
||||
} else if (openingScreen instanceof TitleScreen && gameStartTimeSeconds < 0) {
|
||||
gameStartTimeSeconds = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f;
|
||||
ModernFix.LOGGER.warn("Game took " + gameStartTimeSeconds + " seconds to start");
|
||||
}
|
||||
}
|
||||
|
||||
public void onRecipesUpdated() {
|
||||
recipesUpdated = true;
|
||||
}
|
||||
|
||||
public void onTagsUpdated() {
|
||||
tagsUpdated = true;
|
||||
}
|
||||
|
||||
public void onRenderTickEnd() {
|
||||
if(recipesUpdated
|
||||
&& tagsUpdated
|
||||
&& worldLoadStartTime != -1
|
||||
&& Minecraft.getInstance().player != null
|
||||
&& numRenderTicks++ >= 10) {
|
||||
float timeSpentLoading = ((float)(System.nanoTime() - worldLoadStartTime) / 1000000000f);
|
||||
ModernFix.LOGGER.warn("Time from main menu to in-game was " + timeSpentLoading + " seconds");
|
||||
ModernFix.LOGGER.warn("Total time to load game and open world was " + (timeSpentLoading + gameStartTimeSeconds) + " seconds");
|
||||
resetWorldLoadStateMachine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the IDs match and remap them if not.
|
||||
* @return true if ID remap was needed
|
||||
*/
|
||||
private static boolean compareAndSwitchIds(Class<? extends Entity> eClass, String fieldName, EntityDataAccessor<?> accessor, int newId) {
|
||||
if(accessor.id != newId) {
|
||||
ModernFix.LOGGER.warn("Corrected ID mismatch on {} field {}. Client had {} but server wants {}.",
|
||||
eClass,
|
||||
fieldName,
|
||||
accessor.id,
|
||||
newId);
|
||||
accessor.id = newId;
|
||||
return true;
|
||||
} else {
|
||||
ModernFix.LOGGER.debug("{} {} ID fine: {}", eClass, fieldName, newId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Horrendous hack to allow tracking every synced entity data manager.
|
||||
*
|
||||
* This is to ensure we can perform ID fixup on already constructed managers.
|
||||
*/
|
||||
public static final Set<SynchedEntityData> allEntityDatas = Collections.newSetFromMap(new WeakHashMap<>());
|
||||
|
||||
private static final Field entriesArrayField;
|
||||
static {
|
||||
Field field;
|
||||
try {
|
||||
field = SynchedEntityData.class.getDeclaredField("entriesArray");
|
||||
field.setAccessible(true);
|
||||
} catch(ReflectiveOperationException e) {
|
||||
field = null;
|
||||
}
|
||||
entriesArrayField = field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extremely hacky method to detect and correct mismatched entity data parameter IDs on the client and server.
|
||||
*
|
||||
* The technique is far from ideal, but it should detect reliably and also not break already constructed entities.
|
||||
*/
|
||||
public static void handleEntityIDSync(EntityIDSyncPacket packet) {
|
||||
Map<Class<? extends Entity>, List<Pair<String, Integer>>> info = packet.getFieldInfo();
|
||||
boolean fixNeeded = false;
|
||||
for(Map.Entry<Class<? extends Entity>, List<Pair<String, Integer>>> entry : info.entrySet()) {
|
||||
Class<? extends Entity> eClass = entry.getKey();
|
||||
for(Pair<String, Integer> field : entry.getValue()) {
|
||||
String fieldName = field.getFirst();
|
||||
int newId = field.getSecond();
|
||||
try {
|
||||
Field f = eClass.getDeclaredField(fieldName);
|
||||
f.setAccessible(true);
|
||||
EntityDataAccessor<?> accessor = (EntityDataAccessor<?>)f.get(null);
|
||||
if(compareAndSwitchIds(eClass, fieldName, accessor, newId))
|
||||
fixNeeded = true;
|
||||
} catch(NoSuchFieldException e) {
|
||||
ModernFix.LOGGER.warn("Couldn't find field on {}: {}", eClass, fieldName);
|
||||
} catch(ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Unexpected exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Now the ID mappings on synced entity data instances are probably all wrong. Fix that. */
|
||||
List<SynchedEntityData> dataEntries;
|
||||
synchronized (allEntityDatas) {
|
||||
if(fixNeeded) {
|
||||
dataEntries = new ArrayList<>(allEntityDatas);
|
||||
for(SynchedEntityData manager : dataEntries) {
|
||||
Int2ObjectOpenHashMap<SynchedEntityData.DataItem<?>> fixedMap = new Int2ObjectOpenHashMap<>();
|
||||
List<SynchedEntityData.DataItem<?>> items = new ArrayList<>(manager.itemsById.values());
|
||||
for(SynchedEntityData.DataItem<?> item : items) {
|
||||
fixedMap.put(item.getAccessor().id, item);
|
||||
}
|
||||
manager.lock.writeLock().lock();
|
||||
try {
|
||||
manager.itemsById.replaceAll((id, parameter) -> fixedMap.get((int)id));
|
||||
if(entriesArrayField != null) {
|
||||
try {
|
||||
SynchedEntityData.DataItem<?>[] dataArray = new SynchedEntityData.DataItem[items.size()];
|
||||
for(int i = 0; i < dataArray.length; i++) {
|
||||
dataArray[i] = fixedMap.get(i);
|
||||
}
|
||||
entriesArrayField.set(manager, dataArray);
|
||||
} catch(ReflectiveOperationException e) {
|
||||
ModernFix.LOGGER.error(e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
manager.lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
allEntityDatas.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void onServerStarted(MinecraftServer server) {
|
||||
IntegratedWatchdog watchdog = new IntegratedWatchdog(server);
|
||||
watchdog.start();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.embeddedt.modernfix.annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface ClientOnlyMixin {
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package org.embeddedt.modernfix.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface RequiresMod {
|
||||
String value() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package org.embeddedt.modernfix.blockstate;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.embeddedt.modernfix.duck.IBlockState;
|
||||
|
||||
public class BlockStateCacheHandler {
|
||||
public static void rebuildParallel(boolean force) {
|
||||
synchronized (BlockBehaviour.BlockStateBase.class) {
|
||||
for (BlockState blockState : Block.BLOCK_STATE_REGISTRY) {
|
||||
((IBlockState)blockState).clearCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package org.embeddedt.modernfix.blockstate;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.chunk_deadlock;
|
||||
package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import net.minecraft.core.Holder;
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.concurrency;
|
||||
package org.embeddedt.modernfix.common.mixin.bugfix.concurrency;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.thread.BlockableEventLoop;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
@ClientOnlyMixin
|
||||
public abstract class MinecraftMixin<R extends Runnable> extends BlockableEventLoop<R> {
|
||||
|
||||
protected MinecraftMixin(String p_i50403_1_) {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.edge_chunk_not_saved;
|
||||
package org.embeddedt.modernfix.common.mixin.bugfix.edge_chunk_not_saved;
|
||||
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.paper_chunk_patches;
|
||||
package org.embeddedt.modernfix.common.mixin.bugfix.paper_chunk_patches;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.paper_chunk_patches;
|
||||
package org.embeddedt.modernfix.common.mixin.bugfix.paper_chunk_patches;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
|
@ -9,8 +9,8 @@ import net.minecraft.world.level.ChunkPos;
|
|||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import net.minecraftforge.server.ServerLifecycleHooks;
|
||||
import org.embeddedt.modernfix.duck.IPaperChunkHolder;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
|
@ -45,10 +45,10 @@ public abstract class ChunkMapMixin {
|
|||
@Shadow @Final private StructureTemplateManager structureTemplateManager;
|
||||
private Executor mainInvokingExecutor;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"), cancellable = true)
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void setup(CallbackInfo ci) {
|
||||
this.mainInvokingExecutor = (runnable) -> {
|
||||
if(ServerLifecycleHooks.getCurrentServer().isSameThread())
|
||||
if(ModernFixPlatformHooks.getCurrentServer().isSameThread())
|
||||
runnable.run();
|
||||
else
|
||||
this.mainThreadExecutor.execute(runnable);
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.paper_chunk_patches;
|
||||
package org.embeddedt.modernfix.common.mixin.bugfix.paper_chunk_patches;
|
||||
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
package org.embeddedt.modernfix.mixin.core;
|
||||
package org.embeddedt.modernfix.common.mixin.core;
|
||||
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.embeddedt.modernfix.ModernFixClient;
|
||||
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.CallbackInfo;
|
||||
|
||||
@Mixin(SynchedEntityData.class)
|
||||
@ClientOnlyMixin
|
||||
public class SynchedEntityDataMixin {
|
||||
/**
|
||||
* Store this in our set of all entity data objects.
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
package org.embeddedt.modernfix.mixin.devenv;
|
||||
package org.embeddedt.modernfix.common.mixin.devenv;
|
||||
|
||||
import com.mojang.authlib.minecraft.UserApiService;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.main.GameConfig;
|
||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
@ClientOnlyMixin
|
||||
public class MinecraftMixin {
|
||||
@Overwrite
|
||||
private UserApiService createUserApiService(YggdrasilAuthenticationService yggdrasilAuthenticationService, GameConfig arg) {
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
package org.embeddedt.modernfix.mixin.devenv;
|
||||
package org.embeddedt.modernfix.common.mixin.devenv;
|
||||
|
||||
import com.mojang.text2speech.Narrator;
|
||||
import net.minecraft.client.GameNarrator;
|
||||
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.Redirect;
|
||||
|
||||
@Mixin(GameNarrator.class)
|
||||
@ClientOnlyMixin
|
||||
public class NarratorMixin {
|
||||
@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lcom/mojang/text2speech/Narrator;getNarrator()Lcom/mojang/text2speech/Narrator;", remap = false))
|
||||
private Narrator useDummyNarrator() {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.feature.direct_stack_trace;
|
||||
package org.embeddedt.modernfix.common.mixin.feature.direct_stack_trace;
|
||||
|
||||
import net.minecraft.CrashReport;
|
||||
import net.minecraft.CrashReportCategory;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.feature.measure_time;
|
||||
package org.embeddedt.modernfix.common.mixin.feature.measure_time;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
import net.minecraft.server.Bootstrap;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.feature.measure_time;
|
||||
package org.embeddedt.modernfix.common.mixin.feature.measure_time;
|
||||
|
||||
import com.mojang.datafixers.util.Function4;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
|
@ -10,6 +10,7 @@ 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.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
|
@ -19,6 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
import java.util.function.Function;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
@ClientOnlyMixin
|
||||
public class MinecraftMixin {
|
||||
/* not supported in 1.19
|
||||
private long datapackReloadStartTime;
|
||||
|
|
@ -34,7 +36,7 @@ public class MinecraftMixin {
|
|||
ModernFix.LOGGER.warn("Datapack reload took " + timeSpentReloading + " seconds.");
|
||||
}
|
||||
*/
|
||||
@Inject(method = "m_261031_", at = @At("HEAD"), remap = false)
|
||||
@Inject(method = "doWorldLoad", at = @At("HEAD"), remap = false)
|
||||
private void recordWorldLoadStart(CallbackInfo ci) {
|
||||
ModernFixClient.worldLoadStartTime = System.nanoTime();
|
||||
}
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
package org.embeddedt.modernfix.mixin.feature.measure_time;
|
||||
package org.embeddedt.modernfix.common.mixin.feature.measure_time;
|
||||
|
||||
import net.minecraft.server.packs.resources.PreparableReloadListener;
|
||||
import net.minecraft.server.packs.resources.ProfiledReloadInstance;
|
||||
import org.embeddedt.modernfix.util.NamedPreparableResourceListener;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -1,22 +1,20 @@
|
|||
package org.embeddedt.modernfix.mixin.feature.measure_time;
|
||||
package org.embeddedt.modernfix.common.mixin.feature.measure_time;
|
||||
|
||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
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.ModifyArg;
|
||||
|
||||
@Mixin(ReloadableResourceManager.class)
|
||||
public class SimpleReloadableResourceManagerMixin {
|
||||
|
||||
// TODO maybe expose as a mixin config
|
||||
private static final boolean ENABLE_DEBUG_RELOADER = Boolean.getBoolean("modernfix.debugReloader");
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason add ability to use this feature in modpacks
|
||||
*/
|
||||
@ModifyArg(method = "createReload", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/resources/SimpleReloadInstance;create(Lnet/minecraft/server/packs/resources/ResourceManager;Ljava/util/List;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/concurrent/CompletableFuture;Z)Lnet/minecraft/server/packs/resources/ReloadInstance;"), index = 5)
|
||||
private boolean enableDebugReloader(boolean bl) {
|
||||
return bl || (ModernFixConfig.isLoaded() && ModernFixConfig.ENABLE_DEBUG_RELOADER.get());
|
||||
return bl || ENABLE_DEBUG_RELOADER;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.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;
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.cache_model_materials;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.cache_model_materials;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.multipart.MultiPart;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
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;
|
||||
|
|
@ -10,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
import java.util.Collection;
|
||||
|
||||
@Mixin(MultiPart.class)
|
||||
@ClientOnlyMixin
|
||||
public class MultipartMixin {
|
||||
private Collection<ResourceLocation> dependencyCache = null;
|
||||
@Inject(method = "getDependencies", at = @At("HEAD"), cancellable = true)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.cache_strongholds;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.cache_strongholds;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.Holder;
|
||||
|
|
@ -10,10 +10,10 @@ import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
|
|||
import net.minecraft.world.level.levelgen.RandomState;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
|
||||
import net.minecraftforge.server.ServerLifecycleHooks;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.duck.IChunkGenerator;
|
||||
import org.embeddedt.modernfix.duck.IServerLevel;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.embeddedt.modernfix.world.StrongholdLocationCache;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.cache_strongholds;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.cache_strongholds;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.cache_upgraded_structures;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.cache_upgraded_structures;
|
||||
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.compress_blockstate;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.compress_blockstate;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.compress_blockstate;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.compress_blockstate;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.serialization.MapCodec;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dedicated_reload_executor;
|
||||
|
||||
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dedicated_reload_executor;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
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.Redirect;
|
||||
|
|
@ -10,6 +11,7 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
@ClientOnlyMixin
|
||||
public class MinecraftMixin {
|
||||
@Redirect(method = { "<init>", "reloadResourcePacks(Z)Ljava/util/concurrent/CompletableFuture;" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;backgroundExecutor()Ljava/util/concurrent/ExecutorService;", ordinal = 0))
|
||||
private ExecutorService getResourceReloadExecutor() {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dedicated_reload_executor;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dedicated_reload_executor;
|
||||
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldOpenFlows;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.deduplicate_location;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.deduplicate_location;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.embeddedt.modernfix.dedup.IdentifierCaches;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dynamic_dfu;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_dfu;
|
||||
|
||||
import com.mojang.datafixers.DSL;
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dynamic_resources;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonElement;
|
||||
import net.minecraft.client.renderer.block.model.BlockElementFace;
|
||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.embeddedt.modernfix.dynamicresources.UVController;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
|
@ -11,6 +12,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||
import java.lang.reflect.Type;
|
||||
|
||||
@Mixin(BlockElementFace.Deserializer.class)
|
||||
@ClientOnlyMixin
|
||||
public class BlockElementFaceDeserializerMixin {
|
||||
|
||||
@Redirect(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/renderer/block/model/BlockElementFace;",
|
||||
|
|
@ -1,32 +1,19 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dynamic_resources;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.renderer.block.BlockModelShaper;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
|
||||
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.Redirect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Mixin(BlockModelShaper.class)
|
||||
@ClientOnlyMixin
|
||||
public class BlockModelShaperMixin {
|
||||
@Shadow @Final private ModelManager modelManager;
|
||||
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;
|
||||
|
||||
import net.minecraft.client.renderer.ItemModelShaper;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import org.embeddedt.modernfix.dynamicresources.ModelLocationCache;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
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.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(ItemModelShaper.class)
|
||||
public abstract class ItemModelShaperMixin {
|
||||
|
||||
@Shadow public abstract ModelManager getModelManager();
|
||||
|
||||
private Map<Item, ModelResourceLocation> overrideLocationsVanilla;
|
||||
|
||||
public ItemModelShaperMixin() {
|
||||
super();
|
||||
}
|
||||
|
||||
private static final ModelResourceLocation SENTINEL_VANILLA = new ModelResourceLocation(new ResourceLocation("modernfix", "sentinel"), "sentinel");
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void replaceLocationMap(CallbackInfo ci) {
|
||||
overrideLocationsVanilla = new HashMap<>();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private ModelResourceLocation mfix$getLocation(Item item) {
|
||||
ModelResourceLocation map = overrideLocationsVanilla.getOrDefault(item, SENTINEL_VANILLA);
|
||||
if(map == SENTINEL_VANILLA) {
|
||||
/* generate the appropriate location from our cache */
|
||||
map = ModelLocationCache.get(item);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Get the stored location for that item and meta, and get the model
|
||||
* from that location from the model manager.
|
||||
**/
|
||||
@Overwrite
|
||||
public BakedModel getItemModel(Item item) {
|
||||
ModelResourceLocation map = mfix$getLocation(item);
|
||||
return map == null ? null : getModelManager().getModel(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Don't get all models during init (with dynamic loading, that would
|
||||
* generate them all). Just store location instead.
|
||||
**/
|
||||
@Overwrite
|
||||
public void register(Item item, ModelResourceLocation location) {
|
||||
overrideLocationsVanilla.put(item, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* @reason Disable cache rebuilding (with dynamic loading, that would generate
|
||||
* all models).
|
||||
**/
|
||||
@Overwrite
|
||||
public void rebuildCache() {}
|
||||
}
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dynamic_resources;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;
|
||||
|
||||
import net.minecraft.client.renderer.ItemModelShaper;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
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.Redirect;
|
||||
|
||||
@Mixin(ItemRenderer.class)
|
||||
@ClientOnlyMixin
|
||||
public class ItemRendererMixin {
|
||||
/**
|
||||
* Don't waste space putting all these locations into the cache, compute them on demand later.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.dynamic_structure_manager;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.dynamic_structure_manager;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
|
@ -1,25 +1,25 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.faster_texture_stitching;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.faster_texture_stitching;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.client.renderer.texture.Stitcher;
|
||||
import net.minecraftforge.fml.ModLoader;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.embeddedt.modernfix.textures.StbStitcher;
|
||||
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.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Mixin(Stitcher.class)
|
||||
@ClientOnlyMixin
|
||||
public class StitcherMixin<T extends Stitcher.Entry> {
|
||||
@Shadow @Final private List<Stitcher.Holder<T>> texturesToBeStitched;
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ public class StitcherMixin<T extends Stitcher.Entry> {
|
|||
*/
|
||||
@Inject(method = "stitch", at = @At("HEAD"), cancellable = true)
|
||||
private void stitchFast(CallbackInfo ci) {
|
||||
if(!ModLoader.isLoadingStateValid()) {
|
||||
if(!ModernFixPlatformHooks.isLoadingNormally()) {
|
||||
ModernFix.LOGGER.error("Using vanilla stitcher implementation due to invalid loading state");
|
||||
return;
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ public class StitcherMixin<T extends Stitcher.Entry> {
|
|||
*/
|
||||
@Inject(method = "gatherSprites", at = @At("HEAD"), cancellable = true)
|
||||
private void gatherSpritesFast(Stitcher.SpriteLoader<T> spriteLoader, CallbackInfo ci) {
|
||||
if(!ModLoader.isLoadingStateValid())
|
||||
if(!ModernFixPlatformHooks.isLoadingNormally())
|
||||
return;
|
||||
ci.cancel();
|
||||
for(StbStitcher.LoadableSpriteInfo<T> info : loadableSpriteInfos) {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.model_optimizations;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.model_optimizations;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.model_optimizations;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.model_optimizations;
|
||||
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.embeddedt.modernfix.dedup.IdentifierCaches;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(Property.class)
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.model_optimizations;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.model_optimizations;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.client.renderer.block.model.multipart.Selector;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
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;
|
||||
|
|
@ -13,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.function.Predicate;
|
||||
|
||||
@Mixin(Selector.class)
|
||||
@ClientOnlyMixin
|
||||
public class SelectorMixin {
|
||||
private ConcurrentHashMap<StateDefinition<Block, BlockState>, Predicate<BlockState>> predicateCache = new ConcurrentHashMap<>();
|
||||
@Inject(method = "getPredicate", at = @At("HEAD"), cancellable = true)
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.model_optimizations;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.model_optimizations;
|
||||
|
||||
import com.mojang.math.Transformation;
|
||||
import org.joml.Matrix4f;
|
||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
|
@ -10,6 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
|||
import java.util.Objects;
|
||||
|
||||
@Mixin(Transformation.class)
|
||||
@ClientOnlyMixin
|
||||
public class TransformationMatrixMixin {
|
||||
@Shadow @Final private Matrix4f matrix;
|
||||
private Integer cachedHashCode = null;
|
||||
|
|
@ -1,15 +1,12 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.nbt_memory_usage;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.nbt_memory_usage;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import org.embeddedt.modernfix.util.CanonizingStringMap;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.Map;
|
||||
|
|
@ -1,18 +1,13 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.reduce_blockstate_cache_rebuilds;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuilds;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.duck.IBlockState;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
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.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Mixin(BlockBehaviour.BlockStateBase.class)
|
||||
public abstract class BlockStateBaseMixin implements IBlockState {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.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 org.embeddedt.modernfix.blockstate.BlockStateCacheHandler;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.remove_biome_temperature_cache;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.remove_biome_temperature_cache;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.remove_spawn_chunks;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.remove_spawn_chunks;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
||||
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.remove_spawn_chunks;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.remove_spawn_chunks;
|
||||
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.state_definition_construct;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.state_definition_construct;
|
||||
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.StateHolder;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
||||
import org.embeddedt.modernfix.blockstate.FakeStateMap;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
|
@ -15,6 +15,7 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
|||
import java.util.Map;
|
||||
|
||||
@Mixin(StateDefinition.class)
|
||||
@RequiresMod("ferritecore")
|
||||
public class StateDefinitionMixin<O, S extends StateHolder<O, S>> {
|
||||
@Shadow @Final private ImmutableSortedMap<String, Property<?>> propertiesByName;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.thread_priorities;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.thread_priorities;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.server.Services;
|
||||
|
|
@ -7,18 +7,18 @@ import net.minecraft.server.packs.repository.PackRepository;
|
|||
import net.minecraft.client.server.IntegratedServer;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
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.CallbackInfo;
|
||||
|
||||
@Mixin(IntegratedServer.class)
|
||||
@ClientOnlyMixin
|
||||
public class IntegratedServerMixin {
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void adjustServerPriority(Thread thread, Minecraft arg, LevelStorageSource.LevelStorageAccess arg2, PackRepository arg3, WorldStem arg4, Services arg5, ChunkProgressListenerFactory arg6, CallbackInfo ci) {
|
||||
int pri = ModernFixConfig.INTEGRATED_SERVER_PRIORITY.get();
|
||||
int pri = 4;
|
||||
thread.setPriority(pri);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package org.embeddedt.modernfix.mixin.perf.thread_priorities;
|
||||
package org.embeddedt.modernfix.common.mixin.perf.thread_priorities;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
package org.embeddedt.modernfix.mixin.safety;
|
||||
package org.embeddedt.modernfix.common.mixin.safety;
|
||||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.color.block.BlockColors;
|
||||
import net.minecraft.client.color.block.BlockColor;
|
||||
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;
|
||||
|
|
@ -13,6 +11,7 @@ import java.util.concurrent.locks.Lock;
|
|||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Mixin(value = BlockColors.class, priority = 700)
|
||||
@ClientOnlyMixin
|
||||
public class BlockColorsMixin {
|
||||
private Lock mapLock = new ReentrantLock();
|
||||
@Inject(method = "register", at = @At("HEAD"))
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package org.embeddedt.modernfix.mixin.safety;
|
||||
package org.embeddedt.modernfix.common.mixin.safety;
|
||||
|
||||
import net.minecraft.client.color.item.ItemColors;
|
||||
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;
|
||||
|
|
@ -10,6 +11,7 @@ import java.util.concurrent.locks.Lock;
|
|||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Mixin(value = ItemColors.class, priority = 700)
|
||||
@ClientOnlyMixin
|
||||
public class ItemColorsMixin {
|
||||
private Lock mapLock = new ReentrantLock();
|
||||
@Inject(method = "register", at = @At("HEAD"))
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
package org.embeddedt.modernfix.core;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig;
|
||||
import org.embeddedt.modernfix.core.config.Option;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ModernFixMixinPlugin implements IMixinConfigPlugin {
|
||||
private static final String MIXIN_PACKAGE_ROOT = "org.embeddedt.modernfix.mixin.";
|
||||
|
||||
public final Logger logger = LogManager.getLogger("ModernFix");
|
||||
public ModernFixEarlyConfig config = null;
|
||||
public static ModernFixMixinPlugin instance;
|
||||
|
||||
public ModernFixMixinPlugin() {
|
||||
boolean firstConfig = instance == null;
|
||||
if(firstConfig) {
|
||||
instance = this;
|
||||
try {
|
||||
config = ModernFixEarlyConfig.load(new File("./config/modernfix-mixins.properties"));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Could not load configuration file for ModernFix", e);
|
||||
}
|
||||
|
||||
this.logger.info("Loaded configuration file for ModernFix: {} options available, {} override(s) found",
|
||||
config.getOptionCount(), config.getOptionOverrideCount());
|
||||
|
||||
if(ModernFixEarlyConfig.OPTIFINE_PRESENT)
|
||||
this.logger.fatal("OptiFine detected. Use of ModernFix with OptiFine is not supported due to its impact on launch time and breakage of Forge features.");
|
||||
|
||||
try {
|
||||
Class.forName("sun.misc.Unsafe").getDeclaredMethod("defineAnonymousClass", Class.class, byte[].class, Object[].class);
|
||||
} catch(ReflectiveOperationException | NullPointerException e) {
|
||||
this.logger.info("Applying Nashorn fix");
|
||||
Properties properties = System.getProperties();
|
||||
properties.setProperty("nashorn.args", properties.getProperty("nashorn.args", "") + " --anonymous-classes=false");
|
||||
}
|
||||
|
||||
/* We abuse the constructor of a mixin plugin as a safe location to start modifying the classloader */
|
||||
ModernFixPlatformHooks.injectPlatformSpecificHacks();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRefMapperConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
mixinClassName = ModernFixEarlyConfig.sanitize(mixinClassName);
|
||||
if (!mixinClassName.startsWith(MIXIN_PACKAGE_ROOT)) {
|
||||
this.logger.error("Expected mixin '{}' to start with package root '{}', treating as foreign and " +
|
||||
"disabling!", mixinClassName, MIXIN_PACKAGE_ROOT);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String mixin = mixinClassName.substring(MIXIN_PACKAGE_ROOT.length());
|
||||
if(!instance.isOptionEnabled(mixin))
|
||||
return false;
|
||||
String disabledBecauseMod = instance.config.getPermanentlyDisabledMixins().get(mixin);
|
||||
return disabledBecauseMod == null;
|
||||
}
|
||||
|
||||
public boolean isOptionEnabled(String mixin) {
|
||||
Option option = instance.config.getEffectiveOptionForMixin(mixin);
|
||||
|
||||
if (option == null) {
|
||||
this.logger.error("No rules matched mixin '{}', treating as foreign and disabling!", mixin);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (option.isOverridden()) {
|
||||
String source = "[unknown]";
|
||||
|
||||
if (option.isUserDefined()) {
|
||||
source = "user configuration";
|
||||
} else if (option.isModDefined()) {
|
||||
source = "mods [" + String.join(", ", option.getDefiningMods()) + "]";
|
||||
}
|
||||
|
||||
if (option.isEnabled()) {
|
||||
this.logger.warn("Force-enabling mixin '{}' as rule '{}' (added by {}) enables it", mixin,
|
||||
option.getName(), source);
|
||||
} else {
|
||||
this.logger.warn("Force-disabling mixin '{}' as rule '{}' (added by {}) disables it and children", mixin,
|
||||
option.getName(), source);
|
||||
}
|
||||
}
|
||||
|
||||
return option.isEnabled();
|
||||
}
|
||||
@Override
|
||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMixins() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
ModernFixPlatformHooks.applyASMTransformers(mixinClassName, targetClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,23 @@
|
|||
package org.embeddedt.modernfix.core.config;
|
||||
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ExplodedDirectoryLocator;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.MinecraftLocator;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import net.minecraftforge.forgespi.locating.IModLocator;
|
||||
import net.minecraftforge.forgespi.locating.IModProvider;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.*;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ModernFixEarlyConfig {
|
||||
|
|
@ -36,65 +43,140 @@ public class ModernFixEarlyConfig {
|
|||
if(modId.equals("optifine"))
|
||||
return OPTIFINE_PRESENT;
|
||||
else
|
||||
return FMLLoader.getLoadingModList().getModFileById(modId) != null;
|
||||
return ModernFixPlatformHooks.modPresent(modId);
|
||||
}
|
||||
|
||||
private static final String MIXIN_DESC = "Lorg/spongepowered/asm/mixin/Mixin;";
|
||||
private static final String MIXIN_CLIENT_ONLY_DESC = "Lorg/embeddedt/modernfix/annotation/ClientOnlyMixin;";
|
||||
private static final String MIXIN_REQUIRES_MOD_DESC = "Lorg/embeddedt/modernfix/annotation/RequiresMod;";
|
||||
|
||||
private static final Pattern PLATFORM_PREFIX = Pattern.compile("(forge|fabric|common)\\.");
|
||||
|
||||
public static String sanitize(String mixinClassName) {
|
||||
return PLATFORM_PREFIX.matcher(mixinClassName).replaceFirst("");
|
||||
}
|
||||
|
||||
private final Set<String> mixinOptions = new ObjectOpenHashSet<>();
|
||||
private final Map<String, String> mixinsMissingMods = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
public Map<String, String> getPermanentlyDisabledMixins() {
|
||||
return mixinsMissingMods;
|
||||
}
|
||||
|
||||
private void scanForAndBuildMixinOptions() {
|
||||
List<String> configFiles = ImmutableList.of("modernfix-common.mixins.json", "modernfix-fabric.mixins.json", "modernfix-forge.mixins.json");
|
||||
List<String> mixinPaths = new ArrayList<>();
|
||||
for(String configFile : configFiles) {
|
||||
InputStream stream = ModernFixEarlyConfig.class.getClassLoader().getResourceAsStream(configFile);
|
||||
if(stream == null)
|
||||
continue;
|
||||
try(Reader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
|
||||
JsonObject configObject = (JsonObject)new JsonParser().parse(reader);
|
||||
JsonArray mixinList = configObject.getAsJsonArray("mixins");
|
||||
String packageName = configObject.get("package").getAsString().replace('.', '/');
|
||||
for(JsonElement mixin : mixinList) {
|
||||
mixinPaths.add(packageName + "/" + mixin.getAsString().replace('.', '/') + ".class");
|
||||
}
|
||||
} catch(IOException | JsonParseException e) {
|
||||
LOGGER.error("Error loading config " + configFile, e);
|
||||
}
|
||||
}
|
||||
Splitter dotSplitter = Splitter.on('.');
|
||||
for(String mixinPath : mixinPaths) {
|
||||
try(InputStream stream = ModernFixEarlyConfig.class.getClassLoader().getResourceAsStream(mixinPath)) {
|
||||
ClassReader reader = new ClassReader(stream);
|
||||
ClassNode node = new ClassNode();
|
||||
reader.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
|
||||
if(node.invisibleAnnotations == null)
|
||||
return;
|
||||
boolean isMixin = false, isClientOnly = false, requiredModPresent = true;
|
||||
String requiredModId = "";
|
||||
for(AnnotationNode annotation : node.invisibleAnnotations) {
|
||||
if(Objects.equals(annotation.desc, MIXIN_DESC)) {
|
||||
isMixin = true;
|
||||
} else if(Objects.equals(annotation.desc, MIXIN_CLIENT_ONLY_DESC)) {
|
||||
isClientOnly = true;
|
||||
} else if(Objects.equals(annotation.desc, MIXIN_REQUIRES_MOD_DESC)) {
|
||||
for(int i = 0; i < annotation.values.size(); i += 2) {
|
||||
if(annotation.values.get(i).equals("value")) {
|
||||
String modId = (String)annotation.values.get(i + 1);
|
||||
if(modId != null) {
|
||||
requiredModPresent = modPresent(modId);
|
||||
requiredModId = modId;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isMixin) {
|
||||
String mixinClassName = sanitize(node.name.replace('/', '.')).replace("org.embeddedt.modernfix.mixin.", "");
|
||||
if(!requiredModPresent)
|
||||
mixinsMissingMods.put(mixinClassName, requiredModId);
|
||||
else if(isClientOnly && !ModernFixPlatformHooks.isClient())
|
||||
mixinsMissingMods.put(mixinClassName, "[not client]");
|
||||
List<String> mixinOptionNames = dotSplitter.splitToList(mixinClassName);
|
||||
StringBuilder optionBuilder = new StringBuilder(mixinClassName.length());
|
||||
optionBuilder.append("mixin");
|
||||
for(int i = 0; i < mixinOptionNames.size() - 1; i++) {
|
||||
optionBuilder.append('.');
|
||||
optionBuilder.append(mixinOptionNames.get(i));
|
||||
mixinOptions.add(optionBuilder.toString());
|
||||
}
|
||||
}
|
||||
} catch(IOException e) {
|
||||
ModernFix.LOGGER.error("Error scanning file " + mixinPath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final boolean shouldReplaceSearchTrees;
|
||||
private static final boolean isDevEnv = ModernFixPlatformHooks.isDevEnv();
|
||||
|
||||
static {
|
||||
shouldReplaceSearchTrees = modPresent("jei");
|
||||
}
|
||||
|
||||
private static final ImmutableMap<String, Boolean> DEFAULT_SETTING_OVERRIDES = ImmutableMap.<String, Boolean>builder()
|
||||
.put("mixin.perf.dynamic_resources", false)
|
||||
.put("mixin.feature.reduce_loading_screen_freezes", false)
|
||||
.put("mixin.feature.direct_stack_trace", false)
|
||||
.put("mixin.perf.rewrite_registry", false)
|
||||
.put("mixin.perf.clear_mixin_classinfo", false)
|
||||
.put("mixin.perf.compress_blockstate", false)
|
||||
.put("mixin.bugfix.packet_leak", false)
|
||||
.put("mixin.perf.deduplicate_location", false)
|
||||
.put("mixin.perf.preload_block_classes", false)
|
||||
.put("mixin.perf.faster_singleplayer_load", false)
|
||||
.put("mixin.perf.blast_search_trees", shouldReplaceSearchTrees)
|
||||
.put("mixin.devenv", isDevEnv)
|
||||
.put("mixin.perf.remove_spawn_chunks", isDevEnv)
|
||||
.build();
|
||||
|
||||
private ModernFixEarlyConfig(File file) {
|
||||
this.configFile = file;
|
||||
|
||||
this.scanForAndBuildMixinOptions();
|
||||
for(String optionName : mixinOptions) {
|
||||
boolean defaultEnabled = DEFAULT_SETTING_OVERRIDES.getOrDefault(optionName, true);
|
||||
this.options.putIfAbsent(optionName, new Option(optionName, defaultEnabled, false));
|
||||
}
|
||||
// Defines the default rules which can be configured by the user or other mods.
|
||||
// You must manually add a rule for any new mixins not covered by an existing package rule.
|
||||
this.addMixinRule("core", true); // TODO: Don't actually allow the user to disable this
|
||||
this.addMixinRule("perf.modern_resourcepacks", true);
|
||||
this.addMixinRule("feature.branding", true);
|
||||
this.addMixinRule("feature.measure_time", true);
|
||||
this.addMixinRule("feature.reduce_loading_screen_freezes", false);
|
||||
this.addMixinRule("feature.direct_stack_trace", false);
|
||||
this.addMixinRule("perf.fast_registry_validation", true);
|
||||
this.addMixinRule("perf.skip_first_datapack_reload", true);
|
||||
// not stable yet
|
||||
this.addMixinRule("perf.rewrite_registry", false);
|
||||
this.addMixinRule("perf.remove_biome_temperature_cache", true);
|
||||
this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true);
|
||||
this.addMixinRule("perf.model_optimizations", true);
|
||||
this.addMixinRule("perf.dynamic_resources", false);
|
||||
this.addMixinRule("perf.dynamic_entity_renderers", true);
|
||||
this.addMixinRule("perf.dedicated_reload_executor", true);
|
||||
/* Use a simpler ArrayMap if FerriteCore is using the map intelligently anyway */
|
||||
this.addMixinRule("perf.state_definition_construct", modPresent("ferritecore"));
|
||||
this.addMixinRule("perf.cache_strongholds", true);
|
||||
this.addMixinRule("perf.clear_mixin_classinfo", false);
|
||||
this.addMixinRule("perf.cache_upgraded_structures", true);
|
||||
this.addMixinRule("perf.compress_blockstate", false);
|
||||
this.addMixinRule("bugfix.concurrency", true);
|
||||
this.addMixinRule("bugfix.edge_chunk_not_saved", true);
|
||||
this.addMixinRule("perf.fast_forge_dummies", true);
|
||||
this.addMixinRule("perf.dynamic_structure_manager", true);
|
||||
this.addMixinRule("bugfix.chunk_deadlock", true);
|
||||
this.addMixinRule("bugfix.remove_block_chunkloading", true);
|
||||
this.addMixinRule("bugfix.paper_chunk_patches", true);
|
||||
this.addMixinRule("perf.thread_priorities", true);
|
||||
this.addMixinRule("perf.scan_cache", true);
|
||||
this.addMixinRule("perf.kubejs", modPresent("kubejs"));
|
||||
this.addMixinRule("perf.flatten_model_predicates", true);
|
||||
this.addMixinRule("perf.tag_id_caching", true);
|
||||
this.addMixinRule("perf.deduplicate_location", false);
|
||||
this.addMixinRule("perf.cache_blockstate_cache_arrays", true);
|
||||
this.addMixinRule("perf.cache_model_materials", true);
|
||||
this.addMixinRule("perf.nbt_memory_usage", true);
|
||||
this.addMixinRule("perf.patchouli_deduplicate_books", modPresent("patchouli"));
|
||||
this.addMixinRule("perf.datapack_reload_exceptions", true);
|
||||
this.addMixinRule("perf.dynamic_dfu", true);
|
||||
this.addMixinRule("perf.faster_texture_stitching", true);
|
||||
/* off by default in 1.18 because it doesn't work as well */
|
||||
this.addMixinRule("perf.faster_singleplayer_load", false);
|
||||
/* Keep this off if JEI/REI isn't installed to prevent breaking vanilla gameplay */
|
||||
this.addMixinRule("perf.blast_search_trees", FMLLoader.getLoadingModList().getModFileById("jei") != null || FMLLoader.getLoadingModList().getModFileById("roughlyenoughitems") != null);
|
||||
this.addMixinRule("safety", true);
|
||||
this.addMixinRule("launch.class_search_cache", true);
|
||||
IModProvider mfLocator = FMLLoader.getLoadingModList().getModFileById("modernfix").getFile().getProvider();
|
||||
boolean isDevEnv = !FMLLoader.isProduction() && (mfLocator instanceof ExplodedDirectoryLocator || mfLocator instanceof MinecraftLocator);
|
||||
this.addMixinRule("devenv", isDevEnv);
|
||||
this.addMixinRule("perf.remove_spawn_chunks", isDevEnv);
|
||||
/*
|
||||
this.addMixinRule("perf.use_integrated_resources.jepb", modPresent("jepb"));
|
||||
this.addMixinRule("perf.use_integrated_resources.jeresources", modPresent("jeresources"));
|
||||
this.addMixinRule("perf.jeresources_startup", modPresent("jeresources"));
|
||||
this.addMixinRule("perf.state_definition_construct", modPresent("ferritecore"));
|
||||
this.addMixinRule("bugfix.starlight_emptiness", modPresent("starlight"));
|
||||
this.addMixinRule("bugfix.chunk_deadlock.valhesia", modPresent("valhelsia_structures"));
|
||||
this.addMixinRule("bugfix.tf_cme_on_load", modPresent("twilightforest"));
|
||||
this.addMixinRule("bugfix.refinedstorage", modPresent("refinedstorage"));
|
||||
this.addMixinRule("perf.async_jei", modPresent("jei"));
|
||||
this.addMixinRule("perf.patchouli_deduplicate_books", modPresent("patchouli"));
|
||||
this.addMixinRule("perf.kubejs", modPresent("kubejs"));
|
||||
*/
|
||||
|
||||
/* Mod compat */
|
||||
disableIfModPresent("mixin.perf.thread_priorities", "smoothboot");
|
||||
|
|
@ -12,7 +12,6 @@ import org.embeddedt.modernfix.ModernFix;
|
|||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.IntFunction;
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package org.embeddedt.modernfix.dfu;
|
||||
|
||||
import com.mojang.datafixers.DSL;
|
||||
import com.mojang.datafixers.DataFix;
|
||||
import com.mojang.datafixers.DataFixUtils;
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import com.mojang.datafixers.schemas.Schema;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package org.embeddedt.modernfix.duck;
|
||||
|
||||
import org.embeddedt.modernfix.util.BakeReason;
|
||||
|
||||
public interface IBlockState {
|
||||
void clearCache();
|
||||
|
|
@ -11,7 +11,6 @@ import org.apache.commons.lang3.tuple.Triple;
|
|||
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
|
@ -76,7 +75,6 @@ public class DynamicBakedModelProvider implements Map<ResourceLocation, BakedMod
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BakedModel put(ResourceLocation resourceLocation, BakedModel bakedModel) {
|
||||
BakedModel m = permanentOverrides.put(resourceLocation, bakedModel);
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package org.embeddedt.modernfix.dynamicresources;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ModelBakeryHelpers {
|
||||
|
||||
private static <T extends Comparable<T>, V extends T> BlockState setPropertyGeneric(BlockState state, Property<T> prop, Object o) {
|
||||
return state.setValue(prop, (V)o);
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> T getValueHelper(Property<T> property, String value) {
|
||||
return property.getValue(value).orElse((T) null);
|
||||
}
|
||||
|
||||
private static final Splitter COMMA_SPLITTER = Splitter.on(',');
|
||||
private static final Splitter EQUAL_SPLITTER = Splitter.on('=').limit(2);
|
||||
|
||||
public static ImmutableList<BlockState> getBlockStatesForMRL(StateDefinition<Block, BlockState> stateDefinition, ModelResourceLocation location) {
|
||||
if(Objects.equals(location.getVariant(), "inventory"))
|
||||
return ImmutableList.of();
|
||||
Set<Property<?>> fixedProperties = new HashSet<>();
|
||||
BlockState fixedState = stateDefinition.any();
|
||||
for(String s : COMMA_SPLITTER.split(location.getVariant())) {
|
||||
Iterator<String> iterator = EQUAL_SPLITTER.split(s).iterator();
|
||||
if (iterator.hasNext()) {
|
||||
String s1 = iterator.next();
|
||||
Property<?> property = stateDefinition.getProperty(s1);
|
||||
if (property != null && iterator.hasNext()) {
|
||||
String s2 = iterator.next();
|
||||
Object value = getValueHelper(property, s2);
|
||||
if (value == null) {
|
||||
throw new RuntimeException("Unknown value: '" + s2 + "' for blockstate property: '" + s1 + "' " + property.getPossibleValues());
|
||||
}
|
||||
fixedState = setPropertyGeneric(fixedState, property, value);
|
||||
fixedProperties.add(property);
|
||||
} else if (!s1.isEmpty()) {
|
||||
throw new RuntimeException("Unknown blockstate property: '" + s1 + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
// generate all possible blockstates from the remaining properties
|
||||
ArrayList<Property<?>> anyProperties = new ArrayList<>(stateDefinition.getProperties());
|
||||
anyProperties.removeAll(fixedProperties);
|
||||
ArrayList<BlockState> finalList = new ArrayList<>();
|
||||
finalList.add(fixedState);
|
||||
for(Property<?> property : anyProperties) {
|
||||
ArrayList<BlockState> newPermutations = new ArrayList<>();
|
||||
for(BlockState state : finalList) {
|
||||
for(Comparable<?> value : property.getPossibleValues()) {
|
||||
newPermutations.add(setPropertyGeneric(state, property, value));
|
||||
}
|
||||
}
|
||||
finalList = newPermutations;
|
||||
}
|
||||
return ImmutableList.copyOf(finalList);
|
||||
}
|
||||
}
|
||||
|
|
@ -3,22 +3,13 @@ package org.embeddedt.modernfix.dynamicresources;
|
|||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.renderer.block.BlockModelShaper;
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class ModelLocationCache {
|
||||
|
|
@ -36,7 +27,7 @@ public class ModelLocationCache {
|
|||
.build(new CacheLoader<Item, ModelResourceLocation>() {
|
||||
@Override
|
||||
public ModelResourceLocation load(Item key) throws Exception {
|
||||
return new ModelResourceLocation(ForgeRegistries.ITEMS.getKey(key), "inventory");
|
||||
return new ModelResourceLocation(BuiltInRegistries.ITEM.getKey(key), "inventory");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package org.embeddedt.modernfix.entity;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EntityDataIDSyncHandler {
|
||||
private static Map<Class<? extends Entity>, List<Pair<String, Integer>>> fieldsToSyncMap;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void onDatapackSyncEvent(ServerPlayer targetPlayer) {
|
||||
if(targetPlayer != null) {
|
||||
/* Compute the current set of serializer IDs in use and send them */
|
||||
if(fieldsToSyncMap == null) {
|
||||
fieldsToSyncMap = new HashMap<>();
|
||||
Map<Class<? extends Entity>, Integer> entityPoolMap = SynchedEntityData.ENTITY_ID_POOL;
|
||||
List<Field> fieldsToSync = new ArrayList<>();
|
||||
for(Class<? extends Entity> eClass : entityPoolMap.keySet()) {
|
||||
fieldsToSync.clear();
|
||||
try {
|
||||
Field[] classFields = eClass.getDeclaredFields();
|
||||
for(Field field : classFields) {
|
||||
if(!Modifier.isStatic(field.getModifiers()))
|
||||
continue;
|
||||
field.setAccessible(true);
|
||||
Object o = field.get(null);
|
||||
if(o != null && EntityDataAccessor.class.isAssignableFrom(o.getClass())) {
|
||||
fieldsToSync.add(field);
|
||||
}
|
||||
}
|
||||
for(Field field : fieldsToSync) {
|
||||
int id = ((EntityDataAccessor<?>)field.get(null)).id;
|
||||
fieldsToSyncMap.computeIfAbsent(eClass, k -> new ArrayList<>()).add(Pair.of(field.getName(), id));
|
||||
}
|
||||
} catch(Throwable e) {
|
||||
ModernFix.LOGGER.error("Skipping entity ID sync for {}: {}", eClass.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
EntityIDSyncPacket packet = new EntityIDSyncPacket(fieldsToSyncMap);
|
||||
ModernFix.LOGGER.debug("Sending ID correction packet to client with " + fieldsToSyncMap.size() + " classes");
|
||||
ModernFixPlatformHooks.sendPacket(targetPlayer, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package org.embeddedt.modernfix.platform;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.packs.resources.Resource;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ModernFixPlatformHooks {
|
||||
@ExpectPlatform
|
||||
public static boolean isClient() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static boolean isDedicatedServer() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static String getVersionString() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static boolean modPresent(String modId) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static boolean isDevEnv() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static void injectPlatformSpecificHacks() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static void applyASMTransformers(String mixinClassName, ClassNode targetClass) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static MinecraftServer getCurrentServer() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static boolean isLoadingNormally() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static Path getGameDirectory() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static void sendPacket(ServerPlayer player, Object packet) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,6 @@ package org.embeddedt.modernfix.resources;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
|
|
@ -6,15 +6,13 @@ import net.minecraft.client.gui.screens.Screen;
|
|||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ModernFixConfigScreen extends Screen {
|
||||
private OptionList optionList;
|
||||
private Screen lastScreen;
|
||||
|
||||
public boolean madeChanges = false;
|
||||
private Button doneButton;
|
||||
public ModernFixConfigScreen(@Nullable Screen lastScreen) {
|
||||
public ModernFixConfigScreen(Screen lastScreen) {
|
||||
super(Component.translatable("modernfix.config"));
|
||||
this.lastScreen = lastScreen;
|
||||
}
|
||||
|
|
@ -3,12 +3,10 @@ package org.embeddedt.modernfix.screen;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.components.toasts.SystemToast;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
|
@ -20,7 +18,6 @@ import java.io.IOException;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||
|
|
@ -38,7 +35,7 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
|||
this.mainScreen = arg;
|
||||
|
||||
int maxW = 0;
|
||||
Map<String, Option> optionMap = ModernFixMixinPlugin.config.getOptionMap();
|
||||
Map<String, Option> optionMap = ModernFixMixinPlugin.instance.config.getOptionMap();
|
||||
List<String> sortedKeys = optionMap.keySet().stream().filter(key -> !key.equals("mixin.core")).sorted().collect(Collectors.toList());
|
||||
for(String key : sortedKeys) {
|
||||
Option option = optionMap.get(key);
|
||||
|
|
@ -69,7 +66,7 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
|||
this.toggleButton = new Button.Builder(Component.literal(""), (arg) -> {
|
||||
this.option.setEnabled(!this.option.isEnabled(), !this.option.isUserDefined());
|
||||
try {
|
||||
ModernFixMixinPlugin.config.save();
|
||||
ModernFixMixinPlugin.instance.config.save();
|
||||
if(!OptionList.this.mainScreen.madeChanges) {
|
||||
OptionList.this.mainScreen.madeChanges = true;
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package org.embeddedt.modernfix.structure;
|
||||
|
||||
import com.mojang.datafixers.DataFixer;
|
||||
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
|
@ -11,16 +10,23 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.util.datafix.DataFixTypes;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
import net.minecraftforge.fml.loading.FMLPaths;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.embeddedt.modernfix.util.FileUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class CachingStructureManager {
|
||||
private static ThreadLocal<MessageDigest> digestThreadLocal = ThreadLocal.withInitial(() -> LamdbaExceptionUtils.uncheck(() -> MessageDigest.getInstance("SHA-256")));
|
||||
private static final File STRUCTURE_CACHE_FOLDER = FileUtil.childFile(FMLPaths.GAMEDIR.get().resolve("modernfix").resolve("structureCacheV1").toFile());
|
||||
private static ThreadLocal<MessageDigest> digestThreadLocal = ThreadLocal.withInitial(() -> {
|
||||
try {
|
||||
return MessageDigest.getInstance("SHA-256");
|
||||
} catch(NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
private static final File STRUCTURE_CACHE_FOLDER = FileUtil.childFile(ModernFixPlatformHooks.getGameDirectory().resolve("modernfix").resolve("structureCacheV1").toFile());
|
||||
|
||||
static {
|
||||
STRUCTURE_CACHE_FOLDER.mkdirs();
|
||||
|
|
@ -16,7 +16,6 @@ import static java.lang.invoke.MethodHandles.*;
|
|||
import static java.lang.invoke.MethodType.*;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.sql.Ref;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
|
@ -191,10 +190,13 @@ public class StbStitcher {
|
|||
throw new StitcherException(holder.entry(),
|
||||
Stream.of(holders).map(Stitcher.Holder::entry).collect(ImmutableList.toImmutableList()));
|
||||
}
|
||||
}
|
||||
|
||||
for (STBRPRect rect : rectBuf) {
|
||||
Stitcher.Holder<T> holder = holders[rect.id()];
|
||||
|
||||
// Initialize the sprite now with the position and size that we've calculated so far
|
||||
infoList.add(new LoadableSpriteInfo(holder.entry(), longestWidth, longestHeight, getX(rect), getY(rect)));
|
||||
//holder.spriteInfo.initSprite(size, size, rect.x(), rect.y(), false);
|
||||
}
|
||||
|
||||
return Pair.of(Pair.of(longestWidth, longestHeight), infoList);
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
package org.embeddedt.modernfix.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import cpw.mods.jarhandling.SecureJar;
|
||||
import cpw.mods.jarhandling.impl.Jar;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
|
@ -41,6 +37,8 @@ public class ClassInfoManager {
|
|||
|
||||
// Clear manifest entries
|
||||
int numManifestsCleared = 0;
|
||||
// TODO port
|
||||
/*
|
||||
for(IModFileInfo mod : ModList.get().getModFiles()) {
|
||||
Manifest manifest = mod.getFile().getSecureJar().moduleDataProvider().getManifest();
|
||||
if(manifest.getEntries() instanceof HashMap<String, Attributes> entryMap) {
|
||||
|
|
@ -56,6 +54,8 @@ public class ClassInfoManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
if(numManifestsCleared > 0)
|
||||
ModernFix.LOGGER.info("Cleared {} manifest attributes", numManifestsCleared);
|
||||
|
||||
|
|
@ -68,6 +68,7 @@ public class ClassInfoManager {
|
|||
}
|
||||
|
||||
private static void clearSecureJarStructs() throws Throwable {
|
||||
/*
|
||||
// Clear Jar signing data
|
||||
Unsafe unsafe;
|
||||
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
|
|
@ -91,6 +92,8 @@ public class ClassInfoManager {
|
|||
unsafe.putObject(secureJar, verifiedSignersOffset, EmptyCodeSignerTable.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
static class EmptyCodeSignerTable extends Hashtable<String, CodeSigner[]> {
|
||||
|
|
@ -11,7 +11,6 @@ import net.minecraft.world.level.levelgen.WorldOptions;
|
|||
import net.minecraft.world.level.storage.WorldData;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Set;
|
||||
|
||||
public class DummyServerConfiguration implements WorldData {
|
||||
|
|
@ -40,14 +39,13 @@ public class DummyServerConfiguration implements WorldData {
|
|||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CompoundTag getCustomBossEvents() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomBossEvents(@Nullable CompoundTag nbt) {
|
||||
public void setCustomBossEvents(CompoundTag nbt) {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +60,7 @@ public class DummyServerConfiguration implements WorldData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag createTag(RegistryAccess registries, @Nullable CompoundTag hostPlayerNBT) {
|
||||
public CompoundTag createTag(RegistryAccess registries, CompoundTag hostPlayerNBT) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package org.embeddedt.modernfix.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class FileUtil {
|
||||
public static File childFile(File file) {
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
package org.embeddedt.modernfix.util;
|
||||
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
|
@ -12,16 +11,16 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ItemMesherMap implements Map<Holder.Reference<Item>, ModelResourceLocation> {
|
||||
private final Function<Item, ModelResourceLocation> getLocation;
|
||||
public class ItemMesherMap<K> implements Map<K, ModelResourceLocation> {
|
||||
private final Function<K, ModelResourceLocation> getLocation;
|
||||
|
||||
public ItemMesherMap(Function<Item, ModelResourceLocation> getLocation) {
|
||||
public ItemMesherMap(Function<K, ModelResourceLocation> getLocation) {
|
||||
this.getLocation = getLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return ForgeRegistries.ITEMS.getValues().size();
|
||||
return BuiltInRegistries.ITEM.keySet().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -41,12 +40,12 @@ public class ItemMesherMap implements Map<Holder.Reference<Item>, ModelResourceL
|
|||
|
||||
@Override
|
||||
public ModelResourceLocation get(Object key) {
|
||||
return getLocation.apply(((Holder.Reference<Item>)key).get());
|
||||
return getLocation.apply((K)key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ModelResourceLocation put(Holder.Reference<Item> key, ModelResourceLocation value) {
|
||||
public ModelResourceLocation put(K key, ModelResourceLocation value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +55,7 @@ public class ItemMesherMap implements Map<Holder.Reference<Item>, ModelResourceL
|
|||
}
|
||||
|
||||
@Override
|
||||
public void putAll(@NotNull Map<? extends Holder.Reference<Item>, ? extends ModelResourceLocation> m) {
|
||||
public void putAll(@NotNull Map<? extends K, ? extends ModelResourceLocation> m) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +66,7 @@ public class ItemMesherMap implements Map<Holder.Reference<Item>, ModelResourceL
|
|||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Holder.Reference<Item>> keySet() {
|
||||
public Set<K> keySet() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +78,7 @@ public class ItemMesherMap implements Map<Holder.Reference<Item>, ModelResourceL
|
|||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Map.Entry<Holder.Reference<Item>, ModelResourceLocation>> entrySet() {
|
||||
public Set<Map.Entry<K, ModelResourceLocation>> entrySet() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user