├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── feature_request.yml └── workflows │ ├── build.yml │ ├── gradle.yml │ ├── matrix_prep.yml │ ├── release.yml │ └── scripts │ ├── matrix.py │ └── summary.py ├── .gitignore ├── HEADER.txt ├── LICENSE ├── README.md ├── build.gradle ├── common.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── settings.gradle ├── settings.json ├── src └── main │ ├── java │ └── me │ │ └── fallenbreath │ │ └── morestatistics │ │ ├── MoreStatisticsCommand.java │ │ ├── MoreStatisticsMod.java │ │ ├── MoreStatisticsRegistry.java │ │ ├── MoreStatisticsScoreboardCriterion.java │ │ ├── mixins │ │ ├── core │ │ │ ├── CommandManagerMixin.java │ │ │ ├── scoreboard │ │ │ │ ├── ObjectiveCriteriaArgumentTypeMixin.java │ │ │ │ ├── ScoreboardCriterionAccessor.java │ │ │ │ └── ScoreboardCriterionMixin.java │ │ │ └── stats │ │ │ │ ├── ServerStatHandlerMixin.java │ │ │ │ ├── StatsAccessor.java │ │ │ │ ├── StatsMixin.java │ │ │ │ └── StatsScreenMixin.java │ │ ├── network │ │ │ └── FanetlibPacketRegistrationCenterMixin.java │ │ ├── scoreboard │ │ │ └── blockPlacedCount │ │ │ │ └── BlockItemMixin.java │ │ └── stats │ │ │ ├── break_bedrock │ │ │ ├── BlockItemMixin.java │ │ │ ├── MinecraftServerMixin.java │ │ │ └── PistonBlockMixin.java │ │ │ ├── ender_pearl_one_cm │ │ │ └── ThrownEnderpearlEntityMixin.java │ │ │ ├── firework_boost │ │ │ └── FireworkItemMixin.java │ │ │ ├── mend_durability │ │ │ └── ExperienceOrbEntityMixin.java │ │ │ └── summon_phantom │ │ │ └── PhantomSpawnerMixin.java │ │ ├── network │ │ ├── ClientHandler.java │ │ ├── MoreStatisticsPayload.java │ │ ├── Network.java │ │ └── ServerHandler.java │ │ └── utils │ │ ├── DimensionWrapper.java │ │ ├── DummyClass.java │ │ ├── IdentifierUtil.java │ │ ├── PistonPlacingMemory.java │ │ └── Util.java │ └── resources │ ├── assets │ └── more-statistics │ │ ├── icon.png │ │ └── lang │ │ ├── en_us.yml │ │ └── zh_cn.yml │ ├── fabric.mod.json │ └── more-statistics.mixins.json └── versions ├── 1.14.4 └── gradle.properties ├── 1.15.2 └── gradle.properties ├── 1.16.5 └── gradle.properties ├── 1.17.1 └── gradle.properties ├── 1.18.2 └── gradle.properties ├── 1.19.4 └── gradle.properties ├── 1.20.4 └── gradle.properties ├── 1.20.6 └── gradle.properties ├── 1.21.1 ├── gradle.properties └── src │ └── main │ └── java │ └── me │ └── fallenbreath │ └── morestatistics │ └── mixins │ └── stats │ ├── ender_pearl_one_cm │ └── ThrownEnderpearlEntityMixin.java │ └── mend_durability │ └── ExperienceOrbEntityMixin.java ├── 1.21.3 └── gradle.properties ├── 1.21.4 └── gradle.properties ├── 1.21.5 └── gradle.properties └── mainProject /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Something doesn't seem correct and it might be a bug 3 | labels: [] 4 | body: 5 | - type: textarea 6 | id: description 7 | attributes: 8 | label: Bug description 9 | description: | 10 | A clear and concise description of what the bug is. 11 | Is it a game crash, an unexpected behavior, or has something gone wrong? 12 | If applicable, add screenshots to help explain the bug. 13 | placeholder: Tell us what you see! 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: to-reproduce 18 | attributes: 19 | label: Steps to reproduce 20 | description: Steps to reproduce the bug 21 | placeholder: | 22 | 1. Create a world 23 | 2. Wait until midnight 24 | 3. Hug a creeper 25 | validations: 26 | required: true 27 | - type: textarea 28 | id: expected-behavior 29 | attributes: 30 | label: Expected behavior 31 | description: What did you expect to happen? 32 | placeholder: The creeper explodes 33 | - type: textarea 34 | id: actual-behavior 35 | attributes: 36 | label: Actual behavior 37 | description: What actually happened? 38 | placeholder: The creeper launches itself into the sky 39 | - type: textarea 40 | id: logs 41 | attributes: 42 | label: Relevant logs 43 | description: |- 44 | If it's a crash, send the corresponding Minecraft log in the `logs` folder, or crash report in the `crash-reports` folder, here. 45 | Please upload the log file as an attachment, or upload the log to [pastebin](https://pastebin.com/) / [mclo.gs](https://mclo.gs/) and paste the url here. 46 | Please refrain from pasting the entire log file directly. 47 | Leave empty if there is none. 48 | placeholder: https://pastebin.com/J6b7lKxR 49 | - type: input 50 | id: minecraft-version 51 | attributes: 52 | label: Minecraft version 53 | description: The Minecraft version(s) where this bug occurs in. 54 | placeholder: 1.15.2 55 | validations: 56 | required: true 57 | - type: input 58 | id: mod-version 59 | attributes: 60 | label: More Statistics version 61 | description: The More Statistics version(s) where this bug occurs in. 62 | placeholder: 1.2.3 63 | validations: 64 | required: true 65 | - type: textarea 66 | id: other-information 67 | attributes: 68 | label: Other information 69 | description: Other useful information to this bug report, e.g. other related mod version(s). Leave empty if there is none. 70 | placeholder: The issue only occurs if the player is in survival mode 71 | - type: checkboxes 72 | id: check-list 73 | attributes: 74 | label: Check list 75 | options: 76 | - label: I have verified that the issue persists in the latest version of the mod. 77 | required: true 78 | - label: I have searched the existing issues and confirmed that this is not a duplicate. 79 | required: true 80 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Suggest an idea for this project 3 | labels: [] 4 | body: 5 | - type: textarea 6 | id: motivation 7 | attributes: 8 | label: Motivation 9 | description: Why do you want this feature? What problem do you want to solve? How can the suggested feature help with that? 10 | placeholder: Tell us what you want! 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: description 15 | attributes: 16 | label: Description 17 | description: Describe the feature you want, as detailed as possible 18 | placeholder: I want to see a fancy starry sky when I look up at midnight. 19 | validations: 20 | required: true 21 | - type: textarea 22 | id: other-information 23 | attributes: 24 | label: Other information 25 | description: Other useful information to this feature request. Leave empty if there is none. 26 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: _step.build 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | release: 7 | type: boolean 8 | required: false 9 | default: false 10 | target_subproject: 11 | description: see release.yml, leave it empty to build all 12 | type: string 13 | required: false 14 | default: '' 15 | mixin_audit: 16 | description: run mixin audit for Minecraft after build 17 | type: boolean 18 | required: false 19 | default: false 20 | 21 | jobs: 22 | build: 23 | runs-on: ubuntu-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Set up JDK 21 28 | uses: actions/setup-java@v4 29 | with: 30 | distribution: 'temurin' 31 | java-version: 21 32 | 33 | - name: Cache gradle files 34 | uses: actions/cache@v4 35 | with: 36 | path: | 37 | ~/.gradle/caches 38 | ~/.gradle/wrapper 39 | ./.gradle/loom-cache 40 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle.properties', '**/*.accesswidener', 'settings.json') }} 41 | restore-keys: | 42 | ${{ runner.os }}-gradle- 43 | 44 | - name: Build with gradle 45 | run: | 46 | chmod +x gradlew 47 | if [ -z "${{ inputs.target_subproject }}" ]; then 48 | echo "Building all subprojects" 49 | ./gradlew build 50 | else 51 | args=$(echo "${{ inputs.target_subproject }}" | tr ',' '\n' | sed 's/$/:build/' | paste -sd ' ') 52 | echo "Building with arguments=$args" 53 | ./gradlew $args 54 | fi 55 | env: 56 | BUILD_ID: ${{ github.run_number }} 57 | BUILD_RELEASE: ${{ inputs.release }} 58 | 59 | - name: Run mixin audit check for Minecraft client 60 | if: ${{ inputs.mixin_audit }} 61 | timeout-minutes: 10 62 | run: | 63 | mkdir -p ./run 64 | echo eula=true > ./run/eula.txt 65 | ./gradlew runClientMixinAudit 66 | 67 | - name: Upload artifacts 68 | uses: actions/upload-artifact@v4 69 | with: 70 | name: build-artifacts 71 | path: versions/*/build/libs/ 72 | 73 | - name: Collect mod jars 74 | run: | 75 | shopt -s extglob 76 | mkdir mod-jars 77 | for jar in versions/*/build/libs/!(*-@(dev|sources|shadow)).jar; do 78 | cp -p "$jar" mod-jars/ 79 | done 80 | ls -l mod-jars 81 | 82 | # This is the artifact recommended for users to download 83 | - name: Upload mod jars 84 | uses: actions/upload-artifact@v4 85 | with: 86 | name: mod-jars 87 | path: mod-jars/*.jar 88 | 89 | - name: Publish with gradle 90 | if: inputs.release || github.ref == 'refs/heads/dev' 91 | run: | 92 | if [ -z "${{ inputs.target_subproject }}" ]; then 93 | echo "Publishing all subprojects" 94 | ./gradlew publish 95 | else 96 | args=$(echo "${{ inputs.target_subproject }}" | tr ',' '\n' | sed 's/$/:publish/' | paste -sd ' ') 97 | echo "Publishing with arguments=$args" 98 | ./gradlew $args 99 | fi 100 | env: 101 | BUILD_ID: ${{ github.run_number }} 102 | BUILD_RELEASE: ${{ inputs.release }} 103 | FALLENS_MAVEN_TOKEN: ${{ secrets.FALLENS_MAVEN_TOKEN }} 104 | 105 | summary: 106 | runs-on: ubuntu-latest 107 | needs: 108 | - build 109 | 110 | steps: 111 | - uses: actions/checkout@v4 112 | - uses: actions/setup-python@v5 113 | with: 114 | python-version: 3.12 115 | 116 | - name: Download build artifacts 117 | uses: actions/download-artifact@v4 118 | with: 119 | name: build-artifacts 120 | path: build-artifacts 121 | 122 | - name: Make build summary 123 | run: | 124 | pip install jproperties 125 | python .github/workflows/scripts/summary.py 126 | env: 127 | TARGET_SUBPROJECT: ${{ inputs.target_subproject }} 128 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Dev Builds 2 | 3 | on: 4 | push: 5 | paths: 6 | - "*.gradle" 7 | - "gradle.properties" 8 | - "src/**" 9 | - "versions/**" 10 | - ".github/**" 11 | pull_request: 12 | 13 | 14 | jobs: 15 | build: 16 | uses: ./.github/workflows/build.yml 17 | secrets: inherit 18 | with: 19 | mixin_audit: true 20 | -------------------------------------------------------------------------------- /.github/workflows/matrix_prep.yml: -------------------------------------------------------------------------------- 1 | name: _step.matrix_prepare 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | target_subproject: 7 | description: see release.yml, for generating matrix entries 8 | type: string 9 | required: false 10 | default: '' 11 | outputs: 12 | matrix: 13 | description: The generated run matrix 14 | value: ${{ jobs.matrix_prep.outputs.matrix }} 15 | 16 | 17 | jobs: 18 | matrix_prep: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | - uses: actions/setup-python@v5 23 | with: 24 | python-version: 3.12 25 | 26 | - id: setmatrix 27 | run: python .github/workflows/scripts/matrix.py 28 | env: 29 | TARGET_SUBPROJECT: ${{ inputs.target_subproject }} 30 | 31 | outputs: 32 | matrix: ${{ steps.setmatrix.outputs.matrix }} 33 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | # release: (release title) 4 | # dispatch (all): Manual release for $target_release_tag 5 | # dispatch (specified): Manual release for $target_release_tag (subproject: $target_subproject) 6 | run-name: |- 7 | ${{ github.event_name == 'workflow_dispatch' && format('Manual release for {0}{1}', inputs.target_release_tag, inputs.target_subproject && format(' (subproject: {0})', inputs.target_subproject) || '') || '' }} 8 | 9 | on: 10 | release: 11 | types: 12 | - published 13 | workflow_dispatch: 14 | inputs: 15 | target_subproject: 16 | description: |- 17 | The subproject name(s) of the specified Minecraft version to be released, seperated with ",". 18 | By default all subprojects will be released 19 | type: string 20 | required: false 21 | default: '' 22 | target_release_tag: 23 | description: The tag of the release you want to append the artifact to 24 | type: string 25 | required: true 26 | 27 | 28 | jobs: 29 | show_action_parameters: 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Show action parameters 33 | run: | 34 | cat < $GITHUB_STEP_SUMMARY 35 | ## Action Parameters 36 | - target_subproject: \`${{ github.event.inputs.target_subproject }}\` 37 | - target_release_tag: \`${{ github.event.inputs.target_release_tag }}\` 38 | EOF 39 | 40 | matrix_prep: 41 | uses: ./.github/workflows/matrix_prep.yml 42 | with: 43 | target_subproject: ${{ github.event.inputs.target_subproject }} 44 | 45 | # ensure the input release tag is valid 46 | validate_release: 47 | runs-on: ubuntu-latest 48 | steps: 49 | - name: Get github release information 50 | if: ${{ github.event_name == 'workflow_dispatch' }} 51 | uses: cardinalby/git-get-release-action@1.2.5 52 | env: 53 | GITHUB_TOKEN: ${{ github.token }} 54 | with: 55 | tag: ${{ github.event.inputs.target_release_tag }} 56 | 57 | build: 58 | uses: ./.github/workflows/build.yml 59 | secrets: inherit 60 | needs: 61 | - validate_release 62 | with: 63 | target_subproject: ${{ github.event.inputs.target_subproject }} 64 | release: true 65 | 66 | release: 67 | needs: 68 | - matrix_prep 69 | - build 70 | runs-on: ubuntu-latest 71 | 72 | # allow the mod publish step to add asserts to release 73 | # https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token 74 | permissions: 75 | contents: write 76 | 77 | strategy: 78 | matrix: ${{ fromJson(needs.matrix_prep.outputs.matrix) }} 79 | 80 | steps: 81 | - uses: actions/checkout@v4 82 | 83 | - name: Display context 84 | run: | 85 | echo ref_name = ${{ github.ref_name }} 86 | echo target_subproject = ${{ github.event.inputs.target_subproject }} 87 | echo target_release_tag = ${{ github.event.inputs.target_release_tag }} 88 | 89 | - name: Download build artifacts 90 | uses: actions/download-artifact@v4 91 | with: 92 | name: build-artifacts 93 | path: build-artifacts 94 | 95 | - name: Get github release information 96 | if: ${{ github.event_name == 'workflow_dispatch' }} 97 | id: get_release 98 | uses: cardinalby/git-get-release-action@1.2.5 99 | env: 100 | GITHUB_TOKEN: ${{ github.token }} 101 | with: 102 | tag: ${{ github.event.inputs.target_release_tag }} 103 | 104 | - name: Generate publish related information 105 | id: release_info 106 | run: | 107 | if [ $GITHUB_EVENT_NAME == 'release' ] 108 | then 109 | # Leave an empty value here, so Kir-Antipov/mc-publish will infer the tag from the action context 110 | echo "tag_name=" >> $GITHUB_OUTPUT 111 | elif [ $GITHUB_EVENT_NAME == 'workflow_dispatch' ] 112 | then 113 | echo "tag_name=${{ github.event.inputs.target_release_tag }}" >> $GITHUB_OUTPUT 114 | else 115 | echo Unknown github event name $GITHUB_EVENT_NAME 116 | exit 1 117 | fi 118 | 119 | - name: Read common properties 120 | id: properties_g 121 | uses: BrycensRanch/read-properties-action@v1 122 | with: 123 | file: gradle.properties 124 | all: true 125 | 126 | - name: Read version-specific properties 127 | id: properties_v 128 | uses: BrycensRanch/read-properties-action@v1 129 | with: 130 | file: ${{ format('versions/{0}/gradle.properties', matrix.subproject) }} 131 | all: true 132 | 133 | - name: Prepare file information 134 | id: file_info 135 | run: | 136 | shopt -s extglob 137 | FILE_PATHS=$(ls ${{ format('build-artifacts/{0}/build/libs/!(*-@(dev|sources|shadow)).jar', matrix.subproject) }}) 138 | if (( ${#FILE_PATHS[@]} != 1 )); then 139 | echo "Error: Found ${#FILE_PATHS[@]} files, expected exactly 1" 140 | exit 1 141 | else 142 | FILE_PATH=${FILE_PATHS[0]} 143 | fi 144 | 145 | FILE_NAME=$(basename $FILE_PATH) 146 | FILE_HASH=$(sha256sum $FILE_PATH | awk '{ print $1 }') 147 | echo "path=$FILE_PATH" >> $GITHUB_OUTPUT 148 | echo "name=$FILE_NAME" >> $GITHUB_OUTPUT 149 | echo "hash=$FILE_HASH" >> $GITHUB_OUTPUT 150 | cat $GITHUB_OUTPUT 151 | 152 | - name: Prepare changelog 153 | uses: actions/github-script@v7 154 | id: changelog 155 | with: 156 | script: return process.env.CHANGELOG 157 | result-encoding: string 158 | env: 159 | CHANGELOG: |- 160 | ${{ format('{0}{1}', github.event.release.body, steps.get_release.outputs.body) }} 161 | 162 | ------- 163 | 164 | Build Information 165 | 166 | - File name: `${{ steps.file_info.outputs.name }}` 167 | - SHA-256: `${{ steps.file_info.outputs.hash }}` 168 | - Built from: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 169 | 170 | - name: Publish Minecraft Mods 171 | uses: Kir-Antipov/mc-publish@v3.3 172 | with: 173 | # https://modrinth.com/settings/pats 174 | modrinth-id: EhoUIqvO 175 | modrinth-token: ${{ secrets.MODRINTH_API_TOKEN }} 176 | 177 | # https://legacy.curseforge.com/account/api-tokens 178 | # curseforge-id: 314159 179 | # curseforge-token: ${{ secrets.CF_API_TOKEN }} 180 | 181 | github-tag: ${{ steps.release_info.outputs.tag_name }} 182 | github-token: ${{ secrets.GITHUB_TOKEN }} 183 | 184 | files: ${{ steps.file_info.outputs.path }} 185 | 186 | name: ${{ format('{0} v{1} for mc{2}', steps.properties_g.outputs.mod_name, steps.properties_g.outputs.mod_version, steps.properties_v.outputs.minecraft_version) }} 187 | version: ${{ format('v{1}-mc{0}', steps.properties_v.outputs.minecraft_version, steps.properties_g.outputs.mod_version) }} 188 | version-type: release 189 | 190 | loaders: fabric 191 | game-versions: ${{ steps.properties_v.outputs.game_versions }} 192 | game-version-filter: any 193 | dependencies: '' # declare the dependencies explicitly, so mc-publish won't try to load from fabric.mod.json 194 | 195 | github-changelog: ${{ format('{0}{1}', github.event.release.body, steps.get_release.outputs.body) }} 196 | modrinth-changelog: ${{ steps.changelog.outputs.result }} 197 | curseforge-changelog: ${{ steps.changelog.outputs.result }} 198 | 199 | retry-attempts: 3 200 | retry-delay: 10000 201 | -------------------------------------------------------------------------------- /.github/workflows/scripts/matrix.py: -------------------------------------------------------------------------------- 1 | """ 2 | A script to scan through the versions directory and collect all folder names as the subproject list, 3 | then output a json as the github action include matrix 4 | """ 5 | __author__ = 'Fallen_Breath' 6 | 7 | import json 8 | import os 9 | import sys 10 | 11 | 12 | def main(): 13 | target_subproject_env = os.environ.get('TARGET_SUBPROJECT', '') 14 | target_subprojects = list(filter(None, target_subproject_env.split(',') if target_subproject_env != '' else [])) 15 | print('target_subprojects: {}'.format(target_subprojects)) 16 | 17 | with open('settings.json') as f: 18 | settings: dict = json.load(f) 19 | 20 | if len(target_subprojects) == 0: 21 | subprojects = settings['versions'] 22 | else: 23 | subprojects = [] 24 | for subproject in settings['versions']: 25 | if subproject in target_subprojects: 26 | subprojects.append(subproject) 27 | target_subprojects.remove(subproject) 28 | if len(target_subprojects) > 0: 29 | print('Unexpected subprojects: {}'.format(target_subprojects), file=sys.stderr) 30 | sys.exit(1) 31 | 32 | matrix_entries = [] 33 | for subproject in subprojects: 34 | matrix_entries.append({ 35 | 'subproject': subproject, 36 | }) 37 | matrix = {'include': matrix_entries} 38 | with open(os.environ['GITHUB_OUTPUT'], 'w') as f: 39 | f.write('matrix={}\n'.format(json.dumps(matrix))) 40 | 41 | print('matrix:') 42 | print(json.dumps(matrix, indent=2)) 43 | 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /.github/workflows/scripts/summary.py: -------------------------------------------------------------------------------- 1 | """ 2 | A script to scan through all valid mod jars in build-artifacts.zip/$version/build/libs, 3 | and generate an artifact summary table for that to GitHub action step summary 4 | """ 5 | __author__ = 'Fallen_Breath' 6 | 7 | import functools 8 | import glob 9 | import hashlib 10 | import json 11 | import os 12 | 13 | import jproperties 14 | 15 | 16 | def read_prop(file_name: str, key: str) -> str: 17 | configs = jproperties.Properties() 18 | with open(file_name, 'rb') as f: 19 | configs.load(f) 20 | return configs[key].data 21 | 22 | 23 | def get_sha256_hash(file_path: str) -> str: 24 | sha256_hash = hashlib.sha256() 25 | 26 | with open(file_path, 'rb') as f: 27 | for buf in iter(functools.partial(f.read, 4096), b''): 28 | sha256_hash.update(buf) 29 | 30 | return sha256_hash.hexdigest() 31 | 32 | 33 | def main(): 34 | target_subproject_env = os.environ.get('TARGET_SUBPROJECT', '') 35 | target_subprojects = list(filter(None, target_subproject_env.split(',') if target_subproject_env != '' else [])) 36 | print('target_subprojects: {}'.format(target_subprojects)) 37 | 38 | with open('settings.json') as f: 39 | settings: dict = json.load(f) 40 | 41 | with open(os.environ['GITHUB_STEP_SUMMARY'], 'w') as f: 42 | f.write('## Build Artifacts Summary\n\n') 43 | f.write('| Subproject | for Minecraft | File | Size | SHA-256 |\n') 44 | f.write('| --- | --- | --- | --- | --- |\n') 45 | 46 | warnings = [] 47 | for subproject in settings['versions']: 48 | if len(target_subprojects) > 0 and subproject not in target_subprojects: 49 | print('skipping {}'.format(subproject)) 50 | continue 51 | game_versions = read_prop('versions/{}/gradle.properties'.format(subproject), 'game_versions') 52 | game_versions = game_versions.strip().replace('\r', '').replace('\n', ', ') 53 | file_paths = glob.glob('build-artifacts/{}/build/libs/*.jar'.format(subproject)) 54 | file_paths = list(filter(lambda fp: not fp.endswith('-sources.jar') and not fp.endswith('-dev.jar') and not fp.endswith('-shadow.jar'), file_paths)) 55 | if len(file_paths) == 0: 56 | file_name = '*not found*' 57 | sha256 = '*N/A*' 58 | else: 59 | file_name = '`{}`'.format(os.path.basename(file_paths[0])) 60 | file_size = '{} B'.format(os.path.getsize(file_paths[0])) 61 | sha256 = '`{}`'.format(get_sha256_hash(file_paths[0])) 62 | if len(file_paths) > 1: 63 | warnings.append('Found too many build files in subproject {}: {}'.format(subproject, ', '.join(file_paths))) 64 | 65 | f.write('| {} | {} | {} | {} | {} |\n'.format(subproject, game_versions, file_name, file_size, sha256)) 66 | 67 | if len(warnings) > 0: 68 | f.write('\n### Warnings\n\n') 69 | for warning in warnings: 70 | f.write('- {}\n'.format(warning)) 71 | 72 | 73 | if __name__ == '__main__': 74 | main() 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # gradle 2 | 3 | .gradle/ 4 | build/ 5 | out/ 6 | classes/ 7 | 8 | # eclipse 9 | 10 | *.launch 11 | 12 | # idea 13 | 14 | .idea/ 15 | *.iml 16 | *.ipr 17 | *.iws 18 | 19 | # vscode 20 | 21 | .settings/ 22 | .vscode/ 23 | bin/ 24 | .classpath 25 | .project 26 | 27 | # fabric 28 | 29 | run/ 30 | /logs/latest.log 31 | -------------------------------------------------------------------------------- /HEADER.txt: -------------------------------------------------------------------------------- 1 | This file is part of the ${name} project, licensed under the 2 | GNU Lesser General Public License v3.0 3 | 4 | Copyright (C) ${year} ${author} and contributors 5 | 6 | ${name} is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | ${name} is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with ${name}. If not, see . 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | More Statistics 2 | ----------- 3 | 4 | [![Modrinth](https://img.shields.io/modrinth/dt/EhoUIqvO?label=Modrinth%20Downloads)](https://modrinth.com/mod/more-statistics) 5 | 6 | A light-weight mod to add custom statistics to the game and more 7 | 8 | Install it on your fabric server and enjoy new statistics 9 | 10 | If you have also installed it on your client you can query the custom statistics in the statistics screen too 11 | 12 | 13 | # Statistics List 14 | 15 | ## break_bedrock 16 | 17 | When a bedrock is deleted by a piston or a sticky piston, the player who placed a piston block at that position in the previous gametick increases this stat by 1 18 | 19 | Criteria: `minecraft.custom:minecraft.break_bedrock` 20 | 21 | ## ender_pearl_one_cm 22 | 23 | When the player uses an ender pearl to teleport, the value of this statistic will increase the distance between the teleportation's origin position and destination position 24 | 25 | For MC >= 1.21, only teleportations within the same dimension will increase this stat 26 | 27 | Criteria: `minecraft.custom:minecraft.ender_pearl_one_cm` 28 | 29 | ## firework_boost 30 | 31 | Increases when a player uses a firework rocket to speed up in elytra flight 32 | 33 | Criteria: `minecraft.custom:minecraft.firework_boost` 34 | 35 | ## mend_durability 36 | 37 | Increases when a player repair an item with mending enchantment 38 | 39 | Criteria: `minecraft.custom:minecraft.mend_durability` 40 | 41 | ## summon_phantom 42 | 43 | The total amount of phantom you have summoned 44 | 45 | Criteria: `minecraft.custom:minecraft.summon_phantom` 46 | 47 | 48 | # Scoreboard Criterion 49 | 50 | ## blockPlacedCount 51 | 52 | Triggers when a player places a block 53 | 54 | Technically the time it gets triggered is right after a player uses a `BlockItem` successfully 55 | 56 | Criteria: `blockPlacedCount` 57 | 58 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'maven-publish' 3 | id 'com.github.hierynomus.license' version '0.16.1' apply false 4 | id 'fabric-loom' version '1.10-SNAPSHOT' apply false 5 | 6 | // https://github.com/ReplayMod/preprocessor 7 | // https://github.com/Fallen-Breath/preprocessor 8 | id 'com.replaymod.preprocess' version '9d21b334a7' 9 | 10 | // https://github.com/Fallen-Breath/yamlang 11 | id 'me.fallenbreath.yamlang' version '1.4.1' apply false 12 | } 13 | 14 | preprocess { 15 | strictExtraMappings = false 16 | 17 | def mc114 = createNode('1.14.4', 1_14_04, '') 18 | def mc115 = createNode('1.15.2', 1_15_02, '') 19 | def mc116 = createNode('1.16.5', 1_16_05, '') 20 | def mc117 = createNode('1.17.1', 1_17_01, '') 21 | def mc118 = createNode('1.18.2', 1_18_02, '') 22 | def mc119 = createNode('1.19.4', 1_19_04, '') 23 | def mc1204 = createNode('1.20.4', 1_20_04, '') 24 | def mc1206 = createNode('1.20.6', 1_20_06, '') 25 | def mc1211 = createNode('1.21.1', 1_21_01, '') 26 | def mc1213 = createNode('1.21.3', 1_21_03, '') 27 | def mc1214 = createNode('1.21.4', 1_21_04, '') 28 | def mc1215 = createNode('1.21.5', 1_21_05, '') 29 | 30 | mc115 .link(mc114 , null) 31 | mc115 .link(mc116 , null) 32 | mc116 .link(mc117 , null) 33 | mc117 .link(mc118 , null) 34 | mc118 .link(mc119 , null) 35 | mc119 .link(mc1204, null) 36 | mc1204.link(mc1206, null) 37 | mc1206.link(mc1211, null) 38 | mc1211.link(mc1213, null) 39 | mc1213.link(mc1214, null) 40 | mc1214.link(mc1215, null) 41 | } 42 | 43 | tasks.register('buildAndGather') { 44 | subprojects { 45 | dependsOn project.tasks.named('build').get() 46 | } 47 | doFirst { 48 | println 'Gathering builds' 49 | def buildLibs = { 50 | p -> p.buildDir.toPath().resolve('libs') 51 | } 52 | delete fileTree(buildLibs(rootProject)) { 53 | include '*' 54 | } 55 | subprojects { 56 | copy { 57 | from(buildLibs(project)) { 58 | include '*.jar' 59 | exclude '*-dev.jar', '*-sources.jar', '*-shadow.jar' 60 | } 61 | into buildLibs(rootProject) 62 | duplicatesStrategy = DuplicatesStrategy.INCLUDE 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /common.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven-publish' 2 | apply plugin: 'com.github.hierynomus.license' 3 | apply plugin: 'fabric-loom' 4 | apply plugin: 'com.replaymod.preprocess' 5 | apply plugin: 'me.fallenbreath.yamlang' 6 | 7 | int mcVersion = project.mcVersion 8 | 9 | repositories { 10 | maven { 11 | url = 'https://jitpack.io' 12 | } 13 | maven { 14 | url 'https://www.cursemaven.com' 15 | } 16 | maven { 17 | url = 'https://maven.fallenbreath.me/releases' 18 | } 19 | } 20 | 21 | // https://github.com/FabricMC/fabric-loader/issues/783 22 | configurations { 23 | modRuntimeOnly.exclude group: 'net.fabricmc', module: 'fabric-loader' 24 | } 25 | 26 | dependencies { 27 | // loom 28 | minecraft "com.mojang:minecraft:${project.minecraft_version}" 29 | mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" 30 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" 31 | 32 | // runtime mods 33 | if (mcVersion < 11904) { 34 | modRuntimeOnly(mcVersion < 11900 ? "com.github.astei:lazydfu:0.1.2" : "com.github.Fallen-Breath:lazydfu:a7cfc44c0c") 35 | } 36 | modRuntimeOnly 'me.fallenbreath:mixin-auditor:0.1.0' 37 | 38 | // dependencies 39 | include(modImplementation(fabricApi.module("fabric-resource-loader-v0", project.fabric_api_version))) 40 | 41 | def fanetlibMcVer = mcVersion >= 12100 ? '1.21' : mcVersion >= 12006 ? '1.20.6' : mcVersion >= 12002 ? '1.20.2': '1.15.2' 42 | include(modImplementation("me.fallenbreath:fanetlib:${project.fanetlib_version}-mc${fanetlibMcVer}")) 43 | } 44 | 45 | String MIXIN_CONFIG_PATH = 'more-statistics.mixins.json' 46 | String LANG_DIR = 'assets/more-statistics/lang' 47 | JavaVersion JAVA_COMPATIBILITY 48 | if (mcVersion >= 12005) { 49 | JAVA_COMPATIBILITY = JavaVersion.VERSION_21 50 | } else if (mcVersion >= 11800) { 51 | JAVA_COMPATIBILITY = JavaVersion.VERSION_17 52 | } else if (mcVersion >= 11700) { 53 | JAVA_COMPATIBILITY = JavaVersion.VERSION_16 54 | } else { 55 | JAVA_COMPATIBILITY = JavaVersion.VERSION_1_8 56 | } 57 | JavaVersion MIXIN_COMPATIBILITY_LEVEL = JAVA_COMPATIBILITY 58 | 59 | loom { 60 | def commonVmArgs = ['-Dmixin.debug.export=true', '-Dmixin.debug.countInjections=true'] 61 | runConfigs.configureEach { 62 | // to make sure it generates all "Minecraft Client (:subproject_name)" applications 63 | ideConfigGenerated = true 64 | runDir '../../run' 65 | vmArgs commonVmArgs 66 | } 67 | runs { 68 | def auditVmArgs = [*commonVmArgs, '-DmixinAuditor.audit=true'] 69 | serverMixinAudit { 70 | server() 71 | vmArgs auditVmArgs 72 | ideConfigGenerated false 73 | } 74 | clientMixinAudit { 75 | client() 76 | vmArgs auditVmArgs 77 | ideConfigGenerated false 78 | } 79 | } 80 | } 81 | 82 | String modVersionSuffix = '' 83 | String artifactVersion = project.mod_version 84 | String artifactVersionSuffix = '' 85 | // detect github action environment variables 86 | // https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables 87 | if (System.getenv("BUILD_RELEASE") != "true") { 88 | String buildNumber = System.getenv("BUILD_ID") 89 | modVersionSuffix += buildNumber != null ? ('+build.' + buildNumber) : '-SNAPSHOT' 90 | artifactVersionSuffix = '-SNAPSHOT' // A non-release artifact is always a SNAPSHOT artifact 91 | } 92 | String fullModVersion = project.mod_version + modVersionSuffix 93 | String fullProjectVersion, fullArtifactVersion 94 | 95 | // Example version values: 96 | // project.mod_version 1.0.3 (the base mod version) 97 | // modVersionSuffix +build.88 (use github action build number if possible) 98 | // artifactVersionSuffix -SNAPSHOT 99 | // fullModVersion 1.0.3+build.88 (the actual mod version to use in the mod) 100 | // fullProjectVersion v1.0.3-mc1.15.2+build.88 (in build output jar name) 101 | // fullArtifactVersion 1.0.3-mc1.15.2-SNAPSHOT (maven artifact version) 102 | 103 | group = project.maven_group 104 | if (System.getenv("JITPACK") == "true") { 105 | // move mc version into archivesBaseName, so jitpack will be able to organize archives from multiple subprojects correctly 106 | base.archivesName = project.archives_base_name + '-mc' + project.minecraft_version 107 | fullProjectVersion = 'v' + project.mod_version + modVersionSuffix 108 | fullArtifactVersion = artifactVersion + artifactVersionSuffix 109 | } else { 110 | base.archivesName = project.archives_base_name 111 | fullProjectVersion = 'v' + project.mod_version + '-mc' + project.minecraft_version + modVersionSuffix 112 | fullArtifactVersion = artifactVersion + '-mc' + project.minecraft_version + artifactVersionSuffix 113 | } 114 | version = fullProjectVersion 115 | 116 | // See https://youtrack.jetbrains.com/issue/IDEA-296490 117 | // if IDEA complains about "Cannot resolve resource filtering of MatchingCopyAction" and you want to know why 118 | processResources { 119 | inputs.property "id", project.mod_id 120 | inputs.property "name", project.mod_name 121 | inputs.property "version", fullModVersion 122 | inputs.property "minecraft_dependency", project.minecraft_dependency 123 | 124 | filesMatching("fabric.mod.json") { 125 | def valueMap = [ 126 | "id": project.mod_id, 127 | "name": project.mod_name, 128 | "version": fullModVersion, 129 | "minecraft_dependency": project.minecraft_dependency, 130 | ] 131 | expand valueMap 132 | } 133 | 134 | filesMatching(MIXIN_CONFIG_PATH) { 135 | filter { s -> s.replace('{{COMPATIBILITY_LEVEL}}', "JAVA_${MIXIN_COMPATIBILITY_LEVEL.ordinal() + 1}") } 136 | } 137 | } 138 | 139 | // https://github.com/Fallen-Breath/yamlang 140 | yamlang { 141 | targetSourceSets = [sourceSets.main] 142 | inputDir = LANG_DIR 143 | } 144 | 145 | // ensure that the encoding is set to UTF-8, no matter what the system default is 146 | // this fixes some edge cases with special characters not displaying correctly 147 | // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html 148 | tasks.withType(JavaCompile).configureEach { 149 | options.encoding = "UTF-8" 150 | options.compilerArgs << "-Xlint:deprecation" << "-Xlint:unchecked" 151 | if (JAVA_COMPATIBILITY <= JavaVersion.VERSION_1_8) { 152 | // suppressed "source/target value 8 is obsolete and will be removed in a future release" 153 | options.compilerArgs << '-Xlint:-options' 154 | } 155 | } 156 | 157 | java { 158 | sourceCompatibility = JAVA_COMPATIBILITY 159 | targetCompatibility = JAVA_COMPATIBILITY 160 | 161 | // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task 162 | // if it is present. 163 | // If you remove this line, sources will not be generated. 164 | withSourcesJar() 165 | } 166 | 167 | jar { 168 | from(rootProject.file('LICENSE')) { 169 | rename { "${it}_${project.archives_base_name}" } 170 | } 171 | } 172 | 173 | // https://github.com/hierynomus/license-gradle-plugin 174 | license { 175 | // use "gradle licenseFormat" to apply license headers 176 | header = rootProject.file('HEADER.txt') 177 | include '**/*.java' 178 | skipExistingHeaders = true 179 | 180 | headerDefinitions { 181 | // ref: https://github.com/mathieucarbou/license-maven-plugin/blob/4c42374bb737378f5022a3a36849d5e23ac326ea/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/header/HeaderType.java#L48 182 | // modification: add a newline at the end 183 | SLASHSTAR_STYLE_NEWLINE { 184 | firstLine = "/*" 185 | beforeEachLine = " * " 186 | endLine = " */" + System.lineSeparator() 187 | afterEachLine = "" 188 | skipLinePattern = null 189 | firstLineDetectionPattern = "(\\s|\\t)*/\\*.*\$" 190 | lastLineDetectionPattern = ".*\\*/(\\s|\\t)*\$" 191 | allowBlankLines = false 192 | isMultiline = true 193 | padLines = false 194 | } 195 | } 196 | mapping { 197 | java = 'SLASHSTAR_STYLE_NEWLINE' 198 | } 199 | ext { 200 | name = project.mod_name 201 | author = 'Fallen_Breath' 202 | year = Calendar.getInstance().get(Calendar.YEAR).toString() 203 | } 204 | } 205 | classes.dependsOn licenseFormatMain 206 | testClasses.dependsOn licenseFormatTest 207 | 208 | // configure the maven publication 209 | publishing { 210 | publications { 211 | mavenJava(MavenPublication) { 212 | from components.java 213 | artifactId = base.archivesName.get() 214 | version = fullArtifactVersion 215 | } 216 | } 217 | 218 | // select the repositories you want to publish to 219 | repositories { 220 | // mavenLocal() 221 | 222 | maven { 223 | url = fullArtifactVersion.endsWith("SNAPSHOT") ? "https://maven.fallenbreath.me/snapshots" : "https://maven.fallenbreath.me/releases" 224 | credentials(PasswordCredentials) { 225 | username = 'fallen' 226 | password = System.getenv("FALLENS_MAVEN_TOKEN") 227 | } 228 | authentication { 229 | basic(BasicAuthentication) 230 | } 231 | } 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Gradle Properties 2 | org.gradle.jvmargs=-Xmx6G 3 | 4 | # Fabric Basic Properties 5 | # https://fabricmc.net/versions.html 6 | loader_version=0.16.10 7 | 8 | # Mod Properties 9 | mod_id=more-statistics 10 | mod_name=More Statistics 11 | mod_version=2.3.9 12 | maven_group=me.fallenbreath 13 | archives_base_name=more-statistics 14 | 15 | # Global Dependencies 16 | # https://github.com/Fallen-Breath/fanetlib 17 | fanetlib_version=0.2.2 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fallen-Breath/more-statistics/b25c2d17bfed2ef6662c9b5ec311df7e67e436ee/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /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 | # SPDX-License-Identifier: Apache-2.0 19 | # 20 | 21 | ############################################################################## 22 | # 23 | # Gradle start up script for POSIX generated by Gradle. 24 | # 25 | # Important for running: 26 | # 27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 | # noncompliant, but you have some other compliant shell such as ksh or 29 | # bash, then to run this script, type that shell name before the whole 30 | # command line, like: 31 | # 32 | # ksh Gradle 33 | # 34 | # Busybox and similar reduced shells will NOT work, because this script 35 | # requires all of these POSIX shell features: 36 | # * functions; 37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 | # * compound commands having a testable exit status, especially «case»; 40 | # * various built-in commands including «command», «set», and «ulimit». 41 | # 42 | # Important for patching: 43 | # 44 | # (2) This script targets any POSIX shell, so it avoids extensions provided 45 | # by Bash, Ksh, etc; in particular arrays are avoided. 46 | # 47 | # The "traditional" practice of packing multiple parameters into a 48 | # space-separated string is a well documented source of bugs and security 49 | # problems, so this is (mostly) avoided, by progressively accumulating 50 | # options in "$@", and eventually passing that to Java. 51 | # 52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 | # see the in-line comments for details. 55 | # 56 | # There are tweaks for specific operating systems such as AIX, CygWin, 57 | # Darwin, MinGW, and NonStop. 58 | # 59 | # (3) This script is generated from the Groovy template 60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 | # within the Gradle project. 62 | # 63 | # You can find Gradle at https://github.com/gradle/gradle/. 64 | # 65 | ############################################################################## 66 | 67 | # Attempt to set APP_HOME 68 | 69 | # Resolve links: $0 may be a link 70 | app_path=$0 71 | 72 | # Need this for daisy-chained symlinks. 73 | while 74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 | [ -h "$app_path" ] 76 | do 77 | ls=$( ls -ld "$app_path" ) 78 | link=${ls#*' -> '} 79 | case $link in #( 80 | /*) app_path=$link ;; #( 81 | *) app_path=$APP_HOME$link ;; 82 | esac 83 | done 84 | 85 | # This is normally unused 86 | # shellcheck disable=SC2034 87 | APP_BASE_NAME=${0##*/} 88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s 90 | ' "$PWD" ) || exit 91 | 92 | # Use the maximum available, or set MAX_FD != -1 to use that value. 93 | MAX_FD=maximum 94 | 95 | warn () { 96 | echo "$*" 97 | } >&2 98 | 99 | die () { 100 | echo 101 | echo "$*" 102 | echo 103 | exit 1 104 | } >&2 105 | 106 | # OS specific support (must be 'true' or 'false'). 107 | cygwin=false 108 | msys=false 109 | darwin=false 110 | nonstop=false 111 | case "$( uname )" in #( 112 | CYGWIN* ) cygwin=true ;; #( 113 | Darwin* ) darwin=true ;; #( 114 | MSYS* | MINGW* ) msys=true ;; #( 115 | NONSTOP* ) nonstop=true ;; 116 | esac 117 | 118 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 119 | 120 | 121 | # Determine the Java command to use to start the JVM. 122 | if [ -n "$JAVA_HOME" ] ; then 123 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 124 | # IBM's JDK on AIX uses strange locations for the executables 125 | JAVACMD=$JAVA_HOME/jre/sh/java 126 | else 127 | JAVACMD=$JAVA_HOME/bin/java 128 | fi 129 | if [ ! -x "$JAVACMD" ] ; then 130 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 131 | 132 | Please set the JAVA_HOME variable in your environment to match the 133 | location of your Java installation." 134 | fi 135 | else 136 | JAVACMD=java 137 | if ! command -v java >/dev/null 2>&1 138 | then 139 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 140 | 141 | Please set the JAVA_HOME variable in your environment to match the 142 | location of your Java installation." 143 | fi 144 | fi 145 | 146 | # Increase the maximum file descriptors if we can. 147 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 148 | case $MAX_FD in #( 149 | max*) 150 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 151 | # shellcheck disable=SC2039,SC3045 152 | MAX_FD=$( ulimit -H -n ) || 153 | warn "Could not query maximum file descriptor limit" 154 | esac 155 | case $MAX_FD in #( 156 | '' | soft) :;; #( 157 | *) 158 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 159 | # shellcheck disable=SC2039,SC3045 160 | ulimit -n "$MAX_FD" || 161 | warn "Could not set maximum file descriptor limit to $MAX_FD" 162 | esac 163 | fi 164 | 165 | # Collect all arguments for the java command, stacking in reverse order: 166 | # * args from the command line 167 | # * the main class name 168 | # * -classpath 169 | # * -D...appname settings 170 | # * --module-path (only if needed) 171 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 172 | 173 | # For Cygwin or MSYS, switch paths to Windows format before running java 174 | if "$cygwin" || "$msys" ; then 175 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 176 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 177 | 178 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 179 | 180 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 181 | for arg do 182 | if 183 | case $arg in #( 184 | -*) false ;; # don't mess with options #( 185 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 186 | [ -e "$t" ] ;; #( 187 | *) false ;; 188 | esac 189 | then 190 | arg=$( cygpath --path --ignore --mixed "$arg" ) 191 | fi 192 | # Roll the args list around exactly as many times as the number of 193 | # args, so each arg winds up back in the position where it started, but 194 | # possibly modified. 195 | # 196 | # NB: a `for` loop captures its iteration list before it begins, so 197 | # changing the positional parameters here affects neither the number of 198 | # iterations, nor the values presented in `arg`. 199 | shift # remove old arg 200 | set -- "$@" "$arg" # push replacement arg 201 | done 202 | fi 203 | 204 | 205 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 206 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 207 | 208 | # Collect all arguments for the java command: 209 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 210 | # and any embedded shellness will be escaped. 211 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 212 | # treated as '${Hostname}' itself on the command line. 213 | 214 | set -- \ 215 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 216 | -classpath "$CLASSPATH" \ 217 | org.gradle.wrapper.GradleWrapperMain \ 218 | "$@" 219 | 220 | # Stop when "xargs" is not available. 221 | if ! command -v xargs >/dev/null 2>&1 222 | then 223 | die "xargs is not available" 224 | fi 225 | 226 | # Use "xargs" to parse quoted args. 227 | # 228 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 229 | # 230 | # In Bash we could simply go: 231 | # 232 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 233 | # set -- "${ARGS[@]}" "$@" 234 | # 235 | # but POSIX shell has neither arrays nor command substitution, so instead we 236 | # post-process each arg (as a line of input to sed) to backslash-escape any 237 | # character that might be a shell metacharacter, then use eval to reverse 238 | # that process (while maintaining the separation between arguments), and wrap 239 | # the whole thing up as a single "set" statement. 240 | # 241 | # This will of course break if any of these variables contains a newline or 242 | # an unmatched quote. 243 | # 244 | 245 | eval "set -- $( 246 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 247 | xargs -n1 | 248 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 249 | tr '\n' ' ' 250 | )" '"$@"' 251 | 252 | exec "$JAVACMD" "$@" 253 | -------------------------------------------------------------------------------- /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 | @rem SPDX-License-Identifier: Apache-2.0 17 | @rem 18 | 19 | @if "%DEBUG%"=="" @echo off 20 | @rem ########################################################################## 21 | @rem 22 | @rem Gradle startup script for Windows 23 | @rem 24 | @rem ########################################################################## 25 | 26 | @rem Set local scope for the variables with windows NT shell 27 | if "%OS%"=="Windows_NT" setlocal 28 | 29 | set DIRNAME=%~dp0 30 | if "%DIRNAME%"=="" set DIRNAME=. 31 | @rem This is normally unused 32 | set APP_BASE_NAME=%~n0 33 | set APP_HOME=%DIRNAME% 34 | 35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 | 38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 | 41 | @rem Find java.exe 42 | if defined JAVA_HOME goto findJavaFromJavaHome 43 | 44 | set JAVA_EXE=java.exe 45 | %JAVA_EXE% -version >NUL 2>&1 46 | if %ERRORLEVEL% equ 0 goto execute 47 | 48 | echo. 1>&2 49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 | echo. 1>&2 51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 | echo location of your Java installation. 1>&2 53 | 54 | goto fail 55 | 56 | :findJavaFromJavaHome 57 | set JAVA_HOME=%JAVA_HOME:"=% 58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 | 60 | if exist "%JAVA_EXE%" goto execute 61 | 62 | echo. 1>&2 63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 | echo. 1>&2 65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 | echo location of your Java installation. 1>&2 67 | 68 | goto fail 69 | 70 | :execute 71 | @rem Setup the command line 72 | 73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 | 75 | 76 | @rem Execute Gradle 77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 | 79 | :end 80 | @rem End local scope for the variables with windows NT shell 81 | if %ERRORLEVEL% equ 0 goto mainEnd 82 | 83 | :fail 84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 | rem the _cmd.exe /c_ return code! 86 | set EXIT_CODE=%ERRORLEVEL% 87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 | exit /b %EXIT_CODE% 90 | 91 | :mainEnd 92 | if "%OS%"=="Windows_NT" endlocal 93 | 94 | :omega 95 | -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - sdk install java 21.0.5-tem 3 | - sdk use java 21.0.5-tem 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | import groovy.json.JsonSlurper 2 | 3 | pluginManagement { 4 | repositories { 5 | maven { 6 | name = 'Fabric' 7 | url = 'https://maven.fabricmc.net/' 8 | } 9 | maven { 10 | name = 'Jitpack' 11 | url = 'https://jitpack.io' 12 | } 13 | mavenCentral() 14 | gradlePluginPortal() 15 | } 16 | resolutionStrategy { 17 | eachPlugin { 18 | switch (requested.id.id) { 19 | case "com.replaymod.preprocess": { 20 | useModule("com.github.Fallen-Breath:preprocessor:${requested.version}") 21 | break 22 | } 23 | } 24 | } 25 | } 26 | } 27 | 28 | def settings = new JsonSlurper().parseText(file('settings.json').text) 29 | for (String version : settings.versions) { 30 | include(":$version") 31 | 32 | def proj = project(":$version") 33 | proj.projectDir = file("versions/$version") 34 | proj.buildFileName = "../../common.gradle" 35 | } 36 | -------------------------------------------------------------------------------- /settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "versions": [ 3 | "1.14.4", 4 | "1.15.2", 5 | "1.16.5", 6 | "1.17.1", 7 | "1.18.2", 8 | "1.19.4", 9 | "1.20.4", 10 | "1.20.6", 11 | "1.21.1", 12 | "1.21.3", 13 | "1.21.4", 14 | "1.21.5" 15 | ] 16 | } -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/MoreStatisticsCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics; 22 | 23 | import com.mojang.brigadier.CommandDispatcher; 24 | import com.mojang.brigadier.builder.LiteralArgumentBuilder; 25 | import net.minecraft.command.arguments.ScoreHolderArgumentType; 26 | import net.minecraft.server.command.CommandManager; 27 | import net.minecraft.server.command.ServerCommandSource; 28 | 29 | import static net.minecraft.server.command.CommandManager.literal; 30 | 31 | public class MoreStatisticsCommand 32 | { 33 | private static final String PREFIX = "morestatistics"; 34 | 35 | public static void registerCommand(CommandDispatcher dispatcher) 36 | { 37 | // LiteralArgumentBuilder rootNode = literal(PREFIX). 38 | // requires(serverCommandSource -> serverCommandSource.hasPermissionLevel(2)). 39 | // then(literal("show"). 40 | // then(literal(MoreStatisticsScoreboardCriterion.BLOCK_PLACED_COUNT.getName()). 41 | // then(CommandManager.argument("target", ScoreHolderArgumentType.scoreHolder()). 42 | // executes( 43 | // c -> showBlockPlaceCount(c.getSource(), ScoreHolderArgumentType.getScoreHolder(c, "target")) 44 | // ) 45 | // ) 46 | // ) 47 | // ); 48 | // maybe not 49 | // dispatcher.register(rootNode); 50 | } 51 | 52 | private static int showBlockPlaceCount(ServerCommandSource source, String target) 53 | { 54 | // Registry.ITEM.stream().filter(item -> item instanceof BlockItem); 55 | return 1; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/MoreStatisticsMod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics; 22 | 23 | import me.fallenbreath.morestatistics.network.Network; 24 | import me.fallenbreath.morestatistics.utils.IdentifierUtil; 25 | import net.fabricmc.api.ModInitializer; 26 | import net.fabricmc.loader.api.FabricLoader; 27 | import net.minecraft.util.Identifier; 28 | import org.apache.logging.log4j.LogManager; 29 | import org.apache.logging.log4j.Logger; 30 | 31 | public class MoreStatisticsMod implements ModInitializer 32 | { 33 | public static final String NAME = "More Statistics"; 34 | public static final String MOD_ID = "more-statistics"; 35 | public static String version; 36 | public static final Logger LOGGER = LogManager.getLogger(); 37 | 38 | @Override 39 | public void onInitialize() 40 | { 41 | version = FabricLoader.getInstance().getModContainer(MOD_ID).orElseThrow(RuntimeException::new).getMetadata().getVersion().getFriendlyString(); 42 | 43 | Network.initEvents(); 44 | } 45 | 46 | public static String getModId() 47 | { 48 | return MOD_ID; 49 | } 50 | 51 | public static String getModVersion() 52 | { 53 | return version; 54 | } 55 | 56 | public static Identifier id(String name) 57 | { 58 | return IdentifierUtil.of(MOD_ID, name); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/MoreStatisticsRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics; 22 | 23 | import com.google.common.collect.Sets; 24 | import me.fallenbreath.morestatistics.mixins.core.stats.StatsAccessor; 25 | import me.fallenbreath.morestatistics.utils.IdentifierUtil; 26 | import net.minecraft.stat.StatFormatter; 27 | import net.minecraft.util.Identifier; 28 | import net.minecraft.util.registry.Registry; 29 | 30 | //#if MC >= 11903 31 | //$$ import net.minecraft.registry.Registries; 32 | //#endif 33 | 34 | import java.util.Set; 35 | 36 | public class MoreStatisticsRegistry 37 | { 38 | private static final Set STATS_SET = Sets.newLinkedHashSet(); 39 | public static final Identifier BREAK_BEDROCK = register("break_bedrock", StatFormatter.DEFAULT); 40 | public static final Identifier ENDER_PEARL_ONE_CM = register("ender_pearl_one_cm", StatFormatter.DISTANCE); 41 | public static final Identifier FIREWORK_BOOST = register("firework_boost", StatFormatter.DEFAULT); 42 | public static final Identifier MEND_DURABILITY = register("mend_durability", StatFormatter.DEFAULT); 43 | public static final Identifier SUMMON_PHANTOM = register("summon_phantom", StatFormatter.DEFAULT); 44 | 45 | private static Identifier register(String name, StatFormatter statFormatter) 46 | { 47 | // vanilla stuffs, just like net.minecraft.stat.Stats#register 48 | Identifier statId = IdentifierUtil.of(name); // using minecraft namespace. it's fine xd 49 | Registry.register( 50 | //#if MC >= 11903 51 | //$$ Registries.CUSTOM_STAT, 52 | //#else 53 | Registry.CUSTOM_STAT, 54 | //#endif 55 | statId, statId 56 | ); 57 | StatsAccessor.getCUSTOM().getOrCreateStat(statId, statFormatter); 58 | 59 | // our stuffs 60 | STATS_SET.add(statId); 61 | MoreStatisticsMod.LOGGER.info("Added custom statistic " + statId); 62 | 63 | return statId; 64 | } 65 | 66 | public static void init() 67 | { 68 | // stuffs are done in 69 | MoreStatisticsMod.LOGGER.info(String.format("%s enabled with %d new statistics", MoreStatisticsMod.NAME, STATS_SET.size())); 70 | } 71 | 72 | public static Set getStatsSet() 73 | { 74 | return STATS_SET; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/MoreStatisticsScoreboardCriterion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics; 22 | 23 | import com.google.common.collect.Sets; 24 | import net.minecraft.scoreboard.ScoreboardCriterion; 25 | 26 | import java.util.List; 27 | import java.util.Set; 28 | import java.util.stream.Collectors; 29 | //#if MC >= 11700 30 | //$$ import me.fallenbreath.morestatistics.mixins.core.scoreboard.ScoreboardCriterionAccessor; 31 | //#endif 32 | 33 | public class MoreStatisticsScoreboardCriterion 34 | { 35 | private static final Set SCOREBOARD_CRITERION_SET = Sets.newLinkedHashSet(); 36 | public static final ScoreboardCriterion BLOCK_PLACED_COUNT = createCriterion("blockPlacedCount"); 37 | 38 | private static ScoreboardCriterion createCriterion(String name) 39 | { 40 | ScoreboardCriterion scoreboardCriterion = 41 | //#if MC >= 11700 42 | //$$ ScoreboardCriterionAccessor.invokeCreate(name); 43 | //#else 44 | new ScoreboardCriterion(name); 45 | //#endif 46 | SCOREBOARD_CRITERION_SET.add(scoreboardCriterion); 47 | return scoreboardCriterion; 48 | } 49 | 50 | public static Set getCriterionSet() 51 | { 52 | return SCOREBOARD_CRITERION_SET; 53 | } 54 | 55 | public static List getCriterionNameList() 56 | { 57 | return getCriterionSet().stream().map(ScoreboardCriterion::getName).collect(Collectors.toList()); 58 | } 59 | 60 | public static void init() 61 | { 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/CommandManagerMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core; 22 | 23 | import com.mojang.brigadier.CommandDispatcher; 24 | import me.fallenbreath.morestatistics.MoreStatisticsCommand; 25 | import net.minecraft.server.command.CommandManager; 26 | import net.minecraft.server.command.ServerCommandSource; 27 | import org.spongepowered.asm.mixin.Final; 28 | import org.spongepowered.asm.mixin.Mixin; 29 | import org.spongepowered.asm.mixin.Shadow; 30 | import org.spongepowered.asm.mixin.injection.At; 31 | import org.spongepowered.asm.mixin.injection.Inject; 32 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 33 | 34 | @Mixin(CommandManager.class) 35 | public abstract class CommandManagerMixin 36 | { 37 | @Shadow @Final private CommandDispatcher dispatcher; 38 | 39 | @Inject(method = "", at = @At("TAIL")) 40 | private void registerMoreStatisticsCommand(CallbackInfo ci) 41 | { 42 | MoreStatisticsCommand.registerCommand(this.dispatcher); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/scoreboard/ObjectiveCriteriaArgumentTypeMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core.scoreboard; 22 | 23 | import com.google.common.collect.Lists; 24 | import com.mojang.brigadier.context.CommandContext; 25 | import com.mojang.brigadier.suggestion.SuggestionsBuilder; 26 | import me.fallenbreath.morestatistics.MoreStatisticsScoreboardCriterion; 27 | import me.fallenbreath.morestatistics.network.ClientHandler; 28 | import net.minecraft.client.network.ClientCommandSource; 29 | import net.minecraft.command.arguments.ObjectiveCriteriaArgumentType; 30 | import org.spongepowered.asm.mixin.Mixin; 31 | import org.spongepowered.asm.mixin.injection.At; 32 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 33 | 34 | import java.util.HashSet; 35 | import java.util.List; 36 | import java.util.Set; 37 | 38 | @Mixin(ObjectiveCriteriaArgumentType.class) 39 | public abstract class ObjectiveCriteriaArgumentTypeMixin 40 | { 41 | @SuppressWarnings("InvalidInjectorMethodSignature") 42 | @ModifyVariable( 43 | method = "listSuggestions", 44 | at = @At( 45 | value = "INVOKE_ASSIGN", 46 | target = "Lcom/google/common/collect/Lists;newArrayList(Ljava/lang/Iterable;)Ljava/util/ArrayList;", 47 | shift = At.Shift.AFTER, 48 | ordinal = 0, 49 | remap = false 50 | ) 51 | ) 52 | private List adjustCriterionSuggestions(List suggestions, CommandContext context, SuggestionsBuilder builder) 53 | { 54 | // only modify at client side 55 | if (context.getSource() instanceof ClientCommandSource) 56 | { 57 | List newSuggestions = Lists.newArrayList(); 58 | Set msCriterions = new HashSet<>(MoreStatisticsScoreboardCriterion.getCriterionNameList()); 59 | suggestions.forEach(suggestion -> { 60 | boolean vanillaCriterion = !msCriterions.contains(suggestion); 61 | boolean butServerRecognizesThis = ClientHandler.getScoreboardCriterionNames().contains(suggestion); 62 | if (vanillaCriterion || butServerRecognizesThis) 63 | { 64 | newSuggestions.add(suggestion); 65 | } 66 | }); 67 | suggestions = newSuggestions; 68 | } 69 | return suggestions; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/scoreboard/ScoreboardCriterionAccessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core.scoreboard; 22 | 23 | import net.minecraft.scoreboard.ScoreboardCriterion; 24 | import org.spongepowered.asm.mixin.Mixin; 25 | //#if MC >= 11700 26 | //$$ import org.spongepowered.asm.mixin.gen.Invoker; 27 | //#endif 28 | 29 | @Mixin(ScoreboardCriterion.class) 30 | public interface ScoreboardCriterionAccessor 31 | { 32 | //#if MC >= 11700 33 | //$$ @Invoker 34 | //$$ static ScoreboardCriterion invokeCreate(String name) 35 | //$$ { 36 | //$$ throw new RuntimeException(); 37 | //$$ } 38 | //#endif 39 | } -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/scoreboard/ScoreboardCriterionMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core.scoreboard; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsScoreboardCriterion; 24 | import net.minecraft.scoreboard.ScoreboardCriterion; 25 | import org.spongepowered.asm.mixin.Mixin; 26 | 27 | @Mixin(ScoreboardCriterion.class) 28 | public abstract class ScoreboardCriterionMixin 29 | { 30 | static 31 | { 32 | MoreStatisticsScoreboardCriterion.init(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/stats/ServerStatHandlerMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core.stats; 22 | 23 | import it.unimi.dsi.fastutil.objects.Object2IntMap; 24 | import me.fallenbreath.morestatistics.network.ServerHandler; 25 | import net.minecraft.server.network.ServerPlayerEntity; 26 | import net.minecraft.stat.ServerStatHandler; 27 | import net.minecraft.stat.Stat; 28 | import org.spongepowered.asm.mixin.Mixin; 29 | import org.spongepowered.asm.mixin.injection.At; 30 | import org.spongepowered.asm.mixin.injection.Redirect; 31 | 32 | @Mixin(ServerStatHandler.class) 33 | public abstract class ServerStatHandlerMixin 34 | { 35 | @Redirect( 36 | method = "sendStats", 37 | at = @At( 38 | value = "INVOKE", 39 | target = "Lit/unimi/dsi/fastutil/objects/Object2IntMap;put(Ljava/lang/Object;I)I", 40 | remap = false 41 | ) 42 | ) 43 | private int dontPutNotVanillaStat(Object2IntMap> map, Object obj, int value, ServerPlayerEntity player) 44 | { 45 | if (ServerHandler.canSendStat(player, (Stat)obj)) 46 | { 47 | return map.put((Stat)obj, value); 48 | } 49 | else 50 | { 51 | return map.defaultReturnValue(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/stats/StatsAccessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core.stats; 22 | 23 | import net.minecraft.stat.StatType; 24 | import net.minecraft.stat.Stats; 25 | import net.minecraft.util.Identifier; 26 | import org.spongepowered.asm.mixin.Mixin; 27 | import org.spongepowered.asm.mixin.gen.Accessor; 28 | 29 | @Mixin(Stats.class) 30 | public interface StatsAccessor 31 | { 32 | @Accessor 33 | static StatType getCUSTOM() 34 | { 35 | throw new RuntimeException(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/stats/StatsMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core.stats; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 24 | import net.minecraft.stat.Stats; 25 | import org.spongepowered.asm.mixin.Mixin; 26 | 27 | @Mixin(Stats.class) 28 | public abstract class StatsMixin 29 | { 30 | static 31 | { 32 | MoreStatisticsRegistry.init(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/core/stats/StatsScreenMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.core.stats; 22 | 23 | import me.fallenbreath.morestatistics.network.ClientHandler; 24 | import net.minecraft.client.MinecraftClient; 25 | import net.minecraft.client.gui.screen.Screen; 26 | import net.minecraft.client.gui.screen.StatsScreen; 27 | import net.minecraft.text.Text; 28 | import org.spongepowered.asm.mixin.Mixin; 29 | import org.spongepowered.asm.mixin.injection.At; 30 | import org.spongepowered.asm.mixin.injection.Inject; 31 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 32 | 33 | @Mixin(StatsScreen.class) 34 | public abstract class StatsScreenMixin extends Screen 35 | { 36 | protected StatsScreenMixin(Text title) 37 | { 38 | super(title); 39 | } 40 | 41 | @Inject(method = "init", at = @At(value = "HEAD")) 42 | private void onStatsScreenInit(CallbackInfo ci) 43 | { 44 | //#if MC >= 11600 45 | //$$ MinecraftClient mc = this.client; 46 | //#else 47 | MinecraftClient mc = this.minecraft; 48 | //#endif 49 | if (mc != null && mc.getNetworkHandler() != null) 50 | { 51 | ClientHandler.sendAcceptedStatList(mc.getNetworkHandler()); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/network/FanetlibPacketRegistrationCenterMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Litematica Server Paster project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2024 Fallen_Breath and contributors 6 | * 7 | * Litematica Server Paster is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * Litematica Server Paster is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with Litematica Server Paster. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.network; 22 | 23 | import me.fallenbreath.fanetlib.api.packet.FanetlibPacketRegistrationCenter; 24 | import me.fallenbreath.morestatistics.network.Network; 25 | import org.spongepowered.asm.mixin.Mixin; 26 | import org.spongepowered.asm.mixin.injection.At; 27 | import org.spongepowered.asm.mixin.injection.Inject; 28 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 29 | 30 | @Mixin(FanetlibPacketRegistrationCenter.class) 31 | public abstract class FanetlibPacketRegistrationCenterMixin 32 | { 33 | @Inject(method = "common", at = @At("HEAD"), remap = false) 34 | private static void register(CallbackInfo ci) 35 | { 36 | Network.initPackets(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/scoreboard/blockPlacedCount/BlockItemMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.scoreboard.blockPlacedCount; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsScoreboardCriterion; 24 | import net.minecraft.item.BlockItem; 25 | import net.minecraft.server.network.ServerPlayerEntity; 26 | import org.spongepowered.asm.mixin.Mixin; 27 | import org.spongepowered.asm.mixin.injection.At; 28 | import org.spongepowered.asm.mixin.injection.ModifyArg; 29 | 30 | //#if MC >= 12004 31 | //$$ import net.minecraft.scoreboard.ScoreAccess; 32 | //#else 33 | import net.minecraft.scoreboard.ScoreboardPlayerScore; 34 | //#endif 35 | 36 | @Mixin(BlockItem.class) 37 | public abstract class BlockItemMixin 38 | { 39 | @ModifyArg( 40 | method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", 41 | at = @At( 42 | value = "INVOKE", 43 | //#if MC >= 12000 44 | //$$ target = "Lnet/minecraft/advancement/criterion/ItemCriterion;trigger(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/ItemStack;)V" 45 | //#else 46 | target = "Lnet/minecraft/advancement/criterion/PlacedBlockCriterion;trigger(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/ItemStack;)V" 47 | //#endif 48 | ), 49 | index = 0 50 | ) 51 | private ServerPlayerEntity onPlayerPlacedBlock(ServerPlayerEntity player) 52 | { 53 | player.getScoreboard().forEachScore( 54 | MoreStatisticsScoreboardCriterion.BLOCK_PLACED_COUNT, 55 | //#if MC >= 12004 56 | //$$ player, ScoreAccess::incrementScore 57 | //#else 58 | player.getEntityName(), ScoreboardPlayerScore::incrementScore 59 | //#endif 60 | ); 61 | return player; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/stats/break_bedrock/BlockItemMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.break_bedrock; 22 | 23 | import me.fallenbreath.morestatistics.utils.PistonPlacingMemory; 24 | import net.minecraft.block.Block; 25 | import net.minecraft.block.PistonBlock; 26 | import net.minecraft.item.BlockItem; 27 | import net.minecraft.server.network.ServerPlayerEntity; 28 | import net.minecraft.util.math.BlockPos; 29 | import org.spongepowered.asm.mixin.Mixin; 30 | import org.spongepowered.asm.mixin.Shadow; 31 | import org.spongepowered.asm.mixin.injection.At; 32 | import org.spongepowered.asm.mixin.injection.ModifyArgs; 33 | import org.spongepowered.asm.mixin.injection.invoke.arg.Args; 34 | 35 | @Mixin(BlockItem.class) 36 | public abstract class BlockItemMixin 37 | { 38 | @Shadow public abstract Block getBlock(); 39 | 40 | @ModifyArgs( 41 | method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", 42 | at = @At( 43 | value = "INVOKE", 44 | //#if MC >= 12000 45 | //$$ target = "Lnet/minecraft/advancement/criterion/ItemCriterion;trigger(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/ItemStack;)V" 46 | //#else 47 | target = "Lnet/minecraft/advancement/criterion/PlacedBlockCriterion;trigger(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/ItemStack;)V" 48 | //#endif 49 | ) 50 | ) 51 | private void rememberPistonPlacing(Args args) 52 | { 53 | if (this.getBlock() instanceof PistonBlock) 54 | { 55 | ServerPlayerEntity player = args.get(0); 56 | BlockPos blockPos = args.get(1); 57 | PistonPlacingMemory.onPlayerPlacedPiston(player, blockPos); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/stats/break_bedrock/MinecraftServerMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.break_bedrock; 22 | 23 | import me.fallenbreath.morestatistics.utils.PistonPlacingMemory; 24 | import net.minecraft.server.MinecraftServer; 25 | import org.spongepowered.asm.mixin.Mixin; 26 | import org.spongepowered.asm.mixin.injection.At; 27 | import org.spongepowered.asm.mixin.injection.Inject; 28 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 29 | 30 | @Mixin(MinecraftServer.class) 31 | public abstract class MinecraftServerMixin 32 | { 33 | @Inject( 34 | method = "tickWorlds", 35 | at = @At( 36 | value = "INVOKE", 37 | //#if MC >= 12102 38 | //$$ target = "Lnet/minecraft/server/MinecraftServer;tickNetworkIo()V" 39 | //#else 40 | target = "Lnet/minecraft/server/ServerNetworkIo;tick()V" 41 | //#endif 42 | ) 43 | ) 44 | private void cleanPistonPlacingMemory(CallbackInfo ci) 45 | { 46 | PistonPlacingMemory.cleanMemory(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/stats/break_bedrock/PistonBlockMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.break_bedrock; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 24 | import me.fallenbreath.morestatistics.utils.PistonPlacingMemory; 25 | import net.minecraft.block.BlockState; 26 | import net.minecraft.block.Blocks; 27 | import net.minecraft.block.PistonBlock; 28 | import net.minecraft.server.network.ServerPlayerEntity; 29 | import net.minecraft.util.math.BlockPos; 30 | import net.minecraft.world.World; 31 | import org.spongepowered.asm.mixin.Mixin; 32 | import org.spongepowered.asm.mixin.injection.At; 33 | import org.spongepowered.asm.mixin.injection.ModifyArgs; 34 | import org.spongepowered.asm.mixin.injection.invoke.arg.Args; 35 | 36 | @Mixin(PistonBlock.class) 37 | public abstract class PistonBlockMixin 38 | { 39 | @ModifyArgs( 40 | //#if MC >= 11600 41 | //$$ method = "onSyncedBlockEvent", 42 | //#else 43 | method = "onBlockAction", 44 | //#endif 45 | at = @At( 46 | value = "INVOKE", 47 | target = "Lnet/minecraft/world/World;removeBlock(Lnet/minecraft/util/math/BlockPos;Z)Z" 48 | ), 49 | require = 2 50 | ) 51 | private void removeBlock(Args args, BlockState state, World world, BlockPos pistonPos, int type, int data) 52 | { 53 | BlockPos posToRemove = args.get(0); 54 | if (world.getBlockState(posToRemove).getBlock() == Blocks.BEDROCK) 55 | { 56 | ServerPlayerEntity player = PistonPlacingMemory.getTheOneWhoJustPlacedPiston(world, pistonPos); 57 | if (player != null) 58 | { 59 | player.increaseStat(MoreStatisticsRegistry.BREAK_BEDROCK, 1); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/stats/ender_pearl_one_cm/ThrownEnderpearlEntityMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.ender_pearl_one_cm; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 24 | //#if MC >= 11600 25 | //$$ import net.minecraft.entity.Entity; 26 | //#else 27 | import net.minecraft.entity.LivingEntity; 28 | //#endif 29 | import net.minecraft.entity.thrown.ThrownEnderpearlEntity; 30 | import net.minecraft.server.network.ServerPlayerEntity; 31 | import net.minecraft.util.hit.HitResult; 32 | import org.spongepowered.asm.mixin.Mixin; 33 | import org.spongepowered.asm.mixin.injection.At; 34 | import org.spongepowered.asm.mixin.injection.Inject; 35 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 36 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 37 | 38 | // impl for mc < 1.21 39 | @Mixin(ThrownEnderpearlEntity.class) 40 | public abstract class ThrownEnderpearlEntityMixin 41 | { 42 | @Inject( 43 | method = "onCollision", 44 | at = @At( 45 | value = "INVOKE", 46 | //#if MC >= 11600 47 | //$$ target = "Lnet/minecraft/entity/Entity;requestTeleport(DDD)V", 48 | //#else 49 | target = "Lnet/minecraft/entity/LivingEntity;requestTeleport(DDD)V", 50 | //#endif 51 | ordinal = 0 52 | ), 53 | locals = LocalCapture.CAPTURE_FAILHARD 54 | ) 55 | private void onEnderPearlHit( 56 | HitResult hitResult, CallbackInfo ci, 57 | //#if MC >= 11600 58 | //$$ Entity entity 59 | //#else 60 | LivingEntity entity 61 | //#endif 62 | ) 63 | { 64 | if (entity instanceof ServerPlayerEntity) 65 | { 66 | ServerPlayerEntity player = (ServerPlayerEntity)entity; 67 | int distance = Math.round(player.distanceTo((ThrownEnderpearlEntity)(Object)this) * 100.0F); 68 | if (distance > 0) { 69 | player.increaseStat(MoreStatisticsRegistry.ENDER_PEARL_ONE_CM, distance); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/stats/firework_boost/FireworkItemMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.firework_boost; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 24 | import net.minecraft.entity.player.PlayerEntity; 25 | import net.minecraft.item.FireworkItem; 26 | import net.minecraft.util.Hand; 27 | import net.minecraft.world.World; 28 | import org.spongepowered.asm.mixin.Mixin; 29 | import org.spongepowered.asm.mixin.injection.At; 30 | import org.spongepowered.asm.mixin.injection.Inject; 31 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 32 | 33 | @Mixin(FireworkItem.class) 34 | public abstract class FireworkItemMixin 35 | { 36 | @Inject( 37 | method = "use", 38 | at = @At( 39 | value = "INVOKE", 40 | //#if MC >= 12102 41 | //$$ target = "Lnet/minecraft/entity/projectile/ProjectileEntity;spawn(Lnet/minecraft/entity/projectile/ProjectileEntity;Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/entity/projectile/ProjectileEntity;" 42 | //#else 43 | target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z" 44 | //#endif 45 | ) 46 | ) 47 | private void onFireworkBoost(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable ci) 48 | { 49 | user.increaseStat(MoreStatisticsRegistry.FIREWORK_BOOST, 1); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/stats/mend_durability/ExperienceOrbEntityMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.mend_durability; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 24 | import net.minecraft.entity.ExperienceOrbEntity; 25 | import net.minecraft.entity.player.PlayerEntity; 26 | import org.spongepowered.asm.mixin.Mixin; 27 | import org.spongepowered.asm.mixin.injection.At; 28 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 29 | 30 | // impl for mc < 1.21 31 | @Mixin(ExperienceOrbEntity.class) 32 | public abstract class ExperienceOrbEntityMixin 33 | { 34 | @ModifyVariable( 35 | //#if MC >= 11700 36 | //$$ method = "repairPlayerGears", 37 | //#else 38 | method = "onPlayerCollision", 39 | //#endif 40 | at = @At( 41 | value = "INVOKE", 42 | target = "Lnet/minecraft/item/ItemStack;setDamage(I)V" 43 | //#if MC >= 11700 44 | //$$ ), 45 | //$$ ordinal = 1 46 | //#else 47 | ) 48 | //#endif 49 | ) 50 | private int onMendingApplied( 51 | int durabilityMended, PlayerEntity player 52 | //#if MC >= 11700 53 | //$$ , int amount 54 | //#endif 55 | ) 56 | { 57 | player.increaseStat(MoreStatisticsRegistry.MEND_DURABILITY, durabilityMended); 58 | return durabilityMended; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/mixins/stats/summon_phantom/PhantomSpawnerMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.summon_phantom; 22 | 23 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 24 | import net.minecraft.entity.player.PlayerEntity; 25 | import net.minecraft.world.gen.PhantomSpawner; 26 | import org.spongepowered.asm.mixin.Mixin; 27 | import org.spongepowered.asm.mixin.injection.At; 28 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 29 | 30 | //#if MC >= 11200 31 | //$$ import net.minecraft.server.network.ServerPlayerEntity; 32 | //#endif 33 | 34 | @Mixin(PhantomSpawner.class) 35 | public abstract class PhantomSpawnerMixin 36 | { 37 | private PlayerEntity currentPlayer$moreStatistics = null; 38 | 39 | @ModifyVariable( 40 | method = "spawn", 41 | at = @At( 42 | value = "INVOKE", 43 | target = "Lnet/minecraft/util/math/MathHelper;clamp(III)I" 44 | ) 45 | ) 46 | //#if MC >= 12000 47 | //$$ private ServerPlayerEntity recordsCurrentPlayer$moreStatistics(ServerPlayerEntity player) 48 | //#else 49 | private PlayerEntity recordsCurrentPlayer$moreStatistics(PlayerEntity player) 50 | //#endif 51 | { 52 | this.currentPlayer$moreStatistics = player; 53 | return player; 54 | } 55 | 56 | @ModifyVariable( 57 | method = "spawn", 58 | at = @At( 59 | value = "FIELD", 60 | target = "Lnet/minecraft/entity/EntityType;PHANTOM:Lnet/minecraft/entity/EntityType;" 61 | ), 62 | ordinal = 1 63 | ) 64 | private int addSummonPhantomStat$moreStatistics(int amount) 65 | { 66 | if (this.currentPlayer$moreStatistics != null) 67 | { 68 | this.currentPlayer$moreStatistics.increaseStat(MoreStatisticsRegistry.SUMMON_PHANTOM, amount); 69 | this.currentPlayer$moreStatistics = null; 70 | } 71 | return amount; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/network/ClientHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.network; 22 | 23 | import com.google.common.collect.Sets; 24 | import me.fallenbreath.morestatistics.MoreStatisticsMod; 25 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 26 | import me.fallenbreath.morestatistics.utils.Util; 27 | import net.minecraft.client.network.ClientPlayNetworkHandler; 28 | import net.minecraft.client.network.ClientPlayerEntity; 29 | import net.minecraft.nbt.CompoundTag; 30 | import net.minecraft.util.Identifier; 31 | 32 | import java.util.Collections; 33 | import java.util.List; 34 | import java.util.Objects; 35 | import java.util.Set; 36 | import java.util.stream.Collectors; 37 | 38 | public class ClientHandler 39 | { 40 | private static Set SCOREBOARD_CRITERION_NAMES = Collections.emptySet(); 41 | 42 | public static void handleServerPacket(MoreStatisticsPayload payload, ClientPlayerEntity player) 43 | { 44 | int id = payload.getPacketId(); 45 | switch (id) 46 | { 47 | case Network.S2C.SCOREBOARD_CRITERION_LIST: 48 | CompoundTag nbt = Objects.requireNonNull(payload.getNbt()); 49 | SCOREBOARD_CRITERION_NAMES = Sets.newHashSet(Util.nbt2StringList(Util.getNbtOrEmpty(nbt, "data"))); 50 | MoreStatisticsMod.LOGGER.debug("Received CRITERION NAMES: {}", SCOREBOARD_CRITERION_NAMES); 51 | break; 52 | } 53 | } 54 | 55 | public static Set getScoreboardCriterionNames() 56 | { 57 | return SCOREBOARD_CRITERION_NAMES; 58 | } 59 | 60 | public static void sendAcceptedStatList(ClientPlayNetworkHandler clientPlayNetworkHandler) 61 | { 62 | List myAcceptedStats = MoreStatisticsRegistry.getStatsSet().stream().map(Identifier::toString).collect(Collectors.toList()); 63 | clientPlayNetworkHandler.sendPacket(Network.C2S.packet(Network.C2S.STATS_LIST, nbt -> { 64 | nbt.put("data", Util.stringList2Nbt(myAcceptedStats)); 65 | })); 66 | } 67 | 68 | public static void requestScoreboardCriterionList(ClientPlayNetworkHandler clientPlayNetworkHandler) 69 | { 70 | clientPlayNetworkHandler.sendPacket(Network.C2S.packet(Network.C2S.SCOREBOARD_CRITERION_QUERY, nbt -> {})); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/network/MoreStatisticsPayload.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.network; 22 | 23 | import me.fallenbreath.fanetlib.api.nbt.FanetlibNbtUtils; 24 | import net.minecraft.nbt.CompoundTag; 25 | import net.minecraft.util.PacketByteBuf; 26 | 27 | public class MoreStatisticsPayload 28 | { 29 | private final int id; 30 | private final CompoundTag nbt; 31 | 32 | public MoreStatisticsPayload(int id, CompoundTag nbt) 33 | { 34 | this.id = id; 35 | this.nbt = nbt; 36 | } 37 | 38 | public MoreStatisticsPayload(PacketByteBuf buf) 39 | { 40 | this(buf.readVarInt(), FanetlibNbtUtils.readNbtAuto(buf)); 41 | } 42 | 43 | public void write(PacketByteBuf buf) 44 | { 45 | buf.writeVarInt(this.id); 46 | buf.writeCompoundTag(this.nbt); 47 | } 48 | 49 | public int getPacketId() 50 | { 51 | return this.id; 52 | } 53 | 54 | public CompoundTag getNbt() 55 | { 56 | return this.nbt; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/network/Network.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.network; 22 | 23 | import me.fallenbreath.fanetlib.api.event.FanetlibClientEvents; 24 | import me.fallenbreath.fanetlib.api.packet.FanetlibPackets; 25 | import me.fallenbreath.fanetlib.api.packet.PacketCodec; 26 | import me.fallenbreath.fanetlib.api.packet.PacketId; 27 | import me.fallenbreath.morestatistics.MoreStatisticsMod; 28 | import net.fabricmc.api.EnvType; 29 | import net.fabricmc.loader.api.FabricLoader; 30 | import net.minecraft.nbt.CompoundTag; 31 | import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket; 32 | import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket; 33 | 34 | import java.util.function.Consumer; 35 | 36 | public class Network 37 | { 38 | public static final PacketId FANETLIB_PACKET_ID = PacketId.of(MoreStatisticsMod.id("network_v2")); 39 | 40 | public static class C2S 41 | { 42 | public static final int STATS_LIST = 1; 43 | public static final int SCOREBOARD_CRITERION_QUERY = 2; 44 | 45 | public static CustomPayloadC2SPacket packet(int packetId, Consumer payloadBuilder) 46 | { 47 | CompoundTag nbt = new CompoundTag(); 48 | payloadBuilder.accept(nbt); 49 | return FanetlibPackets.createC2S(FANETLIB_PACKET_ID, new MoreStatisticsPayload(packetId, nbt)); 50 | } 51 | } 52 | 53 | public static class S2C 54 | { 55 | public static final int SCOREBOARD_CRITERION_LIST = 1; 56 | 57 | public static CustomPayloadS2CPacket packet(int packetId, Consumer payloadBuilder) 58 | { 59 | CompoundTag nbt = new CompoundTag(); 60 | payloadBuilder.accept(nbt); 61 | return FanetlibPackets.createS2C(FANETLIB_PACKET_ID, new MoreStatisticsPayload(packetId, nbt)); 62 | } 63 | } 64 | 65 | public static void initPackets() 66 | { 67 | FanetlibPackets.registerDual( 68 | FANETLIB_PACKET_ID, 69 | PacketCodec.of(MoreStatisticsPayload::write, MoreStatisticsPayload::new), 70 | (payload, ctx) -> ServerHandler.handleClientPacket(payload, ctx.getPlayer()), 71 | (payload, ctx) -> ClientHandler.handleServerPacket(payload, ctx.getPlayer()) 72 | ); 73 | } 74 | 75 | public static void initEvents() 76 | { 77 | if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) 78 | { 79 | FanetlibClientEvents.registerGameJoinListener((client, networkHandler) -> { 80 | ClientHandler.requestScoreboardCriterionList(networkHandler); 81 | }); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/network/ServerHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.network; 22 | 23 | import com.google.common.collect.Sets; 24 | import me.fallenbreath.morestatistics.MoreStatisticsMod; 25 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 26 | import me.fallenbreath.morestatistics.MoreStatisticsScoreboardCriterion; 27 | import me.fallenbreath.morestatistics.utils.IdentifierUtil; 28 | import me.fallenbreath.morestatistics.utils.Util; 29 | import net.minecraft.nbt.CompoundTag; 30 | import net.minecraft.server.network.ServerPlayerEntity; 31 | import net.minecraft.stat.Stat; 32 | import net.minecraft.util.Identifier; 33 | 34 | import java.util.*; 35 | import java.util.stream.Collectors; 36 | 37 | public class ServerHandler 38 | { 39 | private static final Object LOCK = new Object(); 40 | private static final Map> acceptedStats = new WeakHashMap<>(); 41 | 42 | public static void handleClientPacket(MoreStatisticsPayload payload, ServerPlayerEntity player) 43 | { 44 | int id = payload.getPacketId(); 45 | switch (id) 46 | { 47 | case Network.C2S.STATS_LIST: 48 | CompoundTag nbt = Objects.requireNonNull(payload.getNbt()); 49 | List list = Util.nbt2StringList(Util.getNbtOrEmpty(nbt, "data")).stream().map(IdentifierUtil::of).collect(Collectors.toList()); 50 | MoreStatisticsMod.LOGGER.debug("Received accepted stats list from player {}: {}", player.getName().getString(), list); 51 | synchronized (LOCK) 52 | { 53 | acceptedStats.put(player, Sets.newHashSet(list)); 54 | } 55 | break; 56 | 57 | case Network.C2S.SCOREBOARD_CRITERION_QUERY: 58 | MoreStatisticsMod.LOGGER.debug("Received scoreboard criterion query from player {}", player.getName().getString()); 59 | player.networkHandler.sendPacket(Network.S2C.packet(Network.S2C.SCOREBOARD_CRITERION_LIST, nbt2 -> { 60 | nbt2.put("data", Util.stringList2Nbt(MoreStatisticsScoreboardCriterion.getCriterionNameList())); 61 | })); 62 | break; 63 | } 64 | } 65 | 66 | public static boolean canSendStat(ServerPlayerEntity player, Stat stat) 67 | { 68 | Object key = stat.getValue(); 69 | if (key instanceof Identifier) 70 | { 71 | Identifier statId = (Identifier)key; 72 | if (MoreStatisticsRegistry.getStatsSet().contains(statId)) 73 | { 74 | synchronized (LOCK) 75 | { 76 | return acceptedStats.getOrDefault(player, Collections.emptySet()).contains(statId); 77 | } 78 | } 79 | } 80 | return true; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/utils/DimensionWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.utils; 22 | 23 | //#if MC >= 11600 24 | //$$ import net.minecraft.util.registry.RegistryKey; 25 | //#else 26 | import net.minecraft.world.dimension.DimensionType; 27 | //#endif 28 | import net.minecraft.world.World; 29 | 30 | import java.util.Objects; 31 | 32 | public class DimensionWrapper 33 | { 34 | //#if MC >= 11600 35 | //$$ private final RegistryKey dimensionType; 36 | //#else 37 | private final DimensionType dimensionType; 38 | //#endif 39 | 40 | private DimensionWrapper( 41 | //#if MC >= 11600 42 | //$$ RegistryKey dimensionType 43 | //#else 44 | DimensionType dimensionType 45 | //#endif 46 | ) 47 | { 48 | this.dimensionType = dimensionType; 49 | } 50 | 51 | public static DimensionWrapper of(World world) 52 | { 53 | return new DimensionWrapper( 54 | //#if MC >= 11600 55 | //$$ world.getRegistryKey() 56 | //#else 57 | world.getDimension().getType() 58 | //#endif 59 | ); 60 | } 61 | 62 | @Override 63 | public boolean equals(Object o) 64 | { 65 | if (this == o) return true; 66 | if (o == null || getClass() != o.getClass()) return false; 67 | DimensionWrapper that = (DimensionWrapper) o; 68 | return Objects.equals(dimensionType, that.dimensionType); 69 | } 70 | 71 | @Override 72 | public int hashCode() 73 | { 74 | return this.dimensionType.hashCode(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/utils/DummyClass.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.utils; 22 | 23 | public class DummyClass 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/utils/IdentifierUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2024 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.utils; 22 | 23 | import net.minecraft.util.Identifier; 24 | 25 | public class IdentifierUtil 26 | { 27 | public static Identifier of(String id) 28 | { 29 | //#if MC >= 12100 30 | //$$ return Identifier.of(id); 31 | //#else 32 | return new Identifier(id); 33 | //#endif 34 | } 35 | 36 | public static Identifier of(String namespace, String path) 37 | { 38 | //#if MC >= 12100 39 | //$$ return Identifier.of(namespace, path); 40 | //#else 41 | return new Identifier(namespace, path); 42 | //#endif 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/utils/PistonPlacingMemory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.utils; 22 | 23 | import com.google.common.collect.Maps; 24 | import com.mojang.datafixers.util.Pair; 25 | import net.minecraft.server.network.ServerPlayerEntity; 26 | import net.minecraft.util.math.BlockPos; 27 | import net.minecraft.world.World; 28 | import net.minecraft.world.dimension.DimensionType; 29 | import org.jetbrains.annotations.Nullable; 30 | 31 | import java.util.Map; 32 | 33 | public class PistonPlacingMemory 34 | { 35 | private static final Map, ServerPlayerEntity> MEMORY = Maps.newHashMap(); 36 | 37 | public static void onPlayerPlacedPiston(ServerPlayerEntity player, BlockPos pos) 38 | { 39 | MEMORY.put(makePair(player.getServerWorld(), pos), player); 40 | } 41 | 42 | @Nullable 43 | public static ServerPlayerEntity getTheOneWhoJustPlacedPiston(World world, BlockPos pos) 44 | { 45 | return MEMORY.get(makePair(world, pos)); 46 | } 47 | 48 | private static Pair makePair(World world, BlockPos pos) 49 | { 50 | return Pair.of(DimensionWrapper.of(world), pos); 51 | } 52 | 53 | public static void cleanMemory() 54 | { 55 | MEMORY.clear(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/me/fallenbreath/morestatistics/utils/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.utils; 22 | 23 | import com.google.common.collect.Lists; 24 | import net.minecraft.nbt.CompoundTag; 25 | 26 | import java.util.List; 27 | 28 | public class Util 29 | { 30 | public static String getStringOrEmpty(CompoundTag nbt, String key) 31 | { 32 | //#if MC >= 12105 33 | //$$ return nbt.getString(key, ""); 34 | //#else 35 | return nbt.getString(key); 36 | //#endif 37 | } 38 | 39 | public static int getIntOrZero(CompoundTag nbt, String key) 40 | { 41 | //#if MC >= 12105 42 | //$$ return nbt.getInt(key, 0); 43 | //#else 44 | return nbt.getInt(key); 45 | //#endif 46 | } 47 | 48 | public static CompoundTag getNbtOrEmpty(CompoundTag nbt, String key) 49 | { 50 | //#if MC >= 12105 51 | //$$ return nbt.getCompound(key).orElseGet(NbtCompound::new); 52 | //#else 53 | return nbt.getCompound(key); 54 | //#endif 55 | } 56 | 57 | public static CompoundTag stringList2Nbt(List list) 58 | { 59 | CompoundTag nbt = new CompoundTag(); 60 | nbt.putInt("length", list.size()); 61 | for (int i = 0; i < list.size(); i++) 62 | { 63 | nbt.putString(String.valueOf(i), list.get(i)); 64 | } 65 | return nbt; 66 | } 67 | 68 | public static List nbt2StringList(CompoundTag nbt) 69 | { 70 | List list = Lists.newArrayList(); 71 | int length = getIntOrZero(nbt, "length"); 72 | for (int i = 0; i < length; i++) 73 | { 74 | list.add(getStringOrEmpty(nbt, String.valueOf(i))); 75 | } 76 | return list; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/resources/assets/more-statistics/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fallen-Breath/more-statistics/b25c2d17bfed2ef6662c9b5ec311df7e67e436ee/src/main/resources/assets/more-statistics/icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/more-statistics/lang/en_us.yml: -------------------------------------------------------------------------------- 1 | stat.minecraft: 2 | break_bedrock: Bedrock broken using headless piston 3 | ender_pearl_one_cm: Distance teleported with ender pearl 4 | firework_boost: Firework used to boost 5 | mend_durability: Durability repaired by mending 6 | summon_phantom: Phantom summoned 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/more-statistics/lang/zh_cn.yml: -------------------------------------------------------------------------------- 1 | stat.minecraft: 2 | break_bedrock: 无头活塞破基岩数 3 | ender_pearl_one_cm: 末影珍珠传送距离 4 | firework_boost: 烟花加速次数 5 | mend_durability: 经验修补修复耐久度 6 | summon_phantom: 幻翼召唤数 7 | -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "${id}", 4 | "version": "${version}", 5 | 6 | "name": "${name}", 7 | "description": "Add more statistics to Minecraft", 8 | "authors": [ 9 | "Fallen_Breath" 10 | ], 11 | "contact": { 12 | "homepage": "https://github.com/Fallen-Breath/more-statistics", 13 | "sources": "https://github.com/Fallen-Breath/more-statistics" 14 | }, 15 | 16 | "license": "GPL-3.0", 17 | "icon": "assets/more-statistics/icon.png", 18 | 19 | "environment": "*", 20 | "entrypoints": { 21 | "main": [ 22 | "me.fallenbreath.morestatistics.MoreStatisticsMod" 23 | ] 24 | }, 25 | "mixins": [ 26 | "more-statistics.mixins.json" 27 | ], 28 | 29 | "depends": { 30 | "fabricloader": ">=0.11.4", 31 | "minecraft": "${minecraft_dependency}", 32 | "fanetlib": ">=0.2.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/more-statistics.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "me.fallenbreath.morestatistics.mixins", 5 | "compatibilityLevel": "{{COMPATIBILITY_LEVEL}}", 6 | "mixins": [ 7 | "core.CommandManagerMixin", 8 | "core.scoreboard.ObjectiveCriteriaArgumentTypeMixin", 9 | "core.scoreboard.ScoreboardCriterionAccessor", 10 | "core.scoreboard.ScoreboardCriterionMixin", 11 | "core.stats.ServerStatHandlerMixin", 12 | "core.stats.StatsAccessor", 13 | "core.stats.StatsMixin", 14 | "network.FanetlibPacketRegistrationCenterMixin", 15 | "scoreboard.blockPlacedCount.BlockItemMixin", 16 | "stats.break_bedrock.BlockItemMixin", 17 | "stats.break_bedrock.MinecraftServerMixin", 18 | "stats.break_bedrock.PistonBlockMixin", 19 | "stats.ender_pearl_one_cm.ThrownEnderpearlEntityMixin", 20 | "stats.firework_boost.FireworkItemMixin", 21 | "stats.mend_durability.ExperienceOrbEntityMixin", 22 | "stats.summon_phantom.PhantomSpawnerMixin" 23 | ], 24 | "client": [ 25 | "core.stats.StatsScreenMixin" 26 | ], 27 | "injectors": { 28 | "defaultRequire": 1 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /versions/1.14.4/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.14.4 3 | minecraft_version=1.14.4 4 | yarn_mappings=1.14.4+build.18 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.14.x 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.14.4 12 | 13 | # Dependencies 14 | fabric_api_version=0.28.5+1.14 15 | -------------------------------------------------------------------------------- /versions/1.15.2/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.15.2 3 | minecraft_version=1.15.2 4 | yarn_mappings=1.15.2+build.17 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.15.x 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.15.2 12 | 13 | # Dependencies 14 | fabric_api_version=0.28.5+1.15 15 | -------------------------------------------------------------------------------- /versions/1.16.5/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.16.5 3 | minecraft_version=1.16.5 4 | yarn_mappings=1.16.5+build.10 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.16.x 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.16.4\n1.16.5 12 | 13 | # Dependencies 14 | fabric_api_version=0.42.0+1.16 15 | -------------------------------------------------------------------------------- /versions/1.17.1/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.17.1 3 | minecraft_version=1.17.1 4 | yarn_mappings=1.17.1+build.65 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.17.x 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.17.1 12 | 13 | # Dependencies 14 | fabric_api_version=0.46.1+1.17 15 | -------------------------------------------------------------------------------- /versions/1.18.2/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.18.2 3 | minecraft_version=1.18.2 4 | yarn_mappings=1.18.2+build.4 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.18.x 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.18.2 12 | 13 | # Dependencies 14 | fabric_api_version=0.76.0+1.18.2 15 | -------------------------------------------------------------------------------- /versions/1.19.4/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.19.4 3 | minecraft_version=1.19.4 4 | yarn_mappings=1.19.4+build.2 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.19.x 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.19.4 12 | 13 | # Dependencies 14 | fabric_api_version=0.87.2+1.19.4 15 | -------------------------------------------------------------------------------- /versions/1.20.4/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.20.4 3 | minecraft_version=1.20.4 4 | yarn_mappings=1.20.4+build.3 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=>=1.20.2 <=1.20.4 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.20.2\n1.20.3\n1.20.4 12 | 13 | # Dependencies 14 | fabric_api_version=0.97.2+1.20.4 15 | -------------------------------------------------------------------------------- /versions/1.20.6/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.20.6 3 | minecraft_version=1.20.6 4 | yarn_mappings=1.20.6+build.3 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=>=1.20.5 1.20.x 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.20.5\n1.20.6 12 | 13 | # Dependencies 14 | fabric_api_version=0.100.8+1.20.6 15 | -------------------------------------------------------------------------------- /versions/1.21.1/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.21.1 3 | minecraft_version=1.21.1 4 | yarn_mappings=1.21.1+build.3 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=>=1.21 <=1.21.1 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.21\n1.21.1 12 | 13 | # Dependencies 14 | fabric_api_version=0.115.0+1.21.1 -------------------------------------------------------------------------------- /versions/1.21.1/src/main/java/me/fallenbreath/morestatistics/mixins/stats/ender_pearl_one_cm/ThrownEnderpearlEntityMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2023 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.ender_pearl_one_cm; 22 | 23 | import com.llamalad7.mixinextras.sugar.Local; 24 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 25 | import net.minecraft.entity.Entity; 26 | import net.minecraft.entity.projectile.thrown.EnderPearlEntity; 27 | import net.minecraft.server.network.ServerPlayerEntity; 28 | import net.minecraft.server.world.ServerWorld; 29 | import org.spongepowered.asm.mixin.Mixin; 30 | import org.spongepowered.asm.mixin.injection.At; 31 | import org.spongepowered.asm.mixin.injection.Inject; 32 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 33 | 34 | // impl for mc >= 1.21 35 | @Mixin(EnderPearlEntity.class) 36 | public abstract class ThrownEnderpearlEntityMixin 37 | { 38 | @Inject( 39 | method = "onCollision", 40 | at = @At( 41 | value = "INVOKE", 42 | //#if MC >= 12103 43 | //$$ target = "Lnet/minecraft/server/network/ServerPlayerEntity;teleportTo(Lnet/minecraft/world/TeleportTarget;)Lnet/minecraft/server/network/ServerPlayerEntity;" 44 | //#else 45 | target = "Lnet/minecraft/entity/Entity;teleportTo(Lnet/minecraft/world/TeleportTarget;)Lnet/minecraft/entity/Entity;" 46 | //#endif 47 | ) 48 | ) 49 | private void onEnderPearlHit(CallbackInfo ci, @Local Entity owner, @Local ServerWorld selfWorld) 50 | { 51 | if (owner instanceof ServerPlayerEntity player) 52 | { 53 | // only calculate stats if the pearl and the owner are in a same dimension 54 | if (player.getWorld().getDimensionEntry().equals(selfWorld.getDimensionEntry())) 55 | { 56 | int distance = Math.round(player.distanceTo((EnderPearlEntity)(Object)this) * 100.0F); 57 | if (distance > 0) 58 | { 59 | player.increaseStat(MoreStatisticsRegistry.ENDER_PEARL_ONE_CM, distance); 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /versions/1.21.1/src/main/java/me/fallenbreath/morestatistics/mixins/stats/mend_durability/ExperienceOrbEntityMixin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the More Statistics project, licensed under the 3 | * GNU Lesser General Public License v3.0 4 | * 5 | * Copyright (C) 2024 Fallen_Breath and contributors 6 | * 7 | * More Statistics is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * More Statistics is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with More Statistics. If not, see . 19 | */ 20 | 21 | package me.fallenbreath.morestatistics.mixins.stats.mend_durability; 22 | 23 | import com.llamalad7.mixinextras.injector.ModifyExpressionValue; 24 | import com.llamalad7.mixinextras.sugar.Local; 25 | import me.fallenbreath.morestatistics.MoreStatisticsRegistry; 26 | import net.minecraft.entity.ExperienceOrbEntity; 27 | import net.minecraft.server.network.ServerPlayerEntity; 28 | import org.spongepowered.asm.mixin.Mixin; 29 | import org.spongepowered.asm.mixin.injection.At; 30 | 31 | // impl for mc >= 1.21 32 | @Mixin(ExperienceOrbEntity.class) 33 | public abstract class ExperienceOrbEntityMixin 34 | { 35 | @ModifyExpressionValue( 36 | method = "repairPlayerGears", 37 | at = @At( 38 | value = "INVOKE", 39 | target = "Lnet/minecraft/enchantment/EnchantmentHelper;getRepairWithXp(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/item/ItemStack;I)I", 40 | ordinal = 0 41 | ) 42 | ) 43 | private int onMendingApplied(int durabilityMended, @Local(argsOnly = true) ServerPlayerEntity player) 44 | { 45 | player.increaseStat(MoreStatisticsRegistry.MEND_DURABILITY, durabilityMended); 46 | return durabilityMended; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /versions/1.21.3/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.21.3 3 | minecraft_version=1.21.3 4 | yarn_mappings=1.21.3+build.2 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=>=1.21.2 <=1.21.3 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.21.2\n1.21.3 12 | 13 | # Dependencies 14 | fabric_api_version=0.114.0+1.21.3 -------------------------------------------------------------------------------- /versions/1.21.4/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.21.4 3 | minecraft_version=1.21.4 4 | yarn_mappings=1.21.4+build.8 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.21.4 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.21.4 12 | 13 | # Dependencies 14 | fabric_api_version=0.117.0+1.21.4 15 | -------------------------------------------------------------------------------- /versions/1.21.5/gradle.properties: -------------------------------------------------------------------------------- 1 | # Fabric Properties 2 | # check these on https://fallen-breath.github.io/fabric-versions/?&version=1.21.5 3 | minecraft_version=1.21.5 4 | yarn_mappings=1.21.5+build.1 5 | 6 | # Fabric Mod Metadata 7 | minecraft_dependency=1.21.5 8 | 9 | # Build Information 10 | # The target mc versions for the mod during mod publishing, separated with \n 11 | game_versions=1.21.5 12 | 13 | # Dependencies 14 | fabric_api_version=0.119.5+1.21.5 15 | -------------------------------------------------------------------------------- /versions/mainProject: -------------------------------------------------------------------------------- 1 | 1.15.2 --------------------------------------------------------------------------------