├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md ├── dependabot.yml └── workflows │ ├── build.yml │ └── experiment.yml ├── .gitignore ├── LICENSE ├── PatchAPI.sh ├── PatchServer.sh ├── README.md ├── build-data └── dev-imports.txt ├── build.gradle.kts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── logo.png ├── patches ├── api │ └── 0001-Fusion-Configuration.patch └── server │ ├── 0001-Fusion-Rebrand.patch │ ├── 0002-Fusion-Configuration.patch │ ├── 0003-Fusion-Logo.patch │ ├── 0004-MC-DEV-FIX.patch │ ├── 0005-Fusion-OptimizeDefaultConfiguration.patch │ ├── 0006-Fusion-NoChatReportsConfiguration.patch │ ├── 0007-NoChatReports-Implementation.patch │ ├── 0008-Fusion-LithiumConfiguration.patch │ ├── 0009-Lithium-Math-FastUtil.patch │ ├── 0010-Lithium-HashedReferenceList.patch │ ├── 0011-Lithium-Collections-BlockEntityTickers.patch │ ├── 0012-Lithium-CompactSineLUT.patch │ ├── 0013-Lithium-Math-SineLUT.patch │ ├── 0014-Lithium-Entity-FastRetrieval.patch │ ├── 0015-Lithium-Collections-EntityAIGoals.patch │ ├── 0016-Lithium-CachedHashCode.patch │ ├── 0017-Lithium-Collections-GameRules.patch │ ├── 0018-Lithium-Shapes-PrecomputeShapeArrays.patch │ ├── 0019-Lithium-Entity-FastElytraCheck.patch │ ├── 0020-Lithium-Entity-FastHandSwing.patch │ ├── 0021-Lithium-Entity-FastPowderSnowCheck.patch │ ├── 0022-Lithium-Collections-Attributes.patch │ ├── 0023-Lithium-Collections-EntityByType.patch │ ├── 0024-Lithium-Collections-EntityFiltering.patch │ ├── 0025-Lithium-HashPalette.patch │ ├── 0026-Lithium-Chunk-Serialization.patch │ ├── 0027-Lithium-AI-Raid.patch │ ├── 0028-Lithium-Block-MovingBlockShapes.patch │ ├── 0029-Lithium-Object2BooleanCacheTable.patch │ ├── 0030-Lithium-Shapes-BlockStateCache.patch │ ├── 0031-Lithium-Pos.patch │ ├── 0032-Lithium-Gen-ChunkRegion.patch │ ├── 0033-Lithium-AI-Sensor-SecondaryPoi.patch │ ├── 0034-Lithium-Entity-Collisions-Suffocation.patch │ ├── 0035-Lithium-OrderedTickQueue.patch │ ├── 0036-Lithium-World-TickScheduler.patch │ ├── 0037-Lithium-Collections-Brain.patch │ ├── 0038-Lithium-AI-Task-MemoryChangeCounting.patch │ ├── 0039-Lithium-Range6Int.patch │ ├── 0040-Lithium-PositionedEntityTrackingSection.patch │ ├── 0041-Lithium-Util-EntitySectionPosition.patch │ ├── 0042-Lithium-NearbyEntityTracker.patch │ ├── 0043-Lithium-AI-NearbyEntityTracking.patch │ ├── 0044-Lithium-AI-NearbyEntityTracking-Goals.patch │ ├── 0045-Fusion-C2MEConfiguration.patch │ ├── 0046-C2ME-Opts-Math.patch │ ├── 0047-C2ME-ObjectCachingUtils.patch │ ├── 0048-C2ME-SimpleObjectPool.patch │ ├── 0049-C2ME-PooledFeatureContext.patch │ ├── 0050-C2ME-Opts-Allocs.patch │ ├── 0051-Fusion-VMPConfiguration.patch │ ├── 0052-VMP-Entity-MoveZeroVelocity.patch │ ├── 0053-VMP-General-SpawnDensityCap.patch │ ├── 0054-VMP-Entity-Tracker.patch │ ├── 0055-VMP-General-Ingredient-Matching.patch │ ├── 0056-Fusion-SmoothBootConfiguration.patch │ └── 0057-SmoothBoot-Implementation.patch ├── scripts ├── Clear.bat ├── ClearCache.bat ├── CommitAPI.sh ├── CommitServer.sh ├── CreateAPIFixupPatch.bat ├── CreateServerFixupPatch.bat ├── FixFileNameLengthProblem.sh ├── RemoveAPIDir.bat ├── RemoveServerDir.bat └── UpstreamCommit.sh └── settings.gradle.kts /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Do '...' 17 | 3. See error 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots** 23 | If applicable, add screenshots to help explain your problem. 24 | 25 | **Info (please complete the following information):** 26 | - Releasr: [e.g. 152] 27 | - Version: [e.g. 1.19.2] 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | target-branch: "*" 6 | schedule: 7 | interval: "daily" 8 | - package-ecosystem: "gradle" 9 | directory: "/" 10 | target-branch: "*" 11 | schedule: 12 | interval: "daily" -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build Fusion 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - "ver/1.19.3" 7 | 8 | env: 9 | version: '1.19.3' 10 | branch: ver/1.19.3 11 | debug: 'false' 12 | 13 | jobs: 14 | release: 15 | strategy: 16 | matrix: 17 | jdk: ['17'] 18 | java: ['Java'] 19 | os: ['ubuntu-latest'] 20 | 21 | if: "!startsWith(github.event.commits[0].message, '[CI-Skip]')" 22 | runs-on: ${{ matrix.os }} 23 | steps: 24 | - name: Checkout action 25 | uses: actions/checkout@main 26 | 27 | - name: Validate Gradle Wrapper 28 | uses: gradle/wrapper-validation-action@main 29 | 30 | - name: Set up JDK ${{ matrix.java }} ${{ matrix.jdk }} 31 | uses: graalvm/setup-graalvm@v1 32 | with: 33 | java-version: ${{ matrix.jdk }} 34 | github-token: ${{ secrets.GH_PAT }} 35 | version: 'latest' 36 | cache: 'gradle' 37 | 38 | - name: Configure Git 39 | run: | 40 | git config --global user.email "no-reply@github.com" && git config --global user.name "Github Actions" 41 | echo "workflow=$GITHUB_RUN_NUMBER" >> $GITHUB_ENV 42 | chmod +x gradlew 43 | 44 | - name: Apply Patches 45 | run: | 46 | ./gradlew -Dorg.gradle.jvmargs="-Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true --add-modules jdk.incubator.vector" applyPatches --stacktrace 47 | 48 | - name: Create Reobf Jar 49 | run: ./gradlew -Dorg.gradle.jvmargs="-Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true --add-modules jdk.incubator.vector" createReobfPaperclipJar --stacktrace 50 | 51 | - name: Create Mojmap Jar 52 | run: ./gradlew -Dorg.gradle.jvmargs="-Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true --add-modules jdk.incubator.vector" createMojmapPaperclipJar --stacktrace 53 | 54 | - name: Upload Artifacts 55 | if: env.debug == 'true' 56 | uses: actions/upload-artifact@main 57 | with: 58 | name: Artifacts 59 | path: build/libs 60 | 61 | - name: Release Artifacts 62 | if: github.ref_name == env.branch 63 | uses: marvinpinto/action-automatic-releases@latest 64 | with: 65 | title: "Build #${{ env.workflow }}" 66 | automatic_release_tag: build-${{ env.workflow }} 67 | repo_token: "${{ secrets.GH_PAT }}" 68 | files: build/libs/*.jar 69 | prerelease: false 70 | 71 | - name: Release Artifacts (Latest) 72 | if: github.ref_name == env.branch 73 | uses: marvinpinto/action-automatic-releases@latest 74 | with: 75 | title: "Build #${{ env.workflow }}" 76 | automatic_release_tag: latest-${{ env.version }} 77 | repo_token: "${{ secrets.GH_PAT }}" 78 | files: build/libs/Fusion-paperclip-1.19.3-R0.1-SNAPSHOT-reobf.jar 79 | prerelease: false 80 | -------------------------------------------------------------------------------- /.github/workflows/experiment.yml: -------------------------------------------------------------------------------- 1 | name: Build Fusion (Experimemt Ver) 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - "ver/1.19.3-Rework" 7 | 8 | env: 9 | version: '1.19.3' 10 | branch: ver/1.19.3-Rework 11 | debug: 'false' 12 | 13 | jobs: 14 | release: 15 | strategy: 16 | matrix: 17 | jdk: ['17'] 18 | java: ['Java'] 19 | os: ['ubuntu-latest'] 20 | 21 | if: "!startsWith(github.event.commits[0].message, '[CI-Skip]')" 22 | runs-on: ${{ matrix.os }} 23 | steps: 24 | - name: Checkout action 25 | uses: actions/checkout@main 26 | 27 | - name: Validate Gradle Wrapper 28 | uses: gradle/wrapper-validation-action@main 29 | 30 | - name: Set up JDK ${{ matrix.java }} ${{ matrix.jdk }} 31 | uses: graalvm/setup-graalvm@v1 32 | with: 33 | java-version: ${{ matrix.jdk }} 34 | github-token: ${{ secrets.GITHUB_TOKEN }} 35 | version: 'latest' 36 | cache: 'gradle' 37 | 38 | - name: Configure Git 39 | run: | 40 | git config --global user.email "no-reply@github.com" && git config --global user.name "Github Actions" 41 | echo "workflow=$GITHUB_RUN_NUMBER" >> $GITHUB_ENV 42 | chmod +x gradlew 43 | 44 | - name: Apply Patches 45 | run: | 46 | ./gradlew -Dorg.gradle.jvmargs="-Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true --add-modules jdk.incubator.vector" applyPatches --stacktrace 47 | 48 | - name: Build 49 | run: ./gradlew -Dorg.gradle.jvmargs="-Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true --add-modules jdk.incubator.vector" build --stacktrace 50 | 51 | - name: Create Reobf Jar 52 | run: ./gradlew -Dorg.gradle.jvmargs="-Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true --add-modules jdk.incubator.vector" createReobfPaperclipJar --stacktrace 53 | 54 | - name: Create Mojmap Jar 55 | run: ./gradlew -Dorg.gradle.jvmargs="-Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true --add-modules jdk.incubator.vector" createMojmapPaperclipJar --stacktrace 56 | 57 | - name: Upload Artifacts 58 | if: env.debug == 'true' 59 | uses: actions/upload-artifact@main 60 | with: 61 | name: Artifacts 62 | path: build/libs 63 | 64 | - name: Release Artifacts 65 | if: github.ref_name == env.branch 66 | uses: marvinpinto/action-automatic-releases@latest 67 | with: 68 | title: "Experiment #${{ env.workflow }}" 69 | automatic_release_tag: experiment-${{ env.workflow }} 70 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 71 | files: build/libs/*.jar 72 | prerelease: false 73 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | # User-specific stuff 4 | .idea/ 5 | 6 | *.iml 7 | *.ipr 8 | *.iws 9 | 10 | # IntelliJ 11 | out/ 12 | # mpeltonen/sbt-idea plugin 13 | .idea_modules/ 14 | 15 | # JIRA plugin 16 | atlassian-ide-plugin.xml 17 | 18 | # Compiled class file 19 | *.class 20 | 21 | # Log file 22 | *.log 23 | 24 | # BlueJ files 25 | *.ctxt 26 | 27 | # Package Files # 28 | *.jar 29 | *.war 30 | *.nar 31 | *.ear 32 | *.zip 33 | *.tar.gz 34 | *.rar 35 | 36 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 37 | hs_err_pid* 38 | 39 | *~ 40 | 41 | # temporary files which can be created if a process still has a handle open of a deleted file 42 | .fuse_hidden* 43 | 44 | # KDE directory preferences 45 | .directory 46 | 47 | # Linux trash folder which might appear on any partition or disk 48 | .Trash-* 49 | 50 | # .nfs files are created when an open file is removed but is still being accessed 51 | .nfs* 52 | 53 | # General 54 | .DS_Store 55 | .AppleDouble 56 | .LSOverride 57 | 58 | # Icon must end with two \r 59 | Icon 60 | 61 | # Thumbnails 62 | ._* 63 | 64 | # Files that might appear in the root of a volume 65 | .DocumentRevisions-V100 66 | .fseventsd 67 | .Spotlight-V100 68 | .TemporaryItems 69 | .Trashes 70 | .VolumeIcon.icns 71 | .com.apple.timemachine.donotpresent 72 | 73 | # Directories potentially created on remote AFP share 74 | .AppleDB 75 | .AppleDesktop 76 | Network Trash Folder 77 | Temporary Items 78 | .apdisk 79 | 80 | # Windows thumbnail cache files 81 | Thumbs.db 82 | Thumbs.db:encryptable 83 | ehthumbs.db 84 | ehthumbs_vista.db 85 | 86 | # Dump file 87 | *.stackdump 88 | 89 | # Folder config file 90 | [Dd]esktop.ini 91 | 92 | # Recycle Bin used on file shares 93 | $RECYCLE.BIN/ 94 | 95 | # Windows Installer files 96 | *.cab 97 | *.msi 98 | *.msix 99 | *.msm 100 | *.msp 101 | 102 | # Windows shortcuts 103 | *.lnk 104 | 105 | .gradle 106 | build/ 107 | 108 | # Ignore Gradle GUI config 109 | gradle-app.setting 110 | 111 | # Cache of project 112 | .gradletasknamecache 113 | 114 | **/build/ 115 | 116 | # Common working directory 117 | run/ 118 | 119 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 120 | !gradle-wrapper.jar 121 | 122 | Fusion-API 123 | Fusion-Server -------------------------------------------------------------------------------- /PatchAPI.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # PatchAPI 4 | 5 | PS1="$" 6 | 7 | cd Fusion-API 8 | 9 | git add . 10 | git commit --allow-empty -m $1 11 | 12 | cd ../ 13 | 14 | ./gradlew rebuildAPIPatches -------------------------------------------------------------------------------- /PatchServer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # PatchServer 4 | 5 | PS1="$" 6 | 7 | cd Fusion-Server 8 | 9 | git add . 10 | git commit -m $1 11 | 12 | cd ../ 13 | 14 | ./gradlew rebuildServerPatches -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ![title](https://user-images.githubusercontent.com/80433772/193827393-d3b38086-1a0e-4ca9-9313-e5272fa8c554.png) 4 | 5 |

A Crazy Minecraft Server Software Fusing Amazing Bukkits

6 | 7 | 8 | [![License](https://img.shields.io/github/license/ipecter/Fusion?style=for-the-badge&logo=github)](LICENSE) 9 | [![Build Status](https://img.shields.io/github/actions/workflow/status/ipecter/Fusion/build.yml?branch=ver%2F1.19.3&logo=GoogleAnalytics&style=for-the-badge&logoColor=ffffff)](https://github.com/IPECTER/Fusion/actions) 10 | [![Discord](https://img.shields.io/discord/894887872765771796?color=%235865F2&label=Discord&logo=discord&style=for-the-badge&logoColor=ffffff)](https://discord.gg/WnC2wFa6Uq) 11 | [![MC Version](https://img.shields.io/badge/MC-1.19.3-6047ff?&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAW9yTlQBz6J3mgAAAAFzUkdCAK7OHOkAAAm2SURBVFjDrZd7qOXXVcc/+/F7nHN+53HPvXdmMq8ktaNUWp9UxVZBkIKooShV22goxcFimxDER00h1YoaUPtHTbUhta3VUobSplBrrFRLKlEaJ4/CJJPJzJ3M3Mk87z3nnsfvuX/74R9niGCwNZL97957rc9ee63F+gpe5Xr8xY/Q1f3kpeXWOxtX31N7e0GK5I9+87G/ePrffuGzvOnQna/Knvi/HvyXrb/kJ48cF194/gNv1pL3x1LdsWyroQueWMZnlrb5pBTppwuzd+PuH/lbhBCvDcCjL3yCSfkfBNG/NfjquPHtXZUzR9aSjEhqlFAoIZib0jfe/3uqun/9QxtvemTRLqu33P5b3xFAfrvNLzz7ASKxM1hY3rvXTB5pvLnPeH+kDZ65KbDeUTuDC55h3JV9Hb91EEUPn947/Zmz8+2fCGFbnr32d68+Al858wD9eENfXJx6WyLD3TOz+KnaNckg6qJlRGUNtWtwISCFpKNi1pKMjkqYm5LCNmykw2tKqM81jr/aLU6eO7b5bn76u37t2wN8/Onf513iT/ki936fwL7PBfsOQVjTUhAJSWUNbXB0VPzyndIZtNBY51g2FYcG67jgWbYFa3FGLONTqY4fLpz8+0iE6du/94FXAhRNxT+f+x0iNb6lcfl7dqq99wghXmecRQiIpUYAQgiMMygh6UUpWihmpmQt6bMwBYu2QglJrDTWO/anQyIVs1vPbeP8Y70o+9iR7PavVDY3d7zhQyuAh564F4LWOip/2Yb6bi3EmwvbSBc8EOhHXUII5Lamp1MSqWmDZRz3kVIzrRd4PAJBdRPOh4ASkq6OmTY5jW/ZSAb0dLpogv/yYun/bHxAf+vO1z+Ivjq/QiDsU4r7VeS/uxfHKKFx3jGIO4QANjgEMDc5qUrwIWD9HBsCqdRkUYfGtURC4YKn8ZaOijG+JVGKYdzlQHeNuraD/3zy3J1bW3vX9h/rfAtAu+AAZFHVEXXARJ61Xo9+3KMfdeiohNxWuJDjgmczHWCDZ25KnHe0QrBTL0iUZhCn1M6SifRl8FHcg6A4d3bG409s8cL560hk9MTzlwDQI9dHp5rJdEK+zDH7NZeKGeujHvFAk6oY5z0ShRaeSbMgUREdFaMjxdyUJEoTS4ULgfWkj7gJFRBcurrg6acuc2FrjrEOKo+/Uoc4aVYA2587j5CeVkQk+zKywx0KU3P97JTpqOC2gxt0OpraNSQqQQDWB3paEd90nKgI7z1aKPZMgcezt6w4d3rKuef2WC4NZq9BRAIxsSSFQF6sVgBHOxkieOZ1YH5DsP3Vy6g3prSnCtzBmlo7Dq+P0DrgpENLhRSSSbMk0x0QghACxltiIqqm5bnnrrN1ZsZ8aunGXYadhNmZgmpZoQzEvR6RUisA5z1KSnAFaV0wNprprqUMjrhVVBcrrgVFp6PQsmFz2KebxOioS0cnaCGZtQUueC5dmPPMM1d44YUdrHFkgx5BesoLC1ThGcqUkMLGeEjdlHBpgn7dwTFJpLl4BV7amXP0wIhwaU418bRXS1wM+nDGsJOxu1hw/toO+wZDDo5GlK6hpxOaheebT17ixTMziq0ckSlU6WhNxV6VQ94lFglStmilCCEwynqrCFy8NkNKgTUtsZZcnSywjeNI3KcoG6bO0NwoqWzM5i1DXtqdcP7qLjvTkkPrfU5v73D6uR12d0uUF5A7Qu1wtcNODWJu0bGHSKAjjZQS07ZUzc0kFFLc7HCOrBOzPuiyK8Z4U1LPLyLqwOJrU+qjJfveuInYquGgZ7lRcmprydmTC4ITKKGQAaSFMLNoAd4HRsM+WbdDWTc473HOEwKU9U2ARV7jQyCSgTYEXAhspi03qoY4UkgpafZaXFtz5dqcTmmhDAQtaXcNdtKgcoltLALIooRaB5z3dLspvW6HONYUVYUxlhACaZrgnV8BaCWxziMFWOd5fnuH9UFBJ4kY9FL2r2VUB1ou7yyY24S01yHZnjG7MsfbQJhrzMQxSiTGWpSSKKU4sDmmqOqV41YTRRH9LCM30NqGtHszB8bD7qqP1xV52TDqpQQf2JkVhBAoasP6oMd40OWWSHJlmtPLOjS7FuFBzwydbkwvkQjbozUVUeSpGkMIAa0UbWsZ9LsIHdM2jjovmO7NVgPJdF4yW5bsLSoWec0wSzl2ZAMlBDf2ChZ5w3RZYpxj/3qfA2s9nPOsDVL2jTJ0sJiqIC8b0AlxHGOtY2++xDqHEALrHNPZkrrMyWTNof3rDLN0BeB8wFiH85441jStYy+vufXAiB88dgv7xxkSSGPN1cmSvDJEkaLfTVgfdolvZnavmxL7HJzBOY8UAq0Uo0FGEkc0TYu1jm4nQSvJwX3j1RdsrmUAoqo0jWnJy4YAHFzv40MgSWLyusVZz6Ku8T4QgFE/xdgVtNYaKQV50ZCXFWkSI6TGi4iyqrHWkaYx3U5CY1pAiJerII41WknXmqa9tihJ4wjvPNemOeMsxcuYeDzi1nXP2Uu7DLqrF2zfmBOkomlaqqYlLys6aUI3Tch6KbWPaIyjMavy8z5QNwZrHbWxxtTl6gvS3pDxxr4bXqjfPri59vVjRzZcGmuuT5YUTQuuIVQLducl1nvKpmU87NFNY1rr0FoDkCYxo0HGeNTHuYCtc0yxB0Cvk66iIsQsIB50nk/WrfvvkSyEwFMP3cOiCft2JtNfuj6dv3/76vR7lJR0Ek1ZG4QQJJFmUTYc2FxDDA+ye/lFnj6/g/OBONJEkUZJiRBQlDVKKVprsc61Wbf7j2maPDgab37DNI35zCP/9Mqh9NGHP8xdx+/nzz/4rjdcvjb99TrdvMtMXto4up5iWs+yatidF4yHPUj6bF++zoVJsZoXxKqjhhAIYWVvPBpQNc1TxvoHx2trjyzzfPboN07+77rgZ47fzw5QRhunb/v+t/xu/9Dr3zEc9D6f9dIm68a0zhNrTZZEHM4Cw46mbS3OenwINKZlWdQYEoKQl533fzAcDH+xyWef+uEf/fFXOP+Oyujh3/sVhIwzb/Kfm83zexrT/lgIQYz7HcaDLlf3Cv7hyYuYdlVeSkry2uadjdtOJHb20M+/7a0nnz1zIXz0Uyf+/9Ls1GNf4qEHPsTR224/VOTLX+3E8jdC8Lf30phJYXj8+evUpqWfdV0Sx//auvDRwYFjX3OmqE988UuvnTj9mz+8h8N3fJjLJ977A3VVHp/Ni3dO8mbt1OU5URyfWhsOPu48J4xpdj//1cdfO3H6P9cn7ns34/EoPvnkMz97aXd577wV54JQH/ny17/57Mf+5IO8774/flX2/gtnEWFB1FDO/wAAAABJRU5ErkJggg==&style=for-the-badge&logoColor=ffffff)](https://discord.gg/WnC2wFa6Uq) 12 | [![Download](https://img.shields.io/github/downloads/IPECTER/Fusion/total?&style=for-the-badge&logoColor=ffffff)](https://github.com/IPECTER/Fusion/releases/tag/latest-1.19.3) 13 |
14 | 15 | ## 🌠 We're moving! 16 | Fusion was moved to [PlazmaMC/Plazma](https://github.com/PlazmaMC/PlazmaBukkit)! 17 | I think Fusion dev is too crazy! 18 | 19 | ## About Fusion... 20 | - Fusion began as a small personal project. 21 | - I'm always trying to keep it compatible and performance high. 22 | - Fusion takes only compatible and effective patches from amazing bukkits. 23 | - **❗But Fusion may have many problems❗** 24 | 25 | ## Features 26 | - Fork of [Purpur](https://github.com/PurpurMC/Purpur) 27 | - [Features Details](https://github.com/IPECTER/Fusion/wiki/Features-Details) 28 | - **Upstream & Patched [Bukkits](https://github.com/IPECTER/Fusion/wiki/Author-and-License-of-Upstream-&-Patches#bukkits) / [Mods](https://github.com/IPECTER/Fusion/wiki/Author-and-License-of-Upstream-&-Patches#mods) / [Extensions](https://github.com/IPECTER/Fusion/wiki/Author-and-License-of-Upstream-&-Patches#extensions)** 29 | - Anyway It is Crazy 30 | 31 | ## License 32 | - This project will be granted license following [GPL-3.0](LICENSE). 33 | - [Author and License of Patches](https://github.com/IPECTER/Fusion/wiki/Author-and-License-of-Patches) 34 | 35 | ## bStats 36 | [![](https://bstats.org/signatures/server-implementation/Fusion.svg)](https://bstats.org/plugin/server-implementation/Fusion/16924) 37 | -------------------------------------------------------------------------------- /build-data/dev-imports.txt: -------------------------------------------------------------------------------- 1 | minecraft net.minecraft.world.level.entity.EntitySectionStorage.java 2 | minecraft net.minecraft.world.phys.shapes.CubeVoxelShape.java 3 | minecraft net.minecraft.world.phys.shapes.CubePointRange.java 4 | minecraft net.minecraft.world.level.chunk.PaletteResize.java 5 | minecraft net.minecraft.util.ClassInstanceMultiMap.java 6 | minecraft net.minecraft.world.entity.MobCategory.java 7 | minecraft net.minecraft.world.level.levelgen.synth.ImprovedNoise.java 8 | minecraft net.minecraft.world.level.levelgen.synth.PerlinNoise.java 9 | minecraft net.minecraft.world.level.levelgen.feature.ConfiguredFeature.java 10 | minecraft net.minecraft.world.level.levelgen.feature.OreFeature.java 11 | minecraft net.minecraft.util.Mth.java 12 | minecraft net.minecraft.world.entity.ai.Brain.java 13 | minecraft net.minecraft.network.protocol.status.ServerStatus.java 14 | minecraft net.minecraft.network.protocol.game.ServerboundChatPacket.java 15 | minecraft net.minecraft.network.protocol.game.ServerboundChatSessionUpdatePacket.java 16 | minecraft net.minecraft.world.level.levelgen.material.MaterialRuleList.java 17 | minecraft net.minecraft.world.level.levelgen.feature.ConfiguredFeature.java 18 | minecraft net.minecraft.world.level.levelgen.SurfaceRules.java 19 | minecraft net.minecraft.resources.ResourceLocation.java 20 | minecraft net.minecraft.nbt.CompoundTag.java 21 | minecraft net.minecraft.nbt.ListTag.java 22 | minecraft net.minecraft.Util.java 23 | minecraft net.minecraft.world.level.LocalMobCapCalculator.java 24 | minecraft net.minecraft.server.commands.SeedCommand.java -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | import io.papermc.paperweight.util.constants.PAPERCLIP_CONFIG 2 | import io.papermc.paperweight.util.* 3 | import java.nio.charset.StandardCharsets 4 | 5 | plugins { 6 | java 7 | id("com.github.johnrengelman.shadow") version "8.1.0" apply false 8 | id("io.papermc.paperweight.patcher") version "1.5.3" 9 | } 10 | 11 | repositories { 12 | mavenCentral() 13 | maven("https://papermc.io/repo/repository/maven-public/") { 14 | content { onlyForConfigurations(PAPERCLIP_CONFIG) } 15 | } 16 | } 17 | 18 | dependencies { 19 | remapper("net.fabricmc:tiny-remapper:0.8.6:fat") 20 | decompiler("net.minecraftforge:forgeflower:2.0.627.2") 21 | paperclip("io.papermc:paperclip:3.0.2") 22 | } 23 | 24 | subprojects { 25 | 26 | tasks.withType { 27 | minHeapSize = "2g" 28 | maxHeapSize = "2g" 29 | } 30 | 31 | apply(plugin = "java") 32 | 33 | java { 34 | toolchain { 35 | languageVersion.set(JavaLanguageVersion.of(17)) 36 | } 37 | } 38 | 39 | tasks.withType().configureEach { 40 | options.encoding = StandardCharsets.UTF_8.name() 41 | options.release.set(17) 42 | } 43 | 44 | 45 | tasks.withType { 46 | options.encoding = Charsets.UTF_8.name() 47 | } 48 | 49 | tasks.withType { 50 | filteringCharset = Charsets.UTF_8.name() 51 | } 52 | 53 | repositories { 54 | mavenLocal() 55 | mavenCentral() 56 | maven("https://oss.sonatype.org/content/groups/public/") 57 | maven("https://papermc.io/repo/repository/maven-public/") 58 | maven("https://ci.emc.gs/nexus/content/groups/aikar/") 59 | maven("https://repo.aikar.co/content/groups/aikar") 60 | maven("https://repo.md-5.net/content/repositories/releases/") 61 | maven("https://hub.spigotmc.org/nexus/content/groups/public/") 62 | maven("https://jitpack.io") 63 | } 64 | } 65 | 66 | paperweight { 67 | serverProject.set(project(":Fusion-Server")) 68 | 69 | remapRepo.set("https://maven.fabricmc.net/") 70 | decompileRepo.set("https://files.minecraftforge.net/maven/") 71 | 72 | useStandardUpstream("purpur") { 73 | url.set(github("PurpurMC", "Purpur")) 74 | ref.set(providers.gradleProperty("purpurRef")) 75 | 76 | withStandardPatcher { 77 | apiSourceDirPath.set("Purpur-API") 78 | serverSourceDirPath.set("Purpur-Server") 79 | 80 | apiPatchDir.set(layout.projectDirectory.dir("patches/api")) 81 | serverPatchDir.set(layout.projectDirectory.dir("patches/server")) 82 | 83 | apiOutputDir.set(layout.projectDirectory.dir("Fusion-API")) 84 | serverOutputDir.set(layout.projectDirectory.dir("Fusion-Server")) 85 | } 86 | } 87 | } 88 | 89 | tasks.register("purpurRefLatest") { 90 | // Update the purpurRef in gradle.properties to be the latest commit. 91 | val tempDir = layout.cacheDir("purpurRefLatest"); 92 | val file = "gradle.properties"; 93 | 94 | doFirst { 95 | data class GithubCommit( 96 | val sha: String 97 | ) 98 | 99 | val purpurLatestCommitJson = layout.cache.resolve("purpurLatestCommit.json"); 100 | download.get().download("https://api.github.com/repos/PurpurMC/Purpur/commits/ver/1.19.3", purpurLatestCommitJson); 101 | val purpurLatestCommit = gson.fromJson(purpurLatestCommitJson)["sha"].asString; 102 | 103 | copy { 104 | from(file) 105 | into(tempDir) 106 | filter { line: String -> 107 | line.replace("purpurRef = .*".toRegex(), "purpurRef = $purpurLatestCommit") 108 | } 109 | } 110 | } 111 | 112 | doLast { 113 | copy { 114 | from(tempDir.file("gradle.properties")) 115 | into(project.file(file).parent) 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.caching = true 2 | org.gradle.parallel = true 3 | org.gradle.vfs.watch = false 4 | org.gradle.daemon=true 5 | org.gradle.jvmargs = -Xmx4G -Dfile.encoding=UTF-8 -Dgraal.CompilerConfiguration=community -Dgraal.UsePriorityInlining=true -Dgraal.Vectorization=true -Dgraal.OptDuplication=true -Dgraal.SpeculativeGuardMovement=true -Dgraal.WriteableCodeCache=true 6 | 7 | group = com.github.ipecter.fusion 8 | version = 1.19.3-R0.1-SNAPSHOT 9 | mcVersion = 1.19.3 10 | 11 | purpurRef = 67066cdd463e6e2d02dd26ec9418178d074abd41 12 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RTUStudio/Fusion/8990f858a55e9c4c44f2204842ff08b65b1931c9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionSha256Sum=ff7bf6a86f09b9b2c40bb8f48b25fc19cf2b2664fd1d220cd7ab833ec758d0d7 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip 5 | networkTimeout=10000 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 147 | # shellcheck disable=SC3045 148 | MAX_FD=$( ulimit -H -n ) || 149 | warn "Could not query maximum file descriptor limit" 150 | esac 151 | case $MAX_FD in #( 152 | '' | soft) :;; #( 153 | *) 154 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 155 | # shellcheck disable=SC3045 156 | ulimit -n "$MAX_FD" || 157 | warn "Could not set maximum file descriptor limit to $MAX_FD" 158 | esac 159 | fi 160 | 161 | # Collect all arguments for the java command, stacking in reverse order: 162 | # * args from the command line 163 | # * the main class name 164 | # * -classpath 165 | # * -D...appname settings 166 | # * --module-path (only if needed) 167 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 168 | 169 | # For Cygwin or MSYS, switch paths to Windows format before running java 170 | if "$cygwin" || "$msys" ; then 171 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 172 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 173 | 174 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 175 | 176 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 177 | for arg do 178 | if 179 | case $arg in #( 180 | -*) false ;; # don't mess with options #( 181 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 182 | [ -e "$t" ] ;; #( 183 | *) false ;; 184 | esac 185 | then 186 | arg=$( cygpath --path --ignore --mixed "$arg" ) 187 | fi 188 | # Roll the args list around exactly as many times as the number of 189 | # args, so each arg winds up back in the position where it started, but 190 | # possibly modified. 191 | # 192 | # NB: a `for` loop captures its iteration list before it begins, so 193 | # changing the positional parameters here affects neither the number of 194 | # iterations, nor the values presented in `arg`. 195 | shift # remove old arg 196 | set -- "$@" "$arg" # push replacement arg 197 | done 198 | fi 199 | 200 | # Collect all arguments for the java command; 201 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 202 | # shell script including quotes and variable substitutions, so put them in 203 | # double quotes to make sure that they get re-expanded; and 204 | # * put everything else in single quotes, so that it's not re-expanded. 205 | 206 | set -- \ 207 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 208 | -classpath "$CLASSPATH" \ 209 | org.gradle.wrapper.GradleWrapperMain \ 210 | "$@" 211 | 212 | # Stop when "xargs" is not available. 213 | if ! command -v xargs >/dev/null 2>&1 214 | then 215 | die "xargs is not available" 216 | fi 217 | 218 | # Use "xargs" to parse quoted args. 219 | # 220 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 221 | # 222 | # In Bash we could simply go: 223 | # 224 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 225 | # set -- "${ARGS[@]}" "$@" 226 | # 227 | # but POSIX shell has neither arrays nor command substitution, so instead we 228 | # post-process each arg (as a line of input to sed) to backslash-escape any 229 | # character that might be a shell metacharacter, then use eval to reverse 230 | # that process (while maintaining the separation between arguments), and wrap 231 | # the whole thing up as a single "set" statement. 232 | # 233 | # This will of course break if any of these variables contains a newline or 234 | # an unmatched quote. 235 | # 236 | 237 | eval "set -- $( 238 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 239 | xargs -n1 | 240 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 241 | tr '\n' ' ' 242 | )" '"$@"' 243 | 244 | exec "$JAVACMD" "$@" -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RTUStudio/Fusion/8990f858a55e9c4c44f2204842ff08b65b1931c9/logo.png -------------------------------------------------------------------------------- /patches/api/0001-Fusion-Configuration.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Tue, 4 Oct 2022 20:04:31 +0900 4 | Subject: [PATCH] Fusion-Configuration 5 | 6 | 7 | diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java 8 | index e0f69edf603c2ec99bc92b16b18912272cc41bd9..ee6123a277d88e2368921a83ce697bd85340020e 100644 9 | --- a/src/main/java/org/bukkit/Server.java 10 | +++ b/src/main/java/org/bukkit/Server.java 11 | @@ -1983,6 +1983,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi 12 | } 13 | // Purpur end 14 | 15 | + // Fusion start 16 | + @NotNull 17 | + public org.bukkit.configuration.file.YamlConfiguration getFusionConfig() { 18 | + throw new UnsupportedOperationException("Not supported yet."); 19 | + } 20 | + // Fusion end 21 | + 22 | /** 23 | * Sends the component to the player 24 | * 25 | -------------------------------------------------------------------------------- /patches/server/0006-Fusion-NoChatReportsConfiguration.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 2 Jan 2023 02:48:35 +0900 4 | Subject: [PATCH] Fusion-NoChatReportsConfiguration 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 8 | index 62a83e77c6539b1e5bd4c9ade3350326b9a8398d..7d09004e666aaabc70edc04c4f9f442601fc9207 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | @@ -203,4 +203,14 @@ public class FusionConfig { 12 | } 13 | return builder.build(); 14 | } 15 | + 16 | + public static boolean noChatReportsEnable = true; 17 | + 18 | + private static void noChatReportsConfig() { 19 | + setComment("no-chat-reports", "[ No Chat Reports ] Player Chat Reporting Control Mod"); 20 | + noChatReportsEnable = getBoolean("no-chat-reports.enable", noChatReportsEnable); 21 | + } 22 | + 23 | + private static void noChatReportsConfigSetup() { 24 | + } 25 | } 26 | \ No newline at end of file 27 | -------------------------------------------------------------------------------- /patches/server/0007-NoChatReports-Implementation.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 2 Jan 2023 04:30:45 +0900 4 | Subject: [PATCH] NoChatReports-Implementation 5 | 6 | No Chat Reports - Aizistral Studios - WTFPL 7 | Prismarine - PrismarineTeam - MIT 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index 7d09004e666aaabc70edc04c4f9f442601fc9207..4b83507afdccf4850bc282290b7927ba232a690b 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -205,10 +205,14 @@ public class FusionConfig { 15 | } 16 | 17 | public static boolean noChatReportsEnable = true; 18 | + public static boolean noChatReportsConvertToGameMessage = true; 19 | + public static boolean noChatReportsAddQueryData = true; 20 | 21 | private static void noChatReportsConfig() { 22 | setComment("no-chat-reports", "[ No Chat Reports ] Player Chat Reporting Control Mod"); 23 | noChatReportsEnable = getBoolean("no-chat-reports.enable", noChatReportsEnable); 24 | + noChatReportsConvertToGameMessage = getBoolean("no-chat-reports.convert-to-game-message", noChatReportsConvertToGameMessage) && noChatReportsEnable; 25 | + noChatReportsAddQueryData = getBoolean("no-chat-reports.add-query-data", noChatReportsAddQueryData) && noChatReportsEnable; 26 | } 27 | 28 | private static void noChatReportsConfigSetup() { 29 | diff --git a/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java b/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java 30 | index 6e0a3086da142f1c42007a16bbec7edbab17da04..46409ef273bc8d2c2b20ed76b4cd91b6d2446d66 100644 31 | --- a/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java 32 | +++ b/src/main/java/net/minecraft/network/protocol/status/ServerStatus.java 33 | @@ -28,6 +28,14 @@ public class ServerStatus { 34 | private String favicon; 35 | private boolean enforcesSecureChat; 36 | 37 | + // Fusion start - NoChatReports 38 | + /** 39 | + * Special additional variable that allows the client to know whether server prevents chat reports 40 | + * upon pinging it. 41 | + */ 42 | + private boolean preventsChatReports; 43 | + // Fusion end 44 | + 45 | @Nullable 46 | public Component getDescription() { 47 | return this.description; 48 | @@ -68,9 +76,29 @@ public class ServerStatus { 49 | this.enforcesSecureChat = secureChatEnforced; 50 | } 51 | 52 | + // Fusion start - NoChatReports 53 | + /** 54 | + * @reason Spoof the value of "enforcesSecureChat" in case conversion to system messages is enabled. 55 | + * There is no way for client to verify the value of the option in such case, so that's one less 56 | + * annoying warning. 57 | + * @author Aizistral 58 | + */ 59 | public boolean enforcesSecureChat() { 60 | - return this.enforcesSecureChat; 61 | + return com.github.ipecter.fusion.FusionConfig.noChatReportsConvertToGameMessage ? true : this.enforcesSecureChat; 62 | + } 63 | + 64 | + public boolean preventsChatReports() { 65 | + if (this.getVersion() != null && this.getVersion().getProtocol() < 759 66 | + && this.getVersion().getProtocol() > 0) 67 | + return true; 68 | + 69 | + return this.preventsChatReports; 70 | + } 71 | + 72 | + public void setPreventsChatReports(boolean prevents) { 73 | + this.preventsChatReports = prevents; 74 | } 75 | + // Fusion end 76 | 77 | public static class Players { 78 | private final int maxPlayers; 79 | @@ -173,6 +201,12 @@ public class ServerStatus { 80 | serverStatus.setEnforcesSecureChat(GsonHelper.getAsBoolean(jsonObject, "enforcesSecureChat")); 81 | } 82 | 83 | + // Fusion start - NoChatReports 84 | + if (jsonObject.has("preventsChatReports")) { 85 | + serverStatus.setPreventsChatReports(GsonHelper.getAsBoolean(jsonObject, "preventsChatReports")); 86 | + } 87 | + // Fusiobn end 88 | + 89 | return serverStatus; 90 | } 91 | 92 | @@ -196,6 +230,12 @@ public class ServerStatus { 93 | jsonObject.addProperty("favicon", serverStatus.getFavicon()); 94 | } 95 | 96 | + // Fusion start - NoChatReports 97 | + if (com.github.ipecter.fusion.FusionConfig.noChatReportsAddQueryData) { 98 | + jsonObject.addProperty("preventsChatReports", true); 99 | + } 100 | + // Fusion end 101 | + 102 | return jsonObject; 103 | } 104 | } 105 | diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java 106 | index 4675524988ea2ef346726677f9767382f1e154ab..1a706fbd5b58049d31d7350a2eb500f92a31c743 100644 107 | --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java 108 | +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java 109 | @@ -679,9 +679,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface 110 | return this.getProperties().networkCompressionThreshold; 111 | } 112 | 113 | + // Fusion start - NoChatReports 114 | + /** 115 | + * @reason If mod is installed on server (If NoChatReports is enabled - IPECTER/Fusion) - it does the exact opposite of what this option is 116 | + * designed to enforce, so there's no reason to have it enabled. 117 | + * @author Aizistral 118 | + */ 119 | @Override 120 | public boolean enforceSecureProfile() { 121 | - return this.getProperties().enforceSecureProfile && this.getProperties().onlineMode; 122 | + return com.github.ipecter.fusion.FusionConfig.noChatReportsEnable ? false : this.getProperties().enforceSecureProfile && this.getProperties().onlineMode; 123 | } 124 | 125 | protected boolean convertOldUsers() { 126 | diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java 127 | index a8e205af936efe0909c94575e3b7f8ca50cead2f..118a1acdd79e21a4337376da3bba6d0b255177ee 100644 128 | --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java 129 | +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java 130 | @@ -2229,12 +2229,35 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic 131 | } 132 | } 133 | 134 | + // Fusion start - NoChatReports 135 | + /** 136 | + * @reason Convert player message to system message if mod is configured respectively. 137 | + * This allows to circumvent signature check on client, as it only checks player messages. 138 | + * @author JFronny (original implementation) 139 | + * @author Aizistral 140 | + */ 141 | @Override 142 | public void send(Packet packet) { 143 | + if (com.github.ipecter.fusion.FusionConfig.noChatReportsConvertToGameMessage) { 144 | + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { 145 | + packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(chat.chatType().resolve(this.player.level.registryAccess()).get().decorate(chat.unsignedContent() != null ? chat.unsignedContent() 146 | + : Component.literal(chat.body().content())), false); 147 | + } 148 | + } 149 | this.send(packet, (PacketSendListener) null); 150 | } 151 | 152 | + /** 153 | + * @reason Ensure conversion works regardless of which send method is used. 154 | + * @author Aizistral 155 | + */ 156 | public void send(Packet packet, @Nullable PacketSendListener callbacks) { 157 | + if (com.github.ipecter.fusion.FusionConfig.noChatReportsConvertToGameMessage) { 158 | + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat && callbacks != null) { 159 | + this.send(chat); 160 | + return; 161 | + } 162 | + } 163 | // CraftBukkit start 164 | if (packet == null || this.processedDisconnect) { // Spigot 165 | return; 166 | @@ -2256,6 +2279,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic 167 | throw new ReportedException(crashreport); 168 | } 169 | } 170 | + // Fusion end 171 | 172 | @Override 173 | public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) { 174 | diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java 175 | index c34c5368e336ba4b181a95932a9b40cb4f50ae1d..ccc34617a5aba443426d383f07249b09dd188639 100644 176 | --- a/src/main/java/net/minecraft/server/players/PlayerList.java 177 | +++ b/src/main/java/net/minecraft/server/players/PlayerList.java 178 | @@ -1447,9 +1447,15 @@ public abstract class PlayerList { 179 | 180 | } 181 | 182 | + // Fusion start - NoChatReports 183 | + /** 184 | + * @reason Remove "Not Secure" mark in server chat logs. 185 | + * @author Aizistral 186 | + */ 187 | public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public 188 | - return message.hasSignature() && !message.hasExpiredServer(Instant.now()); 189 | + return com.github.ipecter.fusion.FusionConfig.noChatReportsEnable ? true : message.hasSignature() && !message.hasExpiredServer(Instant.now()); 190 | } 191 | + // Fusion end 192 | 193 | // CraftBukkit start 194 | public ServerStatsCounter getPlayerStats(ServerPlayer entityhuman) { 195 | -------------------------------------------------------------------------------- /patches/server/0008-Fusion-LithiumConfiguration.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Thu, 20 Oct 2022 18:30:51 +0900 4 | Subject: [PATCH] Fusion-LithiumConfiguration 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 8 | index 4b83507afdccf4850bc282290b7927ba232a690b..9ad27576afacba774f07991ac2c31f1f53da70f7 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | @@ -217,4 +217,14 @@ public class FusionConfig { 12 | 13 | private static void noChatReportsConfigSetup() { 14 | } 15 | + 16 | + public static boolean lithiumEnable = true; 17 | + 18 | + private static void lithiumConfig() { 19 | + setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 20 | + lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 21 | + } 22 | + 23 | + private static void lithiumConfigSetup() { 24 | + } 25 | } 26 | \ No newline at end of file 27 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 28 | index fde38b20fae3050f18f11a5098ad482aff0587c1..5d7f7008c42b3976ce57f704861788f39bd329ad 100644 29 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 30 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 31 | @@ -129,4 +129,13 @@ public class FusionWorldConfig { 32 | final Map value = getMap("world-settings." + worldName + "." + path, null); 33 | return value.isEmpty() ? fallback : value; 34 | } 35 | + 36 | + public boolean lithiumEnable = true; 37 | + 38 | + private void lithiumConfig() { 39 | + lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 40 | + } 41 | + 42 | + private void lithiumConfigSetup() { 43 | + } 44 | } 45 | \ No newline at end of file 46 | -------------------------------------------------------------------------------- /patches/server/0009-Lithium-Math-FastUtil.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 14:01:23 +0900 4 | Subject: [PATCH] Lithium-Math-FastUtil 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index 9ad27576afacba774f07991ac2c31f1f53da70f7..b6e759df57b6ab9392765546e0443dde9e12d4bc 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -219,10 +219,12 @@ public class FusionConfig { 15 | } 16 | 17 | public static boolean lithiumEnable = true; 18 | + public static boolean lithiumMathFastUtil = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 23 | + lithiumMathFastUtil = getBoolean("lithium.math.fast-util", lithiumMathFastUtil) && lithiumEnable; 24 | } 25 | 26 | private static void lithiumConfigSetup() { 27 | diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java 28 | index a4dc96b1a3bf309584657e3a1e7dfaea967f9425..16bbaae64a7be30842f6e488dd1eb6d0e5b3d3d1 100644 29 | --- a/src/main/java/net/minecraft/core/Direction.java 30 | +++ b/src/main/java/net/minecraft/core/Direction.java 31 | @@ -191,7 +191,7 @@ public enum Direction implements StringRepresentable { 32 | } 33 | 34 | public Direction getOpposite() { 35 | - return from3DDataValue(this.oppositeIndex); 36 | + return com.github.ipecter.fusion.FusionConfig.lithiumMathFastUtil ? VALUES[this.oppositeIndex] : from3DDataValue(this.oppositeIndex); // Fusion - Lithium: Math FastUtil 37 | } 38 | 39 | public Direction getClockWise(Direction.Axis axis) { 40 | @@ -453,7 +453,7 @@ public enum Direction implements StringRepresentable { 41 | } 42 | 43 | public static Direction getRandom(RandomSource random) { 44 | - return Util.getRandom(VALUES, random); 45 | + return com.github.ipecter.fusion.FusionConfig.lithiumMathFastUtil ? VALUES[random.nextInt(VALUES.length)] : Util.getRandom(VALUES, random); // Fusion - Lithium: Math FastUtil 46 | } 47 | 48 | public static Direction getNearest(double x, double y, double z) { 49 | diff --git a/src/main/java/net/minecraft/world/phys/AABB.java b/src/main/java/net/minecraft/world/phys/AABB.java 50 | index cfb2e46b34b2982d6724f18214557fc80cf4adfa..da5f1a3225744d2bcfb1c43067d98eb6ebbe28e8 100644 51 | --- a/src/main/java/net/minecraft/world/phys/AABB.java 52 | +++ b/src/main/java/net/minecraft/world/phys/AABB.java 53 | @@ -16,6 +16,17 @@ public class AABB { 54 | public final double maxY; 55 | public final double maxZ; 56 | 57 | + // Fusion start - Lithium: Math FastUtil 58 | + static { 59 | + if (com.github.ipecter.fusion.FusionConfig.lithiumMathFastUtil) { 60 | + assert Direction.Axis.X.ordinal() == 0; 61 | + assert Direction.Axis.Y.ordinal() == 1; 62 | + assert Direction.Axis.Z.ordinal() == 2; 63 | + assert Direction.Axis.values().length == 3; 64 | + } 65 | + } 66 | + // Fusion end 67 | + 68 | public AABB(double x1, double y1, double z1, double x2, double y2, double z2) { 69 | this.minX = Math.min(x1, x2); 70 | this.minY = Math.min(y1, y2); 71 | @@ -81,11 +92,39 @@ public class AABB { 72 | } 73 | 74 | public double min(Direction.Axis axis) { 75 | - return axis.choose(this.minX, this.minY, this.minZ); 76 | + // Fusion start - Lithium: Math FastUtil 77 | + if (com.github.ipecter.fusion.FusionConfig.lithiumMathFastUtil){ 78 | + switch (axis.ordinal()) { 79 | + case 0: //X 80 | + return this.minX; 81 | + case 1: //Y 82 | + return this.minY; 83 | + case 2: //Z 84 | + return this.minZ; 85 | + } 86 | + throw new IllegalArgumentException(); 87 | + } else{ 88 | + return axis.choose(this.minX, this.minY, this.minZ); 89 | + } 90 | + // Fusion end 91 | } 92 | 93 | public double max(Direction.Axis axis) { 94 | - return axis.choose(this.maxX, this.maxY, this.maxZ); 95 | + // Fusion start - Lithium: Math FastUtil 96 | + if (com.github.ipecter.fusion.FusionConfig.lithiumMathFastUtil){ 97 | + switch (axis.ordinal()) { 98 | + case 0: //X 99 | + return this.maxX; 100 | + case 1: //Y 101 | + return this.maxY; 102 | + case 2: //Z 103 | + return this.maxZ; 104 | + } 105 | + throw new IllegalArgumentException(); 106 | + } else{ 107 | + return axis.choose(this.maxX, this.maxY, this.maxZ); 108 | + } 109 | + // Fusion end 110 | } 111 | 112 | @Override 113 | -------------------------------------------------------------------------------- /patches/server/0010-Lithium-HashedReferenceList.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 17 Oct 2022 21:12:21 +0900 4 | Subject: [PATCH] Lithium-HashedReferenceList 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java 10 | new file mode 100644 11 | index 0000000000000000000000000000000000000000..cf5dc984fcd5eedbda06752819e5c2fcecdf9770 12 | --- /dev/null 13 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java 14 | @@ -0,0 +1,282 @@ 15 | +package me.jellysquid.mods.lithium.common.util.collections; 16 | + 17 | +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; 18 | +import it.unimi.dsi.fastutil.objects.ReferenceArrayList; 19 | +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; 20 | +import org.jetbrains.annotations.NotNull; 21 | + 22 | +import java.util.*; 23 | + 24 | +/** 25 | + * + * Wraps a {@link List} with a hash table which provides O(1) lookups for {@link Collection#contains(Object)}. The type 26 | + * + * contained by this list must use reference-equality semantics. 27 | + * + 28 | + */ 29 | +@SuppressWarnings("SuspiciousMethodCalls") 30 | +public class HashedReferenceList implements List { 31 | + private final ReferenceArrayList list; 32 | + private final Reference2IntOpenHashMap counter; 33 | + 34 | + public HashedReferenceList(List list) { 35 | + this.list = new ReferenceArrayList<>(); 36 | + this.list.addAll(list); 37 | + 38 | + this.counter = new Reference2IntOpenHashMap<>(); 39 | + this.counter.defaultReturnValue(0); 40 | + 41 | + for (T obj : this.list) { 42 | + this.counter.addTo(obj, 1); 43 | + } 44 | + } 45 | + 46 | + @Override 47 | + public int size() { 48 | + return this.list.size(); 49 | + } 50 | + 51 | + @Override 52 | + public boolean isEmpty() { 53 | + return this.list.isEmpty(); 54 | + } 55 | + 56 | + @Override 57 | + public boolean contains(Object o) { 58 | + return this.counter.containsKey(o); 59 | + } 60 | + 61 | + @Override 62 | + public Iterator iterator() { 63 | + return this.listIterator(); 64 | + } 65 | + 66 | + @Override 67 | + public Object[] toArray() { 68 | + return this.list.toArray(); 69 | + } 70 | + 71 | + @SuppressWarnings("SuspiciousToArrayCall") 72 | + @Override 73 | + public T1[] toArray(T1 @NotNull [] a) { 74 | + return this.list.toArray(a); 75 | + } 76 | + 77 | + @Override 78 | + public boolean add(T t) { 79 | + this.trackReferenceAdded(t); 80 | + 81 | + return this.list.add(t); 82 | + } 83 | + 84 | + @Override 85 | + public boolean remove(Object o) { 86 | + this.trackReferenceRemoved(o); 87 | + 88 | + return this.list.remove(o); 89 | + } 90 | + 91 | + @Override 92 | + public boolean containsAll(Collection c) { 93 | + for (Object obj : c) { 94 | + if (!this.counter.containsKey(obj)) { 95 | + return false; 96 | + } 97 | + } 98 | + 99 | + return true; 100 | + } 101 | + 102 | + @Override 103 | + public boolean addAll(Collection c) { 104 | + for (T obj : c) { 105 | + this.trackReferenceAdded(obj); 106 | + } 107 | + 108 | + return this.list.addAll(c); 109 | + } 110 | + 111 | + @Override 112 | + public boolean addAll(int index, Collection c) { 113 | + for (T obj : c) { 114 | + this.trackReferenceAdded(obj); 115 | + } 116 | + 117 | + return this.list.addAll(index, c); 118 | + } 119 | + 120 | + @Override 121 | + public boolean removeAll(@NotNull Collection c) { 122 | + if (this.size() >= 2 && c.size() > 4 && c instanceof List) { 123 | + //HashReferenceList uses reference equality, so using ReferenceOpenHashSet is fine 124 | + c = new ReferenceOpenHashSet<>(c); 125 | + } 126 | + this.counter.keySet().removeAll(c); 127 | + return this.list.removeAll(c); 128 | + } 129 | + 130 | + @Override 131 | + public boolean retainAll(@NotNull Collection c) { 132 | + this.counter.keySet().retainAll(c); 133 | + return this.list.retainAll(c); 134 | + } 135 | + 136 | + @Override 137 | + public void clear() { 138 | + this.counter.clear(); 139 | + this.list.clear(); 140 | + } 141 | + 142 | + @Override 143 | + public T get(int index) { 144 | + return this.list.get(index); 145 | + } 146 | + 147 | + @Override 148 | + public T set(int index, T element) { 149 | + T prev = this.list.set(index, element); 150 | + 151 | + if (prev != element) { 152 | + if (prev != null) { 153 | + this.trackReferenceRemoved(prev); 154 | + } 155 | + 156 | + this.trackReferenceAdded(element); 157 | + } 158 | + 159 | + return prev; 160 | + } 161 | + 162 | + @Override 163 | + public void add(int index, T element) { 164 | + this.trackReferenceAdded(element); 165 | + 166 | + this.list.add(index, element); 167 | + } 168 | + 169 | + @Override 170 | + public T remove(int index) { 171 | + T prev = this.list.remove(index); 172 | + 173 | + if (prev != null) { 174 | + this.trackReferenceRemoved(prev); 175 | + } 176 | + 177 | + return prev; 178 | + } 179 | + 180 | + @Override 181 | + public int indexOf(Object o) { 182 | + return this.list.indexOf(o); 183 | + } 184 | + 185 | + @Override 186 | + public int lastIndexOf(Object o) { 187 | + return this.list.lastIndexOf(o); 188 | + } 189 | + 190 | + @Override 191 | + public ListIterator listIterator() { 192 | + return this.listIterator(0); 193 | + } 194 | + 195 | + @Override 196 | + public ListIterator listIterator(int index) { 197 | + return new ListIterator<>() { 198 | + private final ListIterator inner = HashedReferenceList.this.list.listIterator(index); 199 | + 200 | + @Override 201 | + public boolean hasNext() { 202 | + return this.inner.hasNext(); 203 | + } 204 | + 205 | + @Override 206 | + public T next() { 207 | + return this.inner.next(); 208 | + } 209 | + 210 | + @Override 211 | + public boolean hasPrevious() { 212 | + return this.inner.hasPrevious(); 213 | + } 214 | + 215 | + @Override 216 | + public T previous() { 217 | + return this.inner.previous(); 218 | + } 219 | + 220 | + @Override 221 | + public int nextIndex() { 222 | + return this.inner.nextIndex(); 223 | + } 224 | + 225 | + @Override 226 | + public int previousIndex() { 227 | + return this.inner.previousIndex(); 228 | + } 229 | + 230 | + @Override 231 | + public void remove() { 232 | + int last = this.previousIndex(); 233 | + 234 | + if (last == -1) { 235 | + throw new NoSuchElementException(); 236 | + } 237 | + 238 | + T prev = HashedReferenceList.this.get(last); 239 | + 240 | + if (prev != null) { 241 | + HashedReferenceList.this.trackReferenceRemoved(prev); 242 | + } 243 | + 244 | + this.inner.remove(); 245 | + } 246 | + 247 | + @Override 248 | + public void set(T t) { 249 | + int last = this.previousIndex(); 250 | + 251 | + if (last == -1) { 252 | + throw new NoSuchElementException(); 253 | + } 254 | + 255 | + T prev = HashedReferenceList.this.get(last); 256 | + 257 | + if (prev != t) { 258 | + if (prev != null) { 259 | + HashedReferenceList.this.trackReferenceRemoved(prev); 260 | + } 261 | + 262 | + HashedReferenceList.this.trackReferenceAdded(t); 263 | + } 264 | + 265 | + this.inner.remove(); 266 | + } 267 | + 268 | + @Override 269 | + public void add(T t) { 270 | + HashedReferenceList.this.trackReferenceAdded(t); 271 | + 272 | + this.inner.add(t); 273 | + } 274 | + }; 275 | + } 276 | + 277 | + @Override 278 | + public List subList(int fromIndex, int toIndex) { 279 | + return this.list.subList(fromIndex, toIndex); 280 | + } 281 | + 282 | + private void trackReferenceAdded(T t) { 283 | + this.counter.addTo(t, 1); 284 | + } 285 | + 286 | + @SuppressWarnings("unchecked") 287 | + private void trackReferenceRemoved(Object o) { 288 | + if (this.counter.addTo((T) o, -1) <= 1) { 289 | + this.counter.removeInt(o); 290 | + } 291 | + } 292 | + 293 | + public static HashedReferenceList wrapper(List list) { 294 | + return new HashedReferenceList<>(list); 295 | + } 296 | +} 297 | \ No newline at end of file 298 | -------------------------------------------------------------------------------- /patches/server/0011-Lithium-Collections-BlockEntityTickers.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 14:35:07 +0900 4 | Subject: [PATCH] Lithium-Collections-BlockEntityTickers 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 11 | index 5d7f7008c42b3976ce57f704861788f39bd329ad..7c14500f529c9d9869a74f2dbe0a01c0594ecb3e 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 14 | @@ -131,9 +131,11 @@ public class FusionWorldConfig { 15 | } 16 | 17 | public boolean lithiumEnable = true; 18 | + public boolean lithiumCollectionsBlockEntityTickers = true; 19 | 20 | private void lithiumConfig() { 21 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 22 | + lithiumCollectionsBlockEntityTickers = getBoolean("lithium.collections.block-entity-tickers", lithiumCollectionsBlockEntityTickers) && lithiumEnable; 23 | } 24 | 25 | private void lithiumConfigSetup() { 26 | diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java 27 | index 76ad4079f4a6b1222b7f424ea37856efe4edadff..3b66cc5eb285f7de68ed1dc237ff96dff422ca67 100644 28 | --- a/src/main/java/net/minecraft/world/level/Level.java 29 | +++ b/src/main/java/net/minecraft/world/level/Level.java 30 | @@ -116,9 +116,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable { 31 | public static final int TICKS_PER_DAY = 24000; 32 | public static final int MAX_ENTITY_SPAWN_Y = 20000000; 33 | public static final int MIN_ENTITY_SPAWN_Y = -20000000; 34 | - protected final List blockEntityTickers = Lists.newArrayList(); public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper 35 | + protected final List blockEntityTickers; public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper // Fusion - Lithium: Collections BlockEntityTickers 36 | protected final NeighborUpdater neighborUpdater; 37 | - private final List pendingBlockEntityTickers = Lists.newArrayList(); 38 | + private final List pendingBlockEntityTickers; // Fusion - Lithium: Collections BlockEntityTickers 39 | private boolean tickingBlockEntities; 40 | public final Thread thread; 41 | private final boolean isDebug; 42 | @@ -336,6 +336,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable { 43 | this.generator = gen; 44 | this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); 45 | 46 | + // Fusion start - Lithium: Collections BlockEntityTickers 47 | + this.blockEntityTickers = this.fusionConfig.lithiumCollectionsBlockEntityTickers ? me.jellysquid.mods.lithium.common.util.collections.HashedReferenceList.wrapper(Lists.newArrayList()) : Lists.newArrayList(); 48 | + this.pendingBlockEntityTickers = this.fusionConfig.lithiumCollectionsBlockEntityTickers ? me.jellysquid.mods.lithium.common.util.collections.HashedReferenceList.wrapper(Lists.newArrayList()) : Lists.newArrayList(); 49 | + // Fusion end 50 | + 51 | // CraftBukkit Ticks things 52 | for (SpawnCategory spawnCategory : SpawnCategory.values()) { 53 | if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { 54 | -------------------------------------------------------------------------------- /patches/server/0012-Lithium-CompactSineLUT.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 17 Oct 2022 21:12:21 +0900 4 | Subject: [PATCH] Lithium-CompactSineLUT 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/math/CompactSineLUT.java b/src/main/java/me/jellysquid/mods/lithium/common/util/math/CompactSineLUT.java 10 | new file mode 100644 11 | index 0000000000000000000000000000000000000000..c8c85140d1ad0a647f25aa218a56f9e70a0a790b 12 | --- /dev/null 13 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/util/math/CompactSineLUT.java 14 | @@ -0,0 +1,90 @@ 15 | +package me.jellysquid.mods.lithium.common.util.math; 16 | + 17 | +import net.minecraft.util.Mth; 18 | + 19 | +/** 20 | + * A replacement for the sine angle lookup table used in {@link Mth}, both reducing the size of LUT and improving 21 | + * the access patterns for common paired sin/cos operations. 22 | + * 23 | + * sin(-x) = -sin(x) 24 | + * ... to eliminate negative angles from the LUT. 25 | + * 26 | + * sin(x) = sin(pi/2 - x) 27 | + * ... to eliminate supplementary angles from the LUT. 28 | + * 29 | + * Using these identities allows us to reduce the LUT from 64K entries (256 KB) to just 16K entries (64 KB), enabling 30 | + * it to better fit into the CPU's caches at the expense of some cycles on the fast path. The implementation has been 31 | + * tightly optimized to avoid branching where possible and to use very quick integer operations. 32 | + * 33 | + * Generally speaking, reducing the size of a lookup table is always a good optimization, but since we need to spend 34 | + * extra CPU cycles trying to maintain parity with vanilla, there is the potential risk that this implementation ends 35 | + * up being slower than vanilla when the lookup table is able to be kept in cache memory. 36 | + * 37 | + * Unlike other "fast math" implementations, the values returned by this class are *bit-for-bit identical* with those 38 | + * from {@link Mth}. Validation is performed during runtime to ensure that the table is correct. 39 | + * 40 | + * @author coderbot16 Author of the original (and very clever) implementation in Rust: 41 | + * https://gitlab.com/coderbot16/i73/-/tree/master/i73-trig/src 42 | + * @author jellysquid3 Additional optimizations, port to Java 43 | + */ 44 | +public class CompactSineLUT { 45 | + private static final int[] SINE_TABLE_INT = new int[16384 + 1]; 46 | + private static final float SINE_TABLE_MIDPOINT; 47 | + 48 | + static { 49 | + final float[] SINE_TABLE = Mth.getSinTable(); 50 | + // Copy the sine table, covering to raw int bits 51 | + for (int i = 0; i < SINE_TABLE_INT.length; i++) { 52 | + SINE_TABLE_INT[i] = Float.floatToRawIntBits(SINE_TABLE[i]); 53 | + } 54 | + 55 | + SINE_TABLE_MIDPOINT = SINE_TABLE[SINE_TABLE.length / 2]; 56 | + 57 | + // Test that the lookup table is correct during runtime 58 | + for (int i = 0; i < SINE_TABLE.length; i++) { 59 | + float expected = SINE_TABLE[i]; 60 | + float value = lookup(i); 61 | + 62 | + if (expected != value) { 63 | + throw new IllegalArgumentException(String.format("LUT error at index %d (expected: %s, found: %s)", i, expected, value)); 64 | + } 65 | + } 66 | + } 67 | + 68 | + // [VanillaCopy] MathHelper#sin(float) 69 | + public static float sin(float f) { 70 | + return lookup((int) (f * 10430.38) & 0xFFFF); 71 | + } 72 | + 73 | + // [VanillaCopy] MathHelper#cos(float) 74 | + public static float cos(float f) { 75 | + return lookup((int) (f * 10430.38 + 16384.0) & 0xFFFF); 76 | + } 77 | + 78 | + private static float lookup(int index) { 79 | + // A special case... Is there some way to eliminate this? 80 | + if (index == 32768) { 81 | + return SINE_TABLE_MIDPOINT; 82 | + } 83 | + 84 | + // Trigonometric identity: sin(-x) = -sin(x) 85 | + // Given a domain of 0 <= x <= 2*pi, just negate the value if x > pi. 86 | + // This allows the sin table size to be halved. 87 | + int neg = (index & 0x8000) << 16; 88 | + 89 | + // All bits set if (pi/2 <= x), none set otherwise 90 | + // Extracts the 15th bit from 'half' 91 | + int mask = (index << 17) >> 31; 92 | + 93 | + // Trigonometric identity: sin(x) = sin(pi/2 - x) 94 | + int pos = (0x8001 & mask) + (index ^ mask); 95 | + 96 | + // Wrap the position in the table. Moving this down to immediately before the array access 97 | + // seems to help the Hotspot compiler optimize the bit math better. 98 | + pos &= 0x7fff; 99 | + 100 | + // Fetch the corresponding value from the LUT and invert the sign bit as needed 101 | + // This directly manipulate the sign bit on the float bits to simplify logic 102 | + return Float.intBitsToFloat(SINE_TABLE_INT[pos] ^ neg); 103 | + } 104 | +} 105 | \ No newline at end of file 106 | -------------------------------------------------------------------------------- /patches/server/0013-Lithium-Math-SineLUT.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 14:45:21 +0900 4 | Subject: [PATCH] Lithium-Math-SineLUT 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index b6e759df57b6ab9392765546e0443dde9e12d4bc..70d9cae563e58549a8561bbb0d7a9dc0c3da3806 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -220,11 +220,13 @@ public class FusionConfig { 15 | 16 | public static boolean lithiumEnable = true; 17 | public static boolean lithiumMathFastUtil = true; 18 | + public static boolean lithiumMathSineLUT = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 23 | lithiumMathFastUtil = getBoolean("lithium.math.fast-util", lithiumMathFastUtil) && lithiumEnable; 24 | + lithiumMathSineLUT = getBoolean("lithium.math.sine-lut", lithiumMathSineLUT) && lithiumEnable; 25 | } 26 | 27 | private static void lithiumConfigSetup() { 28 | diff --git a/src/main/java/net/minecraft/util/Mth.java b/src/main/java/net/minecraft/util/Mth.java 29 | index 618f19d70a61062ed5989ec6cf0c036f2e047466..063d0e8b92f9b59ecc69353a758d553701520169 100644 30 | --- a/src/main/java/net/minecraft/util/Mth.java 31 | +++ b/src/main/java/net/minecraft/util/Mth.java 32 | @@ -32,6 +32,7 @@ public class Mth { 33 | 34 | }); 35 | private static final RandomSource RANDOM = RandomSource.createThreadSafe(); 36 | + public static float[] getSinTable() { return SIN; } // Fusion - Lithium: Math SineLUT 37 | private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; 38 | private static final double ONE_SIXTH = 0.16666666666666666D; 39 | private static final int FRAC_EXP = 8; 40 | @@ -46,11 +47,11 @@ public class Mth { 41 | } 42 | 43 | public static float sin(float value) { 44 | - return SIN[(int)(value * 10430.378F) & '\uffff']; 45 | + return com.github.ipecter.fusion.FusionConfig.lithiumMathSineLUT ? me.jellysquid.mods.lithium.common.util.math.CompactSineLUT.sin(value) : SIN[(int)(value * 10430.378F) & '\uffff']; // Fusion - Lithium: Math SineLUT 46 | } 47 | 48 | public static float cos(float value) { 49 | - return SIN[(int)(value * 10430.378F + 16384.0F) & '\uffff']; 50 | + return com.github.ipecter.fusion.FusionConfig.lithiumMathSineLUT ? me.jellysquid.mods.lithium.common.util.math.CompactSineLUT.cos(value) : SIN[(int)(value * 10430.378F + 16384.0F) & '\uffff']; // Fusion - Lithium: Math SineLUT 51 | } 52 | 53 | public static float sqrt(float value) { 54 | -------------------------------------------------------------------------------- /patches/server/0014-Lithium-Entity-FastRetrieval.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 15:52:42 +0900 4 | Subject: [PATCH] Lithium-Entity-FastRetrieval 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index 70d9cae563e58549a8561bbb0d7a9dc0c3da3806..8fdd30002696e968af8529bcb30e81364572332d 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -221,12 +221,14 @@ public class FusionConfig { 15 | public static boolean lithiumEnable = true; 16 | public static boolean lithiumMathFastUtil = true; 17 | public static boolean lithiumMathSineLUT = true; 18 | + public static boolean lithiumEntityFastRetrieval = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 23 | lithiumMathFastUtil = getBoolean("lithium.math.fast-util", lithiumMathFastUtil) && lithiumEnable; 24 | lithiumMathSineLUT = getBoolean("lithium.math.sine-lut", lithiumMathSineLUT) && lithiumEnable; 25 | + lithiumEntityFastRetrieval = getBoolean("lithium.entity.fast-retrieval", lithiumEntityFastRetrieval) && lithiumEnable; 26 | } 27 | 28 | private static void lithiumConfigSetup() { 29 | diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java 30 | index ee692b49c62f36287bf9d008861f5d47e0e42c00..6026a75057d1e2f49d9ee4075a204021c092da77 100644 31 | --- a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java 32 | +++ b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java 33 | @@ -32,8 +32,12 @@ public class EntitySectionStorage { 34 | this.intialSectionVisibility = chunkStatusDiscriminator; 35 | } 36 | 37 | + // Fusion start - Lithium: Entity FastRetrieval 38 | + /** 39 | + * @author 2No2Name 40 | + * @reason avoid iterating through LongAVLTreeSet, possibly iterating over hundreds of irrelevant longs to save up to 8 hash set gets 41 | + */ 42 | public void forEachAccessibleNonEmptySection(AABB box, AbortableIterationConsumer> consumer) { 43 | - int i = 2; 44 | int j = SectionPos.posToSectionCoord(box.minX - 2.0D); 45 | int k = SectionPos.posToSectionCoord(box.minY - 4.0D); 46 | int l = SectionPos.posToSectionCoord(box.minZ - 2.0D); 47 | @@ -41,6 +45,46 @@ public class EntitySectionStorage { 48 | int n = SectionPos.posToSectionCoord(box.maxY + 0.0D); 49 | int o = SectionPos.posToSectionCoord(box.maxZ + 2.0D); 50 | 51 | + if (com.github.ipecter.fusion.FusionConfig.lithiumEntityFastRetrieval) { 52 | + if (m >= j + 4 || o >= l + 4) { 53 | + // Vanilla is likely more optimized when shooting entities with TNT cannons over huge distances. 54 | + // Choosing a cutoff of 4 chunk size, as it becomes more likely that these entity sections do not exist when 55 | + // they are far away from the shot entity (player despawn range, position maybe not on the ground, etc) 56 | + 57 | + this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer); 58 | + return; 59 | + } else { 60 | + // Vanilla order of the AVL long set is sorting by ascending long value. The x, y, z positions are packed into 61 | + // a long with the x position's lowest 22 bits placed at the MSB. 62 | + // Therefore the long is negative iff the 22th bit of the x position is set, which happens iff the x position 63 | + // is negative. A positive x position will never have its 22th bit set, as these big coordinates are far outside 64 | + // the world. y and z positions are treated as unsigned when sorting by ascending long value, as their sign bits 65 | + // are placed somewhere inside the packed long 66 | + 67 | + for (int x = j; x <= m; x++) { 68 | + for (int z = Math.max(l, 0); z <= o; z++) { 69 | + if (this.forEachInColumn(x, k, n, z, consumer).shouldAbort()) { 70 | + this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer); 71 | + return; 72 | + } 73 | + } 74 | + 75 | + int bound = Math.min(-1, o); 76 | + for (int z = l; z <= bound; z++) { 77 | + if (this.forEachInColumn(x, k, n, z, consumer).shouldAbort()) { 78 | + this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer); 79 | + return; 80 | + } 81 | + } 82 | + } 83 | + } 84 | + } else { 85 | + this.forEachAccessibleNonEmptySectionVanilla(j, k, l, m, n, o, consumer); 86 | + return; 87 | + } 88 | + } 89 | + 90 | + private void forEachAccessibleNonEmptySectionVanilla(int j, int k, int l, int n, int m, int o, AbortableIterationConsumer> consumer) { 91 | for(int p = j; p <= m; ++p) { 92 | long q = SectionPos.asLong(p, 0, 0); 93 | long r = SectionPos.asLong(p, -1, -1); 94 | @@ -58,8 +102,33 @@ public class EntitySectionStorage { 95 | } 96 | } 97 | } 98 | + } 99 | + 100 | + private AbortableIterationConsumer.Continuation forEachInColumn(int x, int k, int n, int z, AbortableIterationConsumer> action) { 101 | + AbortableIterationConsumer.Continuation ret = AbortableIterationConsumer.Continuation.CONTINUE; 102 | + //y from negative to positive, but y is treated as unsigned 103 | + for (int y = Math.max(k, 0); y <= n; y++) { 104 | + if ((ret = this.consumeSection(SectionPos.asLong(x, y, z), action)).shouldAbort()) { 105 | + return ret; 106 | + } 107 | + } 108 | + int bound = Math.min(-1, n); 109 | + for (int y = k; y <= bound; y++) { 110 | + if ((ret = this.consumeSection(SectionPos.asLong(x, y, z), action)).shouldAbort()) { 111 | + return ret; 112 | + } 113 | + } 114 | + return ret; 115 | + } 116 | 117 | + private AbortableIterationConsumer.Continuation consumeSection(long pos, AbortableIterationConsumer> action) { 118 | + EntitySection entitySection = this.getSection(pos); 119 | + if (entitySection != null && 0 != entitySection.size() && entitySection.getStatus().isAccessible()) { 120 | + return action.accept(entitySection); 121 | + } 122 | + return AbortableIterationConsumer.Continuation.CONTINUE; 123 | } 124 | + // Fusion end 125 | 126 | public LongStream getExistingSectionPositionsInChunk(long chunkPos) { 127 | int i = ChunkPos.getX(chunkPos); 128 | -------------------------------------------------------------------------------- /patches/server/0015-Lithium-Collections-EntityAIGoals.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 16:01:17 +0900 4 | Subject: [PATCH] Lithium-Collections-EntityAIGoals 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index 8fdd30002696e968af8529bcb30e81364572332d..84f2eb31ec1c58dbc1f8894996db0748591e642c 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -222,6 +222,7 @@ public class FusionConfig { 15 | public static boolean lithiumMathFastUtil = true; 16 | public static boolean lithiumMathSineLUT = true; 17 | public static boolean lithiumEntityFastRetrieval = true; 18 | + public static boolean lithiumCollectionsGoals = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | @@ -229,6 +230,7 @@ public class FusionConfig { 23 | lithiumMathFastUtil = getBoolean("lithium.math.fast-util", lithiumMathFastUtil) && lithiumEnable; 24 | lithiumMathSineLUT = getBoolean("lithium.math.sine-lut", lithiumMathSineLUT) && lithiumEnable; 25 | lithiumEntityFastRetrieval = getBoolean("lithium.entity.fast-retrieval", lithiumEntityFastRetrieval) && lithiumEnable; 26 | + lithiumCollectionsGoals = getBoolean("lithium.collections.goals", lithiumCollectionsGoals) && lithiumEnable; 27 | } 28 | 29 | private static void lithiumConfigSetup() { 30 | diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java 31 | index 02978315bc2b828cc603ce7478408f3f82c249c2..0e6220ea6c4248e73cb00d24261bc948a866b52e 100644 32 | --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java 33 | +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java 34 | @@ -28,7 +28,7 @@ public class GoalSelector { 35 | } 36 | }; 37 | private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); 38 | - private final Set availableGoals = Sets.newLinkedHashSet(); 39 | + private final Set availableGoals; // Lithium - Collections EntityAIGoals 40 | private final Supplier profiler; 41 | private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be. 42 | private final com.destroystokyo.paper.util.set.OptimizedSmallEnumSet goalTypes = new com.destroystokyo.paper.util.set.OptimizedSmallEnumSet<>(Goal.Flag.class); // Paper - remove streams from pathfindergoalselector 43 | @@ -39,6 +39,7 @@ public class GoalSelector { 44 | 45 | public GoalSelector(Supplier profiler) { 46 | this.profiler = profiler; 47 | + availableGoals = com.github.ipecter.fusion.FusionConfig.lithiumCollectionsGoals ? new it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet<>() : Sets.newLinkedHashSet(); // Lithium - Collections EntityAIGoal - Replace the goal set with an optimized collection type which performs better for iteration. 48 | } 49 | 50 | public void addGoal(int priority, Goal goal) { 51 | -------------------------------------------------------------------------------- /patches/server/0016-Lithium-CachedHashCode.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 16:07:06 +0900 4 | Subject: [PATCH] Lithium-CachedHashCode 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java 10 | index 0c348b366623e350393f035d760adc6ee4142687..eb3d528889890fde4d8dcbe3399710c963a8a4cd 100644 11 | --- a/src/main/java/net/minecraft/world/level/block/Block.java 12 | +++ b/src/main/java/net/minecraft/world/level/block/Block.java 13 | @@ -667,11 +667,18 @@ public class Block extends BlockBehaviour implements ItemLike { 14 | private final BlockState first; 15 | private final BlockState second; 16 | private final Direction direction; 17 | + private final int hash; // Fusion - Lithium: CachedHashCode 18 | 19 | public BlockStatePairKey(BlockState self, BlockState other, Direction facing) { 20 | this.first = self; 21 | this.second = other; 22 | this.direction = facing; 23 | + // Fusion start - Lithium: CachedHashCode - Initialize the object's hashcode and cache it 24 | + int hash = this.first.hashCode(); 25 | + hash = 31 * hash + this.second.hashCode(); 26 | + hash = 31 * hash + this.direction.hashCode(); 27 | + this.hash = hash; 28 | + // Fusion end 29 | } 30 | 31 | public boolean equals(Object object) { 32 | @@ -686,12 +693,14 @@ public class Block extends BlockBehaviour implements ItemLike { 33 | } 34 | } 35 | 36 | + // Fusion start - Lithium: CachedHashCod 37 | + /** 38 | + * @reason Uses the cached hashcode 39 | + * @author JellySquid 40 | + */ 41 | public int hashCode() { 42 | - int i = this.first.hashCode(); 43 | - 44 | - i = 31 * i + this.second.hashCode(); 45 | - i = 31 * i + this.direction.hashCode(); 46 | - return i; 47 | + return this.hash; 48 | } 49 | + // Fusion end 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /patches/server/0017-Lithium-Collections-GameRules.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 16:13:55 +0900 4 | Subject: [PATCH] Lithium-Collections-GameRules 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index 84f2eb31ec1c58dbc1f8894996db0748591e642c..0b941224b23d114728fe2a9cc6f971c4e98e5032 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -223,6 +223,7 @@ public class FusionConfig { 15 | public static boolean lithiumMathSineLUT = true; 16 | public static boolean lithiumEntityFastRetrieval = true; 17 | public static boolean lithiumCollectionsGoals = true; 18 | + public static boolean lithiumCollectionsGameRules = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | @@ -231,6 +232,7 @@ public class FusionConfig { 23 | lithiumMathSineLUT = getBoolean("lithium.math.sine-lut", lithiumMathSineLUT) && lithiumEnable; 24 | lithiumEntityFastRetrieval = getBoolean("lithium.entity.fast-retrieval", lithiumEntityFastRetrieval) && lithiumEnable; 25 | lithiumCollectionsGoals = getBoolean("lithium.collections.goals", lithiumCollectionsGoals) && lithiumEnable; 26 | + lithiumCollectionsGameRules = getBoolean("lithium.collections.gamerules", lithiumCollectionsGameRules) && lithiumEnable; 27 | } 28 | 29 | private static void lithiumConfigSetup() { 30 | diff --git a/src/main/java/net/minecraft/world/level/GameRules.java b/src/main/java/net/minecraft/world/level/GameRules.java 31 | index c15e4d95baacd30f9614dc5526dc8fc12ae5bd06..94dcff30f7d7a7271032b0de701c25b9f2609d1b 100644 32 | --- a/src/main/java/net/minecraft/world/level/GameRules.java 33 | +++ b/src/main/java/net/minecraft/world/level/GameRules.java 34 | @@ -118,14 +118,17 @@ public class GameRules { 35 | 36 | public GameRules() { 37 | // Pufferfish start - use this to ensure gameruleArray is initialized 38 | - this((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> { 39 | - return ((GameRules.Type) entry.getValue()).createRule(); 40 | - }))); 41 | + // Fusion start - Lithium: Collections StoreGameRules 42 | + this(com.github.ipecter.fusion.FusionConfig.lithiumCollectionsGameRules ? 43 | + new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>((Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> ((Type) entry.getValue()).createRule()))) : 44 | + (Map) GameRules.GAME_RULE_TYPES.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry) -> ((Type) entry.getValue()).createRule())) 45 | + ); 46 | + // Fusion end 47 | // Pufferfish end 48 | } 49 | 50 | private GameRules(Map, GameRules.Value> rules) { 51 | - this.rules = rules; 52 | + this.rules = com.github.ipecter.fusion.FusionConfig.lithiumCollectionsGameRules ? new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(rules) : rules; // Fusion - Lithium: Collections StoreGameRules 53 | 54 | // Pufferfish start 55 | int arraySize = rules.keySet().stream().mapToInt(key -> key.gameRuleIndex).max().orElse(-1) + 1; 56 | -------------------------------------------------------------------------------- /patches/server/0018-Lithium-Shapes-PrecomputeShapeArrays.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 21 Dec 2022 16:26:01 +0900 4 | Subject: [PATCH] Lithium-Shapes-PrecomputeShapeArrays 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index 0b941224b23d114728fe2a9cc6f971c4e98e5032..58cf70e7a427a5a81f68b279d29d91c3c2a4397b 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -224,6 +224,7 @@ public class FusionConfig { 15 | public static boolean lithiumEntityFastRetrieval = true; 16 | public static boolean lithiumCollectionsGoals = true; 17 | public static boolean lithiumCollectionsGameRules = true; 18 | + public static boolean lithiumShapesPrecomputeShapeArrays = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | @@ -233,6 +234,7 @@ public class FusionConfig { 23 | lithiumEntityFastRetrieval = getBoolean("lithium.entity.fast-retrieval", lithiumEntityFastRetrieval) && lithiumEnable; 24 | lithiumCollectionsGoals = getBoolean("lithium.collections.goals", lithiumCollectionsGoals) && lithiumEnable; 25 | lithiumCollectionsGameRules = getBoolean("lithium.collections.gamerules", lithiumCollectionsGameRules) && lithiumEnable; 26 | + lithiumShapesPrecomputeShapeArrays = getBoolean("lithium.shapes.precompute-shape-arrays", lithiumShapesPrecomputeShapeArrays) && lithiumEnable; 27 | } 28 | 29 | private static void lithiumConfigSetup() { 30 | diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java 31 | index 16bbaae64a7be30842f6e488dd1eb6d0e5b3d3d1..abdb242b144677449076e323c95314456dd34dcd 100644 32 | --- a/src/main/java/net/minecraft/core/Direction.java 33 | +++ b/src/main/java/net/minecraft/core/Direction.java 34 | @@ -41,7 +41,7 @@ public enum Direction implements StringRepresentable { 35 | private final Direction.Axis axis; 36 | private final Direction.AxisDirection axisDirection; 37 | private final Vec3i normal; 38 | - private static final Direction[] VALUES = values(); 39 | + public static final Direction[] VALUES = values(); // Fusion - Lithium: Shapes PrecomputeShapeArrays 40 | private static final Direction[] BY_3D_DATA = Arrays.stream(VALUES).sorted(Comparator.comparingInt((direction) -> { 41 | return direction.data3d; 42 | })).toArray((i) -> { 43 | diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java 44 | index a544db042c8d2ecec8d323770552c4f10ca758a6..87ecedfd9d752bb8ae28cf97549acec8bbe8f756 100644 45 | --- a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java 46 | +++ b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java 47 | @@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.doubles.AbstractDoubleList; 48 | 49 | public class CubePointRange extends AbstractDoubleList { 50 | private final int parts; 51 | + private double scale; // Fusion - Lithium: Shapes PrecomputeShapeArrays 52 | 53 | CubePointRange(int sectionCount) { 54 | if (sectionCount <= 0) { 55 | @@ -11,11 +12,18 @@ public class CubePointRange extends AbstractDoubleList { 56 | } else { 57 | this.parts = sectionCount; 58 | } 59 | + this.scale = 1.0D / sectionCount; // Fusion - Lithium: Shapes PrecomputeShapeArrays 60 | } 61 | 62 | + // Fusion start - Lithium: Shapes PrecomputeShapeArrays 63 | + /** 64 | + * @author JellySquid 65 | + * @reason Replace division with multiplication 66 | + */ 67 | public double getDouble(int i) { 68 | - return (double)i / (double)this.parts; 69 | + return com.github.ipecter.fusion.FusionConfig.lithiumShapesPrecomputeShapeArrays ? i * this.scale : (double)i / (double)this.parts; 70 | } 71 | + // Fusion end 72 | 73 | public int size() { 74 | return this.parts + 1; 75 | diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java 76 | index 68e89dbd79171627046e89699057964e44c40e7d..e533bacf08958c21bbfbd19f2ad930d9b8d24969 100644 77 | --- a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java 78 | +++ b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java 79 | @@ -5,14 +5,28 @@ import net.minecraft.core.Direction; 80 | import net.minecraft.util.Mth; 81 | 82 | public final class CubeVoxelShape extends VoxelShape { 83 | + private DoubleList[] list; // Fusion - Lithium: Shapes PrecomputeShapeArrays 84 | + 85 | protected CubeVoxelShape(DiscreteVoxelShape voxels) { 86 | super(voxels); 87 | + // Fusion start - Lithium: Shapes PrecomputeShapeArrays 88 | + this.list = new DoubleList[Direction.VALUES.length]; 89 | + for (Direction.Axis axis : Direction.Axis.VALUES) { 90 | + this.list[axis.ordinal()] = new CubePointRange(voxels.getSize(axis)); 91 | + } 92 | + // Fusion end 93 | } 94 | 95 | + // Fusion start - Lithium: Shapes PrecomputeShapeArrays 96 | + /** 97 | + * @author JellySquid 98 | + * @reason Use the cached array 99 | + */ 100 | @Override 101 | protected DoubleList getCoords(Direction.Axis axis) { 102 | - return new CubePointRange(this.shape.getSize(axis)); 103 | + return com.github.ipecter.fusion.FusionConfig.lithiumShapesPrecomputeShapeArrays ? this.list[axis.ordinal()] : new CubePointRange(this.shape.getSize(axis)); 104 | } 105 | + // Fusion end 106 | 107 | @Override 108 | protected int findIndex(Direction.Axis axis, double coord) { 109 | -------------------------------------------------------------------------------- /patches/server/0019-Lithium-Entity-FastElytraCheck.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 28 Dec 2022 15:05:35 +0900 4 | Subject: [PATCH] Lithium-Entity-FastElytraCheck 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 11 | index 7c14500f529c9d9869a74f2dbe0a01c0594ecb3e..b7b030d3679434f02de31ec91bbeca83e5e5e332 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 14 | @@ -132,10 +132,12 @@ public class FusionWorldConfig { 15 | 16 | public boolean lithiumEnable = true; 17 | public boolean lithiumCollectionsBlockEntityTickers = true; 18 | + public boolean lithiumEntityFastElytraCheck = true; 19 | 20 | private void lithiumConfig() { 21 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 22 | lithiumCollectionsBlockEntityTickers = getBoolean("lithium.collections.block-entity-tickers", lithiumCollectionsBlockEntityTickers) && lithiumEnable; 23 | + lithiumEntityFastElytraCheck = getBoolean("lithium.entity.fast-elytra-check", lithiumEntityFastElytraCheck) && lithiumEnable; 24 | } 25 | 26 | private void lithiumConfigSetup() { 27 | diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java 28 | index 094afd5636590608c8ec31c9fec97614dfef60db..c0b5e74b79cfb0fd5028235cd2f7a59b3c7f0747 100644 29 | --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java 30 | +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java 31 | @@ -3581,6 +3581,8 @@ public abstract class LivingEntity extends Entity { 32 | } 33 | 34 | private void updateFallFlying() { 35 | + if (this.level.fusionConfig.lithiumEntityFastElytraCheck && !this.isFallFlying()) return; // Fusion - Lithium: Entity FastElytraCheck 36 | + 37 | boolean flag = this.getSharedFlag(7); 38 | 39 | if (flag && !this.onGround && !this.isPassenger() && !this.hasEffect(MobEffects.LEVITATION)) { 40 | -------------------------------------------------------------------------------- /patches/server/0020-Lithium-Entity-FastHandSwing.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 28 Dec 2022 15:13:21 +0900 4 | Subject: [PATCH] Lithium-Entity-FastHandSwing 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 11 | index b7b030d3679434f02de31ec91bbeca83e5e5e332..753c02d6caff6cef4248f4260134e2f35cc838f8 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 14 | @@ -133,11 +133,13 @@ public class FusionWorldConfig { 15 | public boolean lithiumEnable = true; 16 | public boolean lithiumCollectionsBlockEntityTickers = true; 17 | public boolean lithiumEntityFastElytraCheck = true; 18 | + public boolean lithiumEntityFastHandSwing = true; 19 | 20 | private void lithiumConfig() { 21 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 22 | lithiumCollectionsBlockEntityTickers = getBoolean("lithium.collections.block-entity-tickers", lithiumCollectionsBlockEntityTickers) && lithiumEnable; 23 | lithiumEntityFastElytraCheck = getBoolean("lithium.entity.fast-elytra-check", lithiumEntityFastElytraCheck) && lithiumEnable; 24 | + lithiumEntityFastHandSwing = getBoolean("lithium.entity.fast-hand-swing", lithiumEntityFastHandSwing) && lithiumEnable; 25 | } 26 | 27 | private void lithiumConfigSetup() { 28 | diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java 29 | index c0b5e74b79cfb0fd5028235cd2f7a59b3c7f0747..7cccbb1ec810452d84e140093a028faf69ffa411 100644 30 | --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java 31 | +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java 32 | @@ -2583,6 +2583,8 @@ public abstract class LivingEntity extends Entity { 33 | } 34 | 35 | protected void updateSwingTime() { 36 | + if (this.level.fusionConfig.lithiumEntityFastHandSwing && !this.swinging && this.swingTime == 0) return; // Fusion - Lithium: Entity FastHandSwing 37 | + 38 | int i = this.getCurrentSwingDuration(); 39 | 40 | if (this.swinging) { 41 | -------------------------------------------------------------------------------- /patches/server/0021-Lithium-Entity-FastPowderSnowCheck.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 28 Dec 2022 15:19:49 +0900 4 | Subject: [PATCH] Lithium-Entity-FastPowderSnowCheck 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 11 | index 753c02d6caff6cef4248f4260134e2f35cc838f8..24140bd78be47d987ffaa55f9f118f861d5b996d 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 14 | @@ -134,12 +134,14 @@ public class FusionWorldConfig { 15 | public boolean lithiumCollectionsBlockEntityTickers = true; 16 | public boolean lithiumEntityFastElytraCheck = true; 17 | public boolean lithiumEntityFastHandSwing = true; 18 | + public boolean lithiumEntityFastPowderSnowCheck = true; 19 | 20 | private void lithiumConfig() { 21 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 22 | lithiumCollectionsBlockEntityTickers = getBoolean("lithium.collections.block-entity-tickers", lithiumCollectionsBlockEntityTickers) && lithiumEnable; 23 | lithiumEntityFastElytraCheck = getBoolean("lithium.entity.fast-elytra-check", lithiumEntityFastElytraCheck) && lithiumEnable; 24 | lithiumEntityFastHandSwing = getBoolean("lithium.entity.fast-hand-swing", lithiumEntityFastHandSwing) && lithiumEnable; 25 | + lithiumEntityFastPowderSnowCheck = getBoolean("lithium.entity.fast-powder-snow-check", lithiumEntityFastPowderSnowCheck) && lithiumEnable; 26 | } 27 | 28 | private void lithiumConfigSetup() { 29 | diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java 30 | index 7cccbb1ec810452d84e140093a028faf69ffa411..f1c7fa15c62052f7eee8fd8680faa0d2b5192f55 100644 31 | --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java 32 | +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java 33 | @@ -577,11 +577,11 @@ public abstract class LivingEntity extends Entity { 34 | } 35 | 36 | protected void tryAddFrost() { 37 | - if (!this.getBlockStateOnLegacy().isAir()) { 38 | + if (this.level.fusionConfig.lithiumEntityFastPowderSnowCheck || !this.getBlockStateOnLegacy().isAir()) { // Fusion - Lithium: Entity FastPowderSnowCheck 39 | int i = this.getTicksFrozen(); 40 | 41 | if (i > 0) { 42 | - AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED); 43 | + AttributeInstance attributemodifiable = this.level.fusionConfig.lithiumEntityFastPowderSnowCheck && this.getBlockStateOnLegacy().isAir() ? null : this.getAttribute(Attributes.MOVEMENT_SPEED); // Fusion - Lithium: Entity FastPowderSnowCheck 44 | 45 | if (attributemodifiable == null) { 46 | return; 47 | -------------------------------------------------------------------------------- /patches/server/0022-Lithium-Collections-Attributes.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 28 Dec 2022 15:23:53 +0900 4 | Subject: [PATCH] Lithium-Collections-Attributes 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index 58cf70e7a427a5a81f68b279d29d91c3c2a4397b..b06f9cf296375f760dc23a0699282366be5d3211 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -225,6 +225,7 @@ public class FusionConfig { 15 | public static boolean lithiumCollectionsGoals = true; 16 | public static boolean lithiumCollectionsGameRules = true; 17 | public static boolean lithiumShapesPrecomputeShapeArrays = true; 18 | + public static boolean lithiumCollectionsAttributes = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | @@ -235,6 +236,7 @@ public class FusionConfig { 23 | lithiumCollectionsGoals = getBoolean("lithium.collections.goals", lithiumCollectionsGoals) && lithiumEnable; 24 | lithiumCollectionsGameRules = getBoolean("lithium.collections.gamerules", lithiumCollectionsGameRules) && lithiumEnable; 25 | lithiumShapesPrecomputeShapeArrays = getBoolean("lithium.shapes.precompute-shape-arrays", lithiumShapesPrecomputeShapeArrays) && lithiumEnable; 26 | + lithiumCollectionsAttributes = getBoolean("lithium.collections.attributes", lithiumCollectionsAttributes) && lithiumEnable; 27 | } 28 | 29 | private static void lithiumConfigSetup() { 30 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 31 | index 24140bd78be47d987ffaa55f9f118f861d5b996d..d0da18734cbad828768ad2ed4fed4fc5a783e4e8 100644 32 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 33 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 34 | @@ -135,6 +135,7 @@ public class FusionWorldConfig { 35 | public boolean lithiumEntityFastElytraCheck = true; 36 | public boolean lithiumEntityFastHandSwing = true; 37 | public boolean lithiumEntityFastPowderSnowCheck = true; 38 | + public boolean lithiumCollectionsAttributes = true; 39 | 40 | private void lithiumConfig() { 41 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 42 | @@ -142,6 +143,7 @@ public class FusionWorldConfig { 43 | lithiumEntityFastElytraCheck = getBoolean("lithium.entity.fast-elytra-check", lithiumEntityFastElytraCheck) && lithiumEnable; 44 | lithiumEntityFastHandSwing = getBoolean("lithium.entity.fast-hand-swing", lithiumEntityFastHandSwing) && lithiumEnable; 45 | lithiumEntityFastPowderSnowCheck = getBoolean("lithium.entity.fast-powder-snow-check", lithiumEntityFastPowderSnowCheck) && lithiumEnable; 46 | + lithiumCollectionsAttributes = getBoolean("lithium.collections.attributes", lithiumCollectionsAttributes) && lithiumEnable; 47 | } 48 | 49 | private void lithiumConfigSetup() { 50 | diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java 51 | index 210a0bee1227e4671909dd553ab22027cfc868fb..d4ba9d553a137a79c2188ca5edf7a797ff387d52 100644 52 | --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java 53 | +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java 54 | @@ -20,8 +20,8 @@ import org.slf4j.Logger; 55 | 56 | public class AttributeMap { 57 | private static final Logger LOGGER = LogUtils.getLogger(); 58 | - private final Map attributes = Maps.newHashMap(); 59 | - private final Set dirtyAttributes = Sets.newHashSet(); 60 | + private final Map attributes; // Fusion - Lithium: Collections EntityAttributes 61 | + private final Set dirtyAttributes; // Fusion - Lithium: Collections EntityAttributes 62 | private final AttributeSupplier supplier; 63 | private final java.util.function.Function createInstance; // Pufferfish 64 | private final net.minecraft.world.entity.LivingEntity entity; // Purpur 65 | @@ -33,6 +33,15 @@ public class AttributeMap { 66 | public AttributeMap(AttributeSupplier defaultAttributes, net.minecraft.world.entity.LivingEntity entity) { 67 | this.entity = entity; 68 | // Purpur end 69 | + // Fusion start - Lithium: Collections EntityAttributes 70 | + if (this.entity != null && this.entity.level.fusionConfig != null){ 71 | + this.attributes = this.entity.level.fusionConfig.lithiumCollectionsAttributes ? new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0) : Maps.newHashMap(); 72 | + this.dirtyAttributes = this.entity.level.fusionConfig.lithiumCollectionsAttributes ? new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0) : Sets.newHashSet(); 73 | + } else { 74 | + this.attributes = com.github.ipecter.fusion.FusionConfig.lithiumCollectionsAttributes ? new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(0) : Maps.newHashMap(); 75 | + this.dirtyAttributes = com.github.ipecter.fusion.FusionConfig.lithiumCollectionsAttributes ? new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(0) : Sets.newHashSet(); 76 | + } 77 | + // Fusion end 78 | this.supplier = defaultAttributes; 79 | this.createInstance = attribute -> this.supplier.createInstance(this::onAttributeModified, attribute); // Pufferfish 80 | } 81 | -------------------------------------------------------------------------------- /patches/server/0023-Lithium-Collections-EntityByType.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 28 Dec 2022 15:27:00 +0900 4 | Subject: [PATCH] Lithium-Collections-EntityByType 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index b06f9cf296375f760dc23a0699282366be5d3211..b2751d590a814e1d0605ff92639565c2c336d903 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -226,6 +226,7 @@ public class FusionConfig { 15 | public static boolean lithiumCollectionsGameRules = true; 16 | public static boolean lithiumShapesPrecomputeShapeArrays = true; 17 | public static boolean lithiumCollectionsAttributes = true; 18 | + public static boolean lithiumCollectionsEntityByType = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | @@ -237,6 +238,7 @@ public class FusionConfig { 23 | lithiumCollectionsGameRules = getBoolean("lithium.collections.gamerules", lithiumCollectionsGameRules) && lithiumEnable; 24 | lithiumShapesPrecomputeShapeArrays = getBoolean("lithium.shapes.precompute-shape-arrays", lithiumShapesPrecomputeShapeArrays) && lithiumEnable; 25 | lithiumCollectionsAttributes = getBoolean("lithium.collections.attributes", lithiumCollectionsAttributes) && lithiumEnable; 26 | + lithiumCollectionsEntityByType = getBoolean("lithium.collections.entity-by-type", lithiumCollectionsEntityByType) && lithiumEnable; 27 | } 28 | 29 | private static void lithiumConfigSetup() { 30 | diff --git a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java 31 | index 50a9f33aa31e9273c7c52d4bb2b02f0f884f7ba5..194c1a04f32963e6de81a2e873a6091c0cf52214 100644 32 | --- a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java 33 | +++ b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java 34 | @@ -13,11 +13,12 @@ import java.util.Map; 35 | import java.util.stream.Collectors; 36 | 37 | public class ClassInstanceMultiMap extends AbstractCollection { 38 | - private final Map, List> byClass = Maps.newHashMap(); 39 | + private final Map, List> byClass; // Fusion - Lithium: Collections EntityByType 40 | private final Class baseClass; 41 | private final List allInstances = Lists.newArrayList(); 42 | 43 | public ClassInstanceMultiMap(Class elementType) { 44 | + this.byClass = com.github.ipecter.fusion.FusionConfig.lithiumCollectionsEntityByType ? Maps.newHashMap() : new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>(); // Fusion - Lithium: Collections EntityByType 45 | this.baseClass = elementType; 46 | this.byClass.put(elementType, this.allInstances); 47 | } 48 | -------------------------------------------------------------------------------- /patches/server/0024-Lithium-Collections-EntityFiltering.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 28 Dec 2022 15:37:06 +0900 4 | Subject: [PATCH] Lithium-Collections-EntityFiltering 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | index b2751d590a814e1d0605ff92639565c2c336d903..de11a220f194ceaf226dcfa6cdfc4d2449340a51 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 14 | @@ -227,6 +227,7 @@ public class FusionConfig { 15 | public static boolean lithiumShapesPrecomputeShapeArrays = true; 16 | public static boolean lithiumCollectionsAttributes = true; 17 | public static boolean lithiumCollectionsEntityByType = true; 18 | + public static boolean lithiumCollectionsEntityFiltering = true; 19 | 20 | private static void lithiumConfig() { 21 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 22 | @@ -239,6 +240,7 @@ public class FusionConfig { 23 | lithiumShapesPrecomputeShapeArrays = getBoolean("lithium.shapes.precompute-shape-arrays", lithiumShapesPrecomputeShapeArrays) && lithiumEnable; 24 | lithiumCollectionsAttributes = getBoolean("lithium.collections.attributes", lithiumCollectionsAttributes) && lithiumEnable; 25 | lithiumCollectionsEntityByType = getBoolean("lithium.collections.entity-by-type", lithiumCollectionsEntityByType) && lithiumEnable; 26 | + lithiumCollectionsEntityFiltering = getBoolean("lithium.collections.entity-filtering", lithiumCollectionsEntityFiltering) && lithiumEnable; 27 | } 28 | 29 | private static void lithiumConfigSetup() { 30 | diff --git a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java 31 | index 194c1a04f32963e6de81a2e873a6091c0cf52214..547b8517fa6fdeb01d9574d25c6d155d8ce565c6 100644 32 | --- a/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java 33 | +++ b/src/main/java/net/minecraft/util/ClassInstanceMultiMap.java 34 | @@ -55,17 +55,46 @@ public class ClassInstanceMultiMap extends AbstractCollection { 35 | return this.find(object.getClass()).contains(object); 36 | } 37 | 38 | + // Fusion start - Lithium: Collections EntityFiltering 39 | + /** 40 | + * @reason Only perform the slow Class#isAssignableFrom(Class) if a list doesn't exist for the type, otherwise 41 | + * we can assume it's already valid. The slow-path code is moved to a separate method to help the JVM inline this. 42 | + * @author JellySquid 43 | + */ 44 | public Collection find(Class type) { 45 | - if (!this.baseClass.isAssignableFrom(type)) { 46 | - throw new IllegalArgumentException("Don't know how to search for " + type); 47 | + if (com.github.ipecter.fusion.FusionConfig.lithiumCollectionsEntityFiltering) { 48 | + Collection collection = this.byClass.get(type); 49 | + if (collection == null) { 50 | + collection = this.createAllOfType(type); 51 | + } 52 | + return (Collection) Collections.unmodifiableCollection(collection); 53 | } else { 54 | - List list = this.byClass.computeIfAbsent(type, (typeClass) -> { 55 | - return this.allInstances.stream().filter(typeClass::isInstance).collect(Collectors.toList()); 56 | - }); 57 | - return Collections.unmodifiableCollection(list); 58 | + if (!this.baseClass.isAssignableFrom(type)) { 59 | + throw new IllegalArgumentException("Don't know how to search for " + type); 60 | + } else { 61 | + List list = this.byClass.computeIfAbsent(type, (typeClass) -> { 62 | + return this.allInstances.stream().filter(typeClass::isInstance).collect(Collectors.toList()); 63 | + }); 64 | + return (Collection) Collections.unmodifiableCollection(list); 65 | + } 66 | } 67 | } 68 | 69 | + private Collection createAllOfType(Class type) { 70 | + List list = new java.util.ArrayList<>(); 71 | + 72 | + for (T allElement : this.allInstances) { 73 | + if (type.isInstance(allElement)) { 74 | + list.add(allElement); 75 | + } 76 | + } 77 | + 78 | + this.byClass.put(type, list); 79 | + 80 | + return list; 81 | + } 82 | + // Fusion end 83 | + 84 | @Override 85 | public Iterator iterator() { 86 | return (Iterator)(this.allInstances.isEmpty() ? Collections.emptyIterator() : Iterators.unmodifiableIterator(this.allInstances.iterator())); 87 | -------------------------------------------------------------------------------- /patches/server/0025-Lithium-HashPalette.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Tue, 1 Nov 2022 19:50:50 +0900 4 | Subject: [PATCH] Lithium-HashPalette 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java 10 | new file mode 100644 11 | index 0000000000000000000000000000000000000000..16debe176798f316c122e8e7aef2b50ecb9883a6 12 | --- /dev/null 13 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/world/chunk/LithiumHashPalette.java 14 | @@ -0,0 +1,189 @@ 15 | +package me.jellysquid.mods.lithium.common.world.chunk; 16 | + 17 | +import com.google.common.collect.ImmutableList; 18 | +import it.unimi.dsi.fastutil.HashCommon; 19 | +import it.unimi.dsi.fastutil.objects.Reference2IntMap; 20 | +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; 21 | +import java.util.Arrays; 22 | +import java.util.List; 23 | +import java.util.function.Predicate; 24 | +import net.minecraft.core.IdMap; 25 | +import net.minecraft.network.FriendlyByteBuf; 26 | +import net.minecraft.world.level.chunk.Palette; 27 | +import net.minecraft.world.level.chunk.PaletteResize; 28 | + 29 | +import static it.unimi.dsi.fastutil.Hash.FAST_LOAD_FACTOR; 30 | + 31 | +/** 32 | + * Generally provides better performance over the vanilla {@link net.minecraft.world.level.chunk.HashMapPalette} when calling 33 | + * {@link LithiumHashPalette#idFor(Object)} through using a faster backing map and reducing pointer chasing. 34 | + */ 35 | +public class LithiumHashPalette implements Palette { 36 | + private static final int ABSENT_VALUE = -1; 37 | + 38 | + private final IdMap idList; 39 | + private final PaletteResize resizeHandler; 40 | + private final int indexBits; 41 | + 42 | + private final Reference2IntMap table; 43 | + private T[] entries; 44 | + private int size = 0; 45 | + 46 | + public LithiumHashPalette(IdMap idList, PaletteResize resizeHandler, int indexBits, T[] entries, Reference2IntMap table, int size) { 47 | + this.idList = idList; 48 | + this.resizeHandler = resizeHandler; 49 | + this.indexBits = indexBits; 50 | + this.entries = entries; 51 | + this.table = table; 52 | + this.size = size; 53 | + } 54 | + 55 | + public LithiumHashPalette(IdMap idList, int bits, PaletteResize resizeHandler, List list) { 56 | + this(idList, bits, resizeHandler); 57 | + 58 | + for (T t : list) { 59 | + this.addEntry(t); 60 | + } 61 | + } 62 | + 63 | + @SuppressWarnings("unchecked") 64 | + public LithiumHashPalette(IdMap idList, int bits, PaletteResize resizeHandler) { 65 | + this.idList = idList; 66 | + this.indexBits = bits; 67 | + this.resizeHandler = resizeHandler; 68 | + 69 | + int capacity = 1 << bits; 70 | + 71 | + this.entries = (T[]) new Object[capacity]; 72 | + this.table = new Reference2IntOpenHashMap<>(capacity, FAST_LOAD_FACTOR); 73 | + this.table.defaultReturnValue(ABSENT_VALUE); 74 | + } 75 | + 76 | + @Override 77 | + public int idFor(T obj) { 78 | + int id = this.table.getInt(obj); 79 | + 80 | + if (id == ABSENT_VALUE) { 81 | + id = this.computeEntry(obj); 82 | + } 83 | + 84 | + return id; 85 | + } 86 | + 87 | + @Override 88 | + public boolean maybeHas(Predicate predicate) { 89 | + for (int i = 0; i < this.size; ++i) { 90 | + if (predicate.test(this.entries[i])) { 91 | + return true; 92 | + } 93 | + } 94 | + 95 | + return false; 96 | + } 97 | + 98 | + private int computeEntry(T obj) { 99 | + int id = this.addEntry(obj); 100 | + 101 | + if (id >= 1 << this.indexBits) { 102 | + if (this.resizeHandler == null) { 103 | + throw new IllegalStateException("Cannot grow"); 104 | + } else { 105 | + id = this.resizeHandler.onResize(this.indexBits + 1, obj); 106 | + } 107 | + } 108 | + 109 | + return id; 110 | + } 111 | + 112 | + private int addEntry(T obj) { 113 | + int nextId = this.size; 114 | + 115 | + if (nextId >= this.entries.length) { 116 | + this.resize(this.size); 117 | + } 118 | + 119 | + this.table.put(obj, nextId); 120 | + this.entries[nextId] = obj; 121 | + 122 | + this.size++; 123 | + 124 | + return nextId; 125 | + } 126 | + 127 | + private void resize(int neededCapacity) { 128 | + this.entries = Arrays.copyOf(this.entries, HashCommon.nextPowerOfTwo(neededCapacity + 1)); 129 | + } 130 | + 131 | + @Override 132 | + public T valueFor(int id) { 133 | + T[] entries = this.entries; 134 | + 135 | + if (id >= 0 && id < entries.length) { 136 | + return entries[id]; 137 | + } 138 | + 139 | + return null; 140 | + } 141 | + 142 | + @Override 143 | + public void read(FriendlyByteBuf buf) { 144 | + this.clear(); 145 | + 146 | + int entryCount = buf.readVarInt(); 147 | + 148 | + for (int i = 0; i < entryCount; ++i) { 149 | + this.addEntry(this.idList.byId(buf.readVarInt())); 150 | + } 151 | + } 152 | + 153 | + @Override 154 | + public void write(FriendlyByteBuf buf) { 155 | + int size = this.size; 156 | + buf.writeVarInt(size); 157 | + 158 | + for (int i = 0; i < size; ++i) { 159 | + buf.writeVarInt(this.idList.getId(this.valueFor(i))); 160 | + } 161 | + } 162 | + 163 | + @Override 164 | + public int getSerializedSize() { 165 | + int size = FriendlyByteBuf.getVarIntSize(this.size); 166 | + 167 | + for (int i = 0; i < this.size; ++i) { 168 | + size += FriendlyByteBuf.getVarIntSize(this.idList.getId(this.valueFor(i))); 169 | + } 170 | + 171 | + return size; 172 | + } 173 | + 174 | + @Override 175 | + public int getSize() { 176 | + return this.size; 177 | + } 178 | + 179 | + @Override 180 | + public Palette copy() { 181 | + return new LithiumHashPalette<>(this.idList, this.resizeHandler, this.indexBits, this.entries.clone(), new Reference2IntOpenHashMap<>(this.table), this.size); 182 | + } 183 | + 184 | + private void clear() { 185 | + Arrays.fill(this.entries, null); 186 | + this.table.clear(); 187 | + this.size = 0; 188 | + } 189 | + 190 | + public List getElements() { 191 | + ImmutableList.Builder builder = new ImmutableList.Builder<>(); 192 | + for (T entry : this.entries) { 193 | + if (entry != null) { 194 | + builder.add(entry); 195 | + } 196 | + } 197 | + return builder.build(); 198 | + } 199 | + 200 | + public static Palette create(int bits, IdMap idList, PaletteResize listener, List list) { 201 | + return new LithiumHashPalette<>(idList, bits, listener, list); 202 | + } 203 | +} 204 | \ No newline at end of file 205 | -------------------------------------------------------------------------------- /patches/server/0027-Lithium-AI-Raid.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Thu, 29 Dec 2022 15:22:13 +0900 4 | Subject: [PATCH] Lithium-AI-Raid 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 11 | index d0da18734cbad828768ad2ed4fed4fc5a783e4e8..04aa079ecf35d5f27d087e94bdec4fb33b97074b 100644 12 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 14 | @@ -136,6 +136,7 @@ public class FusionWorldConfig { 15 | public boolean lithiumEntityFastHandSwing = true; 16 | public boolean lithiumEntityFastPowderSnowCheck = true; 17 | public boolean lithiumCollectionsAttributes = true; 18 | + public boolean lithiumAIRaid = true; 19 | 20 | private void lithiumConfig() { 21 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 22 | @@ -144,6 +145,7 @@ public class FusionWorldConfig { 23 | lithiumEntityFastHandSwing = getBoolean("lithium.entity.fast-hand-swing", lithiumEntityFastHandSwing) && lithiumEnable; 24 | lithiumEntityFastPowderSnowCheck = getBoolean("lithium.entity.fast-powder-snow-check", lithiumEntityFastPowderSnowCheck) && lithiumEnable; 25 | lithiumCollectionsAttributes = getBoolean("lithium.collections.attributes", lithiumCollectionsAttributes) && lithiumEnable; 26 | + lithiumAIRaid = getBoolean("lithium.ai.raid", lithiumAIRaid) && lithiumEnable; 27 | } 28 | 29 | private void lithiumConfigSetup() { 30 | diff --git a/src/main/java/net/minecraft/world/entity/raid/Raid.java b/src/main/java/net/minecraft/world/entity/raid/Raid.java 31 | index 08b18428e867baf14f551beb72e3875b0c420639..b488ab89d04545c3be0f796b3c9050e280ba77dc 100644 32 | --- a/src/main/java/net/minecraft/world/entity/raid/Raid.java 33 | +++ b/src/main/java/net/minecraft/world/entity/raid/Raid.java 34 | @@ -269,7 +269,15 @@ public class Raid { 35 | this.status = Raid.RaidStatus.STOPPED; 36 | } 37 | 38 | + private boolean isBarDirty; // Fusion - Lithium: AI Raider 39 | + 40 | public void tick() { 41 | + // Fusion start - Lithium: AI Raider 42 | + if (this.isBarDirty) { 43 | + this.raidEvent.setProgress(Mth.clamp(this.getHealthOfLivingRaiders() / this.totalHealth, 0.0F, 1.0F)); 44 | + this.isBarDirty = false; 45 | + } 46 | + // Fusion end 47 | if (!this.isStopped()) { 48 | if (this.status == Raid.RaidStatus.ONGOING) { 49 | boolean flag = this.active; 50 | @@ -638,7 +646,13 @@ public class Raid { 51 | } 52 | 53 | public void updateBossbar() { 54 | - this.raidEvent.setProgress(Mth.clamp(this.getHealthOfLivingRaiders() / this.totalHealth, 0.0F, 1.0F)); 55 | + // Fusion start - Lithium: AI Raider 56 | + if (this.level.fusionConfig.lithiumAIRaid) { 57 | + this.isBarDirty = true; 58 | + } else { 59 | + this.raidEvent.setProgress(Mth.clamp(this.getHealthOfLivingRaiders() / this.totalHealth, 0.0F, 1.0F)); 60 | + } 61 | + // Fusion end 62 | } 63 | 64 | public float getHealthOfLivingRaiders() { 65 | diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java 66 | index 6c77c67dc6a378b87cd73c6c55b6d41d1542f6f3..49f955ba3e14bd8c3d39d9e2cbe1702be105c4d3 100644 67 | --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java 68 | +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java 69 | @@ -46,8 +46,9 @@ import net.minecraft.world.phys.Vec3; 70 | public abstract class Raider extends PatrollingMonster { 71 | 72 | protected static final EntityDataAccessor IS_CELEBRATING = SynchedEntityData.defineId(Raider.class, EntityDataSerializers.BOOLEAN); 73 | + private static final ItemStack CACHED_OMINOUS_BANNER = Raid.getLeaderBannerInstance(); // Fusion - Lithium: AI Raider 74 | static final Predicate ALLOWED_ITEMS = (entityitem) -> { 75 | - return !entityitem.hasPickUpDelay() && entityitem.isAlive() && ItemStack.matches(entityitem.getItem(), Raid.getLeaderBannerInstance()); 76 | + return !entityitem.hasPickUpDelay() && entityitem.isAlive() && ItemStack.matches(entityitem.getItem(), CACHED_OMINOUS_BANNER); // Fusion - Lithium: AI Raider 77 | }; 78 | @Nullable 79 | protected Raid raid; 80 | @@ -149,7 +150,7 @@ public abstract class Raider extends PatrollingMonster { 81 | } 82 | } 83 | 84 | - if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.getLeaderBannerInstance()) && entityhuman != null) { 85 | + if (!itemstack.isEmpty() && ItemStack.matches(itemstack, CACHED_OMINOUS_BANNER) && entityhuman != null) { // Fusion - Lithium: AI Raider 86 | MobEffectInstance mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); 87 | byte b0 = 1; 88 | int i; 89 | @@ -244,7 +245,7 @@ public abstract class Raider extends PatrollingMonster { 90 | ItemStack itemstack = item.getItem(); 91 | boolean flag = this.hasActiveRaid() && this.getCurrentRaid().getLeader(this.getWave()) != null; 92 | 93 | - if (this.hasActiveRaid() && !flag && ItemStack.matches(itemstack, Raid.getLeaderBannerInstance())) { 94 | + if (this.hasActiveRaid() && !flag && ItemStack.matches(itemstack, CACHED_OMINOUS_BANNER)) { // Fusion - Lithium: AI Raider 95 | // Paper start 96 | if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(this, item, 0, false).isCancelled()) { 97 | return; 98 | @@ -311,6 +312,8 @@ public abstract class Raider extends PatrollingMonster { 99 | public class ObtainRaidLeaderBannerGoal extends Goal { 100 | 101 | private final T mob; 102 | + private final ItemStack CACHED_OMINOUS_BANNER = Raid.getLeaderBannerInstance(); // Fusion - Lithium: AI Raider 103 | + 104 | 105 | public ObtainRaidLeaderBannerGoal(T entityraider) { // CraftBukkit - decompile error 106 | this.mob = entityraider; 107 | @@ -322,7 +325,7 @@ public abstract class Raider extends PatrollingMonster { 108 | if ((!this.mob.level.purpurConfig.pillagerBypassMobGriefing && !this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) || !this.mob.canPickUpLoot()) return false; // Paper - respect game and entity rules for picking up items // Purpur 109 | Raid raid = this.mob.getCurrentRaid(); 110 | 111 | - if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), Raid.getLeaderBannerInstance())) { 112 | + if (this.mob.hasActiveRaid() && !this.mob.getCurrentRaid().isOver() && this.mob.canBeLeader() && !ItemStack.matches(this.mob.getItemBySlot(EquipmentSlot.HEAD), CACHED_OMINOUS_BANNER)) { // Fusion - Lithium: AI Raider 113 | Raider entityraider = raid.getLeader(this.mob.getWave()); 114 | 115 | if (entityraider == null || !entityraider.isAlive()) { 116 | -------------------------------------------------------------------------------- /patches/server/0029-Lithium-Object2BooleanCacheTable.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 9 Nov 2022 18:45:40 +0900 4 | Subject: [PATCH] Lithium-Object2BooleanCacheTable 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java 10 | new file mode 100644 11 | index 0000000000000000000000000000000000000000..a833ec84b2053c805dd33821cc08939c1cb79e96 12 | --- /dev/null 13 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java 14 | @@ -0,0 +1,59 @@ 15 | +package me.jellysquid.mods.lithium.common.util.collections; 16 | + 17 | +import it.unimi.dsi.fastutil.HashCommon; 18 | +import java.util.function.Predicate; 19 | +import net.minecraft.util.Mth; 20 | + 21 | +/** 22 | + * A lossy hashtable implementation that stores a mapping between an object and a boolean. 23 | + *

24 | + * Any hash collisions will result in an overwrite: this is safe because the correct value can always be recomputed, 25 | + * given that the given operator is deterministic. 26 | + *

27 | + * This implementation is safe to use from multiple threads 28 | + */ 29 | +public final class Object2BooleanCacheTable { 30 | + private final int mask; 31 | + 32 | + private final Node[] nodes; 33 | + 34 | + private final Predicate operator; 35 | + 36 | + @SuppressWarnings("unchecked") 37 | + public Object2BooleanCacheTable(int capacity, Predicate operator) { 38 | + int capacity1 = Mth.smallestEncompassingPowerOfTwo(capacity); 39 | + this.mask = capacity1 - 1; 40 | + 41 | + this.nodes = (Node[]) new Node[capacity1]; 42 | + 43 | + this.operator = operator; 44 | + } 45 | + 46 | + private static int hash(T key) { 47 | + return HashCommon.mix(key.hashCode()); 48 | + } 49 | + 50 | + public boolean get(T key) { 51 | + int idx = hash(key) & this.mask; 52 | + 53 | + Node node = this.nodes[idx]; 54 | + if (node != null && key.equals(node.key)) { 55 | + return node.value; 56 | + } 57 | + 58 | + boolean test = this.operator.test(key); 59 | + this.nodes[idx] = new Node<>(key, test); 60 | + 61 | + return test; 62 | + } 63 | + 64 | + static class Node { 65 | + final T key; 66 | + final boolean value; 67 | + 68 | + Node(T key, boolean value) { 69 | + this.key = key; 70 | + this.value = value; 71 | + } 72 | + } 73 | +} 74 | \ No newline at end of file 75 | -------------------------------------------------------------------------------- /patches/server/0030-Lithium-Shapes-BlockStateCache.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Thu, 5 Jan 2023 11:21:19 +0900 4 | Subject: [PATCH] Lithium-Shapes-BlockStateCache 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | Mirai - etil2jz - GPL 3.0 9 | 10 | diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java 11 | index eb3d528889890fde4d8dcbe3399710c963a8a4cd..c598561947f55c7c2282dba32bbe9cdd392f1a5b 100644 12 | --- a/src/main/java/net/minecraft/world/level/block/Block.java 13 | +++ b/src/main/java/net/minecraft/world/level/block/Block.java 14 | @@ -75,11 +75,12 @@ public class Block extends BlockBehaviour implements ItemLike { 15 | private static final Logger LOGGER = LogUtils.getLogger(); 16 | private final Holder.Reference builtInRegistryHolder; 17 | public static final IdMapper BLOCK_STATE_REGISTRY = new IdMapper<>(); 18 | - private static final LoadingCache SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder().maximumSize(512L).weakKeys().build(new CacheLoader() { 19 | - public Boolean load(VoxelShape voxelshape) { 20 | - return !Shapes.joinIsNotEmpty(Shapes.block(), voxelshape, BooleanOp.NOT_SAME); 21 | - } 22 | - }); 23 | + // Fusion start - Lithium: Shapes BlockStateCache 24 | + private static final me.jellysquid.mods.lithium.common.util.collections.Object2BooleanCacheTable FULL_CUBE_CACHE = new me.jellysquid.mods.lithium.common.util.collections.Object2BooleanCacheTable<>( 25 | + 512, 26 | + shape -> !Shapes.joinIsNotEmpty(Shapes.block(), shape, BooleanOp.NOT_SAME) 27 | + ); 28 | + // Fusion end 29 | public static final int UPDATE_NEIGHBORS = 1; 30 | public static final int UPDATE_CLIENTS = 2; 31 | public static final int UPDATE_INVISIBLE = 4; 32 | @@ -289,9 +290,15 @@ public class Block extends BlockBehaviour implements ItemLike { 33 | return Block.isShapeFullBlock(voxelshape1); 34 | } 35 | 36 | + // Fusion start - Lithium: Shapes BlockStateCache 37 | + /** 38 | + * @reason Use a faster cache implementation 39 | + * @author gegy1000 40 | + */ 41 | public static boolean isShapeFullBlock(VoxelShape shape) { 42 | - return (Boolean) Block.SHAPE_FULL_BLOCK_CACHE.getUnchecked(shape); 43 | + return FULL_CUBE_CACHE.get(shape); 44 | } 45 | + // Fusion end 46 | 47 | public boolean propagatesSkylightDown(BlockState state, BlockGetter world, BlockPos pos) { 48 | return !Block.isShapeFullBlock(state.getShape(world, pos)) && state.getFluidState().isEmpty(); 49 | -------------------------------------------------------------------------------- /patches/server/0031-Lithium-Pos.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 9 Nov 2022 19:11:00 +0900 4 | Subject: [PATCH] Lithium-Pos 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java b/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java 10 | new file mode 100644 11 | index 0000000000000000000000000000000000000000..c99eff34c1be07508c88fe9525c3ae1a087fdef7 12 | --- /dev/null 13 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/util/Pos.java 14 | @@ -0,0 +1,92 @@ 15 | +package me.jellysquid.mods.lithium.common.util; 16 | + 17 | +import net.minecraft.core.SectionPos; 18 | +import net.minecraft.world.level.LevelHeightAccessor; 19 | + 20 | +public class Pos { 21 | + 22 | + public static class BlockCoord { 23 | + public static int getYSize(LevelHeightAccessor view) { 24 | + return view.getHeight(); 25 | + } 26 | + public static int getMinY(LevelHeightAccessor view) { 27 | + return view.getMinBuildHeight(); 28 | + } 29 | + public static int getMaxYInclusive(LevelHeightAccessor view) { 30 | + return view.getMaxBuildHeight() - 1; 31 | + } 32 | + public static int getMaxYExclusive(LevelHeightAccessor view) { 33 | + return view.getMaxBuildHeight(); 34 | + } 35 | + 36 | + public static int getMaxInSectionCoord(int sectionCoord) { 37 | + return 15 + getMinInSectionCoord(sectionCoord); 38 | + } 39 | + 40 | + public static int getMaxYInSectionIndex(LevelHeightAccessor view, int sectionIndex){ 41 | + return getMaxInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex)); 42 | + } 43 | + 44 | + public static int getMinInSectionCoord(int sectionCoord) { 45 | + return SectionPos.sectionToBlockCoord(sectionCoord); 46 | + } 47 | + 48 | + public static int getMinYInSectionIndex(LevelHeightAccessor view, int sectionIndex) { 49 | + return getMinInSectionCoord(SectionYCoord.fromSectionIndex(view, sectionIndex)); 50 | + } 51 | + } 52 | + 53 | + public static class ChunkCoord { 54 | + public static int fromBlockCoord(int blockCoord) { 55 | + return SectionPos.blockToSectionCoord(blockCoord); 56 | + } 57 | + 58 | + public static int fromBlockSize(int i) { 59 | + return i >> 4; //same method as fromBlockCoord, just be clear about coord/size semantic difference 60 | + } 61 | + } 62 | + 63 | + public static class SectionYCoord { 64 | + public static int getNumYSections(LevelHeightAccessor view) { 65 | + return view.getSectionsCount(); 66 | + } 67 | + public static int getMinYSection(LevelHeightAccessor view) { 68 | + return view.getMinSection(); 69 | + } 70 | + public static int getMaxYSectionInclusive(LevelHeightAccessor view) { 71 | + return view.getMaxSection() - 1; 72 | + } 73 | + public static int getMaxYSectionExclusive(LevelHeightAccessor view) { 74 | + return view.getMaxSection(); 75 | + } 76 | + 77 | + public static int fromSectionIndex(LevelHeightAccessor view, int sectionCoord) { 78 | + return sectionCoord + SectionYCoord.getMinYSection(view); 79 | + } 80 | + public static int fromBlockCoord(int blockCoord) { 81 | + return SectionPos.blockToSectionCoord(blockCoord); 82 | + } 83 | + } 84 | + 85 | + public static class SectionYIndex { 86 | + public static int getNumYSections(LevelHeightAccessor view) { 87 | + return view.getSectionsCount(); 88 | + } 89 | + public static int getMinYSectionIndex(LevelHeightAccessor view) { 90 | + return 0; 91 | + } 92 | + public static int getMaxYSectionIndexInclusive(LevelHeightAccessor view) { 93 | + return view.getSectionsCount() - 1; 94 | + } 95 | + public static int getMaxYSectionIndexExclusive(LevelHeightAccessor view) { 96 | + return view.getSectionsCount(); 97 | + } 98 | + 99 | + public static int fromSectionCoord(LevelHeightAccessor view, int sectionCoord) { 100 | + return sectionCoord - SectionYCoord.getMinYSection(view); 101 | + } 102 | + public static int fromBlockCoord(LevelHeightAccessor view, int blockCoord) { 103 | + return fromSectionCoord(view, SectionPos.blockToSectionCoord(blockCoord)); 104 | + } 105 | + } 106 | +} 107 | \ No newline at end of file 108 | -------------------------------------------------------------------------------- /patches/server/0032-Lithium-Gen-ChunkRegion.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Thu, 5 Jan 2023 13:04:30 +0900 4 | Subject: [PATCH] Lithium-Gen-ChunkRegion 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | Mirai - etil2jz - GPL 3.0 8 | 9 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 10 | index d142bce10e98f233c3cc424a63305ac280b84750..5ee7f34c3f3f9f5d5c5184db30d075510a22560e 100644 11 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 12 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | @@ -138,6 +138,7 @@ public class FusionWorldConfig { 14 | public boolean lithiumCollectionsAttributes = true; 15 | public boolean lithiumAIRaid = true; 16 | public boolean lithiumBlockMovingBlockShapes = true; 17 | + public boolean lithiumGenChunkRegion = true; 18 | 19 | private void lithiumConfig() { 20 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 21 | @@ -148,6 +149,7 @@ public class FusionWorldConfig { 22 | lithiumCollectionsAttributes = getBoolean("lithium.collections.attributes", lithiumCollectionsAttributes) && lithiumEnable; 23 | lithiumAIRaid = getBoolean("lithium.ai.raid", lithiumAIRaid) && lithiumEnable; 24 | lithiumBlockMovingBlockShapes = getBoolean("lithium.block.moving-block-shapes", lithiumBlockMovingBlockShapes) && lithiumEnable; 25 | + lithiumGenChunkRegion = getBoolean("lithium.gen.chunk-region", lithiumGenChunkRegion) && lithiumEnable; 26 | } 27 | 28 | private void lithiumConfigSetup() { 29 | diff --git a/src/main/java/net/minecraft/server/level/WorldGenRegion.java b/src/main/java/net/minecraft/server/level/WorldGenRegion.java 30 | index acd7468ee3c86d3456e96e4ec3d7e6a4c612e89d..4f0d04a46075b9af446c101c57d45e7e26d5ef4d 100644 31 | --- a/src/main/java/net/minecraft/server/level/WorldGenRegion.java 32 | +++ b/src/main/java/net/minecraft/server/level/WorldGenRegion.java 33 | @@ -83,6 +83,12 @@ public class WorldGenRegion implements WorldGenLevel { 34 | private Supplier currentlyGenerating; 35 | private final AtomicLong subTickCount = new AtomicLong(); 36 | private static final ResourceLocation WORLDGEN_REGION_RANDOM = new ResourceLocation("worldgen_region_random"); 37 | + // Fusion start - Lithium: Gen ChunkRegion 38 | + // Array view of the chunks in the region to avoid an unnecessary de-reference 39 | + private ChunkAccess[] chunksArr; 40 | + // The starting position of this region 41 | + private int minChunkX, minChunkZ; 42 | + // Fusion end 43 | 44 | public WorldGenRegion(ServerLevel world, List chunks, ChunkStatus status, int placementRadius) { 45 | this.generatingStatus = status; 46 | @@ -105,6 +111,12 @@ public class WorldGenRegion implements WorldGenLevel { 47 | this.lastPos = ((ChunkAccess) chunks.get(chunks.size() - 1)).getPos(); 48 | this.structureManager = world.structureManager().forWorldGenRegion(this); 49 | } 50 | + // Fusion start - Lithium: Gen ChunkRegion 51 | + this.minChunkX = this.firstPos.x; 52 | + this.minChunkZ = this.firstPos.z; 53 | + 54 | + this.chunksArr = chunks.toArray(new ChunkAccess[0]); 55 | + // Fusion end 56 | } 57 | 58 | public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) { 59 | @@ -120,10 +132,36 @@ public class WorldGenRegion implements WorldGenLevel { 60 | this.currentlyGenerating = structureName; 61 | } 62 | 63 | + // Fusion start - Lithium: Gen ChunkRegion 64 | + /** 65 | + * Use our chunk fetch function 66 | + */ 67 | + public ChunkAccess getChunk(BlockPos pos) { 68 | + // Skip checking chunk.getStatus().isAtLeast(ChunkStatus.EMPTY) here, because it is always true 69 | + return this.getChunk(me.jellysquid.mods.lithium.common.util.Pos.ChunkCoord.fromBlockCoord(pos.getX()), me.jellysquid.mods.lithium.common.util.Pos.ChunkCoord.fromBlockCoord(pos.getZ())); 70 | + } 71 | + 72 | + /** 73 | + * @reason Use the chunk array for faster access 74 | + * @author SuperCoder7979, 2No2Name 75 | + */ 76 | @Override 77 | public ChunkAccess getChunk(int chunkX, int chunkZ) { 78 | - return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY); 79 | + if (this.level.fusionConfig.lithiumGenChunkRegion) { 80 | + int x = chunkX - this.minChunkX; 81 | + int z = chunkZ - this.minChunkZ; 82 | + int w = this.size; 83 | + 84 | + if (x >= 0 && z >= 0 && x < w && z < w) { 85 | + return this.chunksArr[x + z * w]; 86 | + } else { 87 | + throw new NullPointerException("No chunk exists at " + new ChunkPos(chunkX, chunkZ)); 88 | + } 89 | + } else { 90 | + return this.getChunk(chunkX, chunkZ, ChunkStatus.EMPTY); 91 | + } 92 | } 93 | + // Fusion end 94 | 95 | @Nullable 96 | @Override 97 | @@ -180,10 +218,28 @@ public class WorldGenRegion implements WorldGenLevel { 98 | } 99 | // Paper end 100 | 101 | + // Fusion start - Lithium: Gen ChunkRegion 102 | + /** 103 | + * @reason Avoid pointer de-referencing, make method easier to inline 104 | + * @author JellySquid 105 | + */ 106 | @Override 107 | public BlockState getBlockState(BlockPos pos) { 108 | - return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos); 109 | + if (this.level.fusionConfig.lithiumGenChunkRegion) { 110 | + int x = (me.jellysquid.mods.lithium.common.util.Pos.ChunkCoord.fromBlockCoord(pos.getX())) - this.minChunkX; 111 | + int z = (me.jellysquid.mods.lithium.common.util.Pos.ChunkCoord.fromBlockCoord(pos.getZ())) - this.minChunkZ; 112 | + int w = this.size; 113 | + 114 | + if (x >= 0 && z >= 0 && x < w && z < w) { 115 | + return this.chunksArr[x + z * w].getBlockState(pos); 116 | + } else { 117 | + throw new NullPointerException("No chunk exists at " + new ChunkPos(pos)); 118 | + } 119 | + } else { 120 | + return this.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ())).getBlockState(pos); 121 | + } 122 | } 123 | + // Fusion end 124 | 125 | @Override 126 | public FluidState getFluidState(BlockPos pos) { 127 | -------------------------------------------------------------------------------- /patches/server/0033-Lithium-AI-Sensor-SecondaryPoi.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Thu, 5 Jan 2023 15:11:03 +0900 4 | Subject: [PATCH] Lithium-AI-Sensor-SecondaryPoi 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | Mirai - etil2jz - GPL 3.0 8 | 9 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 10 | index 5ee7f34c3f3f9f5d5c5184db30d075510a22560e..0961183186cc1e947de60e62c7ee977bb9af82b8 100644 11 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 12 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | @@ -139,6 +139,7 @@ public class FusionWorldConfig { 14 | public boolean lithiumAIRaid = true; 15 | public boolean lithiumBlockMovingBlockShapes = true; 16 | public boolean lithiumGenChunkRegion = true; 17 | + public boolean lithiumAISensorSecondaryPoi = true; 18 | 19 | private void lithiumConfig() { 20 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 21 | @@ -150,6 +151,7 @@ public class FusionWorldConfig { 22 | lithiumAIRaid = getBoolean("lithium.ai.raid", lithiumAIRaid) && lithiumEnable; 23 | lithiumBlockMovingBlockShapes = getBoolean("lithium.block.moving-block-shapes", lithiumBlockMovingBlockShapes) && lithiumEnable; 24 | lithiumGenChunkRegion = getBoolean("lithium.gen.chunk-region", lithiumGenChunkRegion) && lithiumEnable; 25 | + lithiumAISensorSecondaryPoi = getBoolean("lithium.ai.sensor.secondary-poi", lithiumAISensorSecondaryPoi) && lithiumEnable; 26 | } 27 | 28 | private void lithiumConfigSetup() { 29 | diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java 30 | index d2703432af207c74ea8d298a784329c3219d2f13..019487e037caff2c1d5b736c014825b55842f3d7 100644 31 | --- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java 32 | +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java 33 | @@ -24,7 +24,7 @@ public class SecondaryPoiSensor extends Sensor { 34 | protected void doTick(ServerLevel world, Villager entity) { 35 | // Purpur start - make sure clerics don't wander to soul sand when the option is off 36 | Brain brain = entity.getBrain(); 37 | - if (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC) { 38 | + if ((world.fusionConfig.lithiumAISensorSecondaryPoi && entity.getVillagerData().getProfession().secondaryPoi().isEmpty()) || (!world.purpurConfig.villagerClericsFarmWarts && entity.getVillagerData().getProfession() == net.minecraft.world.entity.npc.VillagerProfession.CLERIC)) { // Fusion - Lithium: AI Sensor SecondaryPoi 39 | brain.eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); 40 | return; 41 | } 42 | -------------------------------------------------------------------------------- /patches/server/0034-Lithium-Entity-Collisions-Suffocation.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Fri, 6 Jan 2023 15:32:15 +0900 4 | Subject: [PATCH] Lithium-Entity-Collisions-Suffocation 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | Mirai - etil2jz - GPL 3.0 8 | 9 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 10 | index 0961183186cc1e947de60e62c7ee977bb9af82b8..e2cec470613d5f8558a281889859d9f03d403baf 100644 11 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 12 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 13 | @@ -140,6 +140,7 @@ public class FusionWorldConfig { 14 | public boolean lithiumBlockMovingBlockShapes = true; 15 | public boolean lithiumGenChunkRegion = true; 16 | public boolean lithiumAISensorSecondaryPoi = true; 17 | + public boolean lithiumEntityCollisionsSuffocation = true; 18 | 19 | private void lithiumConfig() { 20 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 21 | @@ -152,6 +153,7 @@ public class FusionWorldConfig { 22 | lithiumBlockMovingBlockShapes = getBoolean("lithium.block.moving-block-shapes", lithiumBlockMovingBlockShapes) && lithiumEnable; 23 | lithiumGenChunkRegion = getBoolean("lithium.gen.chunk-region", lithiumGenChunkRegion) && lithiumEnable; 24 | lithiumAISensorSecondaryPoi = getBoolean("lithium.ai.sensor.secondary-poi", lithiumAISensorSecondaryPoi) && lithiumEnable; 25 | + lithiumEntityCollisionsSuffocation = getBoolean("lithium.entity.collisions.suffocation", lithiumEntityCollisionsSuffocation) && lithiumEnable; 26 | } 27 | 28 | private void lithiumConfigSetup() { 29 | diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java 30 | index 1ae7ef3d94d4d3d8413a5419eeb9fadad89d2f8d..d276ed96cef961a5224d120c5f3b02da87801be0 100644 31 | --- a/src/main/java/net/minecraft/world/entity/Entity.java 32 | +++ b/src/main/java/net/minecraft/world/entity/Entity.java 33 | @@ -2615,6 +2615,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { 34 | return !this.isRemoved(); 35 | } 36 | 37 | + // Fusion start - Lithium: Entity Collisions Suffocation 38 | + /** 39 | + * @author 2No2Name 40 | + * @reason Avoid stream code, use optimized chunk section iteration order 41 | + */ 42 | public boolean isInWall() { 43 | if (this.noPhysics) { 44 | return false; 45 | @@ -2622,32 +2627,64 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { 46 | float f = this.dimensions.width * 0.8F; 47 | AABB axisalignedbb = AABB.ofSize(this.getEyePosition(), (double) f, 1.0E-6D, (double) f); 48 | 49 | - BlockPos.MutableBlockPos blockposition = new BlockPos.MutableBlockPos(); 50 | int minX = Mth.floor(axisalignedbb.minX); 51 | int minY = Mth.floor(axisalignedbb.minY); 52 | int minZ = Mth.floor(axisalignedbb.minZ); 53 | int maxX = Mth.floor(axisalignedbb.maxX); 54 | int maxY = Mth.floor(axisalignedbb.maxY); 55 | int maxZ = Mth.floor(axisalignedbb.maxZ); 56 | - for (int fz = minZ; fz <= maxZ; ++fz) { 57 | - for (int fx = minX; fx <= maxX; ++fx) { 58 | - for (int fy = minY; fy <= maxY; ++fy) { 59 | - net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)this.level.getChunkIfLoadedImmediately(fx >> 4, fz >> 4); 60 | - if (chunk == null) { 61 | - continue; 62 | + 63 | + BlockPos.MutableBlockPos blockposition = new BlockPos.MutableBlockPos(); 64 | + net.minecraft.world.phys.shapes.VoxelShape suffocationShape = null; 65 | + 66 | + if (this.level.fusionConfig.lithiumEntityCollisionsSuffocation) { 67 | + //skip getting blocks when the entity is outside the world height 68 | + //also avoids infinite loop with entities below y = Integer.MIN_VALUE (some modded servers do that) 69 | + if (this.level.getMinBuildHeight() > maxY || this.level.getMaxBuildHeight() < minY) { 70 | + return false; 71 | + } 72 | + 73 | + for (int y = minY; y <= maxY; y++) { 74 | + for (int z = minZ; z <= maxZ; z++) { 75 | + for (int x = minX; x <= maxX; x++) { 76 | + blockposition.set(x, y, z); 77 | + BlockState blockState = this.level.getBlockState(blockposition); 78 | + if (!blockState.isAir() && blockState.isSuffocating(this.level, blockposition)) { 79 | + if (suffocationShape == null) { 80 | + suffocationShape = Shapes.box(axisalignedbb.minX, axisalignedbb.minY, axisalignedbb.minZ, axisalignedbb.maxX, axisalignedbb.maxY, axisalignedbb.maxZ); 81 | + } 82 | + if (Shapes.joinIsNotEmpty(blockState.getCollisionShape(this.level, blockposition). 83 | + move(blockposition.getX(), blockposition.getY(), blockposition.getZ()), 84 | + suffocationShape, BooleanOp.AND)) { 85 | + return true; 86 | + } 87 | + } 88 | } 89 | + } 90 | + } 91 | + return false; 92 | + } else { 93 | + for (int fz = minZ; fz <= maxZ; ++fz) { 94 | + for (int fx = minX; fx <= maxX; ++fx) { 95 | + for (int fy = minY; fy <= maxY; ++fy) { 96 | + net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk) this.level.getChunkIfLoadedImmediately(fx >> 4, fz >> 4); 97 | + if (chunk == null) { 98 | + continue; 99 | + } 100 | 101 | - BlockState iblockdata = chunk.getBlockStateFinal(fx, fy, fz); 102 | - blockposition.set(fx, fy, fz); 103 | - if (!iblockdata.isAir() && iblockdata.isSuffocating(this.level, blockposition) && Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level, blockposition).move((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), Shapes.create(axisalignedbb), BooleanOp.AND)) { 104 | - return true; 105 | + BlockState iblockdata = chunk.getBlockStateFinal(fx, fy, fz); 106 | + blockposition.set(fx, fy, fz); 107 | + if (!iblockdata.isAir() && iblockdata.isSuffocating(this.level, blockposition) && Shapes.joinIsNotEmpty(iblockdata.getCollisionShape(this.level, blockposition).move((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), Shapes.create(axisalignedbb), BooleanOp.AND)) { 108 | + return true; 109 | + } 110 | } 111 | } 112 | } 113 | + return false; 114 | } 115 | - return false; 116 | } 117 | } 118 | + // Fusion end 119 | 120 | public InteractionResult interact(Player player, InteractionHand hand) { 121 | return InteractionResult.PASS; 122 | -------------------------------------------------------------------------------- /patches/server/0035-Lithium-OrderedTickQueue.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Fri, 11 Nov 2022 11:31:08 +0900 4 | Subject: [PATCH] Lithium-OrderedTickQueue 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | Mirai - etil2jz - GPL 3.0 8 | 9 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/world/scheduler/OrderedTickQueue.java b/src/main/java/me/jellysquid/mods/lithium/common/world/scheduler/OrderedTickQueue.java 10 | new file mode 100644 11 | index 0000000000000000000000000000000000000000..3812d1e39c8be5963cc6ca9cb3bf401d10f57fb8 12 | --- /dev/null 13 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/world/scheduler/OrderedTickQueue.java 14 | @@ -0,0 +1,192 @@ 15 | +package me.jellysquid.mods.lithium.common.world.scheduler; 16 | + 17 | +import it.unimi.dsi.fastutil.HashCommon; 18 | +import java.util.*; 19 | +import net.minecraft.world.ticks.ScheduledTick; 20 | + 21 | +/** 22 | + 23 | + */ 24 | +public class OrderedTickQueue extends AbstractQueue> { 25 | + private static final int INITIAL_CAPACITY = 16; 26 | + private static final Comparator> COMPARATOR = Comparator.comparingLong(ScheduledTick::subTickOrder); 27 | + 28 | + private ScheduledTick[] arr; 29 | + 30 | + private int lastIndexExclusive; 31 | + private int firstIndex; 32 | + 33 | + private long currentMaxSubTickOrder = Long.MIN_VALUE; 34 | + private boolean isSorted; 35 | + private ScheduledTick unsortedPeekResult; 36 | + 37 | + @SuppressWarnings("unchecked") 38 | + public OrderedTickQueue(int capacity) { 39 | + this.arr = (ScheduledTick[]) new ScheduledTick[capacity]; 40 | + this.lastIndexExclusive = 0; 41 | + this.isSorted = true; 42 | + this.unsortedPeekResult = null; 43 | + this.firstIndex = 0; 44 | + } 45 | + 46 | + public OrderedTickQueue() { 47 | + this(INITIAL_CAPACITY); 48 | + } 49 | + 50 | + @Override 51 | + public void clear() { 52 | + Arrays.fill(this.arr, null); 53 | + this.lastIndexExclusive = 0; 54 | + this.firstIndex = 0; 55 | + this.currentMaxSubTickOrder = Long.MIN_VALUE; 56 | + this.isSorted = true; 57 | + this.unsortedPeekResult = null; 58 | + } 59 | + 60 | + @Override 61 | + public Iterator> iterator() { 62 | + if (this.isEmpty()) { 63 | + return Collections.emptyIterator(); 64 | + } 65 | + this.sort(); 66 | + return new Iterator<>() { 67 | + int nextIndex = OrderedTickQueue.this.firstIndex; 68 | + 69 | + @Override 70 | + public boolean hasNext() { 71 | + return this.nextIndex < OrderedTickQueue.this.lastIndexExclusive; 72 | + } 73 | + 74 | + @Override 75 | + public ScheduledTick next() { 76 | + return OrderedTickQueue.this.arr[this.nextIndex++]; 77 | + } 78 | + }; 79 | + } 80 | + 81 | + @Override 82 | + public ScheduledTick poll() { 83 | + if (this.isEmpty()) { 84 | + return null; 85 | + } 86 | + if (!this.isSorted) { 87 | + this.sort(); 88 | + } 89 | + ScheduledTick nextTick; 90 | + int polledIndex = this.firstIndex++; 91 | + ScheduledTick[] ticks = this.arr; 92 | + nextTick = ticks[polledIndex]; 93 | + ticks[polledIndex] = null; 94 | + return nextTick; 95 | + } 96 | + 97 | + @Override 98 | + public ScheduledTick peek() { 99 | + if (!this.isSorted) { 100 | + return this.unsortedPeekResult; 101 | + } else if (this.lastIndexExclusive > this.firstIndex) { 102 | + return this.getTickAtIndex(this.firstIndex); 103 | + } 104 | + return null; 105 | + } 106 | + 107 | + public boolean offer(ScheduledTick tick) { 108 | + if (this.lastIndexExclusive >= this.arr.length) { 109 | + //todo remove consumed elements first 110 | + this.arr = copyArray(this.arr, HashCommon.nextPowerOfTwo(this.arr.length + 1)); 111 | + } 112 | + if (tick.subTickOrder() <= this.currentMaxSubTickOrder) { 113 | + //Set to unsorted instead of slowing down the insertion 114 | + //This is rare but may happen in bulk 115 | + //Sorting later needs O(n*log(n)) time, but it only needs to happen when unordered insertion needs to happen 116 | + //Therefore it is better than n times log(n) time of the PriorityQueue that happens on ordered insertion too 117 | + ScheduledTick firstTick = this.isSorted ? this.size() > 0 ? this.arr[this.firstIndex] : null : this.unsortedPeekResult; 118 | + this.isSorted = false; 119 | + this.unsortedPeekResult = firstTick == null || tick.subTickOrder() < firstTick.subTickOrder() ? tick : firstTick; 120 | + } else { 121 | + this.currentMaxSubTickOrder = tick.subTickOrder(); 122 | + } 123 | + this.arr[this.lastIndexExclusive++] = tick; 124 | + return true; 125 | + } 126 | + 127 | + public int size() { 128 | + return this.lastIndexExclusive - this.firstIndex; 129 | + } 130 | + 131 | + private void resize(int size) { 132 | + // Only compact the array if it is completely empty or is less than 50% filled 133 | + if (size == 0 || size < this.arr.length / 2) { 134 | + this.arr = copyArray(this.arr, size); 135 | + } else { 136 | + // Fill the unused array elements with nulls to release our references to the elements in it 137 | + for (int i = size; i < this.arr.length; i++) { 138 | + this.arr[i] = null; 139 | + } 140 | + } 141 | + 142 | + this.firstIndex = 0; 143 | + this.lastIndexExclusive = size; 144 | + 145 | + if (size == 0 || !this.isSorted) { 146 | + this.currentMaxSubTickOrder = Long.MIN_VALUE; 147 | + } else { 148 | + ScheduledTick tick = this.arr[size - 1]; 149 | + this.currentMaxSubTickOrder = tick == null ? Long.MIN_VALUE : tick.subTickOrder(); 150 | + } 151 | + } 152 | + 153 | + public void sort() { 154 | + if (this.isSorted) { 155 | + return; 156 | + } 157 | + this.removeNullsAndConsumed(); 158 | + Arrays.sort(this.arr, this.firstIndex, this.lastIndexExclusive, COMPARATOR); 159 | + this.isSorted = true; 160 | + this.unsortedPeekResult = null; 161 | + } 162 | + 163 | + public void removeNullsAndConsumed() { 164 | + int src = this.firstIndex; 165 | + int dst = 0; 166 | + while (src < this.lastIndexExclusive) { 167 | + ScheduledTick orderedTick = this.arr[src]; 168 | + if (orderedTick != null) { 169 | + this.arr[dst] = orderedTick; 170 | + dst++; 171 | + } 172 | + src++; 173 | + } 174 | + this.resize(dst); 175 | + } 176 | + 177 | + public ScheduledTick getTickAtIndex(int index) { 178 | + if (!this.isSorted) { 179 | + throw new IllegalStateException("Unexpected access on unsorted queue!"); 180 | + } 181 | + return this.arr[index]; 182 | + } 183 | + 184 | + public void setTickAtIndex(int index, ScheduledTick tick) { 185 | + if (!this.isSorted) { 186 | + throw new IllegalStateException("Unexpected access on unsorted queue!"); 187 | + } 188 | + this.arr[index] = tick; 189 | + } 190 | + 191 | + @SuppressWarnings("unchecked") 192 | + private static ScheduledTick[] copyArray(ScheduledTick[] src, int size) { 193 | + final ScheduledTick[] copy = new ScheduledTick[size]; 194 | + 195 | + if (size != 0) { 196 | + System.arraycopy(src, 0, copy, 0, Math.min(src.length, size)); 197 | + } 198 | + 199 | + return copy; 200 | + } 201 | + 202 | + @Override 203 | + public boolean isEmpty() { 204 | + return this.lastIndexExclusive <= this.firstIndex; 205 | + } 206 | +} 207 | \ No newline at end of file 208 | -------------------------------------------------------------------------------- /patches/server/0037-Lithium-Collections-Brain.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 9 Jan 2023 11:04:38 +0900 4 | Subject: [PATCH] Lithium-Collections-Brain 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | index 6529508d8b7c6559382af763f2f78e283e3d55ec..1d7d5369745b1fa196d18ebf82b01b8bc57d7703 100644 11 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 12 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | @@ -230,6 +230,7 @@ public class FusionConfig { 14 | public static boolean lithiumCollectionsEntityFiltering = true; 15 | public static boolean lithiumChunkSerialization = true; 16 | public static boolean lithiumWorldTickScheduler = true; 17 | + public static boolean lithiumCollectionsBrain = true; 18 | 19 | private static void lithiumConfig() { 20 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 21 | @@ -244,6 +245,7 @@ public class FusionConfig { 22 | lithiumCollectionsEntityByType = getBoolean("lithium.collections.entity-by-type", lithiumCollectionsEntityByType) && lithiumEnable; 23 | lithiumCollectionsEntityFiltering = getBoolean("lithium.collections.entity-filtering", lithiumCollectionsEntityFiltering) && lithiumEnable; 24 | lithiumChunkSerialization = getBoolean("lithium.chunk.serialization", lithiumChunkSerialization) && lithiumEnable; 25 | + lithiumCollectionsBrain = getBoolean("lithium.collections.brain", lithiumCollectionsBrain) && lithiumEnable; 26 | } 27 | 28 | private static void lithiumConfigSetup() { 29 | diff --git a/src/main/java/net/minecraft/world/entity/ai/Brain.java b/src/main/java/net/minecraft/world/entity/ai/Brain.java 30 | index 663e278df704ef15f6195339d76642914e7e15e1..e400a306f7250dede5cf87f8b413605d7a51f985 100644 31 | --- a/src/main/java/net/minecraft/world/entity/ai/Brain.java 32 | +++ b/src/main/java/net/minecraft/world/entity/ai/Brain.java 33 | @@ -43,8 +43,8 @@ public class Brain { 34 | static final Logger LOGGER = LogUtils.getLogger(); 35 | private final Supplier>> codec; 36 | private static final int SCHEDULE_UPDATE_DELAY = 20; 37 | - private final Map, Optional>> memories = Maps.newHashMap(); 38 | - private final Map>, Sensor> sensors = Maps.newLinkedHashMap(); 39 | + private final Map, Optional>> memories; // Fusion - Lithium: Collections Brain 40 | + private final Map>, Sensor> sensors; // Fusion - Lithium: Collections Brain 41 | private final Map>>> availableBehaviorsByPriority = Maps.newTreeMap(); 42 | private Schedule schedule = Schedule.EMPTY; 43 | private final Map, MemoryStatus>>> activityRequirements = Maps.newHashMap(); 44 | @@ -105,6 +105,11 @@ public class Brain { 45 | } 46 | 47 | public Brain(Collection> memories, Collection>> sensors, ImmutableList> memoryEntries, Supplier>> codecSupplier) { 48 | + // Fusion start - Lithium: Collections Brain 49 | + this.memories = com.github.ipecter.fusion.FusionConfig.lithiumCollectionsBrain ? new it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap<>() : Maps.newHashMap(); 50 | + this.sensors = com.github.ipecter.fusion.FusionConfig.lithiumCollectionsBrain ? new it.unimi.dsi.fastutil.objects.Reference2ReferenceLinkedOpenHashMap<>() : Maps.newLinkedHashMap(); 51 | + // Fusion end 52 | + 53 | this.codec = codecSupplier; 54 | 55 | for(MemoryModuleType memoryModuleType : memories) { 56 | -------------------------------------------------------------------------------- /patches/server/0038-Lithium-AI-Task-MemoryChangeCounting.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 9 Jan 2023 11:08:28 +0900 4 | Subject: [PATCH] Lithium-AI-Task-MemoryChangeCounting 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | index 1d7d5369745b1fa196d18ebf82b01b8bc57d7703..44f23b240c26600a7fe3c8b12f3e5d631304ad17 100644 11 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 12 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 13 | @@ -231,6 +231,7 @@ public class FusionConfig { 14 | public static boolean lithiumChunkSerialization = true; 15 | public static boolean lithiumWorldTickScheduler = true; 16 | public static boolean lithiumCollectionsBrain = true; 17 | + public static boolean lithiumAITaskMemoryChangeCounting = true; 18 | 19 | private static void lithiumConfig() { 20 | setComment("lithium", "[ Lithium ] General-Purpose Optimization Mod"); 21 | @@ -246,6 +247,7 @@ public class FusionConfig { 22 | lithiumCollectionsEntityFiltering = getBoolean("lithium.collections.entity-filtering", lithiumCollectionsEntityFiltering) && lithiumEnable; 23 | lithiumChunkSerialization = getBoolean("lithium.chunk.serialization", lithiumChunkSerialization) && lithiumEnable; 24 | lithiumCollectionsBrain = getBoolean("lithium.collections.brain", lithiumCollectionsBrain) && lithiumEnable; 25 | + lithiumAITaskMemoryChangeCounting = getBoolean("lithium.ai.task.memory-change-counting", lithiumAITaskMemoryChangeCounting) && lithiumEnable; 26 | } 27 | 28 | private static void lithiumConfigSetup() { 29 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 30 | index e2cec470613d5f8558a281889859d9f03d403baf..a9e2d9beb66ba0c340aaca424a5b986a6b73011f 100644 31 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 32 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 33 | @@ -141,6 +141,7 @@ public class FusionWorldConfig { 34 | public boolean lithiumGenChunkRegion = true; 35 | public boolean lithiumAISensorSecondaryPoi = true; 36 | public boolean lithiumEntityCollisionsSuffocation = true; 37 | + public boolean lithiumAITaskMemoryChangeCounting = true; 38 | 39 | private void lithiumConfig() { 40 | lithiumEnable = getBoolean("lithium.enable", lithiumEnable); 41 | @@ -157,5 +158,6 @@ public class FusionWorldConfig { 42 | } 43 | 44 | private void lithiumConfigSetup() { 45 | + lithiumAITaskMemoryChangeCounting = getBoolean("lithium.ai.task.memory-change-counting", lithiumAITaskMemoryChangeCounting) && lithiumEnable; 46 | } 47 | } 48 | \ No newline at end of file 49 | diff --git a/src/main/java/net/minecraft/world/entity/ai/Brain.java b/src/main/java/net/minecraft/world/entity/ai/Brain.java 50 | index e400a306f7250dede5cf87f8b413605d7a51f985..a8e7929a64e353af97020e1bf756963d05f8b12a 100644 51 | --- a/src/main/java/net/minecraft/world/entity/ai/Brain.java 52 | +++ b/src/main/java/net/minecraft/world/entity/ai/Brain.java 53 | @@ -132,6 +132,14 @@ public class Brain { 54 | 55 | } 56 | 57 | + // Fusion start - Lithium: AI Task MemoryChangeCounting 58 | + private long memoryModCount = 1; 59 | + 60 | + public long getModCount() { 61 | + return memoryModCount; 62 | + } 63 | + // Fusion end 64 | + 65 | public DataResult serializeStart(DynamicOps ops) { 66 | return this.codec.get().encodeStart(ops, this); 67 | } 68 | @@ -167,7 +175,12 @@ public class Brain { 69 | if (memory.isPresent() && this.isEmptyCollection(memory.get().getValue())) { 70 | this.eraseMemory(type); 71 | } else { 72 | - this.memories.put(type, memory); 73 | + // Fusion start - Lithium: AI Task MemoryChangeCounting 74 | + Object oldValue = this.memories.put(type, memory); 75 | + if (oldValue == null || ((Optional) oldValue).isPresent() != ((Optional) memory).isPresent()) { 76 | + this.memoryModCount++; 77 | + } 78 | + // Fusion end 79 | } 80 | } 81 | 82 | @@ -376,7 +389,7 @@ public class Brain { 83 | brain.memories.put(memoryModuleType, entry.getValue()); 84 | } 85 | } 86 | - 87 | + brain.memoryModCount = this.memoryModCount + 1; // Fusion - Lithium: AI Task MemoryChangeCounting 88 | return brain; 89 | } 90 | 91 | diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java 92 | index 651c156dc8a5aad04d461add02e22147af657d07..8693af61db7d6b5c65752693912dd9a76c500ec9 100644 93 | --- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java 94 | +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java 95 | @@ -5,6 +5,12 @@ import net.minecraft.server.level.ServerLevel; 96 | import net.minecraft.world.entity.LivingEntity; 97 | import net.minecraft.world.entity.ai.memory.MemoryModuleType; 98 | import net.minecraft.world.entity.ai.memory.MemoryStatus; 99 | +// Fusion start 100 | +import it.unimi.dsi.fastutil.objects.ObjectIterator; 101 | +import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; 102 | +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; 103 | +import net.minecraft.world.entity.ai.Brain; 104 | +// Fusion end 105 | 106 | public abstract class Behavior implements BehaviorControl { 107 | public static final int DEFAULT_DURATION = 60; 108 | @@ -17,6 +23,10 @@ public abstract class Behavior implements BehaviorContro 109 | private final String configKey; 110 | private final co.aikar.timings.Timing timing; 111 | // Paper end 112 | + // Fusion start - Lithium: AI Task MemoryChangeCounting 113 | + private long cachedMemoryModCount = -1; 114 | + private boolean cachedHasRequiredMemoryState; 115 | + // Fusion end 116 | 117 | public Behavior(Map, MemoryStatus> requiredMemoryState) { 118 | this(requiredMemoryState, 60); 119 | @@ -29,7 +39,7 @@ public abstract class Behavior implements BehaviorContro 120 | public Behavior(Map, MemoryStatus> requiredMemoryState, int minRunTime, int maxRunTime) { 121 | this.minDuration = minRunTime; 122 | this.maxDuration = maxRunTime; 123 | - this.entryCondition = requiredMemoryState; 124 | + this.entryCondition = com.github.ipecter.fusion.FusionConfig.lithiumAITaskMemoryChangeCounting ? new Reference2ObjectOpenHashMap<>(requiredMemoryState) : requiredMemoryState; // Fusion - Lithium: AI Task MemoryChangeCounting 125 | // Paper start - configurable behavior tick rate and timings 126 | String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName()); 127 | int lastSeparator = key.lastIndexOf('.'); 128 | @@ -111,17 +121,42 @@ public abstract class Behavior implements BehaviorContro 129 | return this.getClass().getSimpleName(); 130 | } 131 | 132 | + // Fusion start - Lithium: AI Task MemoryChangeCounting 133 | + /** 134 | + * @reason Use cached required memory state test result if memory state is unchanged 135 | + * @author 2No2Name 136 | + */ 137 | protected boolean hasRequiredMemories(E entity) { 138 | - for(Map.Entry, MemoryStatus> entry : this.entryCondition.entrySet()) { 139 | - MemoryModuleType memoryModuleType = entry.getKey(); 140 | - MemoryStatus memoryStatus = entry.getValue(); 141 | - if (!entity.getBrain().checkMemory(memoryModuleType, memoryStatus)) { 142 | - return false; 143 | + if (entity.level.fusionConfig.lithiumAITaskMemoryChangeCounting) { 144 | + Brain brain = entity.getBrain(); 145 | + long modCount = brain.getModCount(); 146 | + if (this.cachedMemoryModCount == modCount) { 147 | + return this.cachedHasRequiredMemoryState; 148 | + } 149 | + this.cachedMemoryModCount = modCount; 150 | + 151 | + ObjectIterator, MemoryStatus>> fastIterator = ((Reference2ObjectOpenHashMap, MemoryStatus>) this.entryCondition).reference2ObjectEntrySet().fastIterator(); 152 | + while (fastIterator.hasNext()) { 153 | + Reference2ObjectMap.Entry, MemoryStatus> entry = fastIterator.next(); 154 | + if (!brain.checkMemory(entry.getKey(), entry.getValue())) { 155 | + return this.cachedHasRequiredMemoryState = false; 156 | + } 157 | } 158 | - } 159 | 160 | - return true; 161 | + return this.cachedHasRequiredMemoryState = true; 162 | + } else { 163 | + for(Map.Entry, MemoryStatus> entry : this.entryCondition.entrySet()) { 164 | + MemoryModuleType memoryModuleType = entry.getKey(); 165 | + MemoryStatus memoryStatus = entry.getValue(); 166 | + if (!entity.getBrain().checkMemory(memoryModuleType, memoryStatus)) { 167 | + return false; 168 | + } 169 | + } 170 | + 171 | + return true; 172 | + } 173 | } 174 | + // Fusion end 175 | 176 | public static enum Status { 177 | STOPPED, 178 | -------------------------------------------------------------------------------- /patches/server/0039-Lithium-Range6Int.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 9 Jan 2023 11:15:06 +0900 4 | Subject: [PATCH] Lithium-Range6Int 5 | 6 | Lithium - CaffeineMC - GPL 3.0 7 | JettPack - Titaniumtown - GPL 3.0 8 | 9 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/tuples/Range6Int.java b/src/main/java/me/jellysquid/mods/lithium/common/util/tuples/Range6Int.java 10 | new file mode 100644 11 | index 0000000000000000000000000000000000000000..673d4b02a4baf779efa64c1d7b4fc284ec0887f9 12 | --- /dev/null 13 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/util/tuples/Range6Int.java 14 | @@ -0,0 +1,4 @@ 15 | +package me.jellysquid.mods.lithium.common.util.tuples; 16 | + 17 | +public record Range6Int(int negativeX, int negativeY, int negativeZ, int positiveX, int positiveY, int positiveZ) { 18 | +} 19 | \ No newline at end of file 20 | -------------------------------------------------------------------------------- /patches/server/0040-Lithium-PositionedEntityTrackingSection.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 9 Jan 2023 12:25:36 +0900 4 | Subject: [PATCH] Lithium-PositionedEntityTrackingSection 5 | 6 | 7 | diff --git a/src/main/java/me/jellysquid/mods/lithium/common/entity/PositionedEntityTrackingSection.java b/src/main/java/me/jellysquid/mods/lithium/common/entity/PositionedEntityTrackingSection.java 8 | new file mode 100644 9 | index 0000000000000000000000000000000000000000..b5fc6ad5c7c4efe3bbd3ec71ae1e3ef3bf3c578e 10 | --- /dev/null 11 | +++ b/src/main/java/me/jellysquid/mods/lithium/common/entity/PositionedEntityTrackingSection.java 12 | @@ -0,0 +1,7 @@ 13 | +package me.jellysquid.mods.lithium.common.entity; 14 | + 15 | +public interface PositionedEntityTrackingSection { 16 | + void setPos(long chunkSectionPos); 17 | + 18 | + long getPos(); 19 | +} 20 | \ No newline at end of file 21 | -------------------------------------------------------------------------------- /patches/server/0041-Lithium-Util-EntitySectionPosition.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Mon, 9 Jan 2023 12:19:42 +0900 4 | Subject: [PATCH] Lithium-Util-EntitySectionPosition 5 | 6 | 7 | diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySection.java b/src/main/java/net/minecraft/world/level/entity/EntitySection.java 8 | index 5dcb7f9cab097990148f5a7c4ccbe1556afdd514..cc07585885496b83cae274238dec2b0534ee46bd 100644 9 | --- a/src/main/java/net/minecraft/world/level/entity/EntitySection.java 10 | +++ b/src/main/java/net/minecraft/world/level/entity/EntitySection.java 11 | @@ -13,12 +13,23 @@ public class EntitySection { 12 | private static final Logger LOGGER = LogUtils.getLogger(); 13 | private final ClassInstanceMultiMap storage; 14 | private Visibility chunkStatus; 15 | + private long pos; // Fusion - Lithium: Util EntitySectionPosition 16 | 17 | public EntitySection(Class entityClass, Visibility status) { 18 | this.chunkStatus = status; 19 | this.storage = new ClassInstanceMultiMap<>(entityClass); 20 | } 21 | 22 | + // Fusion start - Lithium: Util EntitySectionPosition 23 | + public void setPos(long chunkSectionPos) { 24 | + this.pos = chunkSectionPos; 25 | + } 26 | + 27 | + public long getPos() { 28 | + return this.pos; 29 | + } 30 | + // Fusion end 31 | + 32 | public void add(T entity) { 33 | this.storage.add(entity); 34 | } 35 | diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java 36 | index 6026a75057d1e2f49d9ee4075a204021c092da77..1afa1ce43beb810634e7500a86023e7db0ee76ef 100644 37 | --- a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java 38 | +++ b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java 39 | @@ -169,7 +169,11 @@ public class EntitySectionStorage { 40 | long l = getChunkKeyFromSectionKey(sectionPos); 41 | Visibility visibility = this.intialSectionVisibility.get(l); 42 | this.sectionIds.add(sectionPos); 43 | - return new EntitySection<>(this.entityClass, visibility); 44 | + // Fusion start - Lithium: Util EntitySectionPosition 45 | + EntitySection section = new EntitySection<>(this.entityClass, visibility); 46 | + section.setPos(sectionPos); 47 | + return section; 48 | + // Fusion end 49 | } 50 | 51 | public LongSet getAllChunksWithExistingSections() { 52 | -------------------------------------------------------------------------------- /patches/server/0045-Fusion-C2MEConfiguration.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 10:03:06 +0900 4 | Subject: [PATCH] Fusion-C2MEConfiguration 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 8 | index 7a52b7edc7b959c893dfd4c61f1915237d9213c6..152af075e76245f5fd452b5beac3c727ea2ee72c 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | @@ -255,4 +255,14 @@ public class FusionConfig { 12 | lithiumWorldTickScheduler = getBoolean("lithium.world.tick-scheduler", lithiumWorldTickScheduler) && lithiumEnable; 13 | lithiumAINearbyEntityTracking = getBoolean("lithium.ai.nearby-entity-tracking.enable", lithiumAINearbyEntityTracking) && lithiumEnable; 14 | } 15 | + 16 | + public static boolean c2meEnable = true; 17 | + 18 | + private static void c2meConfig() { 19 | + setComment("c2me", "[ C2ME ] Chunk Performance Improve Mod"); 20 | + c2meEnable = getBoolean("c2me.enable", c2meEnable); 21 | + } 22 | + 23 | + private static void c2meConfigSetup() { 24 | + } 25 | } 26 | \ No newline at end of file 27 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 28 | index 0917f78627858130ca45ff35606eb086fe67d235..a5220447a0227e3c6a59ff59861c321e328325c9 100644 29 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 30 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 31 | @@ -162,4 +162,13 @@ public class FusionWorldConfig { 32 | private void lithiumConfigSetup() { 33 | lithiumAITaskMemoryChangeCounting = getBoolean("lithium.ai.task.memory-change-counting", lithiumAITaskMemoryChangeCounting) && lithiumEnable; 34 | } 35 | + 36 | + public boolean c2meEnable = true; 37 | + 38 | + private void c2meConfig() { 39 | + c2meEnable = getBoolean("c2me.enable", c2meEnable); 40 | + } 41 | + 42 | + private void c2meConfigSetup() { 43 | + } 44 | } 45 | \ No newline at end of file 46 | -------------------------------------------------------------------------------- /patches/server/0047-C2ME-ObjectCachingUtils.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 10:20:53 +0900 4 | Subject: [PATCH] C2ME-ObjectCachingUtils 5 | 6 | 7 | diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java b/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java 8 | new file mode 100644 9 | index 0000000000000000000000000000000000000000..35af9788a2cfc9203a9987a1a241870658feece7 10 | --- /dev/null 11 | +++ b/src/main/java/com/ishland/c2me/opts/allocs/common/ObjectCachingUtils.java 12 | @@ -0,0 +1,23 @@ 13 | +package com.ishland.c2me.opts.allocs.common; 14 | + 15 | +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 16 | + 17 | +import java.util.BitSet; 18 | +import java.util.function.IntFunction; 19 | + 20 | +public class ObjectCachingUtils { 21 | + 22 | + private static final IntFunction bitSetConstructor = BitSet::new; 23 | + 24 | + public static ThreadLocal> BITSETS = ThreadLocal.withInitial(Int2ObjectOpenHashMap::new); 25 | + 26 | + private ObjectCachingUtils() { 27 | + } 28 | + 29 | + public static BitSet getCachedOrNewBitSet(int bits) { 30 | + final BitSet bitSet = BITSETS.get().computeIfAbsent(bits, bitSetConstructor); 31 | + bitSet.clear(); 32 | + return bitSet; 33 | + } 34 | + 35 | +} 36 | \ No newline at end of file 37 | -------------------------------------------------------------------------------- /patches/server/0048-C2ME-SimpleObjectPool.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 10:21:34 +0900 4 | Subject: [PATCH] C2ME-SimpleObjectPool 5 | 6 | 7 | diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java b/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java 8 | new file mode 100644 9 | index 0000000000000000000000000000000000000000..35a1d4584e639a30b7acc9cad4a29a68b18e239b 10 | --- /dev/null 11 | +++ b/src/main/java/com/ishland/c2me/opts/allocs/common/SimpleObjectPool.java 12 | @@ -0,0 +1,57 @@ 13 | +package com.ishland.c2me.opts.allocs.common; 14 | + 15 | +import com.google.common.base.Preconditions; 16 | + 17 | +import java.util.Objects; 18 | +import java.util.function.Consumer; 19 | +import java.util.function.Function; 20 | + 21 | +public class SimpleObjectPool { 22 | + 23 | + private final Function, T> constructor; 24 | + private final Consumer initializer; 25 | + private final int size; 26 | + 27 | + private final Object[] cachedObjects; 28 | + private int allocatedCount = 0; 29 | + 30 | + public SimpleObjectPool(Function, T> constructor, Consumer initializer, int size) { 31 | + this.constructor = Objects.requireNonNull(constructor); 32 | + this.initializer = Objects.requireNonNull(initializer); 33 | + Preconditions.checkArgument(size > 0); 34 | + this.cachedObjects = new Object[size]; 35 | + this.size = size; 36 | + 37 | + for (int i = 0; i < size; i++) { 38 | + final T object = constructor.apply(this); 39 | + this.cachedObjects[i] = object; 40 | + } 41 | + } 42 | + 43 | + public T alloc() { 44 | + final T object; 45 | + synchronized (this) { 46 | + if (this.allocatedCount >= this.size) { // oversized, falling back to normal alloc 47 | + object = this.constructor.apply(this); 48 | + return object; 49 | + } 50 | + 51 | + // get an object from the array 52 | + final int ordinal = this.allocatedCount++; 53 | + object = (T) this.cachedObjects[ordinal]; 54 | + this.cachedObjects[ordinal] = null; 55 | + } 56 | + 57 | + this.initializer.accept(object); // initialize the object 58 | + 59 | + return object; 60 | + } 61 | + 62 | + public void release(T object) { 63 | + synchronized (this) { 64 | + if (this.allocatedCount == 0) return; // pool is full 65 | + this.cachedObjects[--this.allocatedCount] = object; // store the object into the pool 66 | + } 67 | + } 68 | + 69 | +} 70 | \ No newline at end of file 71 | -------------------------------------------------------------------------------- /patches/server/0049-C2ME-PooledFeatureContext.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 10:25:16 +0900 4 | Subject: [PATCH] C2ME-PooledFeatureContext 5 | 6 | 7 | diff --git a/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java b/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java 8 | new file mode 100644 9 | index 0000000000000000000000000000000000000000..ab3f0515b0fab016f73a0a46f80a10ddef0b91da 10 | --- /dev/null 11 | +++ b/src/main/java/com/ishland/c2me/opts/allocs/common/PooledFeatureContext.java 12 | @@ -0,0 +1,69 @@ 13 | +package com.ishland.c2me.opts.allocs.common; 14 | + 15 | +import net.minecraft.core.BlockPos; 16 | +import net.minecraft.util.RandomSource; 17 | +import net.minecraft.world.level.WorldGenLevel; 18 | +import net.minecraft.world.level.chunk.ChunkGenerator; 19 | +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; 20 | +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; 21 | +import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; 22 | + 23 | +import java.util.Optional; 24 | + 25 | +public class PooledFeatureContext extends FeaturePlaceContext { 26 | + 27 | + public static final ThreadLocal>> POOL = ThreadLocal.withInitial(() -> new SimpleObjectPool<>(unused -> new PooledFeatureContext<>(), unused -> {}, 2048)); 28 | + 29 | + private Optional> topFeature; 30 | + private WorldGenLevel level; 31 | + private ChunkGenerator chunkGenerator; 32 | + private RandomSource random; 33 | + private BlockPos origin; 34 | + private FC config; 35 | + 36 | + public PooledFeatureContext() { 37 | + super(null, null, null, null, null, null); 38 | + } 39 | + 40 | + public void reInit(Optional> feature, WorldGenLevel world, ChunkGenerator generator, RandomSource random, BlockPos origin, FC config) { 41 | + this.topFeature = feature; 42 | + this.level = world; 43 | + this.chunkGenerator = generator; 44 | + this.random = random; 45 | + this.origin = origin; 46 | + this.config = config; 47 | + } 48 | + 49 | + public void reInit() { 50 | + this.topFeature = null; 51 | + this.level = null; 52 | + this.chunkGenerator = null; 53 | + this.random = null; 54 | + this.origin = null; 55 | + this.config = null; 56 | + } 57 | + 58 | + public Optional> topFeature() { 59 | + return this.topFeature; 60 | + } 61 | + 62 | + public WorldGenLevel level() { 63 | + return this.level; 64 | + } 65 | + 66 | + public ChunkGenerator chunkGenerator() { 67 | + return this.chunkGenerator; 68 | + } 69 | + 70 | + public RandomSource random() { 71 | + return this.random; 72 | + } 73 | + 74 | + public BlockPos origin() { 75 | + return this.origin; 76 | + } 77 | + 78 | + public FC config() { 79 | + return this.config; 80 | + } 81 | +} 82 | \ No newline at end of file 83 | -------------------------------------------------------------------------------- /patches/server/0051-Fusion-VMPConfiguration.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 19:52:29 +0900 4 | Subject: [PATCH] Fusion-VMPConfiguration 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 8 | index 9b86b2d1d8e7cd336c7c051969be563d7ff6fe89..ebd0f8b5fdf0d3b71ca1182e126cfed99307a37e 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | @@ -269,4 +269,14 @@ public class FusionConfig { 12 | private static void c2meConfigSetup() { 13 | c2meOptsAllocs = getBoolean("c2me.opts.allocs", c2meOptsAllocs) && c2meEnable; 14 | } 15 | + 16 | + public static boolean vmpEnable = true; 17 | + 18 | + private static void vmpConfig() { 19 | + setComment("vmp", "[ VMP ] Many Players Server Performance Improvement Mod"); 20 | + vmpEnable = getBoolean("vmp.enable", vmpEnable); 21 | + } 22 | + 23 | + private static void vmpConfigSetup() { 24 | + } 25 | } 26 | \ No newline at end of file 27 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 28 | index a5220447a0227e3c6a59ff59861c321e328325c9..d61c57a8f4c8fc1d155cecdb59d759fecd8257fc 100644 29 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 30 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 31 | @@ -171,4 +171,13 @@ public class FusionWorldConfig { 32 | 33 | private void c2meConfigSetup() { 34 | } 35 | + 36 | + public boolean vmpEnable = true; 37 | + 38 | + private void vmpConfig() { 39 | + vmpEnable = getBoolean("vmp.enable", vmpEnable); 40 | + } 41 | + 42 | + private void vmpConfigSetup() { 43 | + } 44 | } 45 | \ No newline at end of file 46 | -------------------------------------------------------------------------------- /patches/server/0052-VMP-Entity-MoveZeroVelocity.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 21:27:50 +0900 4 | Subject: [PATCH] VMP-Entity-MoveZeroVelocity 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 8 | index d61c57a8f4c8fc1d155cecdb59d759fecd8257fc..eb90338ae04770a371b3bc371d23808d303f24f4 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 11 | @@ -173,11 +173,13 @@ public class FusionWorldConfig { 12 | } 13 | 14 | public boolean vmpEnable = true; 15 | + public boolean vmpEntityMoveZeroVelocity = true; 16 | 17 | private void vmpConfig() { 18 | vmpEnable = getBoolean("vmp.enable", vmpEnable); 19 | } 20 | 21 | private void vmpConfigSetup() { 22 | + vmpEntityMoveZeroVelocity = getBoolean("vmp.entity.move-zero-velocity", vmpEntityMoveZeroVelocity) && vmpEnable; 23 | } 24 | } 25 | \ No newline at end of file 26 | diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java 27 | index 4ca617ca373e211e10e29f49f6c5d7fed59f823e..bf24d6608554329f2338c49a022ffa73eb02b059 100644 28 | --- a/src/main/java/net/minecraft/world/entity/Entity.java 29 | +++ b/src/main/java/net/minecraft/world/entity/Entity.java 30 | @@ -1051,7 +1051,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { 31 | } 32 | // Paper end - detailed watchdog information 33 | 34 | + private boolean boundingBoxChanged = false; // Fusion - VMP: Entity MoveZeroVelocity 35 | + 36 | public void move(MoverType movementType, Vec3 movement) { 37 | + // Fusion start - VMP: Entity MoveZeroVelocity 38 | + if (this.level.fusionConfig.vmpEntityMoveZeroVelocity && !boundingBoxChanged && movement.equals(Vec3.ZERO)) { 39 | + boundingBoxChanged = false; 40 | + return; 41 | + } 42 | + // Fusion end 43 | // Paper start - detailed watchdog information 44 | io.papermc.paper.util.TickThread.ensureTickThread("Cannot move an entity off-main"); 45 | synchronized (this.posLock) { 46 | @@ -3899,6 +3907,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { 47 | } 48 | 49 | public final void setBoundingBox(AABB boundingBox) { 50 | + if (!this.bb.equals(boundingBox)) boundingBoxChanged = true; // Fusion - VMP: Entity MoveZeroVelocity 51 | // CraftBukkit start - block invalid bounding boxes 52 | double minX = boundingBox.minX, 53 | minY = boundingBox.minY, 54 | -------------------------------------------------------------------------------- /patches/server/0053-VMP-General-SpawnDensityCap.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 21:43:27 +0900 4 | Subject: [PATCH] VMP-General-SpawnDensityCap 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 8 | index ebd0f8b5fdf0d3b71ca1182e126cfed99307a37e..f572f0abd6fb0fde64a1ec62dfb6055c0d35aa00 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | @@ -271,6 +271,7 @@ public class FusionConfig { 12 | } 13 | 14 | public static boolean vmpEnable = true; 15 | + public static boolean vmpGeneralSpawnDensityCap = true; 16 | 17 | private static void vmpConfig() { 18 | setComment("vmp", "[ VMP ] Many Players Server Performance Improvement Mod"); 19 | @@ -278,5 +279,6 @@ public class FusionConfig { 20 | } 21 | 22 | private static void vmpConfigSetup() { 23 | + vmpGeneralSpawnDensityCap = getBoolean("vmp.general.spawn-density-cap", vmpGeneralSpawnDensityCap) && vmpEnable; 24 | } 25 | } 26 | \ No newline at end of file 27 | diff --git a/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java b/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java 28 | index 84c766e09898cfc07d6e07e80f4b9aa318050a62..918d973e670600620d093f29e4128ca3bfc93afd 100644 29 | --- a/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java 30 | +++ b/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java 31 | @@ -48,15 +48,34 @@ public class LocalMobCapCalculator { 32 | 33 | static class MobCounts { 34 | private final Object2IntMap counts = new Object2IntOpenHashMap<>(MobCategory.values().length); 35 | + private final int[] spawnGroupDensities = new int[MobCategory.values().length]; // Fusion - VMP: General SpawnDensityCap 36 | 37 | + // Fusion start - VMP: General SpawnDensityCap 38 | + /** 39 | + * @author ishland 40 | + * @reason opt: replace with array access 41 | + */ 42 | public void add(MobCategory spawnGroup) { 43 | - this.counts.computeInt(spawnGroup, (group, density) -> { 44 | - return density == null ? 1 : density + 1; 45 | - }); 46 | + if (com.github.ipecter.fusion.FusionConfig.vmpGeneralSpawnDensityCap) { 47 | + this.spawnGroupDensities[spawnGroup.ordinal()] ++; 48 | + } else { 49 | + this.counts.computeInt(spawnGroup, (group, density) -> { 50 | + return density == null ? 1 : density + 1; 51 | + }); 52 | + } 53 | } 54 | 55 | + /** 56 | + * @author ishland 57 | + * @reason opt: replace with array access 58 | + */ 59 | public boolean canSpawn(MobCategory spawnGroup) { 60 | - return this.counts.getOrDefault(spawnGroup, 0) < spawnGroup.getMaxInstancesPerChunk(); 61 | + if (com.github.ipecter.fusion.FusionConfig.vmpGeneralSpawnDensityCap) { 62 | + return this.spawnGroupDensities[spawnGroup.ordinal()] < spawnGroup.getMaxInstancesPerChunk(); 63 | + } else { 64 | + return this.counts.getOrDefault(spawnGroup, 0) < spawnGroup.getMaxInstancesPerChunk(); 65 | + } 66 | } 67 | + // Fusion end 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /patches/server/0054-VMP-Entity-Tracker.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Wed, 11 Jan 2023 22:42:22 +0900 4 | Subject: [PATCH] VMP-Entity-Tracker 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 8 | index eb90338ae04770a371b3bc371d23808d303f24f4..46b4732a6929eb9bb3dc809ce210d95de8909f1e 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionWorldConfig.java 11 | @@ -174,6 +174,7 @@ public class FusionWorldConfig { 12 | 13 | public boolean vmpEnable = true; 14 | public boolean vmpEntityMoveZeroVelocity = true; 15 | + public boolean vmpEntityTracker = true; 16 | 17 | private void vmpConfig() { 18 | vmpEnable = getBoolean("vmp.enable", vmpEnable); 19 | @@ -181,5 +182,6 @@ public class FusionWorldConfig { 20 | 21 | private void vmpConfigSetup() { 22 | vmpEntityMoveZeroVelocity = getBoolean("vmp.entity.move-zero-velocity", vmpEntityMoveZeroVelocity) && vmpEnable; 23 | + vmpEntityTracker = getBoolean("vmp.entity.tracker", vmpEntityTracker) && vmpEnable; 24 | } 25 | } 26 | \ No newline at end of file 27 | diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java 28 | index 75965afd7b4bed23a5ecf618c7f91ff5e7ffd92f..57ab982bfdb9d8893ec8a3cf5ebe49317a952651 100644 29 | --- a/src/main/java/net/minecraft/server/level/ChunkMap.java 30 | +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java 31 | @@ -108,12 +108,14 @@ import net.minecraft.world.level.storage.LevelStorageSource; 32 | import net.minecraft.world.phys.Vec3; 33 | import org.apache.commons.lang3.mutable.MutableBoolean; 34 | import org.apache.commons.lang3.mutable.MutableObject; 35 | +import org.checkerframework.common.aliasing.qual.Unique; 36 | import org.slf4j.Logger; 37 | import org.bukkit.craftbukkit.generator.CustomChunkGenerator; 38 | import org.bukkit.entity.Player; 39 | // CraftBukkit end 40 | 41 | import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; // Paper 42 | +import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; // Fusion 43 | 44 | public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider { 45 | 46 | @@ -295,7 +297,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider 47 | // Paper - rewrite chunk system 48 | this.tickingGenerated = new AtomicInteger(); 49 | this.playerMap = new PlayerMap(); 50 | - this.entityMap = new Int2ObjectOpenHashMap(); 51 | + this.entityMap = world.fusionConfig.vmpEntityTracker ? new Int2ObjectLinkedOpenHashMap<>() : new Int2ObjectOpenHashMap(); // Fusion - VMP: Entity Tracker 52 | this.chunkTypeCache = new Long2ByteOpenHashMap(); 53 | this.chunkSaveCooldowns = new Long2LongOpenHashMap(); 54 | this.unloadQueue = Queues.newConcurrentLinkedQueue(); 55 | @@ -1501,6 +1503,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider 56 | private final int range; 57 | SectionPos lastSectionPos; 58 | public final Set seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl 59 | + // Fusion start - VMP: Entity Tracker 60 | + private int lastDistanceUpdate = 0; 61 | + private int cachedMaxDistance = 0; 62 | + // Fusion end 63 | 64 | public TrackedEntity(Entity entity, int i, int j, boolean flag) { 65 | this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit 66 | @@ -1599,7 +1605,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider 67 | double vec3d_dx = player.getX() - this.entity.getX(); 68 | double vec3d_dz = player.getZ() - this.entity.getZ(); 69 | // Paper end - remove allocation of Vec3D here 70 | - double d0 = (double) Math.min(this.getEffectiveRange(), io.papermc.paper.chunk.PlayerChunkLoader.getSendViewDistance(player) * 16); // Paper - per player view distance 71 | + // Fusion start - VMP: Entity Tracker 72 | + int effectiveRange; 73 | + if (player.level.fusionConfig.vmpEntityTracker) { 74 | + final int ticks = level.getServer().getTickCount(); 75 | + if (lastDistanceUpdate != ticks || cachedMaxDistance == 0) { 76 | + final int maxTrackDistance = this.getEffectiveRange(); 77 | + this.cachedMaxDistance = maxTrackDistance; 78 | + this.lastDistanceUpdate = ticks; 79 | + effectiveRange = maxTrackDistance; 80 | + } else { 81 | + effectiveRange = this.cachedMaxDistance; 82 | + } 83 | + } else { 84 | + effectiveRange = this.getEffectiveRange(); 85 | + } 86 | + double d0 = (double) Math.min(effectiveRange, io.papermc.paper.chunk.PlayerChunkLoader.getSendViewDistance(player) * 16); // Paper - per player view distance 87 | + // Fusion end 88 | double d1 = vec3d_dx * vec3d_dx + vec3d_dz * vec3d_dz; // Paper 89 | double d2 = d0 * d0; 90 | boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player); 91 | diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java 92 | index 0f9a3a6c05fee59c29764f0c0d7a6cb8a2a861b1..cce6ea4586f8f066f06f0beaad376b3cc5b4e47e 100644 93 | --- a/src/main/java/net/minecraft/server/level/ServerEntity.java 94 | +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java 95 | @@ -263,6 +263,13 @@ public class ServerEntity { 96 | Objects.requireNonNull(player.connection); 97 | this.sendPairingData(playerconnection::send, player); // CraftBukkit - add player 98 | this.entity.startSeenByPlayer(player); 99 | + 100 | + // Fusion start - VMP: Entity Tracker 101 | + if (this.entity.level.fusionConfig.vmpEntityTracker) { 102 | + this.teleportDelay = Integer.MAX_VALUE - 1; 103 | + this.entity.hasImpulse = true; 104 | + } 105 | + // Fusion end 106 | } 107 | 108 | public void sendPairingData(Consumer> consumer, ServerPlayer entityplayer) { // CraftBukkit - add player 109 | -------------------------------------------------------------------------------- /patches/server/0055-VMP-General-Ingredient-Matching.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Thu, 12 Jan 2023 01:47:18 +0900 4 | Subject: [PATCH] VMP-General-Ingredient-Matching 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 8 | index f572f0abd6fb0fde64a1ec62dfb6055c0d35aa00..6f9cf69d508b0b6acb3bdab5fbf8e0a676533f81 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | @@ -272,10 +272,12 @@ public class FusionConfig { 12 | 13 | public static boolean vmpEnable = true; 14 | public static boolean vmpGeneralSpawnDensityCap = true; 15 | + public static boolean vmpGeneralIngredientMatching = false; 16 | 17 | private static void vmpConfig() { 18 | setComment("vmp", "[ VMP ] Many Players Server Performance Improvement Mod"); 19 | vmpEnable = getBoolean("vmp.enable", vmpEnable); 20 | + vmpGeneralIngredientMatching = getBoolean("vmp.general.ingredient-matching", vmpGeneralIngredientMatching) && vmpEnable; 21 | } 22 | 23 | private static void vmpConfigSetup() { 24 | diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java 25 | index e24034d1ce4bb529de084aab69a531227e0c2f79..2fcbde5a3031841d2ebfcabb08723f335056f52a 100644 26 | --- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java 27 | +++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java 28 | @@ -29,6 +29,11 @@ import net.minecraft.world.entity.player.StackedContents; 29 | import net.minecraft.world.item.Item; 30 | import net.minecraft.world.item.ItemStack; 31 | import net.minecraft.world.level.ItemLike; 32 | +// Fusion start 33 | +import java.util.HashSet; 34 | +import java.util.stream.Collectors; 35 | +import java.util.Set; 36 | +// Fusion end 37 | 38 | public final class Ingredient implements Predicate { 39 | 40 | @@ -40,6 +45,10 @@ public final class Ingredient implements Predicate { 41 | private IntList stackingIds; 42 | public boolean exact; // CraftBukkit 43 | public Predicate predicate; 44 | + // Fusion start - VMP: General Ingredient Matching 45 | + private Set matchingItems = null; 46 | + private boolean isEmptyMatch = false; 47 | + // Fusion end 48 | 49 | public Ingredient(Stream entries) { 50 | this.values = (Ingredient.Value[]) entries.toArray((i) -> { 51 | @@ -63,41 +72,62 @@ public final class Ingredient implements Predicate { 52 | return this.itemStacks; 53 | } 54 | 55 | + // Fusion start - VMP: General Ingredient Matching 56 | + /** 57 | + * @author ishland 58 | + * @reason optimize test() 59 | + */ 60 | public boolean test(@Nullable ItemStack itemstack) { 61 | if (itemstack == null) { 62 | return false; 63 | - } else if (this.isEmpty()) { 64 | - return itemstack.isEmpty(); 65 | } else { 66 | - // Purpur start 67 | - if (predicate != null) { 68 | - return predicate.test(itemstack.asBukkitCopy()); 69 | - } 70 | - // Purpur end 71 | + if (com.github.ipecter.fusion.FusionConfig.vmpGeneralIngredientMatching) { 72 | + Set matchingItems = this.matchingItems; 73 | + boolean isEmptyMatch = this.isEmptyMatch; 74 | + if (matchingItems == null) { 75 | + matchingItems = this.matchingItems = Arrays.stream(this.values) 76 | + .flatMap(entry -> entry.getItems().stream()) 77 | + .filter(itemStack1 -> !itemStack1.isEmpty()) 78 | + .map(ItemStack::getItem) 79 | + .collect(Collectors.toCollection(HashSet::new)); 80 | + isEmptyMatch = this.isEmptyMatch = this.matchingItems.isEmpty(); 81 | + } 82 | + if (itemstack.isEmpty()) { 83 | + return isEmptyMatch; 84 | + } 85 | + return matchingItems.contains(itemstack.getItem()); 86 | + } else { 87 | + if (this.isEmpty()) return itemstack.isEmpty(); 88 | + // Purpur start 89 | + if (predicate != null) { 90 | + return predicate.test(itemstack.asBukkitCopy()); 91 | + } 92 | + // Purpur end 93 | + ItemStack[] aitemstack = this.getItems(); 94 | + int i = aitemstack.length; 95 | 96 | - ItemStack[] aitemstack = this.getItems(); 97 | - int i = aitemstack.length; 98 | + for (int j = 0; j < i; ++j) { 99 | + ItemStack itemstack1 = aitemstack[j]; 100 | 101 | - for (int j = 0; j < i; ++j) { 102 | - ItemStack itemstack1 = aitemstack[j]; 103 | + // CraftBukkit start 104 | + if (this.exact) { 105 | + if (itemstack1.getItem() == itemstack.getItem() && ItemStack.tagMatches(itemstack, itemstack1)) { 106 | + return true; 107 | + } 108 | 109 | - // CraftBukkit start 110 | - if (this.exact) { 111 | - if (itemstack1.getItem() == itemstack.getItem() && ItemStack.tagMatches(itemstack, itemstack1)) { 112 | + continue; 113 | + } 114 | + // CraftBukkit end 115 | + if (itemstack1.is(itemstack.getItem())) { 116 | return true; 117 | } 118 | - 119 | - continue; 120 | - } 121 | - // CraftBukkit end 122 | - if (itemstack1.is(itemstack.getItem())) { 123 | - return true; 124 | } 125 | - } 126 | 127 | - return false; 128 | + return false; 129 | + } 130 | } 131 | } 132 | + // Fusion end 133 | 134 | public IntList getStackingIds() { 135 | if (this.stackingIds == null) { 136 | -------------------------------------------------------------------------------- /patches/server/0056-Fusion-SmoothBootConfiguration.patch: -------------------------------------------------------------------------------- 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 2 | From: IPECTER 3 | Date: Thu, 12 Jan 2023 02:50:31 +0900 4 | Subject: [PATCH] Fusion-SmoothBootConfiguration 5 | 6 | 7 | diff --git a/src/main/java/com/github/ipecter/fusion/FusionConfig.java b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 8 | index 6f9cf69d508b0b6acb3bdab5fbf8e0a676533f81..2fff427280b41a23be379e55702c367ca0ef28fc 100644 9 | --- a/src/main/java/com/github/ipecter/fusion/FusionConfig.java 10 | +++ b/src/main/java/com/github/ipecter/fusion/FusionConfig.java 11 | @@ -283,4 +283,14 @@ public class FusionConfig { 12 | private static void vmpConfigSetup() { 13 | vmpGeneralSpawnDensityCap = getBoolean("vmp.general.spawn-density-cap", vmpGeneralSpawnDensityCap) && vmpEnable; 14 | } 15 | + 16 | + public static boolean smoothBootEnable = true; 17 | + 18 | + private static void smoothBootConfig() { 19 | + setComment("smooth-boot", "[ Smooth Boot ] Thread Scheduling Improvement and Tweak Mod"); 20 | + smoothBootEnable = getBoolean("smooth-boot.enable", smoothBootEnable); 21 | + } 22 | + 23 | + private static void smoothBootConfigSetup() { 24 | + } 25 | } 26 | \ No newline at end of file 27 | -------------------------------------------------------------------------------- /scripts/Clear.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | taskkill /f /t /im java.exe >> NUL 3 | taskkill /f /t /im git.exe >> NUL 4 | rd /s /q ../Fusion-API >> NUL 5 | rd /s /q ../Fusion-Server >> NUL 6 | rd /s /q ../.gradle >> NUL 7 | echo Complete. -------------------------------------------------------------------------------- /scripts/ClearCache.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | taskkill /f /t /im java.exe >> NUL 3 | taskkill /f /t /im git.exe >> NUL 4 | rd /s /q ../.gradle >> NUL 5 | echo Complete. -------------------------------------------------------------------------------- /scripts/CommitAPI.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # CommitAPI 4 | 5 | PS1="$" 6 | 7 | cd ../Fusion-API 8 | 9 | git add . 10 | git commit --allow-empty -m $1 -------------------------------------------------------------------------------- /scripts/CommitServer.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # CommitServer 4 | 5 | PS1="$" 6 | 7 | cd ../Fusion-Server 8 | 9 | git add . 10 | git commit -m $1 -------------------------------------------------------------------------------- /scripts/CreateAPIFixupPatch.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cd ../Fusion-API >> NUL 3 | git add . >> NUL 4 | git commit -m "fixup" >> NUL 5 | git format-patch -1 >> NUL 6 | 0001-fixup.patch >> NUL 7 | cd .. >> NUL 8 | echo Complete. -------------------------------------------------------------------------------- /scripts/CreateServerFixupPatch.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cd ../Fusion-Server >> NUL 3 | git add . >> NUL 4 | git commit -m "fixup" >> NUL 5 | git format-patch -1 >> NUL 6 | 0001-fixup.patch >> NUL 7 | cd .. >> NUL 8 | echo Complete. -------------------------------------------------------------------------------- /scripts/FixFileNameLengthProblem.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | git config --global core.longpaths true -------------------------------------------------------------------------------- /scripts/RemoveAPIDir.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | taskkill /f /t /im java.exe >> NUL 3 | taskkill /f /t /im git.exe >> NUL 4 | rd /s /q ../Fusion-API >> NUL 5 | echo Complete. -------------------------------------------------------------------------------- /scripts/RemoveServerDir.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | taskkill /f /t /im java.exe >> NUL 3 | taskkill /f /t /im git.exe >> NUL 4 | rd /s /q ../Fusion-Server >> NUL 5 | echo Complete. -------------------------------------------------------------------------------- /scripts/UpstreamCommit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # requires curl & jq 4 | # upstreamCommit 5 | 6 | current=$(cat ../gradle.properties | grep purpurRef | sed 's/purpurRef = //') 7 | upstream=$(git ls-remote https://github.com/PurpurMC/Purpur | grep ver/1.19.3 | cut -f 1) 8 | 9 | purpur=$(curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/PurpurMC/Purpur/compare/$current...$upstream | jq -r '.commits[] | "PurpurMC/Purpur@\(.sha[:7]) \(.commit.message | split("\r\n")[0] | split("\n")[0])"') 10 | 11 | echo "Current: $current" 12 | echo "Upstream: $upstream" 13 | 14 | 15 | if [ $current == $upstream ]; then 16 | echo "Equal" 17 | exit 0 18 | fi 19 | 20 | updated="" 21 | logsuffix="" 22 | 23 | if [ ! -z "purpur" ]; then 24 | logsuffix="$logsuffix\n\nPurpur Changes:\n$purpur" 25 | updated="Purpur" 26 | fi 27 | 28 | disclaimer="Upstream has released updates that appear to apply and compile correctly" 29 | 30 | log="${UP_LOG_PREFIX}Updated Upstream ($updated)\n\n${disclaimer}${logsuffix}" 31 | 32 | sed -i 's/purpurRef = .*/purpurRef = '"$upstream"'/' ../gradle.properties 33 | 34 | git add ../gradle.properties 35 | echo -e "$log" | git commit -F - 36 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven("https://papermc.io/repo/repository/maven-public/") 5 | } 6 | } 7 | 8 | rootProject.name = "Fusion" 9 | include("Fusion-API", "Fusion-Server") 10 | 11 | --------------------------------------------------------------------------------