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 01/51] 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 02/51] 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 03/51] 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 04/51] 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 05/51] 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 06/51] 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 07/51] 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 08/51] 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 09/51] 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 10/51] 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 11/51] 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 12/51] 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 d52e6467ac1e616a4a4ea8b1a3ca6e965a306091 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 10:37:59 -0400 Subject: [PATCH 13/51] Update testmod to 1.18 --- fabric/testmod/build.gradle | 1 + .../testmod/client/TestModClient.java | 3 +++ .../testmod/mixin/DebugLevelSourceMixin.java | 18 +++++++++------ .../testmod/mixin/RenderChunkMixin.java | 23 +++++++++++++++++++ .../src/main/resources/testmod.mixins.json | 3 +++ 5 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/RenderChunkMixin.java diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle index 8e27f9b9..8fa9f8a2 100644 --- a/fabric/testmod/build.gradle +++ b/fabric/testmod/build.gradle @@ -16,6 +16,7 @@ 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-registry-sync-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' } 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..24f9dbb9 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 net.minecraft.client.Minecraft; import org.embeddedt.modernfix.testmod.TestMod; import java.util.regex.Matcher; @@ -23,5 +24,7 @@ public class TestModClient implements ClientModInitializer { } return null; }); + // needed to make debug level rendering work correctly + Minecraft.getInstance().smartCull = false; } } 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..38301fa1 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 @@ -1,9 +1,12 @@ package org.embeddedt.modernfix.testmod.mixin; import net.minecraft.core.BlockPos; -import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.core.SectionPos; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.levelgen.DebugLevelSource; import org.embeddedt.modernfix.testmod.TestMod; import org.spongepowered.asm.mixin.Mixin; @@ -14,20 +17,21 @@ 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) { + private void showColorCube(WorldGenLevel level, ChunkAccess chunk, StructureFeatureManager structureFeatureManager, CallbackInfo ci) { ci.cancel(); BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); - int i = region.getCenterX(); - int j = region.getCenterZ(); + ChunkPos chunkPos = chunk.getPos(); + int i = chunkPos.x; + int j = chunkPos.z; for(int k = 0; k < 16; ++k) { for(int l = 0; l < 16; ++l) { - int m = (i << 4) + k; - int n = (j << 4) + l; + int m = SectionPos.sectionToBlockCoord(i, k); + int n = SectionPos.sectionToBlockCoord(j, 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); + level.setBlock(mutableBlockPos.set(m, y, n), blockState, 2); } } } diff --git a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/RenderChunkMixin.java b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/RenderChunkMixin.java new file mode 100644 index 00000000..eaa6d1d2 --- /dev/null +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/mixin/RenderChunkMixin.java @@ -0,0 +1,23 @@ +package org.embeddedt.modernfix.testmod.mixin; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; +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(targets = { "net/minecraft/client/renderer/chunk/RenderChunk" }) +public class RenderChunkMixin { + @Shadow @Final private boolean debug; + + @Inject(method = "getBlockState", at = @At("HEAD"), cancellable = true) + private void redirectDebugWorld(BlockPos pos, CallbackInfoReturnable cir) { + if(this.debug) { + cir.setReturnValue(TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ())); + } + } +} diff --git a/fabric/testmod/src/main/resources/testmod.mixins.json b/fabric/testmod/src/main/resources/testmod.mixins.json index 9eeb91ea..46222aa3 100644 --- a/fabric/testmod/src/main/resources/testmod.mixins.json +++ b/fabric/testmod/src/main/resources/testmod.mixins.json @@ -7,6 +7,9 @@ "ChunkMixin", "DebugLevelSourceMixin" ], + "client": [ + "RenderChunkMixin" + ], "injectors": { "defaultRequire": 1 } From f1c0d02bc3d605593c31b913d3965cd5ed72597e Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 10:47:46 -0400 Subject: [PATCH 14/51] Update testmod to 1.19.2 --- .../modernfix/testmod/client/TestModBlockModel.java | 12 ++++++++---- .../testmod/mixin/DebugLevelSourceMixin.java | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) 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 index a890f540..c2f8a5a7 100644 --- 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 @@ -20,13 +20,17 @@ import net.minecraft.client.resources.model.*; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; 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.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; @@ -50,17 +54,17 @@ public class TestModBlockModel implements UnbakedModel, BakedModel, FabricBakedM } @Override - public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + 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) { + 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) { + public List getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand) { return Collections.emptyList(); } 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 38301fa1..d37d0480 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,7 +3,7 @@ package org.embeddedt.modernfix.testmod.mixin; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; @@ -17,7 +17,7 @@ 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(WorldGenLevel level, ChunkAccess chunk, StructureFeatureManager structureFeatureManager, CallbackInfo ci) { + private void showColorCube(WorldGenLevel level, ChunkAccess chunk, StructureManager structureFeatureManager, CallbackInfo ci) { ci.cancel(); BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); ChunkPos chunkPos = chunk.getPos(); From 24e014f326789987034cf24a3c78ecc78abdb8d6 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 10:54:27 -0400 Subject: [PATCH 15/51] Update testmod to 1.19.4 --- .../org/embeddedt/modernfix/testmod/TestBlockItem.java | 3 +-- .../java/org/embeddedt/modernfix/testmod/TestMod.java | 5 +++-- .../modernfix/testmod/client/TestModBlockModel.java | 9 +++------ 3 files changed, 7 insertions(+), 10 deletions(-) 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 index cfc09cfa..f5cbe047 100644 --- a/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlockItem.java +++ b/fabric/testmod/src/main/java/org/embeddedt/modernfix/testmod/TestBlockItem.java @@ -1,11 +1,10 @@ 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); + private static final Item.Properties PROPERTIES = new Item.Properties(); 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 5ad72e50..89f9d5eb 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 @@ -3,6 +3,7 @@ package org.embeddedt.modernfix.testmod; import com.google.common.base.Stopwatch; import net.fabricmc.api.ModInitializer; import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; @@ -32,9 +33,9 @@ public class TestMod implements ModInitializer { 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()); + TestBlock block = Registry.register(BuiltInRegistries.BLOCK, name, new TestBlock()); WOOL_STATES.add(block.defaultBlockState()); - Registry.register(Registry.ITEM, name, new TestBlockItem(block)); + Registry.register(BuiltInRegistries.ITEM, name, new TestBlockItem(block)); numRegistered++; if((numRegistered % progressReport) == 0) { LOGGER.info(String.format("Registering... %.02f%%", ((float)numRegistered)/totalToRegister * 100)); 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 index c2f8a5a7..43ccf4d6 100644 --- 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 @@ -1,7 +1,5 @@ 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; @@ -30,7 +28,6 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; @@ -109,8 +106,8 @@ public class TestModBlockModel implements UnbakedModel, BakedModel, FabricBakedM } @Override - public Collection getMaterials(Function modelGetter, Set> missingTextureErrors) { - return ImmutableList.of(BASE_WOOL); + public void resolveParents(Function function) { + } private static int scaleColor(int c) { @@ -119,7 +116,7 @@ public class TestModBlockModel implements UnbakedModel, BakedModel, FabricBakedM @Nullable @Override - public BakedModel bake(ModelBakery modelBakery, Function spriteGetter, ModelState transform, ResourceLocation location) { + public BakedModel bake(ModelBaker baker, Function spriteGetter, ModelState state, ResourceLocation location) { // Build the mesh using the Renderer API Renderer renderer = RendererAccess.INSTANCE.getRenderer(); MeshBuilder builder = renderer.meshBuilder(); From be4a6abc81e3ccead3d406df9d7fc6a145efd737 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:07:39 -0400 Subject: [PATCH 16/51] Port testmod to 1.20 --- fabric/testmod/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric/testmod/build.gradle b/fabric/testmod/build.gradle index 8fa9f8a2..2f707a79 100644 --- a/fabric/testmod/build.gradle +++ b/fabric/testmod/build.gradle @@ -15,7 +15,7 @@ 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-models-v0", "0.84.0+1.20.1")) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modImplementation(fabricApi.module("fabric-registry-sync-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' } 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 17/51] 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 18/51] 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 19/51] 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 20/51] 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 21/51] 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 22/51] 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 23/51] 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 24/51] 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 25/51] 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 f656aea0291816cd113a114de7435329844bcaa5 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 17:05:17 -0400 Subject: [PATCH 26/51] Remove outdated mixin --- .../blast_search_trees/MinecraftMixin.java | 39 ------------------- 1 file changed, 39 deletions(-) delete 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 deleted file mode 100644 index 06a475b6..00000000 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/blast_search_trees/MinecraftMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -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 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 27/51] 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 28/51] 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 74d28ed997a4434754755ad970f2a963f4b742c9 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 19:50:33 -0400 Subject: [PATCH 29/51] Update mixin --- .../compact_mojang_registries/MappedRegistryMixin.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) 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 index c907ce45..f6e86477 100644 --- 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 @@ -3,8 +3,6 @@ package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries; 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.registry.LifecycleMap; @@ -20,7 +18,7 @@ import java.util.Map; @Mixin(MappedRegistry.class) @IgnoreOutsideDev -public abstract class MappedRegistryMixin extends Registry { +public abstract class MappedRegistryMixin { @Shadow @Final @Mutable @@ -28,11 +26,7 @@ public abstract class MappedRegistryMixin extends Registry { 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")) + @Inject(method = "(Lnet/minecraft/resources/ResourceKey;Lcom/mojang/serialization/Lifecycle;Z)V", at = @At("RETURN")) private void replaceStorage(CallbackInfo ci) { this.lifecycles = new LifecycleMap<>(); /* From fa4d659c5bdb3f6cb8a45c9644adc6520a646717 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 11 Aug 2023 19:52:40 -0400 Subject: [PATCH 30/51] Update testmod mixin --- .../modernfix/testmod/mixin/DebugLevelSourceMixin.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) 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 d3e3dc0a..46f52d31 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 @@ -1,8 +1,6 @@ package org.embeddedt.modernfix.testmod.mixin; import net.minecraft.core.BlockPos; -import net.minecraft.core.HolderSet; -import net.minecraft.core.Registry; import net.minecraft.core.SectionPos; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.StructureManager; @@ -12,16 +10,13 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.FlatLevelSource; -import net.minecraft.world.level.levelgen.structure.StructureSet; import org.embeddedt.modernfix.testmod.TestMod; import org.spongepowered.asm.mixin.Mixin; -import java.util.Optional; - @Mixin(FlatLevelSource.class) public abstract class DebugLevelSourceMixin extends ChunkGenerator { - public DebugLevelSourceMixin(Registry registry, Optional> optional, BiomeSource biomeSource) { - super(registry, optional, biomeSource); + public DebugLevelSourceMixin(BiomeSource biomeSource) { + super(biomeSource); } @Override 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 31/51] 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 32/51] 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 33/51] 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 34/51] 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 35/51] 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 36/51] 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 2f92dbe12c6c793e71ce84eb623811b513de8add Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 12:13:31 -0400 Subject: [PATCH 37/51] Update mixin --- .../perf/rewrite_registry/ForgeRegistrySnapshotMixin.java | 5 ----- 1 file changed, 5 deletions(-) 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 b8dbf343..2412cbf0 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 @@ -1,7 +1,6 @@ package org.embeddedt.modernfix.forge.mixin.perf.rewrite_registry; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.registries.ForgeRegistry; import org.embeddedt.modernfix.annotation.IgnoreOutsideDev; @@ -14,15 +13,12 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Map; -import java.util.Set; @Mixin(ForgeRegistry.Snapshot.class) @IgnoreOutsideDev public class ForgeRegistrySnapshotMixin { @Shadow(remap = false) @Final @Mutable public Map ids; - @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 * anyway so order shouldn't matter. We replace the maps that will be most used. @@ -30,6 +26,5 @@ public class ForgeRegistrySnapshotMixin { @Inject(method = "", at = @At("RETURN")) private void replaceSnapshotMaps(CallbackInfo ci) { this.ids = new Object2ObjectOpenHashMap<>(); - this.dummied = new ObjectOpenHashSet<>(); } } From 97b6672610476b324072f31c0fac69f976fa5fd7 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 12 Aug 2023 16:47:48 -0400 Subject: [PATCH 38/51] Fix MC-251068 --- .../WorldSelectionListMixin.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java new file mode 100644 index 00000000..27f67f7a --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/bugfix/world_screen_skipped/WorldSelectionListMixin.java @@ -0,0 +1,22 @@ +package org.embeddedt.modernfix.common.mixin.bugfix.world_screen_skipped; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; +import net.minecraft.client.gui.screens.worldselection.WorldSelectionList; +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(WorldSelectionList.WorldListEntry.class) +public class WorldSelectionListMixin { + @Shadow @Final private Minecraft minecraft; + + @Inject(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldSelectionList$WorldListEntry;doDeleteWorld()V", ordinal = 0, shift = At.Shift.AFTER), cancellable = true) + private void preventClosingCreateScreenAfterDelete(CallbackInfo ci) { + if(minecraft.screen instanceof CreateWorldScreen) + ci.cancel(); + } +} 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 39/51] 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 40/51] 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 41/51] 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 0aef731a79a85aa9ec00b1733b6199c3c38f47a0 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 13 Aug 2023 13:41:36 -0400 Subject: [PATCH 42/51] Update SafeBlockGetter for 1.18 world height --- .../org/embeddedt/modernfix/chunk/SafeBlockGetter.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java b/common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java index 3671e8fe..3d4efe52 100644 --- a/common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java +++ b/common/src/main/java/org/embeddedt/modernfix/chunk/SafeBlockGetter.java @@ -47,6 +47,16 @@ public class SafeBlockGetter implements BlockGetter { return this.wrapped.getMaxLightLevel(); } + @Override + public int getMinBuildHeight() { + return this.wrapped.getMinBuildHeight(); + } + + @Override + public int getHeight() { + return this.wrapped.getHeight(); + } + @Nullable @Override public BlockEntity getBlockEntity(BlockPos pos) { 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 43/51] 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 47a04c66f10a8f37a32f46bada45fe5ead969d49 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 13 Aug 2023 16:34:23 -0400 Subject: [PATCH 44/51] Fix chunk future chain not being bypassed during entity load Backport of https://github.com/neoforged/NeoForge/pull/99 --- .../chunk_deadlock/ChunkMapLoadMixin.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/chunk_deadlock/ChunkMapLoadMixin.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/chunk_deadlock/ChunkMapLoadMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/chunk_deadlock/ChunkMapLoadMixin.java new file mode 100644 index 00000000..cfed9788 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/chunk_deadlock/ChunkMapLoadMixin.java @@ -0,0 +1,56 @@ +package org.embeddedt.modernfix.forge.mixin.bugfix.chunk_deadlock; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; +import org.embeddedt.modernfix.ModernFix; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +import java.lang.reflect.Field; + +@Mixin(ChunkMap.class) +public abstract class ChunkMapLoadMixin { + @Shadow @Nullable protected abstract ChunkHolder getVisibleChunkIfPresent(long l); + + private static final Field currentlyLoadingField = ObfuscationReflectionHelper.findField(ChunkHolder.class, "currentlyLoading"); + + private static void setCurrentlyLoading(ChunkHolder holder, LevelChunk value) { + try { + currentlyLoadingField.set(holder, value); + } catch(ReflectiveOperationException e) { + e.printStackTrace(); + } + } + + /** + * Set currentlyLoading before calling runPostLoad and restore its old value afterwards. We track the old value + * to avoid conflicting with Forge if/when this feature is added. + */ + @WrapOperation(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/chunk/LevelChunk;runPostLoad()V")) + private void setCurrentLoadingThenPostLoad(LevelChunk chunk, Operation operation) { + ChunkHolder holder = this.getVisibleChunkIfPresent(chunk.getPos().toLong()); + if(holder != null) { + LevelChunk prevLoading = null; + try { + prevLoading = (LevelChunk)currentlyLoadingField.get(holder); + } catch(ReflectiveOperationException e) { + e.printStackTrace(); + } + try { + setCurrentlyLoading(holder, chunk); + operation.call(chunk); + } finally { + setCurrentlyLoading(holder, prevLoading); + } + } else { + ModernFix.LOGGER.warn("Unable to find chunk holder for loading chunk"); + operation.call(chunk); + } + } +} 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 45/51] 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 46/51] 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 47/51] 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 ed0460747cd64b8d1047d6bdbabc00551ae0541a Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 13:08:42 -0400 Subject: [PATCH 48/51] Update world leak patch to 1.18 --- .../common/mixin/bugfix/world_leaks/MinecraftMixin.java | 2 +- common/src/main/resources/modernfix.accesswidener | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) 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 index d3708ff8..e4f0fa57 100644 --- 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 @@ -32,7 +32,7 @@ public class MinecraftMixin { } this.level.getChunkSource().lightEngine = new LevelLightEngine(this.level.getChunkSource(), false, false); // clear BE list otherwise they will hold chunks - this.level.blockEntityList.clear(); + this.level.blockEntityTickers.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 e0e15597..db75195f 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -6,6 +6,8 @@ mutable field net/minecraft/client/multiplayer/ClientChunkCache lightEngine Lnet accessible class net/minecraft/client/multiplayer/ClientChunkCache$Storage accessible field net/minecraft/client/multiplayer/ClientChunkCache$Storage chunks Ljava/util/concurrent/atomic/AtomicReferenceArray; +accessible field net/minecraft/world/level/Level blockEntityTickers Ljava/util/List; + accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType accessible method net/minecraft/nbt/CompoundTag (Ljava/util/Map;)V From a06fca791a68e1cb2a810d440be1b9555fbd4a53 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 21:18:39 -0400 Subject: [PATCH 49/51] Fix Forge experimental world suppression not working on first reopen --- .../CreateWorldScreenMixin.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java new file mode 100644 index 00000000..a8696b54 --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java @@ -0,0 +1,24 @@ +package org.embeddedt.modernfix.forge.mixin.bugfix.extra_experimental_screen; + +import com.mojang.serialization.Lifecycle; +import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; +import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.level.storage.WorldData; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(CreateWorldScreen.class) +public class CreateWorldScreenMixin { + /** + * Fix experimental world dialog still being shown the first time you reopen a world that was created + * as experimental. + */ + @ModifyArg(method = "createNewWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldOpenFlows;createLevelFromExistingSettings(Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lnet/minecraft/server/ReloadableServerResources;Lnet/minecraft/core/RegistryAccess$Frozen;Lnet/minecraft/world/level/storage/WorldData;)V"), index = 3) + private WorldData setExperimentalFlag(WorldData data) { + if(data instanceof PrimaryLevelData pld && data.worldGenSettingsLifecycle() != Lifecycle.stable()) { + pld.withConfirmedWarning(true); + } + return data; + } +} From 9325a8c89251d22ca49b6ae3254c4a42c12e9fb1 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 15 Aug 2023 21:21:10 -0400 Subject: [PATCH 50/51] Update mixin target --- .../extra_experimental_screen/CreateWorldScreenMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java index a8696b54..f83a8e11 100644 --- a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/extra_experimental_screen/CreateWorldScreenMixin.java @@ -14,7 +14,7 @@ public class CreateWorldScreenMixin { * Fix experimental world dialog still being shown the first time you reopen a world that was created * as experimental. */ - @ModifyArg(method = "createNewWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldOpenFlows;createLevelFromExistingSettings(Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lnet/minecraft/server/ReloadableServerResources;Lnet/minecraft/core/RegistryAccess$Frozen;Lnet/minecraft/world/level/storage/WorldData;)V"), index = 3) + @ModifyArg(method = "createNewWorld", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldOpenFlows;createLevelFromExistingSettings(Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lnet/minecraft/server/ReloadableServerResources;Lnet/minecraft/core/LayeredRegistryAccess;Lnet/minecraft/world/level/storage/WorldData;)V"), index = 3) private WorldData setExperimentalFlag(WorldData data) { if(data instanceof PrimaryLevelData pld && data.worldGenSettingsLifecycle() != Lifecycle.stable()) { pld.withConfirmedWarning(true); 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 51/51] 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]);