From c1182944f3222e7563b17038b818e6b3fe54695e Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 8 Aug 2023 18:17:01 -0400 Subject: [PATCH 01/45] Redirect fetchChoiceType directly in vanilla code instead of fully disabling it Should address #204 --- .../dynamic_dfu/BlockEntityTypeMixin.java | 19 +++++++++++++++++++ .../dynamic_dfu/EntityTypeBuilderMixin.java | 19 +++++++++++++++++++ .../dynamic_dfu/SharedConstantsMixin.java | 15 --------------- 3 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/BlockEntityTypeMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/EntityTypeBuilderMixin.java delete mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/SharedConstantsMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/BlockEntityTypeMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/BlockEntityTypeMixin.java new file mode 100644 index 00000000..23180408 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/BlockEntityTypeMixin.java @@ -0,0 +1,19 @@ +package org.embeddedt.modernfix.common.mixin.perf.dynamic_dfu; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.types.Type; +import net.minecraft.world.level.block.entity.BlockEntityType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +/** + * Prevent fetchChoiceType calls from loading DFU early. Vanilla doesn't need the return values here. + */ +@Mixin(BlockEntityType.class) +public class BlockEntityTypeMixin { + @Redirect(method = "register", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;fetchChoiceType(Lcom/mojang/datafixers/DSL$TypeReference;Ljava/lang/String;)Lcom/mojang/datafixers/types/Type;")) + private static Type skipSchemaCheck(DSL.TypeReference ref, String s) { + return null; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/EntityTypeBuilderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/EntityTypeBuilderMixin.java new file mode 100644 index 00000000..737778f7 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/EntityTypeBuilderMixin.java @@ -0,0 +1,19 @@ +package org.embeddedt.modernfix.common.mixin.perf.dynamic_dfu; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.types.Type; +import net.minecraft.world.entity.EntityType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +/** + * Prevent fetchChoiceType calls from loading DFU early. Vanilla doesn't need the return values here. + */ +@Mixin(EntityType.Builder.class) +public class EntityTypeBuilderMixin { + @Redirect(method = "build", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;fetchChoiceType(Lcom/mojang/datafixers/DSL$TypeReference;Ljava/lang/String;)Lcom/mojang/datafixers/types/Type;")) + private Type skipSchemaCheck(DSL.TypeReference ref, String s) { + return null; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/SharedConstantsMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/SharedConstantsMixin.java deleted file mode 100644 index ece6aaf5..00000000 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_dfu/SharedConstantsMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.dynamic_dfu; - -import net.minecraft.SharedConstants; -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(SharedConstants.class) -public class SharedConstantsMixin { - @Inject(method = "", at = @At("RETURN")) - private static void skipSchemaCheck(CallbackInfo ci) { - SharedConstants.CHECK_DATA_FIXER_SCHEMA = false; - } -} From 22f22b931711d0f54a4ca8d6979d443b3267735a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BE=8A=E7=BE=BD=E3=81=A1=E3=82=83=E3=82=93?= <108245985+u7f8au7fbd@users.noreply.github.com> Date: Wed, 9 Aug 2023 07:18:48 +0900 Subject: [PATCH 02/45] Add Japanese translation (#206) --- .../assets/modernfix/lang/ja_jp.json | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 common/src/main/resources/assets/modernfix/lang/ja_jp.json diff --git a/common/src/main/resources/assets/modernfix/lang/ja_jp.json b/common/src/main/resources/assets/modernfix/lang/ja_jp.json new file mode 100644 index 00000000..81103546 --- /dev/null +++ b/common/src/main/resources/assets/modernfix/lang/ja_jp.json @@ -0,0 +1,115 @@ +{ + "key.modernfix": "ModernFix", + "key.modernfix.config": "設定ファイルを開く", + "modernfix.jei_load": "JEIを読み込み中... しばらく時間がかかる可能性があります。", + "modernfix.no_lazydfu": "LazyDFUがインストールされていません。Minecraftが古いバージョンのゲームデータを更新する必要がある場合、目立つラグが発生する可能性があります。", + "modernfix.no_ferritecore": "FerriteCoreがインストールされていません。メモリ使用量は非常に高くなります。", + "modernfix.perf_mod_warning": "Modをインストールすることをお勧めしますが、警告はModernFixの設定で無効にできます。", + "modernfix.config": "ModernFixによるmixinの設定", + "modernfix.config.done_restart": "完了 (再起動が必要)", + "modernfix.option.on": "オン", + "modernfix.option.off": "オフ", + "modernfix.option.disabled": "無効", + "modernfix.option.enabled": "有効", + "modernfix.option.mod_override": " 改造者 [%s]", + "modernfix.config.not_default": " [変更済]", + "asynclocator.map.locating": "マップ(ロケーティング)", + "asynclocator.map.none": "マップ (近くの機能が見つかりません)", + "modernfix.option.category.performance": "パフォーマンス", + "modernfix.option.category.performance.description": "ゲーム/起動パフォーマンスの向上に役立つ機能", + "modernfix.option.category.bugfixes": "バグ修正", + "modernfix.option.category.bugfixes.description": "ゲームの安定性を向上させるためのコアバグ修正", + "modernfix.option.category.troubleshooting": "トラブルシューティング/ユーティリティ", + "modernfix.option.category.troubleshooting.description": "問題の診断に役立つ機能", + "modernfix.option.category.expert_only": "上級者のみ", + "modernfix.option.category.expert_only.description": "あなたが何をしているかを知っていない限り、これを変更しないでください!", + "modernfix.option.name.mixin.perf.async_jei": "JEIのバックグラウンド読み込み", + "modernfix.option.mixin.perf.async_jei": "1.16のみです。**キーの最適化** JEIがバックグラウンドスレッドでリロードされるようにパッチを適用することで、世界の読み込みに追加される長い遅延が完全になくなります。", + "modernfix.option.mixin.perf.async_locator": "1.16 のみ。`/locate`に関連付けられているサーバーのフリーズや、戦利品テーブルの生成などを解消するために、Async Locator modのパッチをバックアップします。", + "modernfix.option.mixin.perf.biome_zoomer": "1.16のみ。1.18からのロジックを使用してバイオームズームのパフォーマンスを向上させるためのマイナーな最適化。", + "modernfix.option.mixin.perf.blast_search_trees": "すべてのバージョン。 REIまたはJEIがインストールされている場合、レシピ検索のためのバニラ検索ツリーの構築が無効になります。 代わりに、これらのmodsの検索実装を使用して検索を行います。 これにより、世界の読み込み中に数秒節約でき、おそらくいくつかのRAMも節約できます(私は測定していませんが)。", + "modernfix.option.mixin.perf.boost_worker_count": "1.16 のみ。Mojang が 1.18 と同様に、ワーカースレッド数のハードコードされたキャップを削除します。", + "modernfix.option.mixin.perf.cache_blockstate_cache_arrays": "すべてのバージョンです。ブロック状態キャッシュが初期化されるたびに列挙型配列の新規コピーを作成するのを避けます。マイナーな最適化ですが、簡単に行えます。", + "modernfix.option.mixin.perf.cache_model_materials": "すべてのバージョン。リクエストごとに再計算する代わりにモデルが返す`RenderMaterial` (テクスチャ) コレクションと依存関係リストをメモします。 モデルのロード/焼成プロセスを加速するのに役立ちます。", + "modernfix.option.mixin.perf.cache_strongholds": "すべてのバージョン。全てのワールドロード時に再生成するのではなく、ワールドで生成された要塞位置のリストを保存します。 1.16で少し時間を節約し、1.18と1.19ではかなり多くの時間を節約します。", + "modernfix.option.mixin.perf.cache_upgraded_structures": "すべてのバージョンです。多くのMODは古い構造ファイルを出荷しています。DFUを使用してゲームをアップグレードする必要があります。 これはかなり遅い可能性があります。このパッチは、アップグレードされたバージョンの構造を保存する代わりにロジックを追加し、次のロードで再利用します。 modが名前ではなく構造ファイルを変更する場合を処理する 元のファイルのハッシュはキャッシュされたバージョンと比較され、一致しない場合は再び構造がアップグレードされます。", + "modernfix.option.mixin.perf.compress_biome_container": "1.16 のみ。可能であればバイオームコンテナ内のスペースを節約しようとする、Hydrogenから借りたマイナーな最適化。 BetterEnd や Chocolate のような競合する Mod がインストールされている場合、自動的に無効になります。", + "modernfix.option.mixin.perf.datapack_reload_exceptions": "すべてのバージョン. ログスパムを削減し、データパックの再ロード中にいくつかの一般的にスローされる例外のスタックトレースを印刷しないことにより、ロード速度をわずかに向上させます (e. を選択します。戦利品のテーブル/レシピに欠落しています。メッセージは印刷されます。", + "modernfix.option.mixin.perf.dedicated_reload_executor": "すべてのバージョンです。デフォルトの `Worker-Main` スレッドを使用する代わりに、リソースパックとデータパックを専用のワーカープールにリロードします。 これにより、Modはスムーズブートを可能にし、限られたスレッド数で起動を遅らせずに実行時のシングルプレイヤーのパフォーマンスを向上させることができます。", + "modernfix.option.mixin.perf.deduplicate_location": "すべてのバージョンですが、時間の影響によりデフォルトでは無効になります。リソースロケーションの名前空間とパスをDeduplicatesします。 これによりRAMは節約されますが、新しい「ResourceLocation」を構築するコストもかなり増加します。", + "modernfix.option.mixin.perf.dynamic_dfu": "すべてのバージョンです。何かをアップグレードする必要があるときにDFU初期化を変更します。 これはLazyDFUに似ているように聞こえますが、LazyDFUはルールの最適化のみを無効にするので、明確に実装されています。 基本的に、このオプションはDataFixerSlayerの安全なバージョンであり、必要に応じてDFUをロードします。\n\nDFUルールの最適化が遅れるため、通常はこのオプションを有効にしてもLazyDFUを使用し続ける必要があります。", + "modernfix.option.mixin.perf.dynamic_resources": "すべてのバージョン。https://github.com/embeddedt/ModernFix/wiki/Dynamic-Resources-FAQを参照してください。", + "modernfix.option.mixin.perf.dynamic_structure_manager": "すべてのバージョンです。生成後、ゲームは永久に読み込まれるのではなく、構造ファイルをアンロードすることができます。", + "modernfix.option.mixin.perf.fast_registry_validation": "すべてのバージョン。Forge はレジストリが検証されるたびに反射を使ってメソッドを検索します。 このパッチは、毎回同じになるため、返された値をキャッシュするだけです。", + "modernfix.option.mixin.perf.faster_font_loading": "すべてのバージョンです。フォントレンダラーを最適化し、フォントの読み込みを高速化し、リソースのリロードを高速化します。", + "modernfix.option.mixin.perf.faster_item_rendering": "すべてのバージョンです。GUI内のアイテムの側面をレンダリングするのを避けます。(はい、バニラがそうするように見えます。\n\n十分なアイテムが表示されている場合、弱いGPUにREI/JEIのようなModがインストールされているとFPSを3倍にすることができます。 新しいものでテストされていないため、デフォルトで無効になっていますが、安全である必要があります。 おそらく、GUIで全く見えないアイテムや、世界中でフラットに見えるアイテムが問題です。", + "modernfix.option.mixin.perf.faster_texture_loading": "1.19.4より前のすべてのバージョン。 テクスチャを2回(非常に遅いコードパスを使用する最初の時) 読み取りを避け、代わりに1回高速負荷を行います(1.19.3以降と同様)。", + "modernfix.option.mixin.perf.faster_texture_stitching": "すべてのバージョンです。スーパーCoder79が1.7でlwjgl3ify用に作成した、より高速なテクスチャステッチシステムを使用できるようになります。 0は読み込み中に時間を節約できます。 まれに、ブロックやGUIに奇妙なアーティファクトが発生することが報告されています。これはナトリウムバグかもしれません。", + "modernfix.option.mixin.perf.jeresources_startup": "1.16のみ。村人を同じ職業に何度も再現しないように十分なリソースを最適化します。JEIのスタートアップ時の時間を節約できます。", + "modernfix.option.mixin.perf.kubejs": "1.16 のみです。不必要な `ItemStack` のコピーなどを避けるために KubeJS への最適化により、データパックの読み込みにかかる時間が短縮されます。", + "modernfix.option.mixin.perf.model_optimizations": "すべてのバージョンです。最適化を実装して、モデルの読み込みプロセスを高速化します。", + "modernfix.option.mixin.perf.nbt_memory_usage": "すべてのバージョン。 キー名をdeduplicateし、非常に小さな化合物の配列マップを使用する複合NBTタグに、より効率的なバッキングマップを使用します。 これにより、メモリに多くの複合タグを格納するオーバーヘッドが軽減されます。", + "modernfix.option.mixin.perf.nuke_empty_chunk_sections": "1.16 は Hydrogen に触発されています。空気がいっぱいのチャンクセクションをメモリに保存しないでください。", + "modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "すべてのバージョン。 **主要な最適化。** 新しい Minecraft バージョン (1.12 以降) では、ブロックステートについて頻繁に使用される情報 (ソリッドかどうか、衝突形状など) をキャッシュするブロックステート キャッシュ システムが実装されました。このキャッシュの再構築はバニラでは非常に高速です。 (わずか 1 ~ 2 秒しかかかりません) ただし、ゲーム内にはさらに多くのブロックステートが存在し、キャッシュを再構築する必要があるため、多くの MOD がインストールされていると非常に遅くなります。 Forge では、次の再構築までにデータがほぼ確実に未使用になる多くの時点でキャッシュが再構築されるため、この問題はさらに悪化します。 例には、メイン メニューに到達する直前 (「データの凍結」段階中) や、ワールドがロードされている複数回 (!) の時間が含まれます。 ModernFix は、代わりにキャッシュの再構築を遅延させることで、このパフォーマンスのボトルネックを解決します。 各ブロック状態は、データが初めてアクセスされるときにキャッシュを再構築します。 バニラまたは Forge がすべてのブロック状態のキャッシュを再構築しようとする時点で、これはリダイレクトされ、代わりに各ブロック状態のキャッシュを単に無効化します。 これは、起動完了後の TPS には影響しません。", + "modernfix.option.mixin.perf.remove_biome_temperature_cache": "すべてのバージョンです。Lithiumが最新バージョンで行うように、バイオーム温度キャッシュを削除します。", + "modernfix.option.mixin.perf.resourcepacks": "すべてのバージョン。**最近のバージョンでは、ファイルシステムへのアクセスが起動の大きなボトルネックとなっている。リソースをリストアップしたり、指定されたリソースが存在するかどうかをチェックするために、リソースパックに多くのリクエストが頻繁に行われ、これらのそれぞれが非常に遅いファイルAPI呼び出しになります。\n\nModernFixは、MODが提供するリソースパックとバニラリソースパック内に存在するすべてのリソースのリストをキャッシュするだけで、このボトルネックのほとんどを完全に排除します。キャッシュはリソースのリロード時に再構築されます(バニラリソースを除く。)\n\nこのパッチには、OptiFine(そのCTMリソースが正しくロードされない)を除いて、既知の互換性の問題はありません。しかし、OptiFineはそれだけで起動時間が数分長くなり、ModernFixとのテストが全く行われていないため、どのようなシナリオでもOptiFineを使用することはお勧めしません。", + "modernfix.option.mixin.perf.reuse_datapacks": "1.16 のみ。可能な場合、データパックのリロードをスキップしてシングルプレイヤー間の切り替えをスピードアップしようとします。 一部のMODとの互換性に問題が生じる可能性がありますが、現在デフォルトで有効になっています。", + "modernfix.option.mixin.perf.rewrite_registry": "すべてのバージョンです。**現在半分壊れています。 * 積極的に Forge レジストリシステムのいくつかの内部をより高速なバージョンに置き換えますが、Modpackをロードすると現在フリーズします。 明白な理由により、デフォルトでオフになります。", + "modernfix.option.mixin.perf.skip_first_datapack_reload": "1.16の開発サイクルの途中で、ForgeはバイオームIDシフトの問題を修正するために、既存のワールドをロードする際にデータパックを2回リロードするようにパッチを適用しました。残念なことに、データパックのリロードには30秒以上かかることが多いため、ワールドのロード時間に深刻な影響を及ぼしています。\n\nModernFixは、未完成のForge PR #8163に基づいて、このリロードを回避するために必要な変更を行います。\n\nこの変更は1.18でForgeによって削除されましたが、その後1.19で同様のパッチが*再び*追加され、新しいシングルプレイヤーワールドを作成する際にMODデータパックがロードされない問題が修正されました。幸いなことに、1.19ではこの問題はワールド作成画面に限定され、既存のワールドは1回のリロードで済むようになりました。しかし、それでも1.19の \"Create New World \"をクリックしたときのラグ・スパイクの長さは2倍になるため、ModernFixは冗長なリロードを行わないように再び変更を加えています。", + "modernfix.option.mixin.perf.state_definition_construct": "すべてのバージョン。FerriteCoreがインストールされている場合にのみ有効です。FerriteCoreのブロック状態の処理を利用して、作成をスピードアップします。 これは、家具モッドなどの多くのブロック状態を追加するModでの立ち上げを加速することができます。", + "modernfix.option.mixin.perf.sync_executor_sleep": "すべてのバージョン。Modloadingワーカーが終了するのを待っている間に、メインスレッドが一度だけCPUコアを消費することを回避します。", + "modernfix.option.mixin.perf.thread_priorities": "すべてのバージョン。ワーカーとサーバースレッドの優先度をクライアントスレッドよりも低く調整します。 これは、Java実装が優先順位を尊重していれば、CPUコアが少ないマシンでのFPSの安定性を向上させるのに役立ちます。", + "modernfix.option.mixin.perf.use_integrated_resources": "主に1.16の場合、JEResourcesがシングルプレイヤーをプレイする場合、戦利品テーブルを無意味にリロードするのではなく、統合サーバーの戦利品テーブルデータを使用するようにパッチします。 JEIの起動中にもう数秒節約します。", + "modernfix.option.mixin.bugfix.concurrency": "このグループのパッチは、Minecraft や Forge 内で同時に発生する問題を修正します。ほとんどのパッチは、読み込み中に稀で診断が難しいクラッシュを引き起こします。", + "modernfix.option.mixin.bugfix.edge_chunk_not_saved": "このオプションは、SuperCoder のチャンク節約修正モジュールのポートです(その時点で Forge ではすでに利用可能であることに気付いていませんでした)。", + "modernfix.option.mixin.bugfix.mc218112": "このオプションは、エンティティデータの処理中に例外が発生した場合に発生するデッドロックを修正します。 バニラは必要なときにデータマネージャのロックを正しく解除しません。 これはバグトラッカーでMC-218112として追跡され、1.17でMojangによって修正されました。", + "modernfix.option.mixin.bugfix.packet_leak": "**実験**はデフォルトで有効になっていません。1.16で十分な長時間再生した後に発生するメモリリーク問題の修正を試みました。", + "modernfix.option.mixin.bugfix.paper_chunk_patches": "1.18 以降。**鍵の最適化** 1の問題を修正する紙のパッチをポートします。 chunkloadは膨大なメモリを必要とし、多くの`ComplettableFuture`インスタンスを生成します。 1.18以降では、1.16のように400MBのメモリでワールドを読み込むことができます。", + "modernfix.option.mixin.bugfix.tf_cme_on_load": "パッチTwilight Forestは、FML ワーカースレッドではなく、メインスレッドを使用して非スレッドセーフなクライアント設定を実行します。", + "modernfix.option.mixin.feature.branding": "タイトル画面のブランドリストにModernFixを追加し、F3画面にも追加します。", + "modernfix.option.mixin.feature.direct_stack_trace": "通常は off にすることで、クラッシュ時にrawスタックトレースをログにダンプさせることができます。 場合によっては、バニラのクラッシュレポートシステムが正常に動作せず、スタックトレース/レポートを完全に無関係にすることがあります。", + "modernfix.option.mixin.feature.measure_time": "ワールドロード時間、データパックのリロード時間、リロード時間、ブートストラップ時間を測定するために、2つの注射を使用します。 そして、必要なフックを追加して、バニラの未使用のプロファイラロジックをリソースの再ロードに有効にします。", + "modernfix.option.mixin.feature.spam_thread_dump": "**デバッグ目的のみに使用するために使用します。** スレッドダンプを60秒ごとにログに出力します。 これにより、読み込み/ゲームプレイ中に解明されていないフリーズを診断するのに役立ちます。", + "modernfix.option.mixin.bugfix.chunk_deadlock": "チャンクシステムのデッドロックを防ぐか、ログに追加のデバッグ情報を提供しようとします。 これらのデッドロックは通常、サーバーが無期限にフリーズする(例えば、エンティティが移動しない)としてマニフェストされ、クライアントは正常に動作し続けます。", + "modernfix.option.mixin.bugfix.chunk_deadlock.valhesia": "パッチValhesia Structures to fix an problem in its code that cause frequent worldgen/chunkloading deadlocks.", + "modernfix.option.mixin.bugfix.cofh_core_crash": "CoFHコアで起動中にまれなクラッシュを引き起こすマルチスレッドの問題を修正しました。", + "modernfix.option.mixin.bugfix.ctm_resourceutil_cme": "ConnectedTexturesModで起動中にまれなクラッシュを引き起こすマルチスレッドの問題を修正しました。", + "modernfix.option.mixin.bugfix.ender_dragon_leak": "以前のクライアントの世界への参照を保持しているエンダードラゴンによって引き起こされるバニラのメモリリークを修正しました。", + "modernfix.option.mixin.bugfix.entity_load_deadlock": "EntityJoinWorldEvent/EntityJoinLevelEvent がエンティティの読み込みを少し遅らせることによって世界的なデッドロックを引き起こす多くの問題を修正します。ただし、ゲーム内で顕著な動作変更を引き起こす必要があります。", + "modernfix.option.mixin.bugfix.fix_config_crashes": "修正されたForgeはゲームを起動する際に時々壊れてしまうことがあります。", + "modernfix.option.mixin.bugfix.item_cache_flag": "MC-258939を修正", + "modernfix.option.mixin.bugfix.preserve_early_window_pos": "Forge の初期ロードから Minecraft コードにコントロールが渡されると、ゲームウィンドウが既存のサイズを保持します。 ドラッグされた後、画面の中心に戻ってテレポートするウィンドウを修正します。", + "modernfix.option.mixin.bugfix.refinedstorage.te_bug": "修理済みストレージ外部ストレージブロックに引き出しの内容などが表示されない場合があります。 ときにロードされます。Refined Storage PR #3435のバックポート。これは1.18以降にのみ適用されました。", + "modernfix.option.mixin.bugfix.remove_block_chunkloading": "Forgeで0チャンクを永久にロードしたゾンビピッグマンを修正。ForgeのPR#8583のバックポート。", + "modernfix.option.mixin.bugfix.starlight_emptiness": "初期化されていない空マップのために時折Starlightがクラッシュする問題を修正します。1.18.xのStarlightで同じ修正をバックポートします。", + "modernfix.option.mixin.core": "ModernFixが動作するために必要なコアパッチです", + "modernfix.option.mixin.devenv": "開発環境で実行するときに使用されるパッチ、速度向上および/またはテストのために使用されるパッチ。", + "modernfix.option.mixin.safety": "起動時にクラッシュを防ぐためにパッチを並行します。", + "modernfix.option.mixin.feature.integrated_server_watchdog": "バニラウォッチドッグをシングルプレイヤーの世界にも追加しますが、強制的に世界を終了するのではなくスタックトレースをプリントアウトします。 このバージョンには、Fullstack Watchdog の機能が含まれていますが、後者はマルチプレイにはまだ必要です。", + "modernfix.option.mixin.feature.snapshot_easter_egg": "スナップショット版で実行中にイースターエッグ機能を追加します (バニラビジュアルや動作には影響しません)。", + "modernfix.option.mixin.feature.spark_profile_launch": "有効にすると、互換性のあるバージョンの Spark がインストールされている場合、起動シーケンス全体がメインメニューまでプロファイルされます。", + "modernfix.option.mixin.feature.warn_missing_perf_mods": "本質的で互換性が高いと考えられる他のパフォーマンスMODが存在しない場合、起動時に警告を表示します", + "modernfix.option.mixin.launch.class_search_cache": "Forgeのリソースファインダー(ゲームとModコードの検索に使用)を大幅に高速なバージョンに置き換え、起動を加速します。", + "modernfix.option.mixin.perf.clear_fabric_mapping_tables": "Modで冗長またはまれに使用されているFabric Loader のマッピングデータ構造をクリアすることで、メモリ使用量を削減します。 互換性の理由により、デフォルトではオフになります。", + "modernfix.option.mixin.perf.clear_mixin_classinfo": "起動時にすべてのミックスインを強制ロードし、ミックスインのデータ構造をクリアして、Mixinのメモリフットプリントの大部分を削除します。 互換性の理由によりデフォルトで無効になっています。", + "modernfix.option.mixin.perf.deduplicate_wall_shapes": "ほとんどの壁ブロックは、それぞれのブロックがそれぞれのブロックにコピーを持つのではなく、同じ形状のオブジェクトを共有するようにします。 Modで多くのウォールブロックを追加すると、メモリ使用量を大幅に削減できます。", + "modernfix.option.mixin.perf.dynamic_resources.ae2": "動的リソースのためのAE2互換性パッチ。", + "modernfix.option.mixin.perf.dynamic_resources.ctm": "動的リソース用のCTM互換性パッチ", + "modernfix.option.mixin.perf.dynamic_resources.rs": "動的リソースのためのAE2互換性パッチ。", + "modernfix.option.mixin.perf.dynamic_resources.supermartijncore": "動的リソースのためのAE2互換性パッチ。", + "modernfix.option.mixin.perf.dynamic_resources.diagonalfences": "動的リソースのためのAE2互換性パッチ。", + "modernfix.option.mixin.perf.faster_advancements": "前進チェックロジックを高速化し、大きなパックで StackOverflowError を引き起こさないように書き換えます。前進ポートは Fabric からデバッグします。", + "modernfix.option.mixin.perf.patchouli_deduplicate_books": "メモリ使用量を削減し、NBTタグで多くの空のアイテムを格納するパッチョリ本を修正しました。", + "modernfix.option.mixin.perf.remove_spawn_chunks": "ゲームからスポーンチャンクを完全に削除します。これらは、Ksyxis とは異なり、もはや読み込まれなくなります。", + "modernfix.option.mixin.perf.use_integrated_resources.jepb": "[空]", + "modernfix.option.mixin.perf.use_integrated_resources.jeresources": "[空]", + "modernfix.option.mixin.bugfix.blueprint_modif_memory_leak": "解決法 設計図のObjectModificationManagerがバニラリソースをリークしているので、メモリ使用量を削減します。PR #195では修正が貢献されているにもかかわらず、リリースはまだ行われていません。", + "modernfix.option.mixin.bugfix.removed_dimensions": "ディメンションMODが削除された場合、ゲームがワールドの読み込みに失敗する問題を修正しました。Forge PR #899のバックポート。", + "modernfix.option.mixin.perf.compact_bit_storage": "ブロックが含まれているかのように空のチャンクを送信する旧式のサーバー (Hypixel など) によって引き起こされるメモリの浪費を修正します。これらのサーバーでメモリ使用量を大幅に削減します。", + "modernfix.option.mixin.perf.deduplicate_climate_parameters": "新しいバイオームシステムによって使用される気候パラメータオブジェクトをdeduplicates, 〜2MBを保存することができますが、また、データパックのリロードが少し遅くなります。", + "modernfix.option.mixin.perf.dynamic_entity_renderers": "起動時の代わりにエンティティモデルを初めて見るときに構築します。 一部の Mod はこのオプションと互換性がないため、EntityRenderer がクラッシュします。", + "modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "Twilight Forest worldgen のチェック構造によって引き起こされる遅延を修正しました。", + "modernfix.option.mixin.perf.fast_forge_dummies": "より高速なコードパスを使用することで、起動中に Forge レジストリの凍結を高速化する", + "modernfix.option.mixin.perf.tag_id_caching": "毎回再作成する代わりにlocationオブジェクトをキャッシュすることでタグエントリの使用を高速化します。", + "modernfix.option.mixin.feature.disable_unihex_font": "Unicodeフォントを削除し、10MBを保存しますが、特殊文字がレンダリングされなくなります" +} From eec5ec7efb0d2c489bf82afb84b150b7158ef899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=B6=E6=99=BA=E4=B9=83=E5=8F=8D=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=8F=8A?= <100760086+qznfbnj@users.noreply.github.com> Date: Wed, 9 Aug 2023 22:05:58 +0800 Subject: [PATCH 03/45] Update zh_cn.json (#207) --- common/src/main/resources/assets/modernfix/lang/zh_cn.json | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/main/resources/assets/modernfix/lang/zh_cn.json b/common/src/main/resources/assets/modernfix/lang/zh_cn.json index 4d3b776e..846a902e 100644 --- a/common/src/main/resources/assets/modernfix/lang/zh_cn.json +++ b/common/src/main/resources/assets/modernfix/lang/zh_cn.json @@ -7,6 +7,7 @@ "modernfix.perf_mod_warning": "推荐安装这些模组,但你也可以在现代化修复的配置中禁用此警告。", "modernfix.config": "现代化修复Mixin配置", "modernfix.config.done_restart": "完成(生效需重启)", + "modernfix.message.reload_config": "在游戏外编辑完配置文件后,使用§b/mfrc§r命令使其生效。", "modernfix.option.on": "开启", "modernfix.option.off": "关闭", "modernfix.option.disabled": "已禁用", From 590c93977832291d88cdaab4e1b5791e3ec05575 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 12:14:50 -0400 Subject: [PATCH 04/45] Increase default heap from 512MB to 1GB to avoid issues with Fabric remapper This is still substantially less than the original 4GB --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index b7a37bc4..358276e6 100644 --- a/build.gradle +++ b/build.gradle @@ -204,8 +204,8 @@ configure(subprojects.findAll {it.name == "forge" || it.name == "fabric"}) { } runs { client { - vmArgs "-Xmx512m" - vmArgs "-Xms512m" + vmArgs "-Xmx1G" + vmArgs "-Xms1G" } } } From 7b23053da0f56d515c969e2098ee3a8c38160174 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 12:38:19 -0400 Subject: [PATCH 05/45] Skip generating remapJar for common project --- common/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/build.gradle b/common/build.gradle index de613044..ab51f236 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -18,6 +18,9 @@ dependencies { // modApi "me.shedaniel:architectury:${rootProject.architectury_version}" } +// don't need remapped common jar +tasks.named('remapJar') { enabled = false } + publishing { publications { mavenCommon(MavenPublication) { From f488df2d45a5841dd3f66cac07c468259acee9e7 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 12:41:49 -0400 Subject: [PATCH 06/45] Minor buildscript improvements --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 358276e6..0df67a03 100644 --- a/build.gradle +++ b/build.gradle @@ -146,7 +146,7 @@ configure(subprojects.findAll {it.name == "common" || it.name == "forge" || it.n } } -tasks.withType(JavaCompile) { +tasks.withType(JavaCompile).configureEach { // ensure that the encoding is set to UTF-8, no matter what the system default is // this fixes some edge cases with special characters not displaying correctly // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html @@ -164,10 +164,10 @@ tasks.withType(JavaCompile) { */ } -task generateChangelog(type: se.bjurr.gitchangelog.plugin.gradle.GitChangelogTask) { +tasks.register('generateChangelog', se.bjurr.gitchangelog.plugin.gradle.GitChangelogTask) { def details = versionDetails(); def theVersionRef - if(details.commitDistance > 0) { + if (details.commitDistance > 0) { theVersionRef = details.lastTag; } else { def secondLastTagCmd = "git describe --abbrev=0 " + details.lastTag + "^" From 27c2a674cf6988f4db35072f55a2e8be62d36809 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:16:51 -0400 Subject: [PATCH 07/45] Allow only applying mixins when mods aren't present --- .../embeddedt/modernfix/core/config/ModernFixEarlyConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index ae5fa9ee..2036f880 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -112,7 +112,7 @@ public class ModernFixEarlyConfig { if(annotation.values.get(i).equals("value")) { String modId = (String)annotation.values.get(i + 1); if(modId != null) { - requiredModPresent = modPresent(modId); + requiredModPresent = modId.startsWith("!") ? !modPresent(modId.substring(1)) : modPresent(modId); requiredModId = modId; } break; From fbfaa178e39059a3b5280daf5c324447be34ad04 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 15:45:14 -0400 Subject: [PATCH 08/45] Allow disabling Fabric API for runtime in dev --- fabric/build.gradle | 22 ++++++++++++++-------- gradle.properties | 2 ++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/fabric/build.gradle b/fabric/build.gradle index cf2c4ad1..42ff963d 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -32,14 +32,20 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" testImplementation "net.fabricmc:fabric-loader-junit:${rootProject.fabric_loader_version}" - modImplementation(fabricApi.module("fabric-api-base", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } - modImplementation(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } - modImplementation(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } - modImplementation(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } - modImplementation(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } - modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { transitive false } - modImplementation "curse.maven:spark-361579:${rootProject.spark_fabric_version}" - modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}") { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modCompileOnly(fabricApi.module("fabric-api-base", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modCompileOnly(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modCompileOnly(fabricApi.module("fabric-command-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modCompileOnly(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modCompileOnly(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + if(project.use_fabric_api_at_runtime.toBoolean()) { + modImplementation("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { transitive false } + modImplementation "curse.maven:spark-361579:${rootProject.spark_fabric_version}" + modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}") { exclude group: 'net.fabricmc', module: 'fabric-loader' } + } else { + modCompileOnly("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { transitive false } + modCompileOnly "curse.maven:spark-361579:${rootProject.spark_fabric_version}" + } + // Remove the next line if you don't want to depend on the API // modApi "me.shedaniel:architectury-fabric:${rootProject.architectury_version}" diff --git a/gradle.properties b/gradle.properties index 507af8cf..0a084c03 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,3 +23,5 @@ modmenu_version=1.16.23 spark_forge_version=3767277 spark_fabric_version=3337642 + +use_fabric_api_at_runtime=true \ No newline at end of file From 5e7d6642a7d61decf009135bce3cb32b6708c88d Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 15:46:40 -0400 Subject: [PATCH 09/45] Implement minor memory usage optimization for environments without FerriteCore This is "FerriteCore at home", used to assist with the large registry tests --- .../StateHolderMixin.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java new file mode 100644 index 00000000..9c81fd6e --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java @@ -0,0 +1,29 @@ +package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size; + +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Table; +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.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * Minor mixin to avoid duplicate empty neighbor tables, used when FerriteCore is not present. Won't be enabled in 99% of + * modded environments but is useful for testing in dev without dragging in Fabric API. + */ +@Mixin(StateHolder.class) +@RequiresMod("!ferritecore") +public class StateHolderMixin { + @Shadow private Table, Comparable, ?> neighbours; + + /* optimize the case where block has no properties */ + @Inject(method = "populateNeighbours", at = @At("RETURN"), require = 0) + private void replaceEmptyTable(CallbackInfo ci) { + if(this.neighbours.isEmpty()) + this.neighbours = ImmutableTable.of(); + } +} From cac291df476e0ab1932c2078610e988500f27e31 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 19:51:59 -0400 Subject: [PATCH 10/45] Add minor Brigadier patch to limit suggestion count to 10000 Fixes lag when there are many items registered --- .../SuggestionsBuilderMixin.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java new file mode 100644 index 00000000..e27b0480 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java @@ -0,0 +1,30 @@ +package org.embeddedt.modernfix.fabric.mixin.perf.faster_command_suggestions; + +import com.mojang.brigadier.suggestion.Suggestion; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.List; + +/** + * Simple hack-fix to limit the number of suggestions being processed. Not a perfect fix but mitigates lag decently + * on an i3-4150. + */ +@Mixin(SuggestionsBuilder.class) +public class SuggestionsBuilderMixin { + @Unique + private static final int MAX_SUGGESTIONS = 10000; + + @Shadow @Final @Mutable + private List result; + + @Redirect(method = "*", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"), require = 0) + private boolean addIfFits(List list, T entry) { + if(list != result || list.size() < MAX_SUGGESTIONS) { + return list.add(entry); + } + return false; + } +} From fed0392ddcf53d15e5d6ef7be1156a96b7681f44 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 20:07:59 -0400 Subject: [PATCH 11/45] Introduce test mod --- common/build.gradle | 2 +- fabric/testmod/build.gradle | 26 +++++++++++++++++++ .../embeddedt/modernfix/testmod/TestMod.java | 10 +++++++ .../src/main/resources/fabric.mod.json | 22 ++++++++++++++++ settings.gradle | 10 +++++-- 5 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 fabric/testmod/build.gradle create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java create mode 100644 fabric/testmod/src/main/resources/fabric.mod.json diff --git a/common/build.gradle b/common/build.gradle index ab51f236..c067d157 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -11,7 +11,7 @@ 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}") { + modCompileOnly("dev.latvian.mods:kubejs:${kubejs_version}") { transitive = false } // Remove the next line if you don't want to depend on the API diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle new file mode 100644 index 00000000..58034253 --- /dev/null +++ b/fabric/testmod/build.gradle @@ -0,0 +1,26 @@ +apply plugin: "dev.architectury.loom" + +dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + mappings loom.layered() { + officialMojangMappings() + if(rootProject.hasProperty("parchment_version")) { + parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip") + } + } + + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modImplementation(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + + implementation project(path: ":common", configuration: "namedElements") + implementation project(path: ":fabric", configuration: "namedElements") +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java new file mode 100644 index 00000000..fb06e5a7 --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java @@ -0,0 +1,10 @@ +package org.embeddedt.modernfix.testmod; + +import net.fabricmc.api.ModInitializer; + +public class TestMod implements ModInitializer { + @Override + public void onInitialize() { + System.out.println("Hello ModernFix world!"); + } +} diff --git a/fabric/testmod/src/main/resources/fabric.mod.json b/fabric/testmod/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..4677a1c6 --- /dev/null +++ b/fabric/testmod/src/main/resources/fabric.mod.json @@ -0,0 +1,22 @@ +{ + "schemaVersion": 1, + "id": "mfix_testmod", + "version": "${version}", + "name": "ModernFix test mod", + "description": "Test mod used to validate features and behaviors of ModernFix, the essential Minecraft performance mod", + "authors": [ + "embeddedt" + ], + "contact": { + "sources": "https://github.com/embeddedt/ModernFix", + "homepage": "https://modrinth.com/mod/modernfix", + "issues": "https://github.com/embeddedt/ModernFix/issues" + }, + "license": "LGPL-3.0", + "environment": "*", + "entrypoints": { + "main": [ + "org.embeddedt.modernfix.testmod.TestMod" + ] + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 739e778f..c5b39d7c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -10,8 +10,14 @@ pluginManagement { include("test_agent") include("common") -getProperty("enabled_platforms").tokenize(',').each { it -> - include(it.trim()) +def current_platforms = getProperty("enabled_platforms").tokenize(',') +current_platforms.each { it -> + def platform_name = it.trim() + include(platform_name) + def testmodFolder = new File(platform_name + "/" + "testmod") + if(testmodFolder.isDirectory()) { + include(platform_name + ":testmod") + } } rootProject.name = 'modernfix' From 365eb80a285a207aeb7d2f17e4f5c487855b67aa Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 9 Aug 2023 21:45:21 -0400 Subject: [PATCH 12/45] Testmod for many blocks/items test --- fabric/testmod/build.gradle | 7 + .../modernfix/testmod/TestBlock.java | 13 ++ .../modernfix/testmod/TestBlockItem.java | 13 ++ .../embeddedt/modernfix/testmod/TestMod.java | 32 +++- .../testmod/client/TestModBlockModel.java | 142 ++++++++++++++++++ .../testmod/client/TestModClient.java | 27 ++++ .../mfix_testmod/textures/block/base_wool.png | Bin 0 -> 560 bytes .../src/main/resources/fabric.mod.json | 3 + fabric/testmod/src/main/resources/pack.mcmeta | 7 + 9 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlock.java create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlockItem.java create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModBlockModel.java create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java create mode 100644 fabric/testmod/src/main/resources/assets/mfix_testmod/textures/block/base_wool.png create mode 100644 fabric/testmod/src/main/resources/pack.mcmeta diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle index 58034253..8e27f9b9 100644 --- a/fabric/testmod/build.gradle +++ b/fabric/testmod/build.gradle @@ -1,5 +1,9 @@ apply plugin: "dev.architectury.loom" +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath +} + dependencies { minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" mappings loom.layered() { @@ -11,6 +15,9 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" modImplementation(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modImplementation(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modImplementation(fabricApi.module("fabric-renderer-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modRuntimeOnly(fabricApi.module("fabric-renderer-indigo", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } implementation project(path: ":common", configuration: "namedElements") implementation project(path: ":fabric", configuration: "namedElements") diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlock.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlock.java new file mode 100644 index 00000000..c10b8c09 --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlock.java @@ -0,0 +1,13 @@ +package org.embeddedt.modernfix.testmod; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockBehaviour; + +public class TestBlock extends Block { + private static final BlockBehaviour.Properties PROPERTIES = BlockBehaviour.Properties.copy(Blocks.STONE); + + public TestBlock() { + super(PROPERTIES); + } +} diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlockItem.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlockItem.java new file mode 100644 index 00000000..cfc09cfa --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlockItem.java @@ -0,0 +1,13 @@ +package org.embeddedt.modernfix.testmod; + +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; + +public class TestBlockItem extends BlockItem { + private static final Item.Properties PROPERTIES = new Item.Properties().tab(CreativeModeTab.TAB_BUILDING_BLOCKS); + + public TestBlockItem(TestBlock block) { + super(block, PROPERTIES); + } +} diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java index fb06e5a7..f519edc5 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java @@ -1,10 +1,40 @@ package org.embeddedt.modernfix.testmod; +import com.google.common.base.Stopwatch; import net.fabricmc.api.ModInitializer; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class TestMod implements ModInitializer { + public static final String ID = "mfix_testmod"; + public static final Logger LOGGER = LogManager.getLogger("ModernFix TestMod"); + + public static final int NUM_COLORS = 32; + public static final int MAX_COLOR = NUM_COLORS - 1; + @Override public void onInitialize() { - System.out.println("Hello ModernFix world!"); + // Register 1 million blocks & items + Stopwatch watch = Stopwatch.createStarted(); + int totalToRegister = NUM_COLORS * NUM_COLORS * NUM_COLORS; + int progressReport = totalToRegister / 20; + int numRegistered = 0; + for(int r = 0; r < NUM_COLORS; r++) { + for(int g = 0; g < NUM_COLORS; g++) { + for(int b = 0; b < NUM_COLORS; b++) { + ResourceLocation name = new ResourceLocation(ID, "wool_" + r + "_" + g + "_" + b); + TestBlock block = Registry.register(Registry.BLOCK, name, new TestBlock()); + Registry.register(Registry.ITEM, name, new TestBlockItem(block)); + numRegistered++; + if((numRegistered % progressReport) == 0) { + LOGGER.info(String.format("Registering... %.02f%%", ((float)numRegistered)/totalToRegister * 100)); + } + } + } + } + watch.stop(); + LOGGER.info("Registered {} registry entries in {}", totalToRegister, watch); } } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModBlockModel.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModBlockModel.java new file mode 100644 index 00000000..a890f540 --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModBlockModel.java @@ -0,0 +1,142 @@ +package org.embeddedt.modernfix.testmod.client; + +import com.google.common.collect.ImmutableList; +import com.mojang.datafixers.util.Pair; +import net.fabricmc.fabric.api.renderer.v1.Renderer; +import net.fabricmc.fabric.api.renderer.v1.RendererAccess; +import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; +import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; +import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import org.embeddedt.modernfix.testmod.TestMod; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; + +public class TestModBlockModel implements UnbakedModel, BakedModel, FabricBakedModel { + private static final Material BASE_WOOL = new Material(TextureAtlas.LOCATION_BLOCKS, new ResourceLocation(TestMod.ID, "block/base_wool")); + + private Mesh mesh; + private TextureAtlasSprite texture; + + private final int r, g, b; + + public TestModBlockModel(int r, int g, int b) { + this.r = r; + this.g = g; + this.b = b; + } + + @Override + public boolean isVanillaAdapter() { + return false; + } + + @Override + public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + context.meshConsumer().accept(mesh); + } + + @Override + public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { + context.meshConsumer().accept(mesh); + } + + @Override + public List getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) { + return Collections.emptyList(); + } + + @Override + public boolean useAmbientOcclusion() { + return true; + } + + @Override + public boolean isGui3d() { + return true; + } + + @Override + public boolean usesBlockLight() { + return true; + } + + @Override + public boolean isCustomRenderer() { + return false; + } + + @Override + public TextureAtlasSprite getParticleIcon() { + return texture; + } + + @Override + public ItemTransforms getTransforms() { + return ModelHelper.MODEL_TRANSFORM_BLOCK; + } + + @Override + public ItemOverrides getOverrides() { + return ItemOverrides.EMPTY; + } + + @Override + public Collection getDependencies() { + return Collections.emptyList(); + } + + @Override + public Collection getMaterials(Function modelGetter, Set> missingTextureErrors) { + return ImmutableList.of(BASE_WOOL); + } + + private static int scaleColor(int c) { + return c * 255 / TestMod.MAX_COLOR; + } + + @Nullable + @Override + public BakedModel bake(ModelBakery modelBakery, Function spriteGetter, ModelState transform, ResourceLocation location) { + // Build the mesh using the Renderer API + Renderer renderer = RendererAccess.INSTANCE.getRenderer(); + MeshBuilder builder = renderer.meshBuilder(); + QuadEmitter emitter = builder.getEmitter(); + + texture = spriteGetter.apply(BASE_WOOL); + + for(Direction direction : Direction.values()) { + // Add a new face to the mesh + emitter.square(direction, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f); + // Set the sprite of the face, must be called after .square() + // We haven't specified any UV coordinates, so we want to use the whole texture. BAKE_LOCK_UV does exactly that. + emitter.spriteBake(0, texture, MutableQuadView.BAKE_LOCK_UV); + int color = (255 << 24) | (scaleColor(r) << 16) | (scaleColor(g) << 8) | scaleColor(b); + // Enable texture usage + emitter.spriteColor(0, color, color, color, color); + // Add the quad to the mesh + emitter.emit(); + } + mesh = builder.build(); + + return this; + } +} diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java new file mode 100644 index 00000000..3bf0c36a --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java @@ -0,0 +1,27 @@ +package org.embeddedt.modernfix.testmod.client; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; +import org.embeddedt.modernfix.testmod.TestMod; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class TestModClient implements ClientModInitializer { + private static final Pattern RGB_PATTERN = Pattern.compile("^wool_([0-9]+)_([0-9]+)_([0-9]+)$"); + @Override + public void onInitializeClient() { + ModelLoadingRegistry.INSTANCE.registerVariantProvider(resourceManager -> (modelId, context) -> { + if(modelId.getNamespace().equals(TestMod.ID)) { + Matcher matcher = RGB_PATTERN.matcher(modelId.getPath()); + if(matcher.matches()) { + int r = Integer.parseInt(matcher.group(1)); + int g = Integer.parseInt(matcher.group(2)); + int b = Integer.parseInt(matcher.group(3)); + return new TestModBlockModel(r, g, b); + } + } + return null; + }); + } +} diff --git a/fabric/testmod/src/main/resources/assets/mfix_testmod/textures/block/base_wool.png b/fabric/testmod/src/main/resources/assets/mfix_testmod/textures/block/base_wool.png new file mode 100644 index 0000000000000000000000000000000000000000..39d6ec76404abdab87916313c39fd0c779574fd1 GIT binary patch literal 560 zcmV-00?+-4P)EX>4Tx04R}tkv&MmP!xqvQ>CR;9PA+CkfAzR5EXIMDionYs1;guFnQ@8G-*gu zTpR`0f`dPcRRQHpmtPe_uLvW80Dz#(EMrcR((qkh_iiQb57W9>6uG1by3X52R1Q81AsGtfP2|9IBEM(|D>Ej=A{Svtpa#g^{ zv49#h$gUrJ2ETi26(=XWq-YZ8eQ}(R5g@b+v>J}{ee5``6B^euaHV(rwI(q0NqVEB z#gBmgZQ$a%qbYm9VN}D=(EtEdZ37*jE)}8x0000 Date: Wed, 9 Aug 2023 22:48:10 -0400 Subject: [PATCH 13/45] Rewrite testmod debug renderer to be cooler --- .../embeddedt/modernfix/testmod/TestMod.java | 26 +++++++++++++- .../modernfix/testmod/mixin/ChunkMixin.java | 25 +++++++++++++ .../testmod/mixin/DebugLevelSourceMixin.java | 36 +++++++++++++++++++ .../src/main/resources/fabric.mod.json | 1 + .../src/main/resources/testmod.mixins.json | 13 +++++++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java create mode 100644 fabric/testmod/src/main/resources/testmod.mixins.json diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java index f519edc5..5ad72e50 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java @@ -4,16 +4,23 @@ import com.google.common.base.Stopwatch; import net.fabricmc.api.ModInitializer; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.ArrayList; +import java.util.List; + public class TestMod implements ModInitializer { public static final String ID = "mfix_testmod"; public static final Logger LOGGER = LogManager.getLogger("ModernFix TestMod"); - public static final int NUM_COLORS = 32; + public static final int NUM_COLORS = 100; public static final int MAX_COLOR = NUM_COLORS - 1; + public static final List WOOL_STATES = new ArrayList<>(); + @Override public void onInitialize() { // Register 1 million blocks & items @@ -26,6 +33,7 @@ public class TestMod implements ModInitializer { for(int b = 0; b < NUM_COLORS; b++) { ResourceLocation name = new ResourceLocation(ID, "wool_" + r + "_" + g + "_" + b); TestBlock block = Registry.register(Registry.BLOCK, name, new TestBlock()); + WOOL_STATES.add(block.defaultBlockState()); Registry.register(Registry.ITEM, name, new TestBlockItem(block)); numRegistered++; if((numRegistered % progressReport) == 0) { @@ -37,4 +45,20 @@ public class TestMod implements ModInitializer { watch.stop(); LOGGER.info("Registered {} registry entries in {}", totalToRegister, watch); } + + private static final BlockState AIR = Blocks.AIR.defaultBlockState(); + + public static BlockState getColorCubeStateFor(int chunkX, int chunkY, int chunkZ) { + BlockState blockState = AIR; + if (chunkX >= 0 && chunkY >= 0 && chunkZ >= 0 && chunkX % 2 == 0 && chunkY % 2 == 0 && chunkZ % 2 == 0) { + chunkX /= 2; + chunkY /= 2; + chunkZ /= 2; + if(chunkX <= TestMod.MAX_COLOR && chunkY <= TestMod.MAX_COLOR && chunkZ <= TestMod.MAX_COLOR) { + blockState = TestMod.WOOL_STATES.get((chunkX * TestMod.NUM_COLORS * TestMod.NUM_COLORS) + (chunkY * TestMod.NUM_COLORS) + chunkZ); + } + } + + return blockState; + } } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java new file mode 100644 index 00000000..1356aece --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java @@ -0,0 +1,25 @@ +package org.embeddedt.modernfix.testmod.mixin; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.LevelChunk; +import org.embeddedt.modernfix.testmod.TestMod; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(LevelChunk.class) +public class ChunkMixin { + @Shadow @Final private Level level; + + @Inject(method = "getBlockState", at = @At("HEAD"), cancellable = true) + private void redirectDebugWorld(BlockPos pos, CallbackInfoReturnable cir) { + if(this.level.isDebug()) { + cir.setReturnValue(TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ())); + } + } +} diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java new file mode 100644 index 00000000..40d3eba9 --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java @@ -0,0 +1,36 @@ +package org.embeddedt.modernfix.testmod.mixin; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.DebugLevelSource; +import org.embeddedt.modernfix.testmod.TestMod; +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(DebugLevelSource.class) +public class DebugLevelSourceMixin { + @Inject(method = "applyBiomeDecoration", at = @At("HEAD"), cancellable = true) + private void showColorCube(WorldGenRegion region, StructureFeatureManager structureManager, CallbackInfo ci) { + ci.cancel(); + BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); + int i = region.getCenterX(); + int j = region.getCenterZ(); + + for(int k = 0; k < 16; ++k) { + for(int l = 0; l < 16; ++l) { + int m = (i << 4) + k; + int n = (j << 4) + l; + for(int y = 0; y < 255; y++) { + BlockState blockState = TestMod.getColorCubeStateFor(m, y, n); + if (blockState != null) { + region.setBlock(mutableBlockPos.set(m, y, n), blockState, 2); + } + } + } + } + } +} diff --git a/fabric/testmod/src/main/resources/fabric.mod.json b/fabric/testmod/src/main/resources/fabric.mod.json index 3188e503..6ebb4d54 100644 --- a/fabric/testmod/src/main/resources/fabric.mod.json +++ b/fabric/testmod/src/main/resources/fabric.mod.json @@ -14,6 +14,7 @@ }, "license": "LGPL-3.0", "environment": "*", + "mixins": [ "testmod.mixins.json" ], "entrypoints": { "main": [ "org.embeddedt.modernfix.testmod.TestMod" diff --git a/fabric/testmod/src/main/resources/testmod.mixins.json b/fabric/testmod/src/main/resources/testmod.mixins.json new file mode 100644 index 00000000..9eeb91ea --- /dev/null +++ b/fabric/testmod/src/main/resources/testmod.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "package": "org.embeddedt.modernfix.testmod.mixin", + "compatibilityLevel": "JAVA_8", + "minVersion": "0.8", + "mixins": [ + "ChunkMixin", + "DebugLevelSourceMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file From 34179fb3133b3f383ce2881e458e0f2cb314d265 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 20:30:55 -0400 Subject: [PATCH 14/45] Implement blast_search_trees on Fabric (dummy mode only) --- .../blast_search_trees/MinecraftMixin.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/blast_search_trees/MinecraftMixin.java diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/blast_search_trees/MinecraftMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/blast_search_trees/MinecraftMixin.java new file mode 100644 index 00000000..06a475b6 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/blast_search_trees/MinecraftMixin.java @@ -0,0 +1,39 @@ +package org.embeddedt.modernfix.fabric.mixin.perf.blast_search_trees; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.searchtree.SearchRegistry; +import net.minecraft.core.NonNullList; +import net.minecraft.core.Registry; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.searchtree.DummySearchTree; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Minecraft.class) +@ClientOnlyMixin +public class MinecraftMixin { + @Shadow @Final private SearchRegistry searchRegistry; + + @Inject(method = "createSearchTrees", at = @At("HEAD"), cancellable = true) + private void replaceSearchTrees(CallbackInfo ci) { + ci.cancel(); + ModernFix.LOGGER.warn("Disabling creative search"); + NonNullList stacks = NonNullList.create(); + for(Item item : Registry.ITEM) { + stacks.clear(); + item.fillItemCategory(CreativeModeTab.TAB_SEARCH, stacks); + } + this.searchRegistry.register(SearchRegistry.CREATIVE_NAMES, new DummySearchTree<>()); + this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, new DummySearchTree<>()); + this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, new DummySearchTree<>()); + } +} + From e9ff7d7ba137037fe01f898441921c0748d05661 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 20:31:39 -0400 Subject: [PATCH 15/45] Allow setting config options via JVM properties --- .../core/config/ModernFixEarlyConfig.java | 14 ++++++++++++++ fabric/testmod/build.gradle | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 2036f880..ddbf0f7b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -11,6 +11,7 @@ import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; import org.embeddedt.modernfix.annotation.RequiresMod; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Type; @@ -253,6 +254,17 @@ public class ModernFixEarlyConfig { } } + private void readJVMProperties() { + for(String optionKey : this.options.keySet()) { + String value = System.getProperty("modernfix.config." + optionKey); + if(value == null || value.length() == 0) + continue; + boolean isEnabled = Boolean.valueOf(value); + ModernFixMixinPlugin.instance.logger.info("Configured {} to '{}' via JVM property.", optionKey, isEnabled); + this.options.get(optionKey).setEnabled(isEnabled, true); + } + } + private void readProperties(Properties props) { if(ALLOW_OVERRIDE_OVERRIDES) LOGGER.fatal("JVM argument given to override mod overrides. Issues opened with this option present will be ignored unless they can be reproduced without."); @@ -341,6 +353,8 @@ public class ModernFixEarlyConfig { } catch (IOException e) { LOGGER.warn("Could not write configuration file", e); } + + config.readJVMProperties(); } return config; diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle index 8e27f9b9..e7f14c44 100644 --- a/fabric/testmod/build.gradle +++ b/fabric/testmod/build.gradle @@ -2,6 +2,13 @@ apply plugin: "dev.architectury.loom" loom { accessWidenerPath = project(":common").loom.accessWidenerPath + runs { + client { + property("modernfix.config.mixin.perf.blast_search_trees", "true") + property("modernfix.config.mixin.perf.dynamic_resources", "true") + property("modernfix.config.mixin.perf.dynamic_block_codecs", "true") + } + } } dependencies { From 8b698452fdb59cf076968d84f494603572c31860 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 22:42:30 -0400 Subject: [PATCH 16/45] Compact Mojang registries (not available yet) --- .../DirectObjectMixin.java | 22 ++ .../MappedRegistryMixin.java | 52 ++++ .../registry/DirectStorageBiMap.java | 183 ++++++++++++++ .../registry/DirectStorageRegistryObject.java | 8 + .../modernfix/registry/LifecycleMap.java | 20 ++ .../modernfix/registry/RegistryStorage.java | 34 +++ .../modernfix/registry/TransformingBiMap.java | 224 ++++++++++++++++++ 7 files changed, 543 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageRegistryObject.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/registry/RegistryStorage.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/registry/TransformingBiMap.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java new file mode 100644 index 00000000..45d8d621 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java @@ -0,0 +1,22 @@ +package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import org.embeddedt.modernfix.registry.DirectStorageRegistryObject; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin({ Block.class, Item.class }) +public class DirectObjectMixin implements DirectStorageRegistryObject { + private ResourceLocation mfix$resourceKey; + + @Override + public ResourceLocation mfix$getResourceKey() { + return mfix$resourceKey; + } + + @Override + public void mfix$setResourceKey(ResourceLocation key) { + mfix$resourceKey = key; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java new file mode 100644 index 00000000..c5e9c813 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/MappedRegistryMixin.java @@ -0,0 +1,52 @@ +package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; + +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableSet; +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; +import org.embeddedt.modernfix.registry.DirectStorageRegistryObject; +import org.embeddedt.modernfix.registry.LifecycleMap; +import org.embeddedt.modernfix.registry.RegistryStorage; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Map; + +@Mixin(MappedRegistry.class) +@IgnoreOutsideDev +public abstract class MappedRegistryMixin extends Registry { + @Shadow + @Final + @Mutable + private Map lifecycles; + @Shadow @Final @Mutable + private BiMap storage; + @Shadow @Final @Mutable + private BiMap, T> keyStorage; + + private static final ImmutableSet MFIX$NEW_STORAGE_KEYS = ImmutableSet.of(new ResourceLocation("block"), new ResourceLocation("item")); + + protected MappedRegistryMixin(ResourceKey> resourceKey, Lifecycle lifecycle) { + super(resourceKey, lifecycle); + } + + @Inject(method = "", at = @At("RETURN")) + private void replaceStorage(CallbackInfo ci) { + this.lifecycles = new LifecycleMap<>(); + if(MFIX$NEW_STORAGE_KEYS.contains(this.key().location())) { + ModernFixMixinPlugin.instance.logger.info("Using experimental registry storage for {}", this.key()); + this.storage = (BiMap) RegistryStorage.createStorage(); + this.keyStorage = (BiMap, T>)RegistryStorage.createKeyStorage(this.key(), (BiMap)this.storage); + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java new file mode 100644 index 00000000..68717081 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java @@ -0,0 +1,183 @@ +package org.embeddedt.modernfix.registry; + +import com.google.common.collect.BiMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class DirectStorageBiMap implements BiMap { + private final Function keyGetter; + private final BiConsumer keySetter; + private final Map forwardMap; + + public DirectStorageBiMap(Function keyGetter, BiConsumer keySetter) { + Objects.requireNonNull(keyGetter); + Objects.requireNonNull(keySetter); + this.keyGetter = keyGetter; + this.keySetter = keySetter; + this.forwardMap = new Object2ObjectOpenHashMap<>(); + } + + @Override + public int size() { + return this.forwardMap.size(); + } + + @Override + public boolean isEmpty() { + return this.forwardMap.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return this.forwardMap.containsKey(o); + } + + @Override + public boolean containsValue(Object o) { + return o != null && keyGetter.apply((V)o) != null; + } + + @Override + public V get(Object o) { + return this.forwardMap.get(o); + } + + @Override + public V put(K key, V value) { + if(this.forwardMap.containsKey(key) || (value != null && keyGetter.apply(value) != null)) + throw new IllegalArgumentException("Already have mapping for " + key); + return forcePut(key, value); + } + + @Override + public V remove(Object o) { + return put((K)o, null); + } + + @Override + public V forcePut(K key, V value) { + V previousValue = this.forwardMap.put(key, value); + if(previousValue != null) + keySetter.accept(previousValue, null); + if(value != null) + keySetter.accept(value, key); + return previousValue; + } + + @Override + public void putAll(Map map) { + map.forEach(this::put); + } + + @Override + public void clear() { + for(V value : this.forwardMap.values()) { + if(value != null) + keySetter.accept(value, null); + } + this.forwardMap.clear(); + } + + @NotNull + @Override + public Set keySet() { + return this.forwardMap.keySet(); + } + + @Override + public Set values() { + return new HashSet<>(this.forwardMap.values()); + } + + @NotNull + @Override + public Set> entrySet() { + return this.forwardMap.entrySet(); + } + + @Override + public BiMap inverse() { + return new Reverse(); + } + + class Reverse implements BiMap { + @Override + public int size() { + return DirectStorageBiMap.this.size(); + } + + @Override + public boolean isEmpty() { + return DirectStorageBiMap.this.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return DirectStorageBiMap.this.containsValue(o); + } + + @Override + public boolean containsValue(Object o) { + return DirectStorageBiMap.this.containsKey(o); + } + + @Override + public K get(Object o) { + return o == null ? null : keyGetter.apply((V)o); + } + + @Override + public K put(V key, K value) { + throw new UnsupportedOperationException(); + } + + @Override + public K remove(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public K forcePut(V key, K value) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Map map) { + throw new UnsupportedOperationException(); + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @NotNull + @Override + public Set keySet() { + return DirectStorageBiMap.this.values(); + } + + @Override + public Set values() { + return DirectStorageBiMap.this.keySet(); + } + + @NotNull + @Override + public Set> entrySet() { + return DirectStorageBiMap.this.entrySet().stream() + .map(entry -> new AbstractMap.SimpleImmutableEntry<>(entry.getValue(), entry.getKey())) + .collect(Collectors.toSet()); + } + + @Override + public BiMap inverse() { + return DirectStorageBiMap.this; + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageRegistryObject.java b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageRegistryObject.java new file mode 100644 index 00000000..c18ac699 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageRegistryObject.java @@ -0,0 +1,8 @@ +package org.embeddedt.modernfix.registry; + +import net.minecraft.resources.ResourceLocation; + +public interface DirectStorageRegistryObject { + ResourceLocation mfix$getResourceKey(); + void mfix$setResourceKey(ResourceLocation key); +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java b/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java new file mode 100644 index 00000000..76285abd --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/LifecycleMap.java @@ -0,0 +1,20 @@ +package org.embeddedt.modernfix.registry; + +import com.mojang.serialization.Lifecycle; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; + +public class LifecycleMap extends Reference2ReferenceOpenHashMap { + public LifecycleMap() { + this.defaultReturnValue(Lifecycle.stable()); + } + + @Override + public Lifecycle put(T t, Lifecycle lifecycle) { + if(lifecycle != defRetValue) + return super.put(t, lifecycle); + else { + // need the duplicate containsKey/get logic here to override the default return value + return super.containsKey(t) ? super.get(t) : null; + } + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/RegistryStorage.java b/common/src/main/java/org/embeddedt/modernfix/registry/RegistryStorage.java new file mode 100644 index 00000000..252676d2 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/RegistryStorage.java @@ -0,0 +1,34 @@ +package org.embeddedt.modernfix.registry; + +import com.google.common.collect.BiMap; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; + +import java.util.Map; +import java.util.function.Function; + +public class RegistryStorage { + public static BiMap createStorage() { + return new DirectStorageBiMap<>(DirectStorageRegistryObject::mfix$getResourceKey, DirectStorageRegistryObject::mfix$setResourceKey); + } + + public static BiMap, DirectStorageRegistryObject> createKeyStorage(ResourceKey> registryKey, BiMap storage) { + if(storage instanceof DirectStorageBiMap) { + DirectStorageBiMap directStorageBiMap = (DirectStorageBiMap)storage; + // silently ignore put/putAll calls on this map + return new TransformingBiMap, DirectStorageRegistryObject>(directStorageBiMap, loc -> ResourceKey.create(registryKey, loc), ResourceKey::location, Function.identity(), Function.identity()) { + @Override + public DirectStorageRegistryObject put(ResourceKey key, DirectStorageRegistryObject value) { + return null; + } + + @Override + public void putAll(Map, ? extends DirectStorageRegistryObject> map) { + + } + }; + } else + throw new UnsupportedOperationException(); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/TransformingBiMap.java b/common/src/main/java/org/embeddedt/modernfix/registry/TransformingBiMap.java new file mode 100644 index 00000000..2fb1beb1 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/registry/TransformingBiMap.java @@ -0,0 +1,224 @@ +package org.embeddedt.modernfix.registry; + +import com.google.common.collect.BiMap; +import com.google.common.collect.Collections2; +import com.google.common.collect.Iterators; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.function.Function; + +public class TransformingBiMap implements BiMap { + private final BiMap delegate; + private final Function keyFwd; + private final Function keyBack; + private final Function valueFwd; + private final Function valueBack; + + public TransformingBiMap(BiMap map, Function keyFwd, Function keyBack, Function valueFwd, Function valueBack) { + this.delegate = map; + this.keyFwd = keyFwd; + this.keyBack = keyBack; + this.valueFwd = valueFwd; + this.valueBack = valueBack; + } + + private KFrom keyBack(KTo key) { + return key == null ? null : this.keyBack.apply(key); + } + + private KTo keyFwd(KFrom key) { + return key == null ? null : this.keyFwd.apply(key); + } + + private VFrom valueBack(VTo value) { + return value == null ? null : this.valueBack.apply(value); + } + + private VTo valueFwd(VFrom value) { + return value == null ? null : this.valueFwd.apply(value); + } + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public boolean isEmpty() { + return this.delegate.isEmpty(); + } + + @Override + public boolean containsKey(Object o) { + return this.delegate.containsKey(keyBack((KTo)o)); + } + + @Override + public boolean containsValue(Object o) { + return false; + } + + @Override + public VTo get(Object o) { + return valueFwd(this.delegate.get(keyBack((KTo)o))); + } + + @Override + public VTo put(KTo key, VTo value) { + return valueFwd(this.delegate.put(keyBack(key), valueBack(value))); + } + + @Override + public VTo remove(Object o) { + return valueFwd(this.delegate.remove(keyBack((KTo)o))); + } + + @Override + public VTo forcePut(KTo key, VTo value) { + return valueFwd(this.delegate.forcePut(keyBack(key), valueBack(value))); + } + + @Override + public void putAll(Map map) { + map.forEach((key, value) -> { + this.delegate.put(keyBack(key), valueBack(value)); + }); + } + + @Override + public void clear() { + this.delegate.clear(); + } + + @NotNull + @Override + public Set keySet() { + return new TransformingSet<>(this.delegate.keySet(), this.keyFwd, this.keyBack); + } + + @Override + public Set values() { + return new TransformingSet<>(this.delegate.values(), this.valueFwd, this.valueBack); + } + + @NotNull + @Override + public Set> entrySet() { + return new TransformingSet<>(this.delegate.entrySet(), entry -> { + return new AbstractMap.SimpleImmutableEntry<>(keyFwd(entry.getKey()), valueFwd(entry.getValue())); + }, entry -> { + return new AbstractMap.SimpleImmutableEntry<>(keyBack(entry.getKey()), valueBack(entry.getValue())); + }); + } + + @Override + public BiMap inverse() { + return new TransformingBiMap<>(this.delegate.inverse(), this.valueFwd, this.valueBack, this.keyFwd, this.keyBack); + } + + static class TransformingSet implements Set { + private final Set delegate; + private final Function forward; + private final Function reverse; + + public TransformingSet(Set set, Function forward, Function reverse) { + this.delegate = set; + this.forward = forward; + this.reverse = reverse; + } + + private TypeTo forward(TypeFrom t) { + return t == null ? null : this.forward.apply(t); + } + + private TypeFrom reverse(TypeTo t) { + return t == null ? null : this.reverse.apply(t); + } + + @Override + public int size() { + return this.delegate.size(); + } + + @Override + public boolean isEmpty() { + return this.delegate.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return this.delegate.contains(reverse((TypeTo)o)); + } + + @NotNull + @Override + public Iterator iterator() { + return Iterators.transform(this.delegate.iterator(), this::forward); + } + + @NotNull + @Override + public Object[] toArray() { + Object[] array = this.delegate.toArray(); + for(int i = 0; i < array.length; i++) { + array[i] = this.forward((TypeFrom)array[i]); + } + return array; + } + + @NotNull + @Override + public T[] toArray(@NotNull T[] ts) { + if(ts.length >= this.delegate.size()) { + Object[] setContents = toArray(); + System.arraycopy(setContents, 0, ts, 0, Math.min(setContents.length, ts.length)); + if(ts.length > setContents.length) + ts[setContents.length] = null; + return ts; + } else { + T[] realArray = Arrays.copyOf(ts, this.delegate.size()); + Iterator iterator = this.iterator(); + int i = 0; + while(iterator.hasNext()) + realArray[i++] = (T)iterator.next(); + return realArray; + } + } + + @Override + public boolean add(TypeTo typeFrom) { + return this.delegate.add(reverse(typeFrom)); + } + + @Override + public boolean remove(Object o) { + return this.delegate.remove(reverse((TypeTo)o)); + } + + @Override + public boolean containsAll(@NotNull Collection collection) { + return this.delegate.containsAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj))); + } + + @Override + public boolean addAll(@NotNull Collection collection) { + return this.delegate.addAll(Collections2.transform(collection, this::reverse)); + } + + @Override + public boolean retainAll(@NotNull Collection collection) { + return this.delegate.retainAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj))); + } + + @Override + public boolean removeAll(@NotNull Collection collection) { + return this.delegate.removeAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj))); + } + + @Override + public void clear() { + this.delegate.clear(); + } + } +} From cb6ff1d68bf33971cc4dc42218f9711cc6aa2e78 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 22:43:45 -0400 Subject: [PATCH 17/45] Add API to skip blockstate/model scanning for specific models --- .../api/dynresources/ModelScanController.java | 20 +++++++++++++++++++ .../dynamic_resources/ModelBakeryMixin.java | 8 ++++++++ 2 files changed, 28 insertions(+) create mode 100644 fabric/src/main/java/org/embeddedt/modernfix/fabric/api/dynresources/ModelScanController.java diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/api/dynresources/ModelScanController.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/api/dynresources/ModelScanController.java new file mode 100644 index 00000000..770efcf8 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/api/dynresources/ModelScanController.java @@ -0,0 +1,20 @@ +package org.embeddedt.modernfix.fabric.api.dynresources; + +import net.minecraft.resources.ResourceLocation; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +public class ModelScanController { + public static final List> SCAN_PREDICATES = new ArrayList<>(); + public static boolean shouldScanAndTestWrapping(ResourceLocation location) { + if(SCAN_PREDICATES.size() > 0) { + for(Predicate predicate : SCAN_PREDICATES) { + if(!predicate.test(location)) + return false; + } + } + return true; + } +} diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java index 30281a73..f8d9211f 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java @@ -39,6 +39,7 @@ import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration; import org.embeddedt.modernfix.duck.IExtendedModelBakery; import org.embeddedt.modernfix.dynamicresources.DynamicBakedModelProvider; import org.embeddedt.modernfix.dynamicresources.ModelBakeryHelpers; +import org.embeddedt.modernfix.fabric.api.dynresources.ModelScanController; import org.embeddedt.modernfix.fabric.bridge.ModelV0Bridge; import org.embeddedt.modernfix.util.LayeredForwardingMap; import org.jetbrains.annotations.Nullable; @@ -174,6 +175,13 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { private boolean forceLoadModel = false; + @Inject(method = "loadTopLevel", at = @At("HEAD"), cancellable = true) + private void ignoreRejectedModel(ModelResourceLocation location, CallbackInfo ci) { + if(this.inTextureGatheringPass && !this.forceLoadModel && !ModelScanController.shouldScanAndTestWrapping(location)) { + ci.cancel(); + } + } + @Inject(method = "loadModel", at = @At(value = "HEAD"), cancellable = true) private void ignoreNonFabricModel(ResourceLocation modelLocation, CallbackInfo ci) throws Exception { if(this.inTextureGatheringPass && !this.forceLoadModel && !this.injectedModels.contains(modelLocation)) { From 8b4c5d4c7a134c1a29541b5de9a22e12d5eefab1 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 22:44:06 -0400 Subject: [PATCH 18/45] C U B E --- fabric/testmod/build.gradle | 3 +++ .../embeddedt/modernfix/testmod/TestMod.java | 11 ++++++---- .../testmod/client/TestModClient.java | 2 ++ .../modernfix/testmod/mixin/ChunkMixin.java | 10 +++------ .../testmod/mixin/DebugLevelSourceMixin.java | 21 +++++++++++-------- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle index e7f14c44..7ecb1346 100644 --- a/fabric/testmod/build.gradle +++ b/fabric/testmod/build.gradle @@ -4,6 +4,7 @@ loom { accessWidenerPath = project(":common").loom.accessWidenerPath runs { client { + vmArgs "-Xmx8G" property("modernfix.config.mixin.perf.blast_search_trees", "true") property("modernfix.config.mixin.perf.dynamic_resources", "true") property("modernfix.config.mixin.perf.dynamic_block_codecs", "true") @@ -24,6 +25,8 @@ dependencies { modImplementation(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modImplementation(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modImplementation(fabricApi.module("fabric-renderer-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modRuntimeOnly(fabricApi.module("fabric-renderer-indigo", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } implementation project(path: ":common", configuration: "namedElements") diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java index 5ad72e50..3541e750 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestMod.java @@ -16,7 +16,7 @@ public class TestMod implements ModInitializer { public static final String ID = "mfix_testmod"; public static final Logger LOGGER = LogManager.getLogger("ModernFix TestMod"); - public static final int NUM_COLORS = 100; + public static final int NUM_COLORS = 256; public static final int MAX_COLOR = NUM_COLORS - 1; public static final List WOOL_STATES = new ArrayList<>(); @@ -34,7 +34,7 @@ public class TestMod implements ModInitializer { ResourceLocation name = new ResourceLocation(ID, "wool_" + r + "_" + g + "_" + b); TestBlock block = Registry.register(Registry.BLOCK, name, new TestBlock()); WOOL_STATES.add(block.defaultBlockState()); - Registry.register(Registry.ITEM, name, new TestBlockItem(block)); + //Registry.register(Registry.ITEM, name, new TestBlockItem(block)); numRegistered++; if((numRegistered % progressReport) == 0) { LOGGER.info(String.format("Registering... %.02f%%", ((float)numRegistered)/totalToRegister * 100)); @@ -49,11 +49,14 @@ public class TestMod implements ModInitializer { private static final BlockState AIR = Blocks.AIR.defaultBlockState(); public static BlockState getColorCubeStateFor(int chunkX, int chunkY, int chunkZ) { - BlockState blockState = AIR; - if (chunkX >= 0 && chunkY >= 0 && chunkZ >= 0 && chunkX % 2 == 0 && chunkY % 2 == 0 && chunkZ % 2 == 0) { + BlockState blockState = null; + if (chunkX >= 0 && chunkY >= 0 && chunkZ >= 0) { // && chunkX % 2 == 0 && chunkY % 2 == 0 && chunkZ % 2 == 0) { + /* chunkX /= 2; chunkY /= 2; chunkZ /= 2; + + */ if(chunkX <= TestMod.MAX_COLOR && chunkY <= TestMod.MAX_COLOR && chunkZ <= TestMod.MAX_COLOR) { blockState = TestMod.WOOL_STATES.get((chunkX * TestMod.NUM_COLORS * TestMod.NUM_COLORS) + (chunkY * TestMod.NUM_COLORS) + chunkZ); } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java index 3bf0c36a..7f82a508 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/client/TestModClient.java @@ -2,6 +2,7 @@ package org.embeddedt.modernfix.testmod.client; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; +import org.embeddedt.modernfix.fabric.api.dynresources.ModelScanController; import org.embeddedt.modernfix.testmod.TestMod; import java.util.regex.Matcher; @@ -11,6 +12,7 @@ public class TestModClient implements ClientModInitializer { private static final Pattern RGB_PATTERN = Pattern.compile("^wool_([0-9]+)_([0-9]+)_([0-9]+)$"); @Override public void onInitializeClient() { + ModelScanController.SCAN_PREDICATES.add(rl -> !rl.getNamespace().equals(TestMod.ID)); ModelLoadingRegistry.INSTANCE.registerVariantProvider(resourceManager -> (modelId, context) -> { if(modelId.getNamespace().equals(TestMod.ID)) { Matcher matcher = RGB_PATTERN.matcher(modelId.getPath()); diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java index 1356aece..142faf51 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/ChunkMixin.java @@ -1,25 +1,21 @@ package org.embeddedt.modernfix.testmod.mixin; import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; import org.embeddedt.modernfix.testmod.TestMod; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LevelChunk.class) public class ChunkMixin { - @Shadow @Final private Level level; - @Inject(method = "getBlockState", at = @At("HEAD"), cancellable = true) private void redirectDebugWorld(BlockPos pos, CallbackInfoReturnable cir) { - if(this.level.isDebug()) { - cir.setReturnValue(TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ())); + BlockState overrideState = TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ()); + if(overrideState != null) { + cir.setReturnValue(overrideState); } } } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java index 40d3eba9..99860393 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/DebugLevelSourceMixin.java @@ -3,19 +3,22 @@ package org.embeddedt.modernfix.testmod.mixin; import net.minecraft.core.BlockPos; import net.minecraft.server.level.WorldGenRegion; import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.DebugLevelSource; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.StructureSettings; import org.embeddedt.modernfix.testmod.TestMod; 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(DebugLevelSource.class) -public class DebugLevelSourceMixin { - @Inject(method = "applyBiomeDecoration", at = @At("HEAD"), cancellable = true) - private void showColorCube(WorldGenRegion region, StructureFeatureManager structureManager, CallbackInfo ci) { - ci.cancel(); +@Mixin(FlatLevelSource.class) +public abstract class DebugLevelSourceMixin extends ChunkGenerator { + public DebugLevelSourceMixin(BiomeSource biomeSource, StructureSettings structureSettings) { + super(biomeSource, structureSettings); + } + + @Override + public void applyBiomeDecoration(WorldGenRegion region, StructureFeatureManager structureManager) { BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); int i = region.getCenterX(); int j = region.getCenterZ(); From 4d3aaceb9c010086f9a588b7f615b44c65fd9a78 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:18:07 -0400 Subject: [PATCH 19/45] Fix crash if FerriteCore detection fails in neighbour table mixin --- .../mixin/perf/mojang_registry_size/StateHolderMixin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java index 9c81fd6e..9e67dd7b 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/StateHolderMixin.java @@ -1,5 +1,7 @@ package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size; +import com.google.common.collect.ArrayTable; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableTable; import com.google.common.collect.Table; import net.minecraft.world.level.block.state.StateHolder; @@ -23,7 +25,7 @@ public class StateHolderMixin { /* optimize the case where block has no properties */ @Inject(method = "populateNeighbours", at = @At("RETURN"), require = 0) private void replaceEmptyTable(CallbackInfo ci) { - if(this.neighbours.isEmpty()) + if((this.neighbours instanceof ArrayTable || this.neighbours instanceof HashBasedTable) && this.neighbours.isEmpty()) this.neighbours = ImmutableTable.of(); } } From 0c822232485ef045c9150d65c53c61fe100293d9 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:44:51 -0400 Subject: [PATCH 20/45] Fix Custom Machinery models --- .../DynamicBakedModelProvider.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java index b0b5b460..456ceea7 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicBakedModelProvider.java @@ -1,5 +1,6 @@ package org.embeddedt.modernfix.dynamicresources; +import com.google.common.collect.ImmutableSet; import com.mojang.math.Transformation; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.renderer.block.model.BakedQuad; @@ -25,6 +26,15 @@ import java.util.function.BiFunction; import java.util.stream.Collectors; public class DynamicBakedModelProvider implements Map { + /** + * The list of blacklisted resource locations that are never baked as top-level models. + * + * This is a hack to get around the fact that we don't really know exactly what models were supposed to end up + * in the baked registry ahead of time. + */ + private static final ImmutableSet BAKE_SKIPPED_TOPLEVEL = ImmutableSet.builder() + .add(new ResourceLocation("custommachinery", "block/custom_machine_block")) + .build(); public static DynamicBakedModelProvider currentInstance = null; private final ModelBakery bakery; private final Map, BakedModel> bakedCache; @@ -135,7 +145,10 @@ public class DynamicBakedModelProvider implements Map Date: Fri, 11 Aug 2023 16:47:38 -0400 Subject: [PATCH 21/45] Add hacky solution for "runtime" remapping in dev --- forge/build.gradle | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/forge/build.gradle b/forge/build.gradle index f7005e78..3769452b 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -27,6 +27,22 @@ configurations { runtimeClasspath.extendsFrom common } +def extraModsDir = "extra-mods" + +repositories { + exclusiveContent { + forRepository { + flatDir { + name "extra-mods" + dir file(extraModsDir) + } + } + filter { + includeGroup "extra-mods" + } + } +} + dependencies { forge "net.minecraftforge:forge:${rootProject.forge_version}" // Remove the next line if you don't want to depend on the API @@ -51,6 +67,16 @@ dependencies { modCompileOnly("vazkii.patchouli:Patchouli:1.16.4-53.3") modImplementation "curse.maven:spark-361579:${rootProject.spark_forge_version}" + // runtime remapping at home + for (extraModJar in fileTree(dir: extraModsDir, include: '*.jar')) { + def basename = extraModJar.name.substring(0, extraModJar.name.length() - ".jar".length()) + def versionSep = basename.lastIndexOf('-') + assert versionSep != -1 + def artifactId = basename.substring(0, versionSep) + def version = basename.substring(versionSep + 1) + modRuntimeOnly("extra-mods:$artifactId:$version") + } + common(project(path: ":common", configuration: "namedElements")) { transitive false } shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } } From 721645f88f577bf2106b330cb107fb9bb7d618cd Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 16:53:21 -0400 Subject: [PATCH 22/45] Add IgnoreOutsideDev marker to forgotten mixin --- .../mixin/perf/compact_mojang_registries/DirectObjectMixin.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java index 45d8d621..02d346d2 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/compact_mojang_registries/DirectObjectMixin.java @@ -3,10 +3,12 @@ package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; +import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; import org.embeddedt.modernfix.registry.DirectStorageRegistryObject; import org.spongepowered.asm.mixin.Mixin; @Mixin({ Block.class, Item.class }) +@IgnoreOutsideDev public class DirectObjectMixin implements DirectStorageRegistryObject { private ResourceLocation mfix$resourceKey; From a51b1563b1f67c0d6bbe620b35f6f15b42b0cd2a Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 19:31:12 -0400 Subject: [PATCH 23/45] Try to make config reload message appear less often Related: #210 --- .../org/embeddedt/modernfix/ModernFixClient.java | 2 +- .../modernfix/forge/config/NightConfigFixer.java | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 11cd9764..29c18315 100644 --- a/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -27,7 +27,7 @@ public class ModernFixClient { public static float gameStartTimeSeconds = -1; - private static boolean recipesUpdated, tagsUpdated = false; + public static boolean recipesUpdated, tagsUpdated = false; public String brandingString = null; diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java index 8ae460a7..8155f186 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java @@ -7,6 +7,7 @@ import net.minecraft.network.chat.TranslatableComponent; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.loading.FMLLoader; import org.embeddedt.modernfix.ModernFix; +import org.embeddedt.modernfix.ModernFixClient; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.util.CommonModUtil; @@ -16,11 +17,11 @@ import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; import java.util.function.Function; public class NightConfigFixer { public static final LinkedHashSet configsToReload = new LinkedHashSet<>(); + public static void monitorFileWatcher() { if(!ModernFixMixinPlugin.instance.isOptionEnabled("bugfix.fix_config_crashes.NightConfigFixerMixin")) return; @@ -49,6 +50,7 @@ public class NightConfigFixer { } } ModernFix.LOGGER.info("Processed {} config reloads", runnablesToRun.size()); + couldShowMessage = true; } static class MonitoringMap extends ConcurrentHashMap { @@ -74,13 +76,13 @@ public class NightConfigFixer { } } - private static long lastConfigTrigger = System.nanoTime(); + private static boolean couldShowMessage = true; private static void triggerConfigMessage() { - if((System.nanoTime() - lastConfigTrigger) >= TimeUnit.SECONDS.toNanos(5)) { - lastConfigTrigger = System.nanoTime(); + if(couldShowMessage && Minecraft.getInstance().level != null && ModernFixClient.recipesUpdated && ModernFixClient.tagsUpdated) { Minecraft.getInstance().execute(() -> { if(Minecraft.getInstance().level != null) { + couldShowMessage = false; Minecraft.getInstance().gui.getChat().addMessage(new TranslatableComponent("modernfix.message.reload_config")); } }); @@ -102,8 +104,9 @@ public class NightConfigFixer { synchronized(configsToReload) { if(FMLLoader.getDist().isClient()) triggerConfigMessage(); - if(configsToReload.size() == 0) + if(configsToReload.size() == 0) { ModernFixMixinPlugin.instance.logger.info("Please use /{} to reload any changed mod config files", FMLLoader.getDist().isDedicatedServer() ? "mfsrc" : "mfrc"); + } configsToReload.add(configTracker); } } From ca8d290870b1c4724b21f1e9bf460a90296da694 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 19:45:19 -0400 Subject: [PATCH 24/45] Message wording change --- common/src/main/resources/assets/modernfix/lang/en_us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json index 5f32b072..bf6eb29f 100644 --- a/common/src/main/resources/assets/modernfix/lang/en_us.json +++ b/common/src/main/resources/assets/modernfix/lang/en_us.json @@ -7,7 +7,7 @@ "modernfix.perf_mod_warning": "It is recommended to install the mods, but the warning(s) can be disabled in the ModernFix config.", "modernfix.config": "ModernFix mixin config", "modernfix.config.done_restart": "Done (restart required)", - "modernfix.message.reload_config": "Run /mfrc after changing configs on disk for them to take effect.", + "modernfix.message.reload_config": "A mod config file change was detected. To prevent loading files that aren't done saving, reloading must be triggered by running /mfrc.", "modernfix.option.on": "on", "modernfix.option.off": "off", "modernfix.option.disabled": "disabled", From 05e74f4141a4c270930c30a39ae8eda7d3c69243 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 11:18:41 -0400 Subject: [PATCH 25/45] Add warning when launched with Continuity and dynamic resources is on --- .../modernfix/ModernFixPreLaunchFabric.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fabric/src/main/java/org/embeddedt/modernfix/ModernFixPreLaunchFabric.java b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixPreLaunchFabric.java index 068cad51..dd803867 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/ModernFixPreLaunchFabric.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/ModernFixPreLaunchFabric.java @@ -1,6 +1,9 @@ package org.embeddedt.modernfix; +import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint; +import net.fabricmc.loader.impl.gui.FabricGuiEntry; +import net.fabricmc.loader.impl.gui.FabricStatusTree; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.fabric.mappings.MappingsClearer; import org.embeddedt.modernfix.fabric.spark.SparkLaunchProfiler; @@ -19,5 +22,18 @@ public class ModernFixPreLaunchFabric implements PreLaunchEntrypoint { if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.clear_fabric_mapping_tables.MappingsClearer")) { MappingsClearer.clear(); } + + // Prevent launching with Continuity when dynamic resources is on + if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dynamic_resources.ContinuityCheck") + && FabricLoader.getInstance().isModLoaded("continuity")) { + CommonModUtil.runWithoutCrash(() -> { + FabricGuiEntry.displayError("Compatibility warning", null, tree -> { + FabricStatusTree.FabricStatusTab crashTab = tree.addTab("Warning"); + crashTab.node.addMessage("Continuity and ModernFix's dynamic resources option are not compatible before Minecraft 1.19.4.", FabricStatusTree.FabricTreeWarningLevel.ERROR); + crashTab.node.addMessage("Remove Continuity or disable dynamic resources in the ModernFix config.", FabricStatusTree.FabricTreeWarningLevel.ERROR); + tree.tabs.removeIf(tab -> tab != crashTab); + }, true); + }, "display Continuity warning"); + } } } From 21ee0dc1cfd53b9f2dc9ff82906e1fadaa95b09b Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 11:28:07 -0400 Subject: [PATCH 26/45] Add warning for Connectedness and dynamic resources --- .../main/resources/assets/modernfix/lang/en_us.json | 1 + .../modernfix/forge/init/ModernFixClientForge.java | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/common/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json index bf6eb29f..eafb38d0 100644 --- a/common/src/main/resources/assets/modernfix/lang/en_us.json +++ b/common/src/main/resources/assets/modernfix/lang/en_us.json @@ -4,6 +4,7 @@ "modernfix.jei_load": "Loading JEI, this may take a while", "modernfix.no_lazydfu": "LazyDFU is not installed. If Minecraft needs to update game data from an older version, there may be noticeable lag.", "modernfix.no_ferritecore": "FerriteCore is not installed. Memory usage will be very high.", + "modernfix.connectedness_dynresources": "Connectedness and ModernFix's dynamic resources option are not compatible. Remove Connectedness or disable dynamic resources in the ModernFix config.", "modernfix.perf_mod_warning": "It is recommended to install the mods, but the warning(s) can be disabled in the ModernFix config.", "modernfix.config": "ModernFix mixin config", "modernfix.config.done_restart": "Done (restart required)", diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixClientForge.java b/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixClientForge.java index 60ac7521..0b3ce1b9 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixClientForge.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/init/ModernFixClientForge.java @@ -14,14 +14,14 @@ import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.ExtensionPoint; -import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.*; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.server.FMLServerStartedEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.embeddedt.modernfix.ModernFixClient; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.forge.config.NightConfigFixer; import org.embeddedt.modernfix.screen.ModernFixConfigScreen; @@ -45,7 +45,12 @@ public class ModernFixClientForge { private void clientSetup(FMLClientSetupEvent event) { configKey = new KeyMapping("key.modernfix.config", KeyConflictContext.UNIVERSAL, InputConstants.UNKNOWN, "key.modernfix"); ClientRegistry.registerKeyBinding(configKey); - + if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dynamic_resources.ConnectednessCheck") + && ModList.get().isLoaded("connectedness")) { + event.enqueueWork(() -> { + ModLoader.get().addWarning(new ModLoadingWarning(ModLoadingContext.get().getActiveContainer().getModInfo(), ModLoadingStage.SIDED_SETUP, "modernfix.connectedness_dynresoruces")); + }); + } } @SubscribeEvent From b5b46888af96bbd0569ac75633f997d9878e77e5 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 11:32:00 -0400 Subject: [PATCH 27/45] Change resource key name Easier to add typo here than fix typo in the other file and deal with merge conflicts --- common/src/main/resources/assets/modernfix/lang/en_us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json index eafb38d0..3afbc788 100644 --- a/common/src/main/resources/assets/modernfix/lang/en_us.json +++ b/common/src/main/resources/assets/modernfix/lang/en_us.json @@ -4,7 +4,7 @@ "modernfix.jei_load": "Loading JEI, this may take a while", "modernfix.no_lazydfu": "LazyDFU is not installed. If Minecraft needs to update game data from an older version, there may be noticeable lag.", "modernfix.no_ferritecore": "FerriteCore is not installed. Memory usage will be very high.", - "modernfix.connectedness_dynresources": "Connectedness and ModernFix's dynamic resources option are not compatible. Remove Connectedness or disable dynamic resources in the ModernFix config.", + "modernfix.connectedness_dynresoruces": "Connectedness and ModernFix's dynamic resources option are not compatible. Remove Connectedness or disable dynamic resources in the ModernFix config.", "modernfix.perf_mod_warning": "It is recommended to install the mods, but the warning(s) can be disabled in the ModernFix config.", "modernfix.config": "ModernFix mixin config", "modernfix.config.done_restart": "Done (restart required)", From d1c9be89000a552d15ab1bf1851a1047b64259d6 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 11:41:04 -0400 Subject: [PATCH 28/45] Clean up warnings --- build.gradle | 5 +++++ .../mixin/perf/dynamic_block_codecs/StateHolderMixin.java | 2 +- .../BlockElementFaceDeserializerMixin.java | 2 +- .../mixin/perf/dynamic_resources/ItemModelShaperMixin.java | 3 +++ .../perf/mojang_registry_size/MappedRegistryMixin.java | 2 +- .../embeddedt/modernfix/registry/DirectStorageBiMap.java | 1 + .../faster_command_suggestions/SuggestionsBuilderMixin.java | 2 +- .../mixin/perf/resourcepacks/ModNioResourcePackMixin.java | 4 ++-- .../bugfix/ctm_resourceutil_cme/ResourceUtilMixin.java | 2 +- .../mixin/bugfix/preserve_early_window_pos/WindowMixin.java | 2 +- .../bugfix/starlight_emptiness/StarLightEngineMixin.java | 4 ++-- .../perf/dynamic_resources/ItemModelMesherForgeMixin.java | 5 ++++- .../dynamic_resources/ctm/CTMPackReloadListenerMixin.java | 6 +++++- .../mixin/perf/dynamic_resources/rs/ClientSetupMixin.java | 2 +- .../supermartijncore/ClientRegistrationHandlerMixin.java | 2 +- .../perf/rewrite_registry/ForgeRegistrySnapshotMixin.java | 4 ++-- 16 files changed, 32 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 0df67a03..904b8102 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,11 @@ allprojects { url 'https://maven.terraformersmc.com/releases' } } + gradle.projectsEvaluated { + tasks.withType(JavaCompile) { + options.compilerArgs << "-Werror" + } + } } configure(subprojects.findAll {it.name == "common" || it.name == "forge" || it.name == "fabric"}) { diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java index 7455fcbb..540c7495 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java @@ -36,7 +36,7 @@ public class StateHolderMixin { } }); - @Redirect(method = "codec", at = @At(value = "INVOKE", target = "Lcom/mojang/serialization/Codec;dispatch(Ljava/lang/String;Ljava/util/function/Function;Ljava/util/function/Function;)Lcom/mojang/serialization/Codec;")) + @Redirect(method = "codec", at = @At(value = "INVOKE", target = "Lcom/mojang/serialization/Codec;dispatch(Ljava/lang/String;Ljava/util/function/Function;Ljava/util/function/Function;)Lcom/mojang/serialization/Codec;", remap = false)) private static > Codec obtainCodec(Codec codec, String typeKey, Function type, Function> codecFn, Codec codecMethodArg, Function stateSupplier) { return codec.dispatch(typeKey, type, block -> { if(block instanceof Block) { diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java index 2cd4a853..17404372 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/BlockElementFaceDeserializerMixin.java @@ -16,7 +16,7 @@ import java.lang.reflect.Type; 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;", - at = @At(value = "INVOKE", target = "Lcom/google/gson/JsonDeserializationContext;deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;)Ljava/lang/Object;", ordinal = 0)) + at = @At(value = "INVOKE", target = "Lcom/google/gson/JsonDeserializationContext;deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;)Ljava/lang/Object;", ordinal = 0, remap = false)) private Object skipUvsForInitialLoad(JsonDeserializationContext context, JsonElement element, Type type) { return UVController.useDummyUv.get() ? UVController.dummyUv : context.deserialize(element, type); } diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java index 66a183f0..bd4609cf 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources/ItemModelShaperMixin.java @@ -48,6 +48,7 @@ public abstract class ItemModelShaperMixin { } /** + * @author embeddedt * @reason Get the stored location for that item and meta, and get the model * from that location from the model manager. **/ @@ -58,6 +59,7 @@ public abstract class ItemModelShaperMixin { } /** + * @author embeddedt * @reason Don't get all models during init (with dynamic loading, that would * generate them all). Just store location instead. **/ @@ -67,6 +69,7 @@ public abstract class ItemModelShaperMixin { } /** + * @author embeddedt * @reason Disable cache rebuilding (with dynamic loading, that would generate * all models). **/ diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/MappedRegistryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/MappedRegistryMixin.java index ad9adc3c..2b9cf966 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/MappedRegistryMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/mojang_registry_size/MappedRegistryMixin.java @@ -15,7 +15,7 @@ public class MappedRegistryMixin { */ @Redirect( method = "registerMapping(ILnet/minecraft/resources/ResourceKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Ljava/lang/Object;", - at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectList;size(I)V") + at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectList;size(I)V", remap = false) ) private void setSizeSmart(ObjectList list, int size) { if(list instanceof ObjectArrayList && size > list.size()) { diff --git a/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java index 68717081..9aa1442a 100644 --- a/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/registry/DirectStorageBiMap.java @@ -9,6 +9,7 @@ import java.util.function.BiConsumer; import java.util.function.Function; import java.util.stream.Collectors; +@SuppressWarnings("unchecked") public class DirectStorageBiMap implements BiMap { private final Function keyGetter; private final BiConsumer keySetter; diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java index e27b0480..435508d2 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/faster_command_suggestions/SuggestionsBuilderMixin.java @@ -17,7 +17,7 @@ public class SuggestionsBuilderMixin { @Unique private static final int MAX_SUGGESTIONS = 10000; - @Shadow @Final @Mutable + @Shadow(remap = false) @Final @Mutable private List result; @Redirect(method = "*", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"), require = 0) diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/resourcepacks/ModNioResourcePackMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/resourcepacks/ModNioResourcePackMixin.java index 89d0681e..40358925 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/resourcepacks/ModNioResourcePackMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/resourcepacks/ModNioResourcePackMixin.java @@ -23,10 +23,10 @@ import java.util.Set; public abstract class ModNioResourcePackMixin implements ICachingResourcePack { @Shadow public abstract Set getNamespaces(PackType type); - @Shadow @Final private Path basePath; + @Shadow(remap = false) @Final private Path basePath; private PackResourcesCacheEngine cacheEngine; - @Inject(method = "", at = @At("RETURN")) + @Inject(method = "", at = @At("RETURN"), remap = false) private void cacheResources(CallbackInfo ci) { invalidateCache(); PackResourcesCacheEngine.track(this); diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/ctm_resourceutil_cme/ResourceUtilMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/ctm_resourceutil_cme/ResourceUtilMixin.java index 7e5e41b2..26844d70 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/ctm_resourceutil_cme/ResourceUtilMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/ctm_resourceutil_cme/ResourceUtilMixin.java @@ -20,7 +20,7 @@ import java.util.concurrent.ConcurrentMap; @ClientOnlyMixin @SuppressWarnings({"rawtypes", "unchecked"}) public class ResourceUtilMixin { - @Shadow @Final @Mutable + @Shadow(remap = false) @Final @Mutable private static Map metadataCache; /** diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/preserve_early_window_pos/WindowMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/preserve_early_window_pos/WindowMixin.java index 85702c55..837e3358 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/preserve_early_window_pos/WindowMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/preserve_early_window_pos/WindowMixin.java @@ -60,7 +60,7 @@ public class WindowMixin { * Grab the original width/height from the window and inject them into our state variables. */ @SuppressWarnings("unchecked") - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/loading/progress/EarlyProgressVisualization;handOffWindow(Ljava/util/function/IntSupplier;Ljava/util/function/IntSupplier;Ljava/util/function/Supplier;Ljava/util/function/LongSupplier;)J"), require = 0) + @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/loading/progress/EarlyProgressVisualization;handOffWindow(Ljava/util/function/IntSupplier;Ljava/util/function/IntSupplier;Ljava/util/function/Supplier;Ljava/util/function/LongSupplier;)J", remap = false), require = 0) private long performHandoff(EarlyProgressVisualization instance, IntSupplier width, IntSupplier height, Supplier title, LongSupplier monitor, WindowEventHandler arg, ScreenManager arg2, DisplayData arg3) { Object visualizer = getEarlyProgressVisualizer(); if(visualizer != null && defaultDisplayData(arg3)) { diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java index e50f321d..4973adf9 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/starlight_emptiness/StarLightEngineMixin.java @@ -17,11 +17,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; public abstract class StarLightEngineMixin { @Shadow protected abstract LevelChunkSection getChunkSection(int chunkX, int chunkY, int chunkZ); - @Shadow @Final protected int minSection; + @Shadow(remap = false) @Final protected int minSection; @Inject(method = "handleEmptySectionChanges(Lnet/minecraft/world/level/chunk/LightChunkGetter;Lnet/minecraft/world/level/chunk/ChunkAccess;[Ljava/lang/Boolean;Z)[Z", at = @At(value = "INVOKE", target = "Lca/spottedleaf/starlight/common/light/StarLightEngine;setEmptinessMapCache(II[Z)V", - shift = At.Shift.AFTER)) + shift = At.Shift.AFTER, remap = false)) private void lazyInitMapIfNeeded(LightChunkGetter lightAccess, ChunkAccess chunk, Boolean[] emptinessChanges, boolean unlit, CallbackInfoReturnable cir) { final int chunkX = chunk.getPos().x; final int chunkZ = chunk.getPos().z; diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java index 9fab54c9..d5792df3 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ItemModelMesherForgeMixin.java @@ -20,7 +20,7 @@ import java.util.Map; @Mixin(net.minecraftforge.client.ItemModelMesherForge.class) @ClientOnlyMixin public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { - @Shadow @Final @Mutable private Map, ModelResourceLocation> locations; + @Shadow(remap = false) @Final @Mutable private Map, ModelResourceLocation> locations; private Map, ModelResourceLocation> overrideLocations; @@ -48,6 +48,7 @@ public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { } /** + * @author embeddedt * @reason Get the stored location for that item and meta, and get the model * from that location from the model manager. **/ @@ -59,6 +60,7 @@ public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { } /** + * @author embeddedt * @reason Don't get all models during init (with dynamic loading, that would * generate them all). Just store location instead. **/ @@ -69,6 +71,7 @@ public abstract class ItemModelMesherForgeMixin extends ItemModelShaper { } /** + * @author embeddedt * @reason Disable cache rebuilding (with dynamic loading, that would generate * all models). **/ diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java index 4c8cc031..095c122b 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ctm/CTMPackReloadListenerMixin.java @@ -35,7 +35,7 @@ import java.util.function.Predicate; @ClientOnlyMixin public abstract class CTMPackReloadListenerMixin implements ModernFixClientIntegration { /* caches the original render checks */ - @Shadow @Final private static Map, Predicate> blockRenderChecks; + @Shadow(remap = false) @Final private static Map, Predicate> blockRenderChecks; private static Map, Predicate> renderCheckOverrides = new ConcurrentHashMap<>(); @@ -50,6 +50,10 @@ public abstract class CTMPackReloadListenerMixin implements ModernFixClientInteg ModernFixClient.CLIENT_INTEGRATIONS.add(this); } + /** + * @author embeddedt + * @reason handle layer changes dynamically + */ @Overwrite(remap = false) private void refreshLayerHacks() { renderCheckOverrides.clear(); diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java index 26cf83b0..0ee9ff6d 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/rs/ClientSetupMixin.java @@ -20,7 +20,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @RequiresMod("refinedstorage") @ClientOnlyMixin public class ClientSetupMixin { - @Shadow @Final private BakedModelOverrideRegistry bakedModelOverrideRegistry; + @Shadow(remap = false) @Final private BakedModelOverrideRegistry bakedModelOverrideRegistry; @Inject(method = "", at = @At("RETURN")) private void addDynamicListener(CallbackInfo ci) { diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java index e4cc3781..12e235a9 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/supermartijncore/ClientRegistrationHandlerMixin.java @@ -31,7 +31,7 @@ import java.util.stream.Stream; @RequiresMod("supermartijn642corelib") @ClientOnlyMixin public class ClientRegistrationHandlerMixin { - @Shadow @Final private List>, Function>> modelOverwrites; + @Shadow(remap = false) @Final private List>, Function>> modelOverwrites; private Map> modelOverwritesByLocation = new Object2ObjectOpenHashMap<>(); diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java index a538a112..b8dbf343 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/rewrite_registry/ForgeRegistrySnapshotMixin.java @@ -19,9 +19,9 @@ import java.util.Set; @Mixin(ForgeRegistry.Snapshot.class) @IgnoreOutsideDev public class ForgeRegistrySnapshotMixin { - @Shadow @Final @Mutable public Map ids; + @Shadow(remap = false) @Final @Mutable public Map ids; - @Shadow @Final @Mutable public Set dummied; + @Shadow(remap = false) @Final @Mutable public Set dummied; /** * The only good reason to use tree maps here is to keep the order the same. But we are tracking IDs From b87c615e5da9626fe77ec3aaeb533f0664e65a01 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 11:51:28 -0400 Subject: [PATCH 29/45] Adjust mixin config --- common/src/main/resources/modernfix-common.mixins.json | 3 +++ fabric/src/main/resources/modernfix-fabric.mixins.json | 3 +++ forge/src/main/resources/modernfix-forge.mixins.json | 3 +++ 3 files changed, 9 insertions(+) diff --git a/common/src/main/resources/modernfix-common.mixins.json b/common/src/main/resources/modernfix-common.mixins.json index 352229f9..94a4e091 100644 --- a/common/src/main/resources/modernfix-common.mixins.json +++ b/common/src/main/resources/modernfix-common.mixins.json @@ -9,5 +9,8 @@ ${mixin_classes} ], "injectors": { "defaultRequire": 1 + }, + "overwrites": { + "conformVisibility": true } } diff --git a/fabric/src/main/resources/modernfix-fabric.mixins.json b/fabric/src/main/resources/modernfix-fabric.mixins.json index c6246634..3d94ea0d 100644 --- a/fabric/src/main/resources/modernfix-fabric.mixins.json +++ b/fabric/src/main/resources/modernfix-fabric.mixins.json @@ -9,5 +9,8 @@ ${mixin_classes} ], "injectors": { "defaultRequire": 1 + }, + "overwrites": { + "conformVisibility": true } } \ No newline at end of file diff --git a/forge/src/main/resources/modernfix-forge.mixins.json b/forge/src/main/resources/modernfix-forge.mixins.json index cd76ed5b..f63f1dfc 100644 --- a/forge/src/main/resources/modernfix-forge.mixins.json +++ b/forge/src/main/resources/modernfix-forge.mixins.json @@ -9,5 +9,8 @@ ${mixin_classes} ], "injectors": { "defaultRequire": 1 + }, + "overwrites": { + "conformVisibility": true } } \ No newline at end of file From 1ad6ec4bd1af7647d5de3c9c1a2748662da79d7a Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 12:09:52 -0400 Subject: [PATCH 30/45] Remove Werror now that almost all warnings are addressed --- build.gradle | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build.gradle b/build.gradle index 904b8102..0df67a03 100644 --- a/build.gradle +++ b/build.gradle @@ -95,11 +95,6 @@ allprojects { url 'https://maven.terraformersmc.com/releases' } } - gradle.projectsEvaluated { - tasks.withType(JavaCompile) { - options.compilerArgs << "-Werror" - } - } } configure(subprojects.findAll {it.name == "common" || it.name == "forge" || it.name == "fabric"}) { From fa47e923f0f5bbbcaba0ecb5b4e4036e9da451ae Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 21:19:43 -0400 Subject: [PATCH 31/45] Better compatibility with mods that inject into initCache --- build.gradle | 1 + .../BlockStateBaseMixin.java | 27 +---- .../modernfix/core/ModernFixMixinPlugin.java | 109 ++++++++++++++++++ 3 files changed, 113 insertions(+), 24 deletions(-) diff --git a/build.gradle b/build.gradle index 0df67a03..5d1c67c9 100644 --- a/build.gradle +++ b/build.gradle @@ -206,6 +206,7 @@ configure(subprojects.findAll {it.name == "forge" || it.name == "fabric"}) { client { vmArgs "-Xmx1G" vmArgs "-Xms1G" + property("mixin.debug.export", "true") } } } diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java index db024b63..3974cdef 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/reduce_blockstate_cache_rebuilds/BlockStateBaseMixin.java @@ -3,13 +3,10 @@ package org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuil import net.minecraft.world.level.block.state.BlockBehaviour; import org.embeddedt.modernfix.duck.IBlockState; import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Dynamic; 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.CallbackInfoReturnable; @Mixin(BlockBehaviour.BlockStateBase.class) @@ -30,7 +27,7 @@ public abstract class BlockStateBaseMixin implements IBlockState { return cacheInvalid; } - private BlockBehaviour.BlockStateBase.Cache generateCache(BlockBehaviour.BlockStateBase base) { + private void mfix$generateCache() { if(cacheInvalid) { // Ensure that only one block's cache is built at a time synchronized (BlockBehaviour.BlockStateBase.class) { @@ -49,7 +46,6 @@ public abstract class BlockStateBaseMixin implements IBlockState { } } - return this.cache; } @Redirect(method = "*", at = @At( @@ -59,24 +55,7 @@ public abstract class BlockStateBaseMixin implements IBlockState { ordinal = 0 )) private BlockBehaviour.BlockStateBase.Cache dynamicCacheGen(BlockBehaviour.BlockStateBase base) { - return generateCache(base); - } - - @Dynamic - @Inject(method = "getPathNodeType", at = @At("HEAD"), require = 0, remap = false) - private void generateCacheLithium(CallbackInfoReturnable cir) { - generateCache((BlockBehaviour.BlockStateBase)(Object)this); - } - - @Dynamic - @Inject(method = "getNeighborPathNodeType", at = @At("HEAD"), require = 0, remap = false) - private void generateCacheLithium2(CallbackInfoReturnable cir) { - generateCache((BlockBehaviour.BlockStateBase)(Object)this); - } - - @Dynamic - @Inject(method = "getAllFlags", at = @At("HEAD"), require = 0, remap = false) - private void generateCacheLithium3(CallbackInfoReturnable cir) { - generateCache((BlockBehaviour.BlockStateBase)(Object)this); + mfix$generateCache(); + return this.cache; } } diff --git a/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java index 6c902036..c61492a3 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -1,14 +1,18 @@ package org.embeddedt.modernfix.core; +import com.google.common.collect.ImmutableSet; 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.embeddedt.modernfix.world.ThreadDumper; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import org.objectweb.asm.tree.*; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; +import org.spongepowered.asm.mixin.transformer.meta.MixinMerged; import java.io.File; import java.util.*; @@ -146,6 +150,111 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { @Override public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { + if(mixinClassName.equals("org.embeddedt.modernfix.common.mixin.perf.reduce_blockstate_cache_rebuilds.BlockStateBaseMixin")) { + try { + applyBlockStateCacheScan(targetClass); + } catch(RuntimeException e) { + ModernFixMixinPlugin.instance.logger.error("Applying blockstate cache ASM patch failed", e); + } + } ModernFixPlatformHooks.INSTANCE.applyASMTransformers(mixinClassName, targetClass); } + + private void applyBlockStateCacheScan(ClassNode targetClass) { + Set initCacheMethodNames = ImmutableSet.of("m_60611_", "func_215692_c", "method_26200", "initCache"); + Set whitelistedInjections = ImmutableSet.of( + "getFluidState", "method_26227", "m_60819_", "func_204520_s" + ); + Map injectorMethodNames = new HashMap<>(); + Map injectorMixinSource = new HashMap<>(); + String descriptor = Type.getDescriptor(MixinMerged.class); + for(MethodNode m : targetClass.methods) { + if((m.access & Opcodes.ACC_STATIC) != 0) + continue; + Set seenNodes = new HashSet<>(); + if(m.invisibleAnnotations != null) { + for(AnnotationNode ann : m.invisibleAnnotations) { + if(ann.desc.equals(descriptor)) { + seenNodes.add(ann); + } + } + } + if(m.visibleAnnotations != null) { + for(AnnotationNode ann : m.visibleAnnotations) { + if(ann.desc.equals(descriptor)) { + seenNodes.add(ann); + } + } + } + if(seenNodes.size() > 0) { + injectorMethodNames.put(m.name, m); + for(AnnotationNode node : seenNodes) { + for(int i = 0; i < node.values.size(); i += 2) { + if(Objects.equals(node.values.get(i), "mixin")) { + injectorMixinSource.put(m.name, (String)node.values.get(i + 1)); + break; + } + } + } + } + } + Set cacheCalledInjectors = new HashSet<>(); + // Search for initCache in the class + for(MethodNode m : targetClass.methods) { + if((m.access & Opcodes.ACC_STATIC) != 0) + continue; + if(initCacheMethodNames.contains(m.name)) { + // This is it. Check for any injectors it calls + for(AbstractInsnNode n : m.instructions) { + if(n instanceof MethodInsnNode) { + MethodInsnNode invoke = (MethodInsnNode)n; + if(((MethodInsnNode)n).owner.equals(targetClass.name) && injectorMethodNames.containsKey(((MethodInsnNode)n).name)) { + cacheCalledInjectors.add(invoke.name); + } + } + } + break; + } + } + Set accessedFieldNames = new HashSet<>(); + // We now know all methods that have been injected into initCache. See what fields they write to + injectorMethodNames.forEach((name, method) -> { + if(cacheCalledInjectors.contains(name)) { + for(AbstractInsnNode n : method.instructions) { + if(n instanceof FieldInsnNode) { + FieldInsnNode fieldAcc = (FieldInsnNode)n; + if(fieldAcc.getOpcode() == Opcodes.PUTFIELD && fieldAcc.owner.equals(targetClass.name)) { + accessedFieldNames.add(fieldAcc.name); + } + } + } + } + }); + // Lastly, scan all injected methods and see if they retrieve from the field. If so, inject a generateCache + // call at the start. + injectorMethodNames.forEach((name, method) -> { + // skip whitelisted injectors, and injectors called by initCache itself (to prevent recursion) + if(whitelistedInjections.contains(name) || cacheCalledInjectors.contains(name)) + return; + boolean needInjection = false; + for(AbstractInsnNode n : method.instructions) { + if(n instanceof FieldInsnNode) { + FieldInsnNode fieldAcc = (FieldInsnNode)n; + if(fieldAcc.getOpcode() == Opcodes.GETFIELD && accessedFieldNames.contains(fieldAcc.name)) { + needInjection = true; + break; + } + } + } + if(needInjection) { + ModernFixMixinPlugin.instance.logger.info("Injecting BlockStateBase cache population hook into {} from {}", + name, injectorMixinSource.getOrDefault(name, "[unknown mixin]")); + // inject this.mfix$generateCache() at method head + InsnList injection = new InsnList(); + injection.add(new VarInsnNode(Opcodes.ALOAD, 0)); + injection.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, targetClass.name, "mfix$generateCache", "()V")); + method.instructions.insert(injection); + } + }); + } } \ No newline at end of file From 33e43f5b8fd23bd2428ed2d3f1250f26cccf1dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=B6=E6=99=BA=E4=B9=83=E5=8F=8D=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E5=8F=8A?= <100760086+qznfbnj@users.noreply.github.com> Date: Mon, 14 Aug 2023 00:24:33 +0800 Subject: [PATCH 32/45] Update zh_cn.json (#211) --- common/src/main/resources/assets/modernfix/lang/zh_cn.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/main/resources/assets/modernfix/lang/zh_cn.json b/common/src/main/resources/assets/modernfix/lang/zh_cn.json index 846a902e..f0686d62 100644 --- a/common/src/main/resources/assets/modernfix/lang/zh_cn.json +++ b/common/src/main/resources/assets/modernfix/lang/zh_cn.json @@ -4,10 +4,11 @@ "modernfix.jei_load": "正在加载JEI,这可能会花费一段时间。", "modernfix.no_lazydfu": "未安装DFU载入优化。如果Minecraft需要从旧版本更新游戏数据,可能会出现极大的延迟。", "modernfix.no_ferritecore": "未安装铁氧体磁芯。内存占用将会非常高。", + "modernfix.connectedness_dynresoruces": "Connectedness模组(用于提供连接纹理)和现代化修复的动态资源(dynamic resources)功能不兼容。请删除Connectedness模组,或在现代化修复配置中禁用动态资源功能。", "modernfix.perf_mod_warning": "推荐安装这些模组,但你也可以在现代化修复的配置中禁用此警告。", "modernfix.config": "现代化修复Mixin配置", "modernfix.config.done_restart": "完成(生效需重启)", - "modernfix.message.reload_config": "在游戏外编辑完配置文件后,使用§b/mfrc§r命令使其生效。", + "modernfix.message.reload_config": "检测到模组配置文件的更改。为了避免加载尚未保存完毕的文件,重载过程必须通过使用§b/mfrc§r命令来触发。", "modernfix.option.on": "开启", "modernfix.option.off": "关闭", "modernfix.option.disabled": "已禁用", From d7b2f5b75b9e12f8351ef45d105e998c48402266 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 13 Aug 2023 13:39:24 -0400 Subject: [PATCH 33/45] Prevent mods from causing deadlocks in BlockState.getOffset If this method is called with a ServerLevel, we switch the BlockGetter for a safe wrapper that will only work on loaded chunks Related: https://github.com/N1nn1/twigs/issues/6 Related: https://github.com/N1nn1/etcetera/issues/28 --- .../modernfix/chunk/SafeBlockGetter.java | 68 +++++++++++++++++++ .../chunk_deadlock/BlockStateBaseMixin.java | 22 ++++++ .../chunk_deadlock/ServerLevelMixin.java | 18 +++++ .../modernfix/duck/ISafeBlockGetter.java | 7 ++ 4 files changed, 115 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/BlockStateBaseMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/ServerLevelMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/duck/ISafeBlockGetter.java diff --git a/common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java b/common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java new file mode 100644 index 00000000..3671e8fe --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java @@ -0,0 +1,68 @@ +package org.embeddedt.modernfix.chunk; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import org.jetbrains.annotations.Nullable; + +public class SafeBlockGetter implements BlockGetter { + private final ServerLevel wrapped; + private final Thread mainThread; + + public SafeBlockGetter(ServerLevel wrapped) { + this.wrapped = wrapped; + this.mainThread = Thread.currentThread(); + } + + public boolean shouldUse() { + return Thread.currentThread() != this.mainThread; + } + + @Nullable + private BlockGetter getChunkSafe(BlockPos pos) { + // can safely call getChunkForLighting off-thread + BlockGetter access = this.wrapped.getChunkSource().getChunkForLighting(pos.getX() >> 4, pos.getZ() >> 4); + if(!(access instanceof ChunkAccess)) + return null; + ChunkAccess chunk = (ChunkAccess)access; + if(!chunk.getStatus().isOrAfter(ChunkStatus.FULL)) + return null; + return chunk; + } + + @Override + public int getMaxBuildHeight() { + return this.wrapped.getMaxBuildHeight(); + } + + @Override + public int getMaxLightLevel() { + return this.wrapped.getMaxLightLevel(); + } + + @Nullable + @Override + public BlockEntity getBlockEntity(BlockPos pos) { + BlockGetter g = getChunkSafe(pos); + return g == null ? null : g.getBlockEntity(pos); + } + + @Override + public BlockState getBlockState(BlockPos pos) { + BlockGetter g = getChunkSafe(pos); + return g == null ? Blocks.AIR.defaultBlockState() : g.getBlockState(pos); + } + + @Override + public FluidState getFluidState(BlockPos pos) { + BlockGetter g = getChunkSafe(pos); + return g == null ? Fluids.EMPTY.defaultFluidState() : g.getFluidState(pos); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/BlockStateBaseMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/BlockStateBaseMixin.java new file mode 100644 index 00000000..464130c8 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/BlockStateBaseMixin.java @@ -0,0 +1,22 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock; + +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockBehaviour; +import org.embeddedt.modernfix.chunk.SafeBlockGetter; +import org.embeddedt.modernfix.duck.ISafeBlockGetter; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(value = BlockBehaviour.BlockStateBase.class, priority = 100) +public class BlockStateBaseMixin { + @ModifyVariable(method = "getOffset", at = @At("HEAD"), argsOnly = true, index = 1) + private BlockGetter useSafeGetter(BlockGetter g) { + if(g instanceof ISafeBlockGetter) { + SafeBlockGetter replacement = ((ISafeBlockGetter) g).mfix$getSafeBlockGetter(); + if(replacement.shouldUse()) + return replacement; + } + return g; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/ServerLevelMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/ServerLevelMixin.java new file mode 100644 index 00000000..e7c3b137 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/chunk_deadlock/ServerLevelMixin.java @@ -0,0 +1,18 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.chunk_deadlock; + +import net.minecraft.server.level.ServerLevel; +import org.embeddedt.modernfix.chunk.SafeBlockGetter; +import org.embeddedt.modernfix.duck.ISafeBlockGetter; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(ServerLevel.class) +public class ServerLevelMixin implements ISafeBlockGetter { + @Unique + private final SafeBlockGetter mfix$safeBlockGetter = new SafeBlockGetter((ServerLevel)(Object)this); + + @Override + public SafeBlockGetter mfix$getSafeBlockGetter() { + return mfix$safeBlockGetter; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/duck/ISafeBlockGetter.java b/common/src/main/java/org/embeddedt/modernfix/duck/ISafeBlockGetter.java new file mode 100644 index 00000000..3fb462ef --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/duck/ISafeBlockGetter.java @@ -0,0 +1,7 @@ +package org.embeddedt.modernfix.duck; + +import org.embeddedt.modernfix.chunk.SafeBlockGetter; + +public interface ISafeBlockGetter { + SafeBlockGetter mfix$getSafeBlockGetter(); +} From d9184833ec430e8ae379f01c95cb53b50319bc83 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 13 Aug 2023 15:53:20 -0400 Subject: [PATCH 34/45] Introduce MixinExtras --- build.gradle | 1 + common/build.gradle | 1 + fabric/build.gradle | 1 + forge/build.gradle | 6 +++++- .../platform/forge/ModernFixPlatformHooksImpl.java | 2 ++ gradle.properties | 1 + 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5d1c67c9..6e8b099b 100644 --- a/build.gradle +++ b/build.gradle @@ -94,6 +94,7 @@ allprojects { maven { url 'https://maven.terraformersmc.com/releases' } + maven { url = "https://jitpack.io" } } } diff --git a/common/build.gradle b/common/build.gradle index c067d157..ec4d9687 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -10,6 +10,7 @@ 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}" + implementation(annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-common:${rootProject.mixinextras_version}")) modCompileOnly("dev.latvian.mods:kubejs:${kubejs_version}") { transitive = false diff --git a/fabric/build.gradle b/fabric/build.gradle index 42ff963d..e970eace 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -31,6 +31,7 @@ configurations { dependencies { modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" testImplementation "net.fabricmc:fabric-loader-junit:${rootProject.fabric_loader_version}" + include(implementation(annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-fabric:${rootProject.mixinextras_version}"))) modCompileOnly(fabricApi.module("fabric-api-base", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modCompileOnly(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } diff --git a/forge/build.gradle b/forge/build.gradle index 3769452b..98886d77 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -45,6 +45,8 @@ repositories { dependencies { forge "net.minecraftforge:forge:${rootProject.forge_version}" + shadow(annotationProcessor("com.github.llamalad7.mixinextras:mixinextras-common:${rootProject.mixinextras_version}")) + runtimeOnly("com.github.llamalad7.mixinextras:mixinextras-common:${rootProject.mixinextras_version}") // Remove the next line if you don't want to depend on the API // modApi "me.shedaniel:architectury-forge:${rootProject.architectury_version}" @@ -93,8 +95,10 @@ shadowJar { exclude "fabric.mod.json" exclude "architectury.common.json" - configurations = [project.configurations.shadowCommon] + configurations = [project.configurations.shadowCommon, project.configurations.shadow] + relocate("com.llamalad7.mixinextras", "org.embeddedt.modernfix.forge.shadow.mixinextras") archiveClassifier.set("dev-shadow") + mergeServiceFiles() } remapJar { diff --git a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java index 6463a58c..b75ed47f 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java +++ b/forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java @@ -3,6 +3,7 @@ package org.embeddedt.modernfix.platform.forge; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.google.common.io.Resources; +import com.llamalad7.mixinextras.MixinExtrasBootstrap; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.brigadier.CommandDispatcher; import cpw.mods.modlauncher.*; @@ -195,6 +196,7 @@ public class ModernFixPlatformHooksImpl implements ModernFixPlatformHooks { } NightConfigFixer.monitorFileWatcher(); + MixinExtrasBootstrap.init(); } private Method defineClassMethod = null; diff --git a/gradle.properties b/gradle.properties index 0a084c03..1cb73b92 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,6 +2,7 @@ org.gradle.jvmargs=-Xmx2G junit_version=5.10.0-M1 +mixinextras_version=0.2.0-beta.9 mod_id=modernfix minecraft_version=1.16.5 From dcb72dfa6275b40b7661245bd3b257df88401da2 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:25:23 -0400 Subject: [PATCH 35/45] Add more links to Mod Menu --- fabric/src/main/resources/fabric.mod.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index e6525d26..7ea779c1 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -14,6 +14,15 @@ }, "license": "LGPL-3.0", "icon": "icon.png", + "custom": { + "modmenu": { + "links": { + "modmenu.kofi": "https://ko-fi.com/embeddedt", + "modmenu.github_releases": "https://github.com/embeddedt/ModernFix/releases", + "modmenu.curseforge": "https://www.curseforge.com/minecraft/mc-mods/modernfix" + } + } + }, "environment": "*", "entrypoints": { "main": [ From 6fa24ec171857aa0ba97e654e916a5edc5514185 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:23:43 -0400 Subject: [PATCH 36/45] Change CanonizingStringMap to use weak interner --- .../java/org/embeddedt/modernfix/util/CanonizingStringMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java index 845fbb1e..015e74a4 100644 --- a/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java +++ b/common/src/main/java/org/embeddedt/modernfix/util/CanonizingStringMap.java @@ -12,7 +12,7 @@ import java.util.Map; * Replacement backing map for CompoundTags that interns keys. */ public class CanonizingStringMap extends HashMap { - private static final Interner KEY_INTERNER = Interners.newStrongInterner(); + private static final Interner KEY_INTERNER = Interners.newWeakInterner(); private static String intern(String key) { return key != null ? KEY_INTERNER.intern(key) : null; From 6908f1490560582ee90918a167298946a629e6c7 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 13:04:04 -0400 Subject: [PATCH 37/45] Mitigation for memory usage from leaked client worlds --- .../bugfix/world_leaks/MinecraftMixin.java | 41 +++++++++++++++++++ .../main/resources/modernfix.accesswidener | 6 +++ 2 files changed, 47 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java new file mode 100644 index 00000000..d3708ff8 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_leaks/MinecraftMixin.java @@ -0,0 +1,41 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.world_leaks; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.lighting.LevelLightEngine; +import org.embeddedt.modernfix.ModernFix; +import org.jetbrains.annotations.Nullable; +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.callback.CallbackInfo; + +import java.util.concurrent.atomic.AtomicReferenceArray; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + @Shadow @Nullable public ClientLevel level; + + /** + * To mitigate the effect of leaked client worlds, clear most of the data structures that waste memory. + */ + @Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/client/Minecraft;level:Lnet/minecraft/client/multiplayer/ClientLevel;")) + private void clearLevelDataForLeaks(CallbackInfo ci) { + if(this.level != null) { + try { + AtomicReferenceArray chunks = this.level.getChunkSource().storage.chunks; + for(int i = 0; i < chunks.length(); i++) { + chunks.set(i, null); + } + this.level.getChunkSource().lightEngine = new LevelLightEngine(this.level.getChunkSource(), false, false); + // clear BE list otherwise they will hold chunks + this.level.blockEntityList.clear(); + } catch(RuntimeException e) { + ModernFix.LOGGER.error("Exception clearing level data", e); + } + } + } +} diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index aa5fa80f..3db3ffae 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -1,5 +1,11 @@ accessWidener v2 named +accessible field net/minecraft/client/multiplayer/ClientChunkCache storage Lnet/minecraft/client/multiplayer/ClientChunkCache$Storage; +accessible field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine; +mutable field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet/minecraft/world/level/lighting/LevelLightEngine; +accessible class net/minecraft/client/multiplayer/ClientChunkCache$Storage +accessible field net/minecraft/client/multiplayer/ClientChunkCache$Storage chunks Ljava/util/concurrent/atomic/AtomicReferenceArray; + accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType accessible method net/minecraft/client/renderer/RenderType$CompositeRenderType (Ljava/lang/String;Lcom/mojang/blaze3d/vertex/VertexFormat;IIZZLnet/minecraft/client/renderer/RenderType$CompositeState;)V accessible method net/minecraft/nbt/CompoundTag (Ljava/util/Map;)V From b54c6751a41c23b6ce4dc10192b5e0cb96c23180 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 22:03:07 -0400 Subject: [PATCH 38/45] Suppress dots and header in stacktraces where possible Requested by TelepathicGrunt (and frankly, why didn't I think of this earlier...) --- .../org/embeddedt/modernfix/world/ThreadDumper.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/world/ThreadDumper.java b/common/src/main/java/org/embeddedt/modernfix/world/ThreadDumper.java index bd57cb0e..a412d009 100644 --- a/common/src/main/java/org/embeddedt/modernfix/world/ThreadDumper.java +++ b/common/src/main/java/org/embeddedt/modernfix/world/ThreadDumper.java @@ -5,16 +5,23 @@ import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; public class ThreadDumper { + private static final String STACKTRACE_TAIL = "\t...\n\n"; public static String obtainThreadDump() { ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean(); ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true); StringBuilder sb = new StringBuilder(); sb.append("Thread Dump:\n"); for(ThreadInfo threadinfo : athreadinfo) { - sb.append(threadinfo); + String tInfo = threadinfo.toString(); StackTraceElement[] elements = threadinfo.getStackTrace(); if(elements.length > 8) { - sb.append("extended trace:\n"); + if(tInfo.endsWith(STACKTRACE_TAIL)) + tInfo = tInfo.substring(0, tInfo.length() - STACKTRACE_TAIL.length()); + else + tInfo = tInfo + "extended trace:\n"; + } + sb.append(tInfo); + if(elements.length > 8) { for(int i = 8; i < elements.length; i++) { sb.append("\tat "); sb.append(elements[i]); From 2629cd484afea5d1727c158ed4d0ed75b0f0f01f Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:48:30 -0400 Subject: [PATCH 39/45] Add runes/ to legacy texture folder list --- .../dynamicresources/ModelBakeryHelpers.java | 26 +++++++++++++++++++ .../dynamic_resources/ModelBakeryMixin.java | 20 +------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java index 2a16fc0c..c4b4a197 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/ModelBakeryHelpers.java @@ -57,6 +57,32 @@ public class ModelBakeryHelpers { */ public static final int MAX_MODEL_LIFETIME_SECS = 300; + /** + * These folders will have all textures stitched onto the atlas when dynamic resources is enabled. + */ + public static String[] getExtraTextureFolders() { + return new String[] { + "attachment", + "bettergrass", + "block", + "blocks", + "cape", + "entity/bed", + "entity/chest", + "item", + "items", + "model", + "models", + "part", + "pipe", + "ropebridge", + "runes", + "solid_block", + "spell_effect", + "spell_projectile" + }; + } + private static JsonElement parseStream(InputStream stream) { JsonParser parser = new JsonParser(); JsonReader jsonReader = new JsonReader(new InputStreamReader(stream, StandardCharsets.UTF_8)); diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java index f8d9211f..d39cb1ff 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/dynamic_resources/ModelBakeryMixin.java @@ -254,25 +254,7 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { blockStateFiles, modelFiles, this.missingModel, json -> BlockModel.GSON.fromJson(json, BlockModel.class), this::getModel); /* take every texture from these folders (1.19.3+ emulation) */ - String[] extraFolders = new String[] { - "attachment", - "bettergrass", - "block", - "blocks", - "cape", - "entity/bed", - "entity/chest", - "item", - "items", - "model", - "models", - "part", - "pipe", - "ropebridge", - "solid_block", - "spell_effect", - "spell_projectile" - }; + String[] extraFolders = ModelBakeryHelpers.getExtraTextureFolders(); for(String folder : extraFolders) { Collection textureLocations = this.resourceManager.listResources("textures/" + folder, p -> p.endsWith(".png")); for(ResourceLocation rl : textureLocations) { From 12aa14cc5464b4b08879aabe9a9a93219d9a4f61 Mon Sep 17 00:00:00 2001 From: TheBossMagnus <92474350+TheBossMagnus@users.noreply.github.com> Date: Wed, 16 Aug 2023 21:04:09 +0100 Subject: [PATCH 40/45] Italian Localization (#217) --- .../assets/modernfix/lang/it_it.json | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 common/src/main/resources/assets/modernfix/lang/it_it.json diff --git a/common/src/main/resources/assets/modernfix/lang/it_it.json b/common/src/main/resources/assets/modernfix/lang/it_it.json new file mode 100644 index 00000000..1d7384a4 --- /dev/null +++ b/common/src/main/resources/assets/modernfix/lang/it_it.json @@ -0,0 +1,117 @@ +{ + "key.modernfix": "ModernFix", + "key.modernfix.config": "Apri la schermata configurazione", + "modernfix.jei_load": "Caricamento JEI in corso, potrebbe richiedere un po' di tempo", + "modernfix.no_lazydfu": "LazyDFU non è installato. Se Minecraft deve aggiornare i dati di gioco da una versione precedente, potrebbe esserci un notevole lag.", + "modernfix.no_ferritecore": "FerriteCore non è installato. L'uso della memoria sarà molto elevato.", + "modernfix.connectedness_dynresoruces": "Connectedness e l'opzione risorse dinamiche di ModernFix non sono compatibili. Rimuovi Connectedness o disabilita le risorse dinamiche nella configurazione di ModernFix.", + "modernfix.perf_mod_warning": "Si consiglia di installare le mod, ma gli avvertimenti possono essere disabilitati nella configurazione di ModernFix.", + "modernfix.config": "Configurazione mixin ModernFix", + "modernfix.config.done_restart": "Fatto (riavvio richiesto)", + "modernfix.message.reload_config": "È stata rilevata una modifica al file di configurazione. Per evitare di caricare file che non sono ancora stati salvati, è necessario avviare nuovamente il caricamento eseguendo /mfrc.", + "modernfix.option.on": "attivo", + "modernfix.option.off": "disattivo", + "modernfix.option.disabled": "disabilitato", + "modernfix.option.enabled": "abilitato", + "modernfix.option.mod_override": " da mod [%s]", + "modernfix.config.not_default": " (modificato)", + "asynclocator.map.locating": "Mappa (Ricerca in corso...)", + "asynclocator.map.none": "Mappa (Nessuna caratteristica vicina trovata)", + "modernfix.option.category.performance": "Prestazioni", + "modernfix.option.category.performance.description": "Funzionalità che aiutano a migliorare le prestazioni di gioco/avvio", + "modernfix.option.category.bugfixes": "Risoluzione errori", + "modernfix.option.category.bugfixes.description": "Correzioni di bug di base per migliorare la stabilità del gioco", + "modernfix.option.category.troubleshooting": "Risoluzione di problemi/Strumenti", + "modernfix.option.category.troubleshooting.description": "Funzionalità pensate per assistere nella diagnosi dei problemi", + "modernfix.option.category.expert_only": "Solo per esperti", + "modernfix.option.category.expert_only.description": "Non modificare a meno che tu sappia cosa stai facendo", + "modernfix.option.name.mixin.perf.async_jei": "Caricamento JEI in background", + "modernfix.option.mixin.perf.async_jei": "Solo per la versione 1.16. **Un'ottimizzazione fondamentale.** Parcheggia JEI per eseguire il ricaricamento su un thread in background, eliminando completamente il lungo ritardo che aggiunge al caricamento del mondo.", + "modernfix.option.mixin.perf.async_locator": "Solo per la versione 1.16. Riporta le patch di Async Locator mod per eliminare i blocchi del server associati a `/locate`, generazione di tabelle del bottino, ecc.", + "modernfix.option.mixin.perf.biome_zoomer": "Solo per la versione 1.16. Ottimizzazione minore per migliorare le prestazioni del zoom sulla biome usando la logica dalla versione 1.18.", + "modernfix.option.mixin.perf.blast_search_trees": "Tutte le versioni. Se sono installate REI o JEI, la costruzione delle tabelle di ricerca vanilla per la ricerca creativa viene disabilitata e la ricerca viene invece effettuata utilizzando le implementazioni di ricerca di queste mod. Questo risparmia alcuni secondi durante il caricamento del mondo e probabilmente risparmia anche un po' di RAM (sebbene non sia stato misurato).", + "modernfix.option.mixin.perf.boost_worker_count": "Solo per la versione 1.16. Rimuove il limite codificato sul conteggio dei thread dei lavoratori, simile a quanto fatto da Mojang nella versione 1.18.", + "modernfix.option.mixin.perf.cache_blockstate_cache_arrays": "Tutte le versioni. Evita di creare copie nuove di array enumerativi ogni volta che viene inizializzata una cache di blockstate. Ottimizzazione minore, ma semplice da fare.", + "modernfix.option.mixin.perf.cache_model_materials": "Tutte le versioni. Memorizza la collezione `RenderMaterial` (texture) e la lista delle dipendenze che i modelli restituiscono invece di richiederne il calcolo ad ogni richiesta. Aiuta ad accelerare il processo di caricamento/modellazione dei modelli.", + "modernfix.option.mixin.perf.cache_strongholds": "Tutte le versioni. Salva l'elenco generato delle posizioni delle fortezze con il mondo, invece di rigenerarlo ad ogni caricamento del mondo. Risparmia un po' di tempo nella versione 1.16, e molto di più nelle versioni 1.18 e 1.19.", + "modernfix.option.mixin.perf.cache_upgraded_structures": "Tutte le versioni. Molti mod includono file di strutture obsoleti, il che richiede al gioco di aggiornarli utilizzando DFU ogni volta che vengono caricati. Questo può essere piuttosto lento. Questa patch aggiunge una logica per invece salvare la versione aggiornata della struttura e riutilizzarla al caricamento successivo. Per gestire il caso in cui il mod cambia un file di struttura ma non il nome, l'hash del file originale viene confrontato con la versione in cache e se non corrispondono la struttura verrà nuovamente aggiornata.", + "modernfix.option.mixin.perf.compress_biome_container": "Solo per la versione 1.16. Ottimizzazione minore presa in prestito da Hydrogen, che cerca di risparmiare spazio nel contenitore della biome quando possibile. Questo viene disabilitato automaticamente se sono installati mod in conflitto come BetterEnd o Chocolate.", + "modernfix.option.mixin.perf.datapack_reload_exceptions": "Tutte le versioni. Riduce lo spam nei log e potrebbe migliorare leggermente la velocità di caricamento evitando di stampare le tracce dello stack per alcune eccezioni comunemente generate durante il ricaricamento dei datapack (ad esempio, oggetti mancanti nelle tabelle di bottino/ricette). Il messaggio verrà comunque stampato.", + "modernfix.option.mixin.perf.dedicated_reload_executor": "Tutte le versioni. Sposta il ricaricamento dei resource pack e dei datapack in un pool di thread dedicato anziché utilizzare i thread predefiniti `Worker-Main`. Questo consente ai mod Smooth Boot di potenzialmente migliorare le prestazioni in modalità singleplayer durante l'esecuzione, senza rallentare l'avvio a causa di un conteggio limitato di thread.", + "modernfix.option.mixin.perf.deduplicate_location": "Tutte le versioni, ma disabilitato per impostazione predefinita a causa dell'impatto sui tempi di caricamento. Duplica i namespace e i percorsi delle risorse. Questo risparmia memoria, ma aumenta anche il costo di costruzione di una nuova `ResourceLocation` in modo significativo.", + "modernfix.option.mixin.perf.dynamic_dfu": "Tutte le versioni. Modifica l'inizializzazione di DFU in modo che avvenga la prima volta che è necessario eseguire un aggiornamento. Questo è simile a LazyDFU, ma si differenzia in quanto evita di caricare *qualsiasi* classe/struttura dati DFU, mentre LazyDFU disabilita solo l'ottimizzazione delle regole. Fondamentalmente, questa opzione è una versione più sicura di DataFixerSlayer, in quanto caricherà comunque DFU quando necessario.\n\nIn genere dovresti continuare a utilizzare LazyDFU anche con questa opzione abilitata, in quanto l'ottimizzazione delle regole DFU altrimenti causerà lag.", + "modernfix.option.mixin.perf.dynamic_resources": "Tutte le versioni. Vedi https://github.com/embeddedt/ModernFix/wiki/Dynamic-Resources-FAQ.", + "modernfix.option.mixin.perf.dynamic_structure_manager": "Tutte le versioni. Consente al gioco di scaricare i file delle strutture dopo la generazione, anziché mantenerli caricati per sempre.", + "modernfix.option.mixin.perf.fast_registry_validation": "Tutte le versioni. Forge cerca inutilmente un metodo tramite riflessione ogni volta che viene convalidato un registro. Questa patch semplicemente memorizza nella cache il valore restituito poiché sarà lo stesso ogni volta.", + "modernfix.option.mixin.perf.faster_font_loading": "Tutte le versioni. Ottimizza il renderer dei font per caricare i font più velocemente, velocizzando il ricaricamento delle risorse.", + "modernfix.option.mixin.perf.faster_item_rendering": "Tutte le versioni. Evita di renderizzare i lati degli oggetti nelle interfacce utente (GUI). (Sì, sembra che anche il gioco di base lo faccia.)\n\nQuesto può triplicare il frame rate (FPS) con un mod come REI/JEI installato su GPU meno potenti, se sono visibili abbastanza oggetti. Disabilitato per impostazione predefinita poiché è una funzionalità nuova e non testata molto, ma dovrebbe essere sicuro. Il problema più probabile è che gli oggetti siano completamente invisibili nelle interfacce utente (GUI) o che appaiano piatti nel mondo.", + "modernfix.option.mixin.perf.faster_texture_loading": "Tutte le versioni precedenti alla 1.19.4. Evita di leggere le texture due volte (la prima volta utilizzando un percorso di codice molto lento) e invece ne effettua un caricamento più veloce (simile a 1.19.3+).", + "modernfix.option.mixin.perf.faster_texture_stitching": "Tutte le versioni. Consente al gioco di utilizzare un sistema di cucitura delle texture più veloce, originariamente sviluppato da SuperCoder79 per lwjgl3ify su 1.7.10, che può risparmiare tempo durante il caricamento. Raramente si è riscontrato che causi artefatti strani su blocchi o interfacce utente (GUI), potrebbe essere un errore di Sodium.", + "modernfix.option.mixin.perf.jeresources_startup": "Solo 1.16. Ottimizza Just Enough Resources in modo da non ricreare inutilmente le entità dei villaggi molte volte per la stessa professione, risparmiando tempo durante l'avvio di JEI.", + "modernfix.option.mixin.perf.kubejs": "Solo 1.16. Ottimizzazioni per KubeJS per evitare copie inutili di `ItemStack`, ecc., riducendo il tempo richiesto per caricare i datapack.", + "modernfix.option.mixin.perf.model_optimizations": "Tutte le versioni. Implementa ottimizzazioni per velocizzare il processo di caricamento dei modelli.", + "modernfix.option.mixin.perf.nbt_memory_usage": "Tutte le versioni. Utilizza una mappa di supporto più efficiente per i tag NBT composti che deduplica i nomi chiave e utilizza anche una mappa di array per i composti molto piccoli. Ciò riduce l'onere di memorizzare molti tag composti in memoria.", + "modernfix.option.mixin.perf.nuke_empty_chunk_sections": "Solo 1.16, ispirato a Hydrogen. Evita di memorizzare in memoria le sezioni di chunk piene di aria, segnalandole invece come vuote.", + "modernfix.option.mixin.perf.remove_biome_temperature_cache": "Tutte le versioni. Rimuove la cache delle temperature dei biome come fa Lithium nelle versioni moderne.", + "modernfix.option.mixin.perf.resourcepacks": "Tutte le versioni. **Un'ottimizzazione fondamentale.** I lanci nelle versioni moderne sono fortemente rallentati dall'accesso al filesystem. Molte richieste vengono fatte frequentemente ai pacchetti di risorse per elencare le risorse o verificare se esiste una risorsa specifica, e ognuna di queste richieste produce una chiamata API al file molto lenta.\n\nModernFix elimina completamente la maggior parte del collo di bottiglia semplicemente memorizzando in cache un elenco di tutte le risorse presenti nei pacchetti di risorse forniti dai mod e in quelli vanilla. La cache viene ricostruita alla ricarica delle risorse (ad eccezione delle risorse vanilla, poiché non dovrebbero mai cambiare mentre il gioco è in esecuzione).\n\nNon ci sono problemi di compatibilità noti con questa patch, ad eccezione di OptiFine (le sue risorse CTM non vengono caricate correttamente). Tuttavia, non consiglio di utilizzare OptiFine in nessuno scenario, poiché aggiunge diversi minuti all'avvio da solo e non è testato con ModernFix.", + "modernfix.option.mixin.perf.reuse_datapacks": "Solo versione 1.16. Tenta di velocizzare il passaggio tra mondi in giocatore singolo saltando il riavvio dei datapack quando possibile. Potrebbe causare problemi di compatibilità con alcuni mod, ma è abilitato per impostazione predefinita.", + "modernfix.option.mixin.perf.rewrite_registry": "Tutte le versioni. **Attualmente semi-rotto.** Sostituisce aggressivamente alcune parti interne del sistema di registro di Forge con versioni più veloci, tuttavia attualmente causa blocchi durante il caricamento di alcuni modpack. Disabilitato per impostazione predefinita per ovvi motivi.", + "modernfix.option.mixin.perf.skip_first_datapack_reload": "Solo versioni 1.16 e 1.19. **Un'ottimizzazione fondamentale.**\n\nNel mezzo del ciclo di sviluppo 1.16, Forge ha patchato il gioco per ricaricare i datapack due volte quando si caricava un mondo esistente, al fine di risolvere un problema di spostamento dell'ID dei biome. Purtroppo, le ricariche dei datapack richiedono spesso più di 30 secondi e quindi questo influisce molto sui tempi di caricamento del mondo.\n\nModernFix apporta le modifiche necessarie per evitare questa ricarica, basandosi sulla pull request incompiuta di Forge #8163.\n\nQuesta modifica è stata rimossa da Forge nella versione 1.18, ma poi una patch simile è stata aggiunta *nuovamente* nella versione 1.19 per risolvere il problema dei datapack dei mod che non venivano caricati durante la creazione di nuovi mondi in giocatore singolo. Fortunatamente, il problema è limitato alla schermata di creazione del mondo nella versione 1.19, e i mondi esistenti richiedono solo una ricarica. Tuttavia, questo raddoppia comunque la durata della lag spike quando si fa clic su \"Crea nuovo mondo\" nella versione 1.19, quindi ModernFix apporta nuovamente modifiche per evitare una ricarica ridondante.", + "modernfix.option.mixin.perf.state_definition_construct": "Tutte le versioni. Abilitato solo se è installato FerriteCore. Sfrutta la gestione dei blockstate di FerriteCore per accelerarne la creazione. Questo può aiutare ad accelerare l'avvio con mod che aggiungono molti blockstate, come ad esempio le mod di mobili.", + "modernfix.option.mixin.perf.sync_executor_sleep": "Tutte le versioni. Evita che il thread principale giri inutilmente consumando un core della CPU mentre aspetta che i lavoratori di caricamento dei mod finiscano.", + "modernfix.option.mixin.perf.thread_priorities": "Tutte le versioni. Regola le priorità dei thread dei lavoratori e del server in modo che siano inferiori al thread del client. Questo aiuta a migliorare la stabilità degli FPS su macchine con pochi core della CPU, purché l'implementazione Java in uso rispetti le priorità.", + "modernfix.option.mixin.perf.use_integrated_resources": "Principalmente per la versione 1.16. Corregge JEResources affinché utilizzi i dati delle tabelle del bottino del server integrato se si gioca in giocatore singolo, anziché ricaricare inutilmente le tabelle del bottino. Risparmia alcuni secondi in più durante l'avvio di JEI.", + "modernfix.option.mixin.bugfix.concurrency": "Le patch in questo gruppo risolvono problemi legati alla concorrenza in Minecraft e/o Forge. La maggior parte di esse provoca crash rari e difficili da diagnosticare durante il caricamento.", + "modernfix.option.mixin.bugfix.edge_chunk_not_saved": "Questa opzione è un porting della mod Chunk Saving Fix di SuperCoder (perché non mi sono reso conto che era già disponibile per Forge all'epoca).", + "modernfix.option.mixin.bugfix.mc218112": "Questa opzione risolve un deadlock che può verificarsi se viene lanciata un'eccezione durante l'elaborazione dei dati dell'entità. Vanilla non sblocca correttamente il gestore dei dati quando dovrebbe farlo. Questo è tracciato come MC-218112 nel bug tracker ed è stato corretto da Mojang nella versione 1.17.", + "modernfix.option.mixin.bugfix.packet_leak": "**Sperimentale**, non abilitato per impostazione predefinita. Un tentativo di correzione per il problema di perdita di memoria che si verifica dopo aver giocato abbastanza a lungo nella versione 1.16.", + "modernfix.option.mixin.bugfix.paper_chunk_patches": "Versioni 1.18 e successive. **Un'ottimizzazione fondamentale.** Porta una patch da Paper che risolve i problemi nella versione 1.17 con il caricamento dei chunk che richiede enormi quantità di memoria e genera molte istanze di `CompletableFuture`. Le versioni 1.18+ ora possono caricare mondi con soli 400MB di memoria come poteva fare la 1.16.", + "modernfix.option.mixin.bugfix.tf_cme_on_load": "Modifica Twilight Forest per eseguire la configurazione client non thread-safe utilizzando il thread principale, come dovrebbe fare, anziché il thread worker FML.", + "modernfix.option.mixin.feature.branding": "Aggiunge ModernFix all'elenco del marchio nella schermata dei titoli e anche alla schermata F3.", + "modernfix.option.mixin.feature.direct_stack_trace": "Di solito disabilitato, può essere abilitato per forzare la traccia dello stack grezzo da registrare quando si verifica un crash. Occasionalmente, il sistema di report dei crash di Vanilla non funziona correttamente e fornisce una traccia/report dello stack completamente irrilevante.", + "modernfix.option.mixin.feature.measure_time": "Utilizza alcune iniezioni per misurare il tempo di caricamento del mondo, il tempo di ricarica dei datapack, il tempo di ricarica delle risorse, il tempo di avvio e aggiunge i ganci necessari per abilitare la logica del profiler inutilizzata di Vanilla per la ricarica delle risorse, se configurato.", + "modernfix.option.mixin.feature.spam_thread_dump": "**Da utilizzare solo per scopi di debug.** Fa sì che venga registrato un thread dump nel registro ogni 60 secondi. Questo può aiutare a diagnosticare i blocchi inspiegabili durante il caricamento/gioco.", + "modernfix.option.mixin.bugfix.chunk_deadlock": "Tenta di prevenire i blocchi del sistema di chunk o fornisce informazioni di debug aggiuntive nel registro quando si verificano. Questi blocchi di solito si manifestano come il server che si blocca indefinitamente (ad esempio, le entità non si muovono), mentre il client continua a funzionare normalmente.", + "modernfix.option.mixin.bugfix.chunk_deadlock.valhesia": "Modifica Valhesia Structures per risolvere un problema nel suo codice che causa blocchi frequenti del worldgen/caricamento dei chunk.", + "modernfix.option.mixin.bugfix.cofh_core_crash": "Corregge un problema di multithreading in CoFH Core che può causare crash rari durante l'avvio.", + "modernfix.option.mixin.bugfix.ctm_resourceutil_cme": "Corregge un problema di multithreading in ConnectedTexturesMod che può causare crash rari durante l'avvio.", + "modernfix.option.mixin.bugfix.ender_dragon_leak": "Corregge una perdita di memoria in Vanilla causata dal drago dell'End che mantiene un riferimento al mondo client precedente.", + "modernfix.option.mixin.bugfix.entity_load_deadlock": "Corregge molti problemi in cui EntityJoinWorldEvent/EntityJoinLevelEvent causano un blocco del worldgen, ritardando leggermente il caricamento dell'entità. Non dovrebbe, tuttavia, causare cambiamenti di comportamento visibili in gioco.", + "modernfix.option.mixin.bugfix.fix_config_crashes": "Corregge il problema di Forge delle configurazioni che occasionalmente diventano corrotte durante il lancio del gioco.", + "modernfix.option.mixin.bugfix.item_cache_flag": "Corregge MC-258939", + "modernfix.option.mixin.bugfix.preserve_early_window_pos": "Fa sì che la finestra di gioco mantenga le sue dimensioni esistenti quando il controllo passa dal caricamento anticipato di Forge al codice di Minecraft. Corregge il problema della finestra che torna al centro dello schermo dopo essere stata trascinata, ecc.", + "modernfix.option.mixin.bugfix.refinedstorage.te_bug": "Corregge i blocchi di archiviazione esterna di Refined Storage che occasionalmente non mostrano i contenuti dei cassetti, ecc. quando vengono caricati. Backport di Refined Storage PR #3435, che è stato applicato solo alla versione 1.18 e successive.", + "modernfix.option.mixin.bugfix.remove_block_chunkloading": "Corregge il fatto che i maiali zombie tengano perpetuamente caricato il chunk 0, 0 su Forge. Backport di Forge PR #8583.", + "modernfix.option.mixin.bugfix.starlight_emptiness": "Corregge un crash occasionale di Starlight dovuto all'inizializzazione non corretta delle mappe di vuoto. Backport della stessa correzione in Starlight per la versione 1.18.x.", + "modernfix.option.mixin.core": "Patch di base necessarie per far funzionare ModernFix", + "modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "Tutte le versioni. **Un'ottimizzazione fondamentale.** Le versioni più recenti di Minecraft (dopo la 1.12) hanno implementato un sistema di cache dei blockstate che memorizza le informazioni frequentemente utilizzate su un blockstate, come ad esempio se è solido, la sua forma di collisione, ecc. Ricostruire questa cache è abbastanza veloce nella versione standard (richiede solo uno o due secondi), ma è molto lento con molti mod installati, poiché sono presenti molti più blockstate nel gioco che devono tutti avere le loro cache ricostruite.\n\nQuesto problema viene esacerbato da Forge poiché la cache viene ricostruita in molti punti quando i dati sarebbero quasi certamente inutilizzati prima della successiva ricostruzione. Esempi includono subito prima di raggiungere il menu principale (durante la fase \"Freezing data\"), nonché più volte (!) quando viene caricato un mondo.\n\nModernFix risolve questo collo di bottiglia delle prestazioni rendendo invece le ricostruzioni della cache pigre. Ogni blockstate ricostruisce la sua cache la prima volta che i dati vengono acceduti. In qualsiasi momento in cui Vanilla o Forge tenterebbero di ricostruire le cache per tutti i blockstate, questo viene ridirezionato per invalidare semplicemente la cache su ciascun blockstate.\n\nQuesto non dovrebbe avere alcun impatto sul TPS dopo che l'avvio è concluso.", + "modernfix.option.mixin.devenv": "Patch utilizzate durante l'esecuzione in un ambiente di sviluppo, per miglioramenti di velocità e/o test", + "modernfix.option.mixin.safety": "Patch di concorrenza per prevenire crash durante il lancio", + "modernfix.option.mixin.feature.integrated_server_watchdog": "Aggiunge il watchdog vanilla anche ai mondi in giocatore singolo, ma stampa solo le tracce dello stack anziché terminare forzatamente il mondo. Questa versione include la funzionalità di Fullstack Watchdog, ma quest'ultimo è comunque necessario per il multiplayer.", + "modernfix.option.mixin.feature.snapshot_easter_egg": "Aggiunge funzionalità easter egg (non influisce su alcuna visualizzazione o comportamento vanilla) quando si esegue una versione snapshot.", + "modernfix.option.mixin.feature.spark_profile_launch": "Se abilitato e installata una versione compatibile di Spark, l'intera sequenza di avvio verrà profilata fino al menu principale.", + "modernfix.option.mixin.feature.warn_missing_perf_mods": "Mostra un avviso all'avvio se altri mod per le prestazioni considerati essenziali e altamente compatibili non sono presenti", + "modernfix.option.mixin.launch.class_search_cache": "Sostituisce il risolutore delle risorse di Forge (usato per trovare il codice del gioco e di un mod) con una versione significativamente più veloce, accelerando l'avvio", + "modernfix.option.mixin.perf.clear_fabric_mapping_tables": "Riduce l'utilizzo della memoria cancellando le strutture di dati di mappatura in Fabric Loader che sono ridondanti o raramente utilizzate dai mod. Disabilitato per impostazione predefinita per motivi di compatibilità.", + "modernfix.option.mixin.perf.clear_mixin_classinfo": "Carica forzatamente tutti i mixin quando il lancio termina e quindi cancella le strutture di dati di mixin per rimuovere gran parte della memoria di Mixin. Disabilitato per impostazione predefinita per motivi di compatibilità.", + "modernfix.option.mixin.perf.deduplicate_wall_shapes": "Rende la maggior parte dei blocchi murari condividere lo stesso oggetto forma anziché avere ognuno la propria copia. Può ridurre notevolmente l'utilizzo della memoria quando vengono aggiunti molti blocchi murari dai mod.", + "modernfix.option.mixin.perf.dynamic_resources.ae2": "Patch di compatibilità AE2 per le risorse dinamiche", + "modernfix.option.mixin.perf.dynamic_resources.ctm": "Patch di compatibilità CTM per le risorse dinamiche", + "modernfix.option.mixin.perf.dynamic_resources.rs": "Patch di compatibilità Refined Storage per le risorse dinamiche", + "modernfix.option.mixin.perf.dynamic_resources.supermartijncore": "Patch di compatibilità SuperMartijn642CoreLib per le risorse dinamiche", + "modernfix.option.mixin.perf.dynamic_resources.diagonalfences": "Patch di compatibilità Diagonal Fences per le risorse dinamiche", + "modernfix.option.mixin.perf.faster_advancements": "Riscrive la logica di controllo degli avanzamenti per renderla più veloce e per evitare StackOverflowError in pacchetti grandi. Porting di Advancements Debug da Fabric.", + "modernfix.option.mixin.perf.patchouli_deduplicate_books": "Risolve il problema dei libri di Patchouli che memorizzano molti oggetti vuoti con tag NBT, riducendo l'utilizzo della memoria.", + "modernfix.option.mixin.perf.remove_spawn_chunks": "Rimuove completamente i chunk di spawn dal gioco. Non vengono più caricati affatto, a differenza di Ksyxis.", + "modernfix.option.mixin.perf.use_integrated_resources.jepb": "", + "modernfix.option.mixin.perf.use_integrated_resources.jeresources": "", + "modernfix.option.mixin.bugfix.blueprint_modif_memory_leak": "Risolve la perdita di risorse vaniglia di ObjectModificationManager in Blueprint, riducendo l'utilizzo della memoria. Nonostante la correzione sia stata contribuita in PR #195, non è ancora stata rilasciata.", + "modernfix.option.mixin.bugfix.removed_dimensions": "Risolve il problema del gioco che non riesce a caricare i mondi se vengono rimossi i mod delle dimensioni. Backport di Forge PR #8959.", + "modernfix.option.mixin.perf.compact_bit_storage": "Corregge lo spreco di memoria causato da alcuni server legacy (ad esempio Hypixel) che inviano chunk vuoti come se contenessero blocchi. Riduce notevolmente l'utilizzo della memoria su questi server.", + "modernfix.option.mixin.perf.deduplicate_climate_parameters": "Deduplica gli oggetti parametro del clima utilizzati dal nuovo sistema di biome, può risparmiare ~2MB ma rallenta leggermente la ricarica dei datapack.", + "modernfix.option.mixin.perf.dynamic_entity_renderers": "Costruisce i modelli delle entità la prima volta che vengono visti anziché durante l'avvio. Alcuni mod non sono compatibili con questa opzione e causeranno crash di EntityRenderer.", + "modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "Risolve il lag causato dal worldgen di Twilight Forest che controlla le strutture in modo molto inefficiente", + "modernfix.option.mixin.perf.fast_forge_dummies": "Velocizza il congelamento del registro di Forge durante l'avvio utilizzando un percorso del codice più veloce", + "modernfix.option.mixin.perf.tag_id_caching": "Velocizza l'uso delle voci dei tag memorizzando nella cache l'oggetto di posizione anziché ricrearlo ogni volta", + "modernfix.option.mixin.feature.disable_unihex_font": "Rimuove il font Unicode, risparmiando 10MB ma causando la mancata visualizzazione dei caratteri speciali" + } From 744622b81d8ca77688ea1227e3be9668ef4af4d0 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Wed, 16 Aug 2023 21:58:26 -0400 Subject: [PATCH 41/45] Create FUNDING.yml [skip ci] --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..9c89146b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +ko_fi: embeddedt From 672ca92aabc94f5cccec563bc42f28b665236563 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:35:01 -0400 Subject: [PATCH 42/45] Show time to bootstrap stage on Forge --- .../modernfix/util/TimeFormatter.java | 67 +++++++++++++++++++ .../forge/mixin/core/BootstrapMixin.java | 5 +- 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 common/src/main/java/org/embeddedt/modernfix/util/TimeFormatter.java diff --git a/common/src/main/java/org/embeddedt/modernfix/util/TimeFormatter.java b/common/src/main/java/org/embeddedt/modernfix/util/TimeFormatter.java new file mode 100644 index 00000000..11356f77 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/util/TimeFormatter.java @@ -0,0 +1,67 @@ +package org.embeddedt.modernfix.util; + +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import static java.util.concurrent.TimeUnit.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; + +/** + * All code here is derived from Guava's Stopwatch and Platform classes. + * Too bad it's not a public method call indeed... + */ +public class TimeFormatter { + static String formatCompact4Digits(double value) { + return String.format(Locale.ROOT, "%.4g", value); + } + + public static String formatNanos(long nanos) { + TimeUnit unit = chooseUnit(nanos); + double value = (double) nanos / NANOSECONDS.convert(1, unit); + + return formatCompact4Digits(value) + " " + abbreviate(unit); + } + + private static TimeUnit chooseUnit(long nanos) { + if (DAYS.convert(nanos, NANOSECONDS) > 0) { + return DAYS; + } + if (HOURS.convert(nanos, NANOSECONDS) > 0) { + return HOURS; + } + if (MINUTES.convert(nanos, NANOSECONDS) > 0) { + return MINUTES; + } + if (SECONDS.convert(nanos, NANOSECONDS) > 0) { + return SECONDS; + } + if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) { + return MILLISECONDS; + } + if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) { + return MICROSECONDS; + } + return NANOSECONDS; + } + + private static String abbreviate(TimeUnit unit) { + switch (unit) { + case NANOSECONDS: + return "ns"; + case MICROSECONDS: + return "\u03bcs"; // μs + case MILLISECONDS: + return "ms"; + case SECONDS: + return "s"; + case MINUTES: + return "min"; + case HOURS: + return "h"; + case DAYS: + return "d"; + default: + throw new AssertionError(); + } + } +} diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java index c80304af..27ec520b 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java @@ -3,6 +3,7 @@ package org.embeddedt.modernfix.forge.mixin.core; import net.minecraft.server.Bootstrap; import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.forge.load.ModWorkManagerQueue; +import org.embeddedt.modernfix.util.TimeFormatter; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -10,6 +11,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.lang.management.ManagementFactory; + @Mixin(Bootstrap.class) public class BootstrapMixin { @Shadow private static boolean isBootstrapped; @@ -19,7 +22,7 @@ public class BootstrapMixin { @Inject(method = "bootStrap", at = @At("HEAD")) private static void doModernFixBootstrap(CallbackInfo ci) { if(!isBootstrapped) { - LOGGER.info("ModernFix bootstrap"); + LOGGER.info("ModernFix reached bootstrap stage ({} after launch)", TimeFormatter.formatNanos(ManagementFactory.getRuntimeMXBean().getUptime() * 1000L)); ModWorkManagerQueue.replace(); } } From fa9103fb06884a93c82656d87df1c9fd157522a6 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:39:07 -0400 Subject: [PATCH 43/45] Convert milliseconds to nanoseconds correctly --- .../embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java index 27ec520b..ab7be02d 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/core/BootstrapMixin.java @@ -22,7 +22,7 @@ public class BootstrapMixin { @Inject(method = "bootStrap", at = @At("HEAD")) private static void doModernFixBootstrap(CallbackInfo ci) { if(!isBootstrapped) { - LOGGER.info("ModernFix reached bootstrap stage ({} after launch)", TimeFormatter.formatNanos(ManagementFactory.getRuntimeMXBean().getUptime() * 1000L)); + LOGGER.info("ModernFix reached bootstrap stage ({} after launch)", TimeFormatter.formatNanos(ManagementFactory.getRuntimeMXBean().getUptime() * 1000L * 1000L)); ModWorkManagerQueue.replace(); } } From 45f92f7fce304c0056b466467dc113e7c183dd54 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:16:20 -0400 Subject: [PATCH 44/45] Disable config reload message for now There isn't a good way to print this in a way that will catch the modification in all scenarios, and that doesn't annoy the user --- .../org/embeddedt/modernfix/forge/config/NightConfigFixer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java index 8155f186..ec27916e 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java @@ -79,7 +79,7 @@ public class NightConfigFixer { private static boolean couldShowMessage = true; private static void triggerConfigMessage() { - if(couldShowMessage && Minecraft.getInstance().level != null && ModernFixClient.recipesUpdated && ModernFixClient.tagsUpdated) { + if(false && couldShowMessage && Minecraft.getInstance().level != null && ModernFixClient.recipesUpdated && ModernFixClient.tagsUpdated) { Minecraft.getInstance().execute(() -> { if(Minecraft.getInstance().level != null) { couldShowMessage = false; From ec66fbc05c43a54dd3ce0836376a3b23856446ca Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 18 Aug 2023 15:31:31 -0400 Subject: [PATCH 45/45] Add wiki button Related: #202 --- .../modernfix/screen/ModernFixConfigScreen.java | 13 ++++++++----- .../main/resources/assets/modernfix/lang/en_us.json | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java b/common/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java index f97ef7a2..a0cc441c 100644 --- a/common/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java +++ b/common/src/main/java/org/embeddedt/modernfix/screen/ModernFixConfigScreen.java @@ -1,11 +1,10 @@ package org.embeddedt.modernfix.screen; import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.Util; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.network.chat.CommonComponents; -import net.minecraft.network.chat.Style; -import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.network.chat.*; import org.jetbrains.annotations.Nullable; public class ModernFixConfigScreen extends Screen { @@ -13,7 +12,7 @@ public class ModernFixConfigScreen extends Screen { private Screen lastScreen; public boolean madeChanges = false; - private Button doneButton; + private Button doneButton, wikiButton; public ModernFixConfigScreen(Screen lastScreen) { super(new TranslatableComponent("modernfix.config")); this.lastScreen = lastScreen; @@ -23,9 +22,13 @@ public class ModernFixConfigScreen extends Screen { protected void init() { this.optionList = new OptionList(this, this.minecraft); this.children.add(this.optionList); - this.doneButton = new Button(this.width / 2 - 100, this.height - 29, 200, 20, CommonComponents.GUI_DONE, (arg) -> { + this.wikiButton = new Button(this.width / 2 - 155, this.height - 29, 150, 20, new TranslatableComponent("modernfix.config.wiki"), (arg) -> { + Util.getPlatform().openUri("https://github.com/embeddedt/ModernFix/wiki/Summary-of-Patches"); + }); + this.doneButton = new Button(this.width / 2 - 155 + 160, this.height - 29, 150, 20, CommonComponents.GUI_DONE, (arg) -> { this.onClose(); }); + this.addButton(this.wikiButton); this.addButton(this.doneButton); } diff --git a/common/src/main/resources/assets/modernfix/lang/en_us.json b/common/src/main/resources/assets/modernfix/lang/en_us.json index 3afbc788..29d2e454 100644 --- a/common/src/main/resources/assets/modernfix/lang/en_us.json +++ b/common/src/main/resources/assets/modernfix/lang/en_us.json @@ -8,6 +8,7 @@ "modernfix.perf_mod_warning": "It is recommended to install the mods, but the warning(s) can be disabled in the ModernFix config.", "modernfix.config": "ModernFix mixin config", "modernfix.config.done_restart": "Done (restart required)", + "modernfix.config.wiki": "Open wiki", "modernfix.message.reload_config": "A mod config file change was detected. To prevent loading files that aren't done saving, reloading must be triggered by running /mfrc.", "modernfix.option.on": "on", "modernfix.option.off": "off",