Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb4c288fb0 | ||
|
|
06821e3ad2 | ||
|
|
3428d489eb | ||
|
|
c84303e236 | ||
|
|
08e3c7a09c | ||
|
|
bb2bc39bad | ||
|
|
5fee18b551 | ||
|
|
e8ae11d574 | ||
|
|
d24ef111a3 | ||
|
|
1e75141ca8 | ||
|
|
f33d17b85e | ||
|
|
25dc1464cd | ||
|
|
f4be87e267 | ||
|
|
25ef74f7da | ||
|
|
2d50c0afdf | ||
|
|
62389c904c | ||
|
|
2f17d95923 |
No files matched your search
@@ -7,8 +7,6 @@ indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 100
|
||||
tab_width = 4
|
||||
end_of_line = crlf
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# intellij specific configuration
|
||||
ij_continuation_indent_size = 8
|
||||
@@ -17,6 +15,3 @@ ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = false
|
||||
ij_smart_tabs = false
|
||||
ij_wrap_on_typing = false
|
||||
|
||||
[.github/ISSUE_TEMPLATE/*.yml]
|
||||
indent_size = 2
|
||||
@@ -5,7 +5,7 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bypass and how to replicate it
|
||||
description: Provide a video or detailed instructions to help replicate it.
|
||||
description: Provide a video, or detailed instructions to help replicate it.
|
||||
placeholder: |
|
||||
Step 1. Do this
|
||||
Step 2. Then do this
|
||||
@@ -17,8 +17,8 @@ body:
|
||||
attributes:
|
||||
label: Grim version
|
||||
description: |
|
||||
Provide the version of Grim running on the server. You can run `/grim version` to check.
|
||||
placeholder: Examples include 2.3.73-8ddd7f1, 2.3.72, etc.
|
||||
Provide the git commit or the version in the jar's name.
|
||||
placeholder: A example would be b85c2d0 or grim version 2.3.5, etc
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -26,23 +26,15 @@ body:
|
||||
attributes:
|
||||
label: Server version
|
||||
description: |
|
||||
Run `/version` on your server to check. Provide both the server type (ie Paper, Airplane, etc) & the Minecraft version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Client version
|
||||
description: |
|
||||
Provide the version of your Minecraft client. Also provide the protocol version if changed.
|
||||
Run `/version` on your server to check. Provide both the server type (paper, airplane, etc) & the minecraft version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugins/Mods
|
||||
label: Plugins
|
||||
description: |
|
||||
List all plugins or mods installed on your server. To list plugins on Bukkit-based servers, run `/plugins`.
|
||||
List all plugins or mods running on your server. To list plugins on bukkit, run `/plugins`.
|
||||
If your server is behind a proxy such as Bungeecord, you should list the proxy's plugins as well.
|
||||
validations:
|
||||
required: true
|
||||
@@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
@@ -6,7 +6,7 @@ body:
|
||||
attributes:
|
||||
label: Stack trace
|
||||
description: |
|
||||
Provide the entire stack trace with no attachments. If you would like, you can use a text pasting site such as https://mclo.gs.
|
||||
Please include the entire stack trace with no attachments. If you would like, you can use a text pasting site such as https://paste.gg.
|
||||
placeholder: Paste the stack trace or link to the stack trace here
|
||||
validations:
|
||||
required: true
|
||||
@@ -14,7 +14,7 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: How to replicate it if known
|
||||
description: A video or detailed instructions to help replicate the issue would help.
|
||||
description: A video, or detailed instructions to help replicate the issue would help.
|
||||
placeholder: |
|
||||
Step 1. Do this
|
||||
Step 2. Then do this
|
||||
@@ -26,8 +26,8 @@ body:
|
||||
attributes:
|
||||
label: Grim version
|
||||
description: |
|
||||
Provide the version of Grim running on the server. You can run `/grim version` to check.
|
||||
placeholder: Examples include 2.3.73-8ddd7f1, 2.3.72, etc.
|
||||
Provide the git commit or the version in the jar's name.
|
||||
placeholder: A example would be b85c2d0 or grim version 2.3.5, etc
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -35,27 +35,27 @@ body:
|
||||
attributes:
|
||||
label: Server version
|
||||
description: |
|
||||
Run `/version` on your server to check. Provide both the server type (ie Paper, Airplane, etc) & the Minecraft version.
|
||||
Run `/version` on your server to check. Provide both the server type (paper, airplane, etc) & the minecraft version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: type
|
||||
attributes:
|
||||
label: Affected Platform(s)
|
||||
description: Which platforms does this issue affect? If you aren't sure, select both.
|
||||
options:
|
||||
- "Bukkit"
|
||||
- "Fabric"
|
||||
multiple: true
|
||||
label: Affected Platform(s)
|
||||
description: Which platforms does this issue affect? If you aren't sure, select both.
|
||||
options:
|
||||
- "Bukkit"
|
||||
- "Fabric"
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugins/Mods
|
||||
label: Plugins/mods
|
||||
description: |
|
||||
List all plugins or mods installed on your server. To list plugins on Bukkit-based servers, run `/plugins`.
|
||||
List all plugins or mods running on your server. To list plugins on bukkit, run `/plugins`.
|
||||
If your server is behind a proxy such as Bungeecord, you should list the proxy's plugins as well.
|
||||
validations:
|
||||
required: true
|
||||
@@ -20,8 +20,8 @@ body:
|
||||
attributes:
|
||||
label: Grim version
|
||||
description: |
|
||||
Provide the version of Grim running on the server. You can run `/grim version` to check.
|
||||
placeholder: Examples include 2.3.73-8ddd7f1, 2.3.72, etc.
|
||||
Provide the git commit or the version in the jar's name.
|
||||
placeholder: A example would be b85c2d0 or grim version 2.3.5, etc
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -29,7 +29,7 @@ body:
|
||||
attributes:
|
||||
label: Server version
|
||||
description: |
|
||||
Run `/version` on your server to check. Provide both the server type (ie Paper, Airplane, etc) & the Minecraft version.
|
||||
Run `/version` on your server to check. Provide both the server type (paper, airplane, etc) & the minecraft version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -37,16 +37,16 @@ body:
|
||||
attributes:
|
||||
label: Client version
|
||||
description: |
|
||||
Provide the version of your Minecraft client. You must be able to reproduce the false positive using a vanilla client.
|
||||
Using Lunar Client, TLauncher, Fabric, etc, will result in your issue being closed.
|
||||
Provide the version of your Minecraft client. You must be able to reproduce the false positive using the vanilla client.
|
||||
Lunar Client, TLauncher etc. will result in your issue being closed.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugins/Mods
|
||||
label: Plugins
|
||||
description: |
|
||||
List all plugins or mods installed on your server. To list plugins on Bukkit-based servers, run `/plugins`.
|
||||
List all plugins or mods running on your server. To list plugins on bukkit, run `/plugins`.
|
||||
If your server is behind a proxy such as Bungeecord, you should list the proxy's plugins as well.
|
||||
validations:
|
||||
required: true
|
||||
@@ -5,6 +5,6 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature description
|
||||
description: Describe the feature and why it should be added.
|
||||
description: Describe the feature and why it should be added
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
@@ -5,7 +5,7 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug and how to replicate it
|
||||
description: A video or detailed instructions to help replicate the issue would help.
|
||||
description: A video, or detailed instructions to help replicate the issue would help.
|
||||
placeholder: |
|
||||
Step 1. Do this
|
||||
Step 2. Then do this
|
||||
@@ -16,8 +16,9 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Grim version
|
||||
description: Provide the version of Grim running on the server. You can run `/grim version` to check.
|
||||
placeholder: Examples include 2.3.73-8ddd7f1, 2.3.72, etc.
|
||||
description: |
|
||||
Provide the git commit or the version in the jar's name.
|
||||
placeholder: A example would be b85c2d0 or grim version 2.3.5, etc
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -25,27 +26,27 @@ body:
|
||||
attributes:
|
||||
label: Server version
|
||||
description: |
|
||||
Run `/version` on your server to check. Provide both the server type (ie Paper, Airplane, etc) & the Minecraft version.
|
||||
Run `/version` on your server to check. Provide both the server type (paper, airplane, etc) & the minecraft version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: type
|
||||
attributes:
|
||||
label: Affected Platform(s)
|
||||
description: Which platforms does this issue affect? If you aren't sure, select both.
|
||||
options:
|
||||
- "Bukkit"
|
||||
- "Fabric"
|
||||
multiple: true
|
||||
label: Affected Platform(s)
|
||||
description: Which platforms does this issue affect? If you aren't sure, select both.
|
||||
options:
|
||||
- "Bukkit"
|
||||
- "Fabric"
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugins/Mods
|
||||
label: Plugins
|
||||
description: |
|
||||
List all plugins or mods installed on your server. To list plugins on Bukkit-based servers, run `/plugins`.
|
||||
List all plugins or mods running on your server. To list plugins on bukkit, run `/plugins`.
|
||||
If your server is behind a proxy such as Bungeecord, you should list the proxy's plugins as well.
|
||||
validations:
|
||||
required: true
|
||||
@@ -19,15 +19,8 @@ body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: Grim Log
|
||||
description: Provide the generated /grim log link.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Grim version
|
||||
description: Provide the version of Grim running on the server. You can run `/grim version` to check.
|
||||
placeholder: Examples include 2.3.73-8ddd7f1, 2.3.72, etc.
|
||||
description: |
|
||||
Provide the generated /grim log link.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -35,7 +28,7 @@ body:
|
||||
attributes:
|
||||
label: Server version
|
||||
description: |
|
||||
Run `/version` on your server to check. Provide both the server type (ie Paper, Airplane, etc) & the Minecraft version.
|
||||
Run `/version` on your server to check. Provide both the server type (paper, airplane, etc) & the minecraft version.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -43,16 +36,16 @@ body:
|
||||
attributes:
|
||||
label: Client version
|
||||
description: |
|
||||
Provide the version of your Minecraft client. You must be able to reproduce the false positive using a vanilla client.
|
||||
Using Lunar Client, TLauncher, Fabric, etc, will result in your issue being closed.
|
||||
Provide the version of your Minecraft client. You must be able to reproduce the false positive using the vanilla client.
|
||||
Lunar Client, TLauncher etc. will result in your issue being closed.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Plugins/Mods
|
||||
label: Plugins
|
||||
description: |
|
||||
List all plugins or mods installed on your server. To list plugins on Bukkit-based servers, run `/plugins`.
|
||||
List all plugins or mods running on your server. To list plugins on bukkit, run `/plugins`.
|
||||
If your server is behind a proxy such as Bungeecord, you should list the proxy's plugins as well.
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
@@ -1,230 +0,0 @@
|
||||
name: Reusable Build and Publish
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
is-release-build:
|
||||
description: 'True if this is a release build, which affects versioning and publishing.'
|
||||
required: true
|
||||
type: boolean
|
||||
release-version-type:
|
||||
description: 'The version type for Modrinth (e.g., release, beta, alpha).'
|
||||
required: true
|
||||
type: string
|
||||
release-changelog:
|
||||
description: 'The changelog content for the release.'
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
run-build-scan:
|
||||
description: 'Whether to enable Develocity build scan'
|
||||
required: true
|
||||
type: boolean
|
||||
publish-artifacts:
|
||||
description: 'If true, uploads artifacts to Modrinth and other distribution sites.'
|
||||
required: true
|
||||
type: boolean
|
||||
secrets:
|
||||
MODRINTH_ID:
|
||||
required: false
|
||||
MODRINTH_TOKEN:
|
||||
required: false
|
||||
BUILD_UPDATE_TOKEN:
|
||||
required: true
|
||||
BUILD_UPDATE_URL:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: tenki-standard-autoscale
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
MODRINTH_ID: ${{ secrets.MODRINTH_ID }}
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
GRIM_MAIN_BRANCH: ${{ github.event.repository.default_branch }}
|
||||
BUILD_UPDATE_TOKEN: ${{ secrets.BUILD_UPDATE_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository with full history
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 200
|
||||
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
server-id: github
|
||||
settings-path: ${{ github.workspace }}
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
cache-read-only: ${{ github.ref_name != github.event.repository.default_branch && github.ref_name != 'dev' }}
|
||||
|
||||
- name: Cache Gradle Loom Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .gradle/loom-cache
|
||||
key: loom-cache-${{ runner.os }}-${{ hashFiles('**/libs.versions.toml', 'fabric/**/build.gradle.kts') }}
|
||||
restore-keys: |
|
||||
loom-cache-${{ runner.os }}
|
||||
|
||||
- name: Set Git Environment Variables
|
||||
run: |
|
||||
echo "GRIM_GIT_REPO=${{ github.event.repository.name }}" >> $GITHUB_ENV
|
||||
echo "GRIM_GIT_ORG=${{ github.repository_owner }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Compute version and Build with Gradle
|
||||
id: build_with_version
|
||||
run: |
|
||||
# If any command in a pipeline fails, treat the pipeline as failed.
|
||||
set -o pipefail
|
||||
|
||||
BUILD_ARGS="build"
|
||||
if [[ "${{ inputs.is-release-build }}" == "true" ]]; then
|
||||
BUILD_ARGS="$BUILD_ARGS -Prelease=true"
|
||||
fi
|
||||
# Conditionally add the --scan flag
|
||||
if [[ "${{ inputs.run-build-scan }}" == "true" ]]; then
|
||||
BUILD_ARGS="$BUILD_ARGS --scan"
|
||||
fi
|
||||
|
||||
echo "Running: ./gradlew printVersion $BUILD_ARGS"
|
||||
|
||||
# Use 'tee' to both display the output live and save it to a file for parsing
|
||||
VERSION=$(./gradlew printVersion $BUILD_ARGS | tee build-output.log | grep '^VERSION=' | tail -n1 | cut -d'=' -f2)
|
||||
|
||||
echo "build_version=$VERSION" >> $GITHUB_OUTPUT
|
||||
echo "BUILD_VERSION=$VERSION" >> $GITHUB_ENV
|
||||
echo "Build version: $VERSION"
|
||||
|
||||
- name: Publish Build Scan URL
|
||||
# Only run this step if a scan was requested
|
||||
if: ${{ inputs.run-build-scan == true }}
|
||||
run: |
|
||||
# Search the log file for the build scan URL and extract it
|
||||
SCAN_URL=$(grep -o 'https://gradle.com/s/[^ ]*' build-output.log | head -n 1 || true)
|
||||
|
||||
if [[ -n "$SCAN_URL" ]]; then
|
||||
echo "Found build scan URL: $SCAN_URL"
|
||||
# Post a highly visible link to the Job Summary page
|
||||
echo "### Gradle Build Scan" >> $GITHUB_STEP_SUMMARY
|
||||
echo "A public build scan has been published and is available for inspection." >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "[**View Build Scan →**]($SCAN_URL)" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "Could not find build scan URL in build-output.log" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
- name: Upload Bukkit Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: grimac-bukkit
|
||||
path: ${{ github.workspace }}/bukkit/build/libs/grimac-bukkit-${{ env.BUILD_VERSION }}.jar
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Fabric Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: grimac-fabric
|
||||
path: ${{ github.workspace }}/fabric/build/libs/grimac-fabric-${{ env.BUILD_VERSION }}.jar
|
||||
if-no-files-found: error
|
||||
|
||||
#------------------------------------------------------------------
|
||||
# Generate/Prepare Changelog
|
||||
#------------------------------------------------------------------
|
||||
- name: Generate Changelog with git-cliff (for Dev Builds)
|
||||
if: ${{ !inputs.is-release-build }}
|
||||
id: git-cliff
|
||||
uses: orhun/git-cliff-action@v4
|
||||
with:
|
||||
config: cliff.toml
|
||||
args: --verbose ${{ github.event.before }}..${{ github.event.after }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # git-cliff needs a token
|
||||
|
||||
- name: Prepare Final Changelog
|
||||
id: changelog
|
||||
# Add this 'env' block to safely load the changelogs as environment variables
|
||||
env:
|
||||
RELEASE_NOTES: ${{ inputs.release-changelog }}
|
||||
DEV_NOTES: ${{ steps.git-cliff.outputs.content }}
|
||||
run: |
|
||||
NOTES=""
|
||||
if [[ "${{ inputs.is-release-build }}" == "true" ]]; then
|
||||
# Use the environment variable for the release changelog.
|
||||
# The double quotes are critical to preserve newlines!
|
||||
NOTES="$RELEASE_NOTES"
|
||||
else
|
||||
# Use the environment variable for the dev changelog.
|
||||
NOTES="$DEV_NOTES"
|
||||
fi
|
||||
|
||||
if [ -z "$NOTES" ]; then
|
||||
NOTES="* No new code changes in this build."
|
||||
fi
|
||||
|
||||
# This is the correct way to set a multi-line output variable in Actions
|
||||
{
|
||||
echo "notes<<EOF"
|
||||
echo "$NOTES"
|
||||
echo "EOF"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Publish Fabric to Modrinth
|
||||
if: ${{ inputs.publish-artifacts == true && env.MODRINTH_ID != '' && env.MODRINTH_TOKEN != '' }}
|
||||
uses: Kir-Antipov/mc-publish@v3.3
|
||||
with:
|
||||
modrinth-id: ${{ secrets.MODRINTH_ID }}
|
||||
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
|
||||
modrinth-featured: ${{ inputs.is-release-build }} # Only feature release builds
|
||||
|
||||
files: fabric/build/libs/grimac-fabric-${{ env.BUILD_VERSION }}.jar
|
||||
name: Grim Anticheat (Fabric) ${{ env.BUILD_VERSION }}
|
||||
version: ${{ env.BUILD_VERSION }}
|
||||
version-type: ${{ inputs.release-version-type }}
|
||||
changelog: ${{ steps.changelog.outputs.notes }}
|
||||
loaders: |
|
||||
fabric
|
||||
game-versions: '>=1.21.5 <=1.21.10'
|
||||
dependencies: 'fabric-api'
|
||||
|
||||
#------------------------------------------------------------------
|
||||
# Publish to Modrinth & API
|
||||
#------------------------------------------------------------------
|
||||
- name: Publish Bukkit to Modrinth
|
||||
if: ${{ inputs.publish-artifacts == true && env.MODRINTH_ID != '' && env.MODRINTH_TOKEN != '' }}
|
||||
uses: Kir-Antipov/mc-publish@v3.3
|
||||
with:
|
||||
modrinth-id: ${{ secrets.MODRINTH_ID }}
|
||||
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
|
||||
modrinth-featured: ${{ inputs.is-release-build }} # Only feature release builds
|
||||
|
||||
files: bukkit/build/libs/grimac-bukkit-${{ env.BUILD_VERSION }}.jar
|
||||
name: Grim Anticheat (Bukkit) ${{ env.BUILD_VERSION }}
|
||||
version: ${{ env.BUILD_VERSION }}
|
||||
version-type: ${{ inputs.release-version-type }}
|
||||
changelog: ${{ steps.changelog.outputs.notes }}
|
||||
loaders: |
|
||||
bukkit
|
||||
spigot
|
||||
paper
|
||||
folia
|
||||
purpur
|
||||
game-versions: '>=1.7 <=1.21.10'
|
||||
|
||||
- name: Publish to API
|
||||
if: ${{ inputs.publish-artifacts == true && env.BUILD_UPDATE_TOKEN != '' }}
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "User-Agent: GrimACBuilder/v1" \
|
||||
-H "Authorization: Bearer ${{ secrets.BUILD_UPDATE_TOKEN }}" \
|
||||
-d '{"org": "${{ github.repository_owner }}", "repository": "${{ github.event.repository.name }}", "branch": "${{ github.ref_name }}", "version": "${{ env.BUILD_VERSION }}"}' \
|
||||
"${{ secrets.BUILD_UPDATE_URL }}"
|
||||
@@ -12,14 +12,18 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [dev]
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '30 15 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: tenki-standard-autoscale
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
@@ -28,14 +32,14 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['java-kotlin']
|
||||
language: [ 'java' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
@@ -47,20 +51,11 @@ jobs:
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
@@ -71,5 +66,6 @@ jobs:
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
uses: github/codeql-action/analyze@v3
|
||||
@@ -1,42 +1,59 @@
|
||||
name: Gradle Package (Development)
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
|
||||
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
|
||||
|
||||
name: Gradle Package
|
||||
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run-build-scan:
|
||||
description: 'Run with public build scan (adds --scan)'
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
publish-artifacts:
|
||||
description: 'Upload to Modrinth & API? (Uncheck for a dry run)'
|
||||
type: boolean
|
||||
default: true
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- '2.0'
|
||||
- 'dev'
|
||||
- 'release'
|
||||
- 'release/**'
|
||||
paths:
|
||||
- 'bukkit/**'
|
||||
- 'common/**'
|
||||
- 'fabric/**'
|
||||
- '**.java'
|
||||
- '**.kt'
|
||||
- '**.kts'
|
||||
- '**.toml'
|
||||
jobs:
|
||||
call-build-workflow:
|
||||
uses: ./.github/workflows/build-and-publish.yml
|
||||
with:
|
||||
is-release-build: false
|
||||
release-version-type: alpha # Dev builds are always 'alpha'
|
||||
run-build-scan: ${{ github.event.inputs.run-build-scan == 'true' }}
|
||||
publish-artifacts: ${{ github.event.inputs.publish-artifacts != 'false' }}
|
||||
secrets:
|
||||
MODRINTH_ID: ${{ secrets.MODRINTH_ID }}
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
BUILD_UPDATE_TOKEN: ${{ secrets.BUILD_UPDATE_TOKEN }}
|
||||
BUILD_UPDATE_URL: ${{ secrets.BUILD_UPDATE_URL }}
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4 # Handles Gradle wrapper validation and basic caching
|
||||
|
||||
- name: Cache Gradle Loom Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .gradle/loom-cache # Path to Loom cache relative to workspace root
|
||||
key: loom-cache-${{ runner.os }}-${{ hashFiles('**/libs.versions.toml', 'fabric/**/build.gradle.kts') }}
|
||||
restore-keys: |
|
||||
loom-cache-${{ runner.os }}
|
||||
|
||||
- name: Build with Gradle (Actual Build for Artifacts)
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Upload Bukkit Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: grimac-bukkit
|
||||
# Adding if-no-files-found for robustness
|
||||
path: ${{ github.workspace }}/bukkit/build/libs/grimac-bukkit-*.jar
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Fabric Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: grimac-fabric
|
||||
# Adding if-no-files-found for robustness
|
||||
path: ${{ github.workspace }}/fabric/build/libs/grimac-fabric-*.jar
|
||||
if-no-files-found: error
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
name: Publish Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
call-release-workflow:
|
||||
uses: ./.github/workflows/build-and-publish.yml
|
||||
with:
|
||||
is-release-build: true
|
||||
release-version-type: release # Official releases are 'release'
|
||||
# Use the body of the GitHub Release as the changelog
|
||||
release-changelog: ${{ github.event.release.body }}
|
||||
run-build-scan: false
|
||||
publish-artifacts: true
|
||||
secrets:
|
||||
MODRINTH_ID: ${{ secrets.MODRINTH_ID }}
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
BUILD_UPDATE_TOKEN: ${{ secrets.BUILD_UPDATE_TOKEN }}
|
||||
BUILD_UPDATE_URL: ${{ secrets.BUILD_UPDATE_URL }}
|
||||
@@ -0,0 +1,6 @@
|
||||
[submodule "GrimAPI"]
|
||||
path = GrimAPI
|
||||
url = https://github.com/GrimAnticheat/GrimAPI
|
||||
[submodule "api"]
|
||||
path = api
|
||||
url = https://github.com/GrimAnticheat/GrimAPI
|
||||
@@ -1,40 +0,0 @@
|
||||
# Contributing to GrimAC
|
||||
|
||||
Thank you for your interest in contributing to GrimAC. This document outlines the guidelines for
|
||||
making pull
|
||||
requests to the project. *We're usually pretty lenient with pull requests, but this guide will help
|
||||
make the process go more smoothly.*
|
||||
|
||||
### Pull Request Guidelines
|
||||
|
||||
- **Compatibility**
|
||||
- Any changes must be compatible with
|
||||
the [supported environments](https://github.com/GrimAnticheat/Grim/wiki/Supported-environments) (Spigot, Paper, Folia, Fabric, etc.)
|
||||
- The plugin must be compatible with minecraft versions 1.8 and higher. Exempting checks from specific versions is acceptable.
|
||||
- The plugin must be able to run on Java 17 or higher. Changes that don't support Java 17 at runtime will not be accepted.
|
||||
|
||||
- **Non-acceptable pull requests**
|
||||
- Heuristic-based checks will not be accepted; however, basic rate limiting such as blocking attacks based on CPS is acceptable.
|
||||
- Checks that can be easily circumvented that don't block packets or fix anything are likely to not be accepted.
|
||||
- Checks or features that are too specific to a single environment or minecraft version are likely to not be accepted.
|
||||
- Changes that require large or unnecessary dependencies will likely not be accepted.
|
||||
|
||||
- **Pull request formatting**
|
||||
- Create a new branch for your feature or fix when forking the repository.
|
||||
- Reference related issues in your pull request description if applicable.
|
||||
- Write clear and descriptive commit messages.
|
||||
|
||||
- **Code styling**
|
||||
- Add code comments for complex logic or significant changes.
|
||||
- Try to keep your code clean and avoid duplication.
|
||||
- Thoroughly test your changes before submitting your pull request.
|
||||
|
||||
### Development Notes
|
||||
|
||||
- GrimAC is built using [Gradle](https://gradle.org/) kotlin scripts.
|
||||
- Java 21 is currently required to build the project. A minimum of Java 17 is required to run it.
|
||||
|
||||
### Questions & Support
|
||||
|
||||
- Join our [Discord](https://discord.grim.ac) if you have questions or need assistance.
|
||||
- Refer to the [Wiki](https://github.com/GrimAnticheat/Grim/wiki) for project documentation.
|
||||
@@ -1,73 +1,40 @@
|
||||
<div align="center">
|
||||
<h1>GrimAC</h1>
|
||||
# GrimAC
|
||||
|
||||
<div>
|
||||
<a href="https://github.com/GrimAnticheat/Grim/actions/workflows/gradle-publish.yml">
|
||||
<img alt="Workflow" src="https://img.shields.io/github/actions/workflow/status/GrimAnticheat/Grim/gradle-publish.yml?style=flat&logo=github"/>
|
||||
</a>
|
||||
<a href="https://modrinth.com/plugin/grimac">
|
||||
<img alt="Modrinth" src="https://img.shields.io/modrinth/v/LJNGWSvH?style=flat&label=version&logo=modrinth">
|
||||
</a>
|
||||
<a href="https://modrinth.com/plugin/grimac#download">
|
||||
<img alt="Downloads" src="https://img.shields.io/modrinth/dt/LJNGWSvH?style=flat&logo=modrinth&label=downloads&link=https%3A%2F%2Fmodrinth.com%2Fplugin%2Fgrimac%23download">
|
||||
</a>
|
||||
<a href="https://discord.grim.ac">
|
||||
<img alt="Discord" src="https://img.shields.io/discord/811396969670901800?style=flat&label=discord&logo=discord">
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
GrimAC is an open source Minecraft anticheat designed for 1.21 and supports 1.8-1.21. It is free while in beta. It will eventually become paid and/or will include offering additional subscription based paid checks. Geyser players are fully exempt.
|
||||
|
||||
GrimAC is an open source Minecraft anticheat designed to support the latest versions of Minecraft.
|
||||
It currently supports minecraft versions 1.8–1.21. Geyser players are fully exempt from the anticheat to prevent false positives.
|
||||
This project is considered feature-complete for the 2.0 (open-source) branch. If you would like a bug fix or enhancement and cannot sponsor the work, pull requests are welcome.
|
||||
A premium version is planned, which will offer additional subscription-based paid checks, such as heuristics.
|
||||
This project is considered feature complete for the 2.0 (open-source) branch of this project. If you would like a bugfix or enhancement and cannot sponsor the work, pull requests are welcome.
|
||||
|
||||
## Downloads
|
||||
- [Modrinth](https://modrinth.com/plugin/grimac)
|
||||
- [Hangar](https://hangar.papermc.io/GrimAnticheat/GrimAnticheat)
|
||||
- [SpigotMC](https://www.spigotmc.org/resources/grim-anticheat.99923/)
|
||||
- *For bleeding edge builds use GitHub artifacts*: [Bukkit](https://nightly.link/GrimAnticheat/Grim/workflows/gradle-publish/2.0/grimac-bukkit.zip), [Fabric](https://nightly.link/GrimAnticheat/Grim/workflows/gradle-publish/2.0/grimac-fabric.zip)
|
||||
|
||||
- Latest updates:
|
||||
- **[Modrinth](https://modrinth.com/plugin/grimac)** *(recommended)*
|
||||
- GitHub
|
||||
artifacts: [Bukkit](https://nightly.link/GrimAnticheat/Grim/workflows/gradle-publish/2.0/grimac-bukkit.zip), [Fabric](https://nightly.link/GrimAnticheat/Grim/workflows/gradle-publish/2.0/grimac-fabric.zip) *(bleeding edge)*
|
||||
- Major releases only:
|
||||
- ~~[Hangar](https://hangar.papermc.io/GrimAnticheat/GrimAnticheat)~~
|
||||
- ~~[SpigotMC](https://www.spigotmc.org/resources/grim-anticheat.99923/)~~
|
||||
## Installation notes
|
||||
> [!WARNING]
|
||||
> Java 17 is now required. More information [here](https://github.com/GrimAnticheat/Grim/wiki/Updating-to-Java-17).
|
||||
- Paper, Spigot, Folia, and Fabric are currently supported.
|
||||
- If you use Geyser, place Floodgate on the backend server so grim can exempt bedrock players. Grim cannot access the Floodgate API if it is on the proxy.
|
||||
- If you use ViaVersion, it should be on the backend server as movement is highly dependent on client version.
|
||||
|
||||
## Requirements & Installation
|
||||
## Support & wiki information
|
||||
- Support & discussion: [Discord](https://discord.com/invite/kqQAhTmkUF)
|
||||
- Report issues: [Issues](https://github.com/GrimAnticheat/Grim/issues/new/choose)
|
||||
- Wiki & examples: [Wiki](https://github.com/GrimAnticheat/Grim/wiki)
|
||||
|
||||
- Java 17 or higher. *For more details, see [Updating-to-Java-17](https://github.com/GrimAnticheat/Grim/wiki/Updating-to-Java-17).*
|
||||
- A Spigot, Paper, Folia, or Fabric server environment. *For more details, see [Supported-environments](https://github.com/GrimAnticheat/Grim/wiki/Supported-environments).*
|
||||
## Developer API
|
||||
Grim's API allows you to integrate Grim into your own plugins.
|
||||
- API repository: [GrimAPI](https://github.com/GrimAnticheat/GrimAPI)
|
||||
- Wiki info: [Wiki](https://github.com/GrimAnticheat/GrimAPI)
|
||||
|
||||
If you use a proxy such as Velocity or Bungeecord:
|
||||
- If you use Geyser, Floodgate must be installed on the backend server (where Grim is) so Grim can access the Floodgate API.
|
||||
- If you use ViaVersion, it must be installed on the backend server (where Grim is) ONLY.
|
||||
Grim does not support having ViaVersion installed on the proxy, even if it is also installed on the backend.
|
||||
|
||||
## Resources
|
||||
|
||||
- For documentation and examples visit the [Wiki](https://github.com/GrimAnticheat/Grim/wiki).
|
||||
- For answers to commonly asked questions visit the [FAQ](https://github.com/GrimAnticheat/Grim/wiki/FAQ).
|
||||
- For community support and project discussion join our [Discord](https://discord.grim.ac).
|
||||
|
||||
## Pull Requests
|
||||
|
||||
See [Contributing](CONTRIBUTING.md) for more information about contributing and what our guidelines
|
||||
are.
|
||||
|
||||
## Developer Plugin API
|
||||
|
||||
Grim's plugin API allows you to integrate Grim into your own plugins. Visit
|
||||
the [plugin API repository](https://github.com/GrimAnticheat/GrimAPI) for the source code and more
|
||||
information.
|
||||
|
||||
## Compiling From Source
|
||||
## How to compile
|
||||
|
||||
1. `git clone https://github.com/GrimAnticheat/Grim.git`
|
||||
2. `cd Grim`
|
||||
3. `./gradlew build`
|
||||
4. The final jars will compile into the `<platform>/build/libs` folders
|
||||
|
||||
## Grim Supremacy
|
||||
## Grim supremacy
|
||||
|
||||
What makes Grim stand out against other anticheats?
|
||||
|
||||
@@ -77,9 +44,7 @@ What makes Grim stand out against other anticheats?
|
||||
* This covers everything from basic walking, swimming, knockback, cobwebs, to bubble columns
|
||||
* It even covers riding entities from boats to pigs to striders
|
||||
* Built upon covering edge cases to confirm accuracy
|
||||
* 1.13+ clients on 1.13+ servers, 1.12- clients on 1.13+ servers, 1.13+ clients on 1.12- servers,
|
||||
and 1.12- clients on 1.12- servers are all supported regardless of the large technical changes
|
||||
between these versions.
|
||||
* 1.13+ clients on 1.13+ servers, 1.12- clients on 1.13+ servers, 1.13+ clients on 1.12- servers, and 1.12- clients on 1.12- servers are all supported regardless of the large technical changes between these versions.
|
||||
* The order of collisions depends on the client version and is correct
|
||||
* Accounts for minor bounding box differences between versions, for example:
|
||||
* Single glass panes will be a + shape for 1.7-1.8 players and * for 1.9+ players
|
||||
@@ -106,8 +71,7 @@ What makes Grim stand out against other anticheats?
|
||||
* Per player, the cache allows for multithreaded design
|
||||
* Sending players fake blocks with packets is safe and does not lead to falses
|
||||
* The world is recreated for each player to allow lag compensation
|
||||
* Client sided blocks cause no issues with packet based blocks. Block glitching does not false the
|
||||
anticheat.
|
||||
* Client sided blocks cause no issues with packet based blocks. Block glitching does not false the anticheat.
|
||||
|
||||
### Latency compensation
|
||||
|
||||
|
||||
Submodule
+1
Submodule api added at 6061ddc684.
+15
-19
@@ -1,10 +1,12 @@
|
||||
/**
|
||||
* GrimAC Build Configuration
|
||||
* ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||||
* ┃ GrimAC Build Configuration ┃
|
||||
* ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||||
*
|
||||
* Build Flags:
|
||||
* -PshadePE=true - Enables 'lite' mode
|
||||
* -Prelocate=false - Adds 'no_relocate' modifier
|
||||
* -Prelease=true - Removes commit/modifiers for release build
|
||||
* 🔧 Build Flags:
|
||||
* -PshadePE=true → Enables 'lite' mode
|
||||
* -Prelocate=false → Adds 'no_relocate' modifier
|
||||
* -Prelease=true → Removes commit/modifiers for release build
|
||||
*
|
||||
* Logic in: buildSrc/versioning/BuildConfig.kt & VersionUtil.kt
|
||||
*/
|
||||
@@ -14,23 +16,17 @@ import versioning.VersionUtil
|
||||
|
||||
BuildConfig.init(project)
|
||||
|
||||
val baseVersion = "2.3.73"
|
||||
val baseVersion = "2.3.72"
|
||||
group = "ac.grim.grimac"
|
||||
version = VersionUtil.computeVersion(baseVersion)
|
||||
description = "Libre simulation anticheat designed for 1.21 with 1.8–1.21 support, powered by PacketEvents 2.0."
|
||||
|
||||
ext["timestamp"] = System.currentTimeMillis().toString()
|
||||
ext["git_branch"] = VersionUtil.getGitBranch(true)
|
||||
ext["git_commit"] = VersionUtil.getGitCommitHash(true)
|
||||
ext["git_org"] = System.getenv("GRIM_GIT_ORG") ?: VersionUtil.getGitUser()
|
||||
ext["git_repo"] = System.getenv("GRIM_GIT_REPO") ?: "Grim"
|
||||
|
||||
println("Build configuration:")
|
||||
println(" shadePE = ${BuildConfig.shadePE}")
|
||||
println(" relocate = ${BuildConfig.relocate}")
|
||||
println(" mavenLocalOverride = ${BuildConfig.mavenLocalOverride}")
|
||||
println(" release = ${BuildConfig.release}")
|
||||
println(" version = $version")
|
||||
println("⚙️ Build configuration:")
|
||||
println(" shadePE = ${BuildConfig.shadePE}")
|
||||
println(" relocate = ${BuildConfig.relocate}")
|
||||
println(" mavenLocalOverride = ${BuildConfig.mavenLocalOverride}")
|
||||
println(" release = ${BuildConfig.release}")
|
||||
println(" version = $version")
|
||||
|
||||
tasks.register("printVersion") {
|
||||
group = "versioning"
|
||||
@@ -46,4 +42,4 @@ subprojects {
|
||||
options.isFork = true
|
||||
options.isIncremental = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ plugins {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import versioning.BuildConfig
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("io.freefair.lombok")
|
||||
@@ -18,6 +16,11 @@ java {
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
// Lombok configuration
|
||||
//lombok {
|
||||
// version.set("1.18.30") // Use the version from your version catalog if available
|
||||
//}
|
||||
|
||||
// Spotless configuration
|
||||
spotless {
|
||||
java {
|
||||
@@ -35,6 +38,7 @@ spotless {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tasks {
|
||||
withType<JavaCompile>().configureEach {
|
||||
options.encoding = "UTF-8"
|
||||
@@ -48,29 +52,11 @@ tasks {
|
||||
|
||||
// Process resources (e.g., for plugin metadata files)
|
||||
processResources {
|
||||
val properties = mapOf(
|
||||
"timestamp" to rootProject.ext["timestamp"],
|
||||
"version" to project.version.toString(),
|
||||
"git_commit" to rootProject.ext["git_commit"],
|
||||
"git_branch" to rootProject.ext["git_branch"],
|
||||
"git_repo" to rootProject.ext["git_repo"],
|
||||
"git_org" to rootProject.ext["git_org"],
|
||||
"build_shade_pe" to BuildConfig.shadePE,
|
||||
"build_relocate" to BuildConfig.relocate,
|
||||
"build_release" to BuildConfig.release,
|
||||
)
|
||||
|
||||
properties.forEach { (key, value) -> inputs.property(key, value) }
|
||||
|
||||
filesMatching(
|
||||
listOf(
|
||||
"bungee.yml",
|
||||
"velocity-plugin.json",
|
||||
"fabric.mod.json",
|
||||
"grimac.properties"
|
||||
)
|
||||
inputs.property("version", project.version)
|
||||
filesMatching(listOf( // "plugin.yml", Bukkit variable expansion taken care of by net.minecrell.plugin-yml.bukkit
|
||||
"bungee.yml", "velocity-plugin.json", "fabric.mod.json")
|
||||
) {
|
||||
expand(properties)
|
||||
expand("version" to project.version)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ fun extractEmbeddedJars(jarFile: File, project: Project): Set<DependencyIdentifi
|
||||
?: throw IllegalStateException("Missing 'id' in fabric.mod.json of embedded JAR: $entryName")
|
||||
val idWithDots = id.replace("_", ".")
|
||||
val lastDotIndex = idWithDots.lastIndexOf(".")
|
||||
val group = if (lastDotIndex != -1) idWithDots.take(lastDotIndex) else ""
|
||||
val group = if (lastDotIndex != -1) idWithDots.substring(0, lastDotIndex) else ""
|
||||
|
||||
// Extract name and version from the JAR filename
|
||||
val jarName = entryName.substringAfterLast("/").removeSuffix(".jar")
|
||||
@@ -127,7 +127,7 @@ fun parseNameAndVersionFromJarName(jarName: String): Pair<String, String>? {
|
||||
val versionStartIndex = versionStartMatch.range.first
|
||||
|
||||
// Split the JAR name into name and version at the version start index
|
||||
val name = jarName.take(versionStartIndex)
|
||||
val name = jarName.substring(0, versionStartIndex)
|
||||
val version = jarName.substring(versionStartIndex + 1) // Skip the hyphen
|
||||
|
||||
return if (name.isNotEmpty() && version.isNotEmpty()) {
|
||||
@@ -300,7 +300,7 @@ project.afterEvaluate {
|
||||
val allEmbeddedDependencies = mutableMapOf<DependencyIdentifier, File>()
|
||||
val actuallyIncludedDependencies = mutableSetOf<DependencyIdentifier>()
|
||||
|
||||
fun collectAllEmbeddedDependenciesForAfterEvaluate(dependencies: Set<ResolvedDependency>) {
|
||||
fun collectAllEmbeddedDependencies(dependencies: Set<ResolvedDependency>) {
|
||||
dependencies.forEach { dep ->
|
||||
val classifier = dep.moduleArtifacts.firstOrNull()?.classifier ?: ""
|
||||
val depKey = "${dep.moduleGroup}:${dep.moduleName}:${dep.moduleVersion}${if (classifier.isNotEmpty()) ":$classifier" else ""}"
|
||||
@@ -318,13 +318,13 @@ project.afterEvaluate {
|
||||
)
|
||||
}
|
||||
}
|
||||
collectAllEmbeddedDependenciesForAfterEvaluate(dep.children)
|
||||
collectAllEmbeddedDependencies(dep.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processed.clear()
|
||||
collectAllEmbeddedDependenciesForAfterEvaluate(resolvedDependencies)
|
||||
collectAllEmbeddedDependencies(resolvedDependencies)
|
||||
|
||||
processed.clear()
|
||||
processDependencies(
|
||||
@@ -345,7 +345,7 @@ tasks.withType<Jar>().configureEach {
|
||||
val allEmbeddedDependencies = mutableMapOf<DependencyIdentifier, File>()
|
||||
val actuallyIncludedDependencies = mutableSetOf<DependencyIdentifier>()
|
||||
|
||||
fun collectAllEmbeddedDependenciesForJar(dependencies: Set<ResolvedDependency>) {
|
||||
fun collectAllEmbeddedDependencies(dependencies: Set<ResolvedDependency>) {
|
||||
dependencies.forEach { dep ->
|
||||
val depKey = "${dep.moduleGroup}:${dep.moduleName}:${dep.moduleVersion}"
|
||||
if (!processed.contains(depKey)) {
|
||||
@@ -362,13 +362,13 @@ tasks.withType<Jar>().configureEach {
|
||||
)
|
||||
}
|
||||
}
|
||||
collectAllEmbeddedDependenciesForJar(dep.children)
|
||||
collectAllEmbeddedDependencies(dep.children)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processed.clear()
|
||||
collectAllEmbeddedDependenciesForJar(resolvedDependencies)
|
||||
collectAllEmbeddedDependencies(resolvedDependencies)
|
||||
|
||||
processed.clear()
|
||||
|
||||
|
||||
@@ -5,10 +5,17 @@ plugins {
|
||||
id("com.gradleup.shadow")
|
||||
}
|
||||
|
||||
// Create a configuration for shading dependencies from common
|
||||
val shadowCommon: Configuration by project.configurations.creating {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
// Extend from the "implementation" configuration of the current project
|
||||
extendsFrom(project.configurations.getByName("implementation"))
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
minimize()
|
||||
archiveFileName = "${rootProject.name}-${project.name}-${rootProject.version}.jar"
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
archiveFileName.set("${rootProject.name}-${project.name}-${rootProject.version}.jar")
|
||||
from(shadowCommon) // Use from() instead of direct assignment
|
||||
|
||||
if (BuildConfig.relocate) {
|
||||
if (BuildConfig.shadePE) {
|
||||
@@ -31,9 +38,9 @@ tasks.named<ShadowJar>("shadowJar") {
|
||||
relocate("org.jetbrains", "ac.grim.grimac.shaded.jetbrains")
|
||||
relocate("org.incendo", "ac.grim.grimac.shaded.incendo")
|
||||
relocate("io.leangen.geantyref", "ac.grim.grimac.shaded.geantyref") // Required by cloud
|
||||
relocate("com.zaxxer", "ac.grim.grimac.shaded.zaxxer") // Database history
|
||||
}
|
||||
mergeServiceFiles()
|
||||
minimize()
|
||||
}
|
||||
|
||||
tasks.named("assemble") {
|
||||
|
||||
@@ -2,11 +2,6 @@ package versioning
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.internal.extensions.stdlib.toDefaultLowerCase
|
||||
import versioning.BuildConfig.init
|
||||
import versioning.BuildConfig.mavenLocalOverride
|
||||
import versioning.BuildConfig.release
|
||||
import versioning.BuildConfig.relocate
|
||||
import versioning.BuildConfig.shadePE
|
||||
|
||||
/**
|
||||
* BuildConfig provides access to user-defined build flags that control how a Grim
|
||||
@@ -15,9 +10,9 @@ import versioning.BuildConfig.shadePE
|
||||
*
|
||||
* Flags can be defined in three ways:
|
||||
*
|
||||
* 1. JVM system properties (-Dflag=value)
|
||||
* 2. Gradle project properties (-Pflag=value or in gradle.properties)
|
||||
* 3. Environment variables (FLAG=value)
|
||||
* ① JVM system properties (-Dflag=value)
|
||||
* ② Gradle project properties (-Pflag=value or in gradle.properties)
|
||||
* ③ Environment variables (FLAG=value)
|
||||
*
|
||||
* You can use these to enable/disable features like shading, relocation, or release mode.
|
||||
*
|
||||
@@ -56,20 +51,29 @@ object BuildConfig {
|
||||
_shadePE = resolveBool(project, "shadePE", altKey = "SHADE_PE", default = true)
|
||||
_relocate = resolveBool(project, "relocate", altKey = "RELOCATE_JAR", default = true)
|
||||
_release = resolveBool(project, "release", default = false)
|
||||
_mavenLocalOverride = resolveBool(project, "mavenLocalOverride", default = false)
|
||||
_mavenLocalOverride = resolveBool(project, "mavenLocalOverride", altKey = "MAVEN_LOCAL_OVERRIDE", default = false)
|
||||
}
|
||||
|
||||
// Unified resolution logic (System > Gradle > Env)
|
||||
private fun resolveRaw(project: Project, key: String): String? =
|
||||
System.getProperty(key) // 1. JVM (-Dkey=value)
|
||||
?: project.findProperty(key)?.toString() // 2. Gradle (-Pkey=value or gradle.properties)
|
||||
?: System.getenv(key.uppercase()) // 3. ENV (KEY=value)
|
||||
System.getProperty(key) // ① JVM (-Dkey=value)
|
||||
?: project.findProperty(key)?.toString() // ② Gradle (-Pkey=value or gradle.properties)
|
||||
?: System.getenv(key.uppercase()) // ③ ENV (KEY=value)
|
||||
|
||||
private fun resolveBool(project: Project, key: String, altKey: String? = null, default: Boolean): Boolean {
|
||||
return resolveRaw(project, key)?.toDefaultLowerCase()?.toBooleanStrictOrNull()
|
||||
?: altKey?.let {
|
||||
resolveRaw(project, it)?.toDefaultLowerCase()?.toBooleanStrictOrNull()
|
||||
} ?: default
|
||||
val primaryValue = resolveRaw(project, key)?.toDefaultLowerCase()?.toBooleanStrictOrNull()
|
||||
if (primaryValue != null) {
|
||||
return primaryValue
|
||||
}
|
||||
|
||||
if (altKey != null) {
|
||||
val altValue = resolveRaw(project, altKey)?.toDefaultLowerCase()?.toBooleanStrictOrNull()
|
||||
if (altValue != null) {
|
||||
return altValue
|
||||
}
|
||||
}
|
||||
|
||||
return default
|
||||
}
|
||||
|
||||
// Private backing vars (nullable because we can't use lateinit with primitives)
|
||||
@@ -92,5 +96,4 @@ object BuildConfig {
|
||||
|
||||
val mavenLocalOverride: Boolean get() = _mavenLocalOverride
|
||||
?: error("BuildConfig.release accessed before init() was called")
|
||||
|
||||
}
|
||||
}
|
||||
@@ -37,31 +37,29 @@ object VersionUtil {
|
||||
val modifiers = buildList {
|
||||
if (!BuildConfig.shadePE) add("lite")
|
||||
if (!BuildConfig.relocate) add("no_relocate")
|
||||
}.joinToString("-").takeIf { it.isNotEmpty() }
|
||||
}.takeIf { it.isNotEmpty() }?.joinToString("-")
|
||||
|
||||
return buildString {
|
||||
append(baseVersion)
|
||||
append("-")
|
||||
branch?.let { append("$it-") }
|
||||
append(commitHash)
|
||||
modifiers?.let { append("+$it") }
|
||||
modifiers?.let { append("+$modifiers") }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current Git commit
|
||||
* Retrieves the current Git commit as a short hash.
|
||||
*/
|
||||
fun getGitCommitHash(full: Boolean = false): String {
|
||||
private fun getGitCommitHash(): String {
|
||||
val stdout = ByteArrayOutputStream()
|
||||
val command = listOfNotNull("git", "rev-parse", if (full) null else "--short", "HEAD")
|
||||
ProcessBuilder(command)
|
||||
ProcessBuilder("git", "rev-parse", "--short", "HEAD")
|
||||
.redirectErrorStream(true)
|
||||
.start()
|
||||
.apply { waitFor() }
|
||||
.inputStream
|
||||
.use { stdout.writeBytes(it.readAllBytes()) }
|
||||
val fullCommit = stdout.toString().trim()
|
||||
return fullCommit.take(minOf(fullCommit.length, 7))
|
||||
return stdout.toString().trim()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +69,7 @@ object VersionUtil {
|
||||
* Any slash (/) in the branch name is replaced with an underscore (_)
|
||||
* to avoid filesystem issues.
|
||||
*/
|
||||
fun getGitBranch(raw: Boolean = false): String? {
|
||||
private fun getGitBranch(): String? {
|
||||
val stdout = ByteArrayOutputStream()
|
||||
|
||||
ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD")
|
||||
@@ -80,34 +78,11 @@ object VersionUtil {
|
||||
.apply { waitFor() }
|
||||
.inputStream.use { stdout.writeBytes(it.readAllBytes()) }
|
||||
|
||||
if (raw) return stdout.toString().trim()
|
||||
|
||||
val branch = stdout.toString().trim()
|
||||
.replace(Regex("[^a-zA-Z0-9_.-]+"), "_")
|
||||
.replace(Regex("_{2,}"), "_")
|
||||
.trim(' ', '.', '_', '-')
|
||||
.removePrefix("heads_")
|
||||
|
||||
val mainBranch = System.getenv("GRIM_MAIN_BRANCH") ?: "2.0"
|
||||
|
||||
return when (branch) {
|
||||
"main", mainBranch -> null // ← ignore these branches
|
||||
else -> branch
|
||||
"main", "2.0" -> null // ← ignore these branches
|
||||
else -> branch.replace("/", "_")
|
||||
}
|
||||
}
|
||||
|
||||
fun getGitUser(): String {
|
||||
try {
|
||||
val stdout = ByteArrayOutputStream()
|
||||
ProcessBuilder("git", "config", "user.name")
|
||||
.redirectErrorStream(true)
|
||||
.start()
|
||||
.apply { waitFor() }
|
||||
.inputStream.use { stdout.writeBytes(it.readAllBytes()) }
|
||||
return stdout.toString().trim()
|
||||
} catch (_: Exception) {
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+22
-79
@@ -5,78 +5,33 @@ plugins {
|
||||
`maven-publish`
|
||||
grim.`base-conventions`
|
||||
grim.`shadow-conventions`
|
||||
id("de.eldoria.plugin-yml.bukkit") version "0.8.0"
|
||||
id("xyz.jpenilla.run-paper") version "3.0.0-beta.1"
|
||||
id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
if (BuildConfig.mavenLocalOverride) {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
// For paper-api
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven {
|
||||
name = "papermc"
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup("io.papermc.paper")
|
||||
includeGroup("net.md-5")
|
||||
}
|
||||
maven {
|
||||
name = "papermc"
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://libraries.minecraft.net") { // Brigadier
|
||||
mavenContent { releasesOnly() }
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeModule("com.mojang", "brigadier")
|
||||
}
|
||||
}
|
||||
|
||||
// For placeholderapi
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
||||
}
|
||||
filter {
|
||||
includeGroup("me.clip")
|
||||
}
|
||||
}
|
||||
|
||||
// For GrimAPI and PacketEvents (transitive from :common, direct in :bukkit)
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://repo.grim.ac/snapshots")
|
||||
}
|
||||
filter {
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") // Spigot
|
||||
maven("https://repo.grim.ac/snapshots") { // Grim API
|
||||
content {
|
||||
includeGroup("ac.grim.grimac")
|
||||
includeGroup("com.github.retrooper")
|
||||
}
|
||||
}
|
||||
|
||||
// For Configuralize (transitive from :common)
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://nexus.scarsz.me/content/repositories/releases") {
|
||||
mavenContent { releasesOnly() }
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup("github.scarsz")
|
||||
}
|
||||
}
|
||||
|
||||
// Maven Central Fallback
|
||||
mavenCentral()
|
||||
maven("https://repo.viaversion.com") // ViaVersion
|
||||
maven("https://nexus.scarsz.me/content/repositories/releases") // Configuralize
|
||||
maven("https://repo.opencollab.dev/maven-snapshots/") // Floodgate
|
||||
maven("https://repo.opencollab.dev/maven-releases/") // Cumulus (for Floodgate)
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") // placeholderapi
|
||||
mavenCentral() // FastUtil
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.paper.api)
|
||||
compileOnly(libs.placeholderapi)
|
||||
@@ -89,8 +44,9 @@ dependencies {
|
||||
implementation(libs.cloud.paper)
|
||||
implementation(libs.adventure.platform.bukkit)
|
||||
|
||||
implementation(project(":common"))
|
||||
shadow(project(":common"))
|
||||
shadowCommon(project(":common", "default"))
|
||||
implementation(project(":api"))
|
||||
implementation(project(":api:packetevents"))
|
||||
}
|
||||
|
||||
bukkit {
|
||||
@@ -170,22 +126,15 @@ bukkit {
|
||||
}
|
||||
|
||||
register("grim.verbose") {
|
||||
description = "Receive verbose alerts for violations"
|
||||
description = "Receive verbose alerts for violations. Requires grim.alerts"
|
||||
default = Permission.Default.OP
|
||||
}
|
||||
|
||||
register("grim.verbose.enable-on-join") {
|
||||
description =
|
||||
"Enable verbose alerts on join"
|
||||
"Enable verbose alerts on join. Requires grim.alerts and grim.alerts.enable-on-join"
|
||||
default = Permission.Default.FALSE
|
||||
}
|
||||
|
||||
register("grim.list") {
|
||||
description =
|
||||
"Shows lists of specific data"
|
||||
default = Permission.Default.FALSE
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,14 +142,8 @@ publishing.publications.create<MavenPublication>("maven") {
|
||||
artifact(tasks["shadowJar"])
|
||||
}
|
||||
|
||||
tasks {
|
||||
runServer {
|
||||
minecraftVersion("1.21.10")
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
manifest {
|
||||
attributes["paperweight-mappings-namespace"] = "mojang"
|
||||
}
|
||||
tasks.shadowJar {
|
||||
manifest {
|
||||
attributes["paperweight-mappings-namespace"] = "mojang"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package ac.grim.grimac.platform.bukkit;
|
||||
|
||||
import ac.grim.grimac.platform.api.PlatformPlugin;
|
||||
import ac.grim.grimac.api.platform.PlatformPlugin;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class BukkitPlatformPlugin implements PlatformPlugin {
|
||||
@@ -20,7 +20,6 @@ public class BukkitPlatformPlugin implements PlatformPlugin {
|
||||
return plugin.getName();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return plugin.getDescription().getVersion();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package ac.grim.grimac.platform.bukkit;
|
||||
|
||||
import ac.grim.grimac.platform.api.PlatformServer;
|
||||
import ac.grim.grimac.platform.api.sender.Sender;
|
||||
import ac.grim.grimac.api.platform.PlatformServer;
|
||||
import ac.grim.grimac.api.platform.sender.Sender;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
package ac.grim.grimac.platform.bukkit;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.lazy.LazyHolder;
|
||||
import ac.grim.grimac.api.packet.MCPacketAPI;
|
||||
import ac.grim.grimac.api.packet.pe.PEPacketAPI;
|
||||
import ac.grim.grimac.api.platform.CoreLoader;
|
||||
import ac.grim.grimac.api.platform.init.Initable;
|
||||
import ac.grim.grimac.api.plugin.BasicGrimPlugin;
|
||||
import ac.grim.grimac.api.GrimAPIProvider;
|
||||
import ac.grim.grimac.api.GrimAbstractAPI;
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.events.GrimExtensionManager;
|
||||
import ac.grim.grimac.manager.init.Initable;
|
||||
import ac.grim.grimac.manager.init.start.ExemptOnlinePlayersOnReload;
|
||||
import ac.grim.grimac.manager.init.start.StartableInitable;
|
||||
import ac.grim.grimac.platform.api.Platform;
|
||||
import ac.grim.grimac.platform.api.PlatformLoader;
|
||||
import ac.grim.grimac.platform.api.PlatformServer;
|
||||
import ac.grim.grimac.platform.api.manager.ItemResetHandler;
|
||||
import ac.grim.grimac.platform.api.manager.MessagePlaceHolderManager;
|
||||
import ac.grim.grimac.platform.api.manager.CommandAdapter;
|
||||
import ac.grim.grimac.platform.api.manager.PlatformPluginManager;
|
||||
import ac.grim.grimac.platform.api.player.PlatformPlayerFactory;
|
||||
import ac.grim.grimac.platform.api.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.platform.api.sender.Sender;
|
||||
import ac.grim.grimac.platform.api.sender.SenderFactory;
|
||||
import ac.grim.grimac.api.platform.init.StartableInitable;
|
||||
import ac.grim.grimac.api.platform.Platform;
|
||||
import ac.grim.grimac.api.platform.PlatformLoader;
|
||||
import ac.grim.grimac.api.platform.PlatformServer;
|
||||
import ac.grim.grimac.api.platform.manager.ItemResetHandler;
|
||||
import ac.grim.grimac.api.platform.manager.MessagePlaceHolderManager;
|
||||
import ac.grim.grimac.api.platform.manager.ParserDescriptorFactory;
|
||||
import ac.grim.grimac.api.platform.manager.PermissionRegistrationManager;
|
||||
import ac.grim.grimac.api.platform.manager.PlatformPluginManager;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayerFactory;
|
||||
import ac.grim.grimac.api.platform.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.api.platform.sender.Sender;
|
||||
import ac.grim.grimac.api.platform.sender.SenderFactory;
|
||||
import ac.grim.grimac.platform.bukkit.initables.BukkitBStats;
|
||||
import ac.grim.grimac.platform.bukkit.initables.BukkitEventManager;
|
||||
import ac.grim.grimac.platform.bukkit.initables.BukkitTickEndEvent;
|
||||
@@ -28,15 +31,12 @@ import ac.grim.grimac.platform.bukkit.manager.BukkitParserDescriptorFactory;
|
||||
import ac.grim.grimac.platform.bukkit.manager.BukkitPermissionRegistrationManager;
|
||||
import ac.grim.grimac.platform.bukkit.manager.BukkitPlatformPluginManager;
|
||||
import ac.grim.grimac.platform.bukkit.player.BukkitPlatformPlayerFactory;
|
||||
import ac.grim.grimac.platform.bukkit.resolver.BukkitResolverRegistrar;
|
||||
import ac.grim.grimac.platform.bukkit.scheduler.bukkit.BukkitPlatformScheduler;
|
||||
import ac.grim.grimac.platform.bukkit.scheduler.folia.FoliaPlatformScheduler;
|
||||
import ac.grim.grimac.platform.bukkit.sender.BukkitSenderFactory;
|
||||
import ac.grim.grimac.platform.bukkit.utils.placeholder.PlaceholderAPIExpansion;
|
||||
import ac.grim.grimac.utils.lazy.LazyHolder;
|
||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
@@ -48,7 +48,7 @@ import org.incendo.cloud.bukkit.CloudBukkitCapabilities;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.paper.LegacyPaperCommandManager;
|
||||
import org.incendo.cloud.setting.Configurable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class GrimACBukkitLoaderPlugin extends JavaPlugin implements PlatformLoader {
|
||||
|
||||
@@ -60,30 +60,33 @@ public final class GrimACBukkitLoaderPlugin extends JavaPlugin implements Platfo
|
||||
private final LazyHolder<CommandManager<Sender>> commandManager = LazyHolder.simple(this::createCommandManager);
|
||||
private final LazyHolder<ItemResetHandler> itemResetHandler = LazyHolder.simple(BukkitItemResetHandler::new);
|
||||
|
||||
@Getter private final PlatformPlayerFactory platformPlayerFactory = new BukkitPlatformPlayerFactory();
|
||||
@Getter private final CommandAdapter commandAdapter = new BukkitParserDescriptorFactory();
|
||||
@Getter private final PlatformPluginManager pluginManager = new BukkitPlatformPluginManager();
|
||||
@Getter private final GrimPlugin plugin;
|
||||
@Getter private final PlatformServer platformServer = new BukkitPlatformServer();
|
||||
@Getter private final MessagePlaceHolderManager messagePlaceHolderManager = new BukkitMessagePlaceHolderManager();
|
||||
@Getter private final BukkitPermissionRegistrationManager permissionManager = new BukkitPermissionRegistrationManager();
|
||||
private final PlatformPlayerFactory playerFactory = new BukkitPlatformPlayerFactory();
|
||||
private final ParserDescriptorFactory parserFactory = new BukkitParserDescriptorFactory();
|
||||
private final PlatformPluginManager platformPluginManager = new BukkitPlatformPluginManager();
|
||||
private final GrimPlugin plugin;
|
||||
private final PlatformServer platformServer = new BukkitPlatformServer();
|
||||
private final MessagePlaceHolderManager messagePlaceHolderManager = new BukkitMessagePlaceHolderManager();
|
||||
private final BukkitPermissionRegistrationManager bukkitPermissionRegistrationManager = new BukkitPermissionRegistrationManager();
|
||||
private final MCPacketAPI mcPacketAPI = new PEPacketAPI();
|
||||
|
||||
public GrimACBukkitLoaderPlugin() {
|
||||
GrimExtensionManager extensionManager = GrimAPI.INSTANCE.getExtensionManager();
|
||||
BukkitResolverRegistrar registrar = new BukkitResolverRegistrar(extensionManager);
|
||||
registrar.registerAll();
|
||||
this.plugin = registrar.resolvePlugin(this);
|
||||
this.plugin = new BasicGrimPlugin(
|
||||
this.getLogger(),
|
||||
this.getDataFolder(),
|
||||
this.getDescription().getVersion(),
|
||||
this.getDescription().getDescription(),
|
||||
this.getDescription().getAuthors()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
LOADER = this;
|
||||
GrimAPI.INSTANCE.load(this, this.getBukkitInitTasks());
|
||||
CoreLoader.Manager.loadAll(this, this.getBukkitInitTasks());
|
||||
}
|
||||
|
||||
private Initable[] getBukkitInitTasks() {
|
||||
return new Initable[] {
|
||||
new ExemptOnlinePlayersOnReload(),
|
||||
new BukkitEventManager(),
|
||||
new BukkitTickEndEvent(),
|
||||
new BukkitBStats(),
|
||||
@@ -97,12 +100,12 @@ public final class GrimACBukkitLoaderPlugin extends JavaPlugin implements Platfo
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
GrimAPI.INSTANCE.start();
|
||||
CoreLoader.Manager.startAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
GrimAPI.INSTANCE.stop();
|
||||
CoreLoader.Manager.stopAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,7 +114,17 @@ public final class GrimACBukkitLoaderPlugin extends JavaPlugin implements Platfo
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketEventsAPI<?> getPacketEvents() {
|
||||
public PlatformPlayerFactory getPlatformPlayerFactory() {
|
||||
return playerFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParserDescriptorFactory getParserDescriptorFactory() {
|
||||
return parserFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketEventsAPI<?> getPacketAPI() {
|
||||
return packetEvents.get();
|
||||
}
|
||||
|
||||
@@ -131,13 +144,43 @@ public final class GrimACBukkitLoaderPlugin extends JavaPlugin implements Platfo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAPIService() {
|
||||
GrimAPIProvider.init(GrimAPI.INSTANCE.getExternalAPI());
|
||||
Bukkit.getServicesManager().register(GrimAbstractAPI.class, GrimAPI.INSTANCE.getExternalAPI(), GrimACBukkitLoaderPlugin.LOADER, ServicePriority.Normal);
|
||||
public GrimPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformPluginManager getPluginManager() {
|
||||
return platformPluginManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformServer getPlatformServer() {
|
||||
return platformServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAPIService(GrimAbstractAPI api) {
|
||||
GrimAPIProvider.init(api);
|
||||
Bukkit.getServicesManager().register(GrimAbstractAPI.class, api, GrimACBukkitLoaderPlugin.LOADER, ServicePriority.Normal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull MessagePlaceHolderManager getMessagePlaceHolderManager() {
|
||||
return messagePlaceHolderManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionRegistrationManager getPermissionManager() {
|
||||
return bukkitPermissionRegistrationManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCPacketAPI getMCPacketAPI() {
|
||||
return mcPacketAPI;
|
||||
}
|
||||
|
||||
private PlatformScheduler createScheduler() {
|
||||
return GrimAPI.INSTANCE.getPlatform() == Platform.FOLIA ? new FoliaPlatformScheduler() : new BukkitPlatformScheduler();
|
||||
return GrimAPIProvider.getDirect().getPlatform() == Platform.FOLIA ? new FoliaPlatformScheduler() : new BukkitPlatformScheduler();
|
||||
}
|
||||
|
||||
private CommandManager<Sender> createCommandManager() {
|
||||
|
||||
+10
-9
@@ -1,18 +1,19 @@
|
||||
package ac.grim.grimac.platform.bukkit.command;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.platform.api.command.PlayerSelector;
|
||||
import ac.grim.grimac.platform.api.sender.Sender;
|
||||
import ac.grim.grimac.api.GrimAPIProvider;
|
||||
import ac.grim.grimac.api.platform.command.PlayerSelector;
|
||||
import ac.grim.grimac.api.platform.sender.Sender;
|
||||
import ac.grim.grimac.platform.bukkit.sender.BukkitSenderFactory;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.incendo.cloud.bukkit.data.SinglePlayerSelector;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BukkitPlayerSelectorAdapter implements PlayerSelector {
|
||||
private final SinglePlayerSelector bukkitSelector;
|
||||
private final org.incendo.cloud.bukkit.data.SinglePlayerSelector bukkitSelector;
|
||||
|
||||
public BukkitPlayerSelectorAdapter(org.incendo.cloud.bukkit.data.SinglePlayerSelector bukkitSelector) {
|
||||
this.bukkitSelector = bukkitSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingle() {
|
||||
@@ -21,12 +22,12 @@ public class BukkitPlayerSelectorAdapter implements PlayerSelector {
|
||||
|
||||
@Override
|
||||
public Sender getSinglePlayer() {
|
||||
return ((BukkitSenderFactory) GrimAPI.INSTANCE.getSenderFactory()).map(bukkitSelector.single());
|
||||
return ((BukkitSenderFactory) GrimAPIProvider.getDirect().getPlatformLoader().getSenderFactory()).map(bukkitSelector.single());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Sender> getPlayers() {
|
||||
return Collections.singletonList(((BukkitSenderFactory) GrimAPI.INSTANCE.getSenderFactory()).map(bukkitSelector.single()));
|
||||
return Collections.singletonList(((BukkitSenderFactory) GrimAPIProvider.getDirect().getPlatformLoader().getSenderFactory()).map(bukkitSelector.single()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package ac.grim.grimac.platform.bukkit.command;
|
||||
|
||||
import ac.grim.grimac.platform.api.command.AbstractPlayerSelectorParser;
|
||||
import ac.grim.grimac.platform.api.command.PlayerSelector;
|
||||
import ac.grim.grimac.api.platform.command.AbstractPlayerSelectorParser;
|
||||
import ac.grim.grimac.api.platform.command.PlayerSelector;
|
||||
import org.incendo.cloud.bukkit.parser.selector.SinglePlayerSelectorParser;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package ac.grim.grimac.platform.bukkit.entity;
|
||||
|
||||
import ac.grim.grimac.platform.api.entity.GrimEntity;
|
||||
import ac.grim.grimac.platform.api.world.PlatformWorld;
|
||||
import ac.grim.grimac.api.platform.entity.GrimEntity;
|
||||
import ac.grim.grimac.api.platform.world.PlatformWorld;
|
||||
import ac.grim.grimac.platform.bukkit.utils.convert.BukkitConversionUtils;
|
||||
import ac.grim.grimac.platform.bukkit.utils.reflection.PaperUtils;
|
||||
import ac.grim.grimac.platform.bukkit.world.BukkitPlatformWorld;
|
||||
import ac.grim.grimac.utils.math.Location;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import ac.grim.grimac.api.math.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
@@ -17,13 +15,12 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class BukkitGrimEntity implements GrimEntity {
|
||||
|
||||
protected static final boolean CAN_USE_DIRECT_GETTERS = PacketEvents.getAPI().getServerManager().getVersion().isNewerThan(ServerVersion.V_1_20_1) && PaperUtils.PAPER;
|
||||
|
||||
private final Entity entity;
|
||||
private BukkitPlatformWorld bukkitPlatformWorld;
|
||||
|
||||
public BukkitGrimEntity(Entity entity) {
|
||||
this.entity = Objects.requireNonNull(entity);
|
||||
Objects.requireNonNull(entity);
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public Entity getBukkitEntity() {
|
||||
@@ -47,7 +44,7 @@ public class BukkitGrimEntity implements GrimEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNull
|
||||
public Entity getNative() {
|
||||
return entity;
|
||||
}
|
||||
@@ -79,26 +76,4 @@ public class BukkitGrimEntity implements GrimEntity {
|
||||
location.getPitch()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distanceSquared(double oX, double oY, double oZ) {
|
||||
if (CAN_USE_DIRECT_GETTERS) {
|
||||
double x = this.entity.getX();
|
||||
double y = this.entity.getY();
|
||||
double z = this.entity.getZ();
|
||||
double distX = (x - oX) * (x - oX);
|
||||
double distY = (y - oY) * (y - oY);
|
||||
double distZ = (z - oZ) * (z - oZ);
|
||||
return distX + distY + distZ;
|
||||
} else {
|
||||
org.bukkit.Location location = this.entity.getLocation();
|
||||
double x = location.getX();
|
||||
double y = location.getY();
|
||||
double z = location.getZ();
|
||||
double distX = (x - oX) * (x - oX);
|
||||
double distY = (y - oY) * (y - oY);
|
||||
double distZ = (z - oZ) * (z - oZ);
|
||||
return distX + distY + distZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
package ac.grim.grimac.platform.bukkit.events;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.GrimAPIProvider;
|
||||
import ac.grim.grimac.api.GrimUser;
|
||||
import ac.grim.grimac.api.data.PistonData;
|
||||
import ac.grim.grimac.api.data.boxes.BaseSCB;
|
||||
import ac.grim.grimac.platform.bukkit.utils.convert.BukkitConversionUtils;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.data.PistonData;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import ac.grim.grimac.api.packet.world.enums.BlockFace;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -20,32 +18,21 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PistonEvent implements Listener {
|
||||
|
||||
private final Material SLIME_BLOCK = Material.getMaterial("SLIME_BLOCK");
|
||||
private final Material HONEY_BLOCK = Material.getMaterial("HONEY_BLOCK");
|
||||
|
||||
private static final double MAX_HORIZONTAL_DISTANCE = 24.0;
|
||||
private static final double MAX_VERTICAL_DISTANCE = 64.0;
|
||||
|
||||
// accuracy isn't that important, it's close enough and performant
|
||||
private static boolean isCloseEnough(Vector3i vectorA, Vector3d vectorB) {
|
||||
return Math.abs(vectorA.getX() - vectorB.getX()) <= MAX_HORIZONTAL_DISTANCE
|
||||
&& Math.abs(vectorA.getY() - vectorB.getY()) <= MAX_VERTICAL_DISTANCE
|
||||
&& Math.abs(vectorA.getZ() - vectorB.getZ()) <= MAX_HORIZONTAL_DISTANCE;
|
||||
}
|
||||
Material SLIME_BLOCK = Material.getMaterial("SLIME_BLOCK");
|
||||
Material HONEY_BLOCK = Material.getMaterial("HONEY_BLOCK");
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPistonPushEvent(BlockPistonExtendEvent event) {
|
||||
boolean hasSlimeBlock = false;
|
||||
boolean hasHoneyBlock = false;
|
||||
|
||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||
List<BaseSCB> boxes = new ArrayList<>();
|
||||
for (Block block : event.getBlocks()) {
|
||||
boxes.add(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true)
|
||||
boxes.add(new BaseSCB(0, 0, 0, 1, 1, 1, true)
|
||||
.offset(block.getX(),
|
||||
block.getY(),
|
||||
block.getZ()));
|
||||
boxes.add(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true)
|
||||
boxes.add(new BaseSCB(0, 0, 0, 1, 1, 1, true)
|
||||
.offset(block.getX() + event.getDirection().getModX(),
|
||||
block.getY() + event.getDirection().getModY(),
|
||||
block.getZ() + event.getDirection().getModZ()));
|
||||
@@ -63,22 +50,21 @@ public class PistonEvent implements Listener {
|
||||
Block piston = event.getBlock();
|
||||
|
||||
// Add bounding box of the actual piston head pushing
|
||||
boxes.add(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true)
|
||||
boxes.add(new BaseSCB(0, 0, 0, 1, 1, 1, true)
|
||||
.offset(piston.getX() + event.getDirection().getModX(),
|
||||
piston.getY() + event.getDirection().getModY(),
|
||||
piston.getZ() + event.getDirection().getModZ()));
|
||||
|
||||
final int chunkX = event.getBlock().getX() >> 4;
|
||||
final int chunkZ = event.getBlock().getZ() >> 4;
|
||||
final BlockFace blockFace = BukkitConversionUtils.fromBukkitFace(event.getDirection());
|
||||
final Vector3i sourcePos = new Vector3i(piston.getX(), piston.getY(), piston.getZ());
|
||||
|
||||
for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
if (isCloseEnough(sourcePos, player.compensatedEntities.self.trackedServerPosition.getPos()) && player.compensatedWorld.isChunkLoaded(chunkX, chunkZ)) {
|
||||
final int lastTrans = player.lastTransactionSent.get();
|
||||
PistonData data = new PistonData(blockFace, boxes, lastTrans, true, hasSlimeBlock, hasHoneyBlock);
|
||||
player.latencyUtils.addRealTimeTaskAsync(lastTrans, () -> player.compensatedWorld.activePistons.add(data));
|
||||
}
|
||||
boolean finalHasSlimeBlock = hasSlimeBlock;
|
||||
boolean finalHasHoneyBlock = hasHoneyBlock;
|
||||
for (GrimUser player : GrimAPIProvider.getDirect().getGrimUsers()) {
|
||||
int lastTrans = player.getLastTransactionSent();
|
||||
player.runSafely(() -> {
|
||||
if (player.getCompensatedWorld().isChunkLoaded(event.getBlock().getX() >> 4, event.getBlock().getZ() >> 4)) {
|
||||
PistonData data = new PistonData(BukkitConversionUtils.fromBukkitFace(event.getDirection()), boxes, lastTrans, true, finalHasSlimeBlock, finalHasHoneyBlock);
|
||||
player.addRealTimeTask(lastTrans, () -> player.getCompensatedWorld().addActivePistons(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +83,7 @@ public class PistonEvent implements Listener {
|
||||
boolean hasSlimeBlock = false;
|
||||
boolean hasHoneyBlock = false;
|
||||
|
||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||
List<BaseSCB> boxes = new ArrayList<>();
|
||||
BlockFace face = BukkitConversionUtils.fromBukkitFace(event.getDirection());
|
||||
|
||||
// The event was called without blocks and is therefore in the right direction
|
||||
@@ -105,16 +91,16 @@ public class PistonEvent implements Listener {
|
||||
Block piston = event.getBlock();
|
||||
|
||||
// Add bounding box of the actual piston head pushing
|
||||
boxes.add(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true)
|
||||
boxes.add(new BaseSCB(0, 0, 0, 1, 1, 1, true)
|
||||
.offset(piston.getX() + face.getModX(),
|
||||
piston.getY() + face.getModY(),
|
||||
piston.getZ() + face.getModZ()));
|
||||
}
|
||||
|
||||
for (Block block : event.getBlocks()) {
|
||||
boxes.add(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true)
|
||||
boxes.add(new BaseSCB(0, 0, 0, 1, 1, 1, true)
|
||||
.offset(block.getX(), block.getY(), block.getZ()));
|
||||
boxes.add(new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true)
|
||||
boxes.add(new BaseSCB(0, 0, 0, 1, 1, 1, true)
|
||||
.offset(block.getX() + face.getModX(), block.getY() + face.getModY(), block.getZ() + face.getModZ()));
|
||||
|
||||
// Support honey block like this because ViaVersion replacement
|
||||
@@ -127,16 +113,16 @@ public class PistonEvent implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
final int chunkX = event.getBlock().getX() >> 4;
|
||||
final int chunkZ = event.getBlock().getZ() >> 4;
|
||||
Vector3i sourcePos = new Vector3i(event.getBlock().getX(), event.getBlock().getY(), event.getBlock().getZ());
|
||||
|
||||
for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
if (isCloseEnough(sourcePos, player.compensatedEntities.self.trackedServerPosition.getPos()) && player.compensatedWorld.isChunkLoaded(chunkX, chunkZ)) {
|
||||
int lastTrans = player.lastTransactionSent.get();
|
||||
PistonData data = new PistonData(face, boxes, lastTrans, false, hasSlimeBlock, hasHoneyBlock);
|
||||
player.latencyUtils.addRealTimeTaskAsync(lastTrans, () -> player.compensatedWorld.activePistons.add(data));
|
||||
}
|
||||
boolean finalHasSlimeBlock = hasSlimeBlock;
|
||||
boolean finalHasHoneyBlock = hasHoneyBlock;
|
||||
for (GrimUser player : GrimAPIProvider.getDirect().getGrimUsers()) {
|
||||
int lastTrans = player.getLastTransactionSent();
|
||||
player.runSafely(() -> {
|
||||
if (player.getCompensatedWorld().isChunkLoaded(event.getBlock().getX() >> 4, event.getBlock().getZ() >> 4)) {
|
||||
PistonData data = new PistonData(BukkitConversionUtils.fromBukkitFace(event.getDirection()), boxes, lastTrans, false, finalHasSlimeBlock, finalHasHoneyBlock);
|
||||
player.addRealTimeTask(lastTrans, () -> player.getCompensatedWorld().addActivePistons(data));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
package ac.grim.grimac.platform.bukkit.initables;
|
||||
|
||||
import ac.grim.grimac.manager.init.start.StartableInitable;
|
||||
import ac.grim.grimac.api.platform.init.StartableInitable;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import ac.grim.grimac.utils.anticheat.Constants;
|
||||
import io.github.retrooper.packetevents.bstats.bukkit.Metrics;
|
||||
|
||||
public class BukkitBStats implements StartableInitable {
|
||||
@Override
|
||||
public void start() {
|
||||
int pluginId = 12820; // <-- Replace with the id of your plugin!
|
||||
try {
|
||||
new Metrics(GrimACBukkitLoaderPlugin.LOADER, Constants.BSTATS_PLUGIN_ID);
|
||||
} catch (Exception ignored) {}
|
||||
new Metrics(GrimACBukkitLoaderPlugin.LOADER, pluginId);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package ac.grim.grimac.platform.bukkit.initables;
|
||||
|
||||
import ac.grim.grimac.manager.init.start.StartableInitable;
|
||||
import ac.grim.grimac.api.platform.init.StartableInitable;
|
||||
import ac.grim.grimac.api.util.LogUtil;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import ac.grim.grimac.platform.bukkit.events.PistonEvent;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class BukkitEventManager implements StartableInitable {
|
||||
|
||||
+18
-19
@@ -1,15 +1,14 @@
|
||||
package ac.grim.grimac.platform.bukkit.initables;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.manager.init.start.AbstractTickEndEvent;
|
||||
import ac.grim.grimac.platform.api.Platform;
|
||||
import ac.grim.grimac.api.GrimAPIProvider;
|
||||
import ac.grim.grimac.api.GrimUser;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.ServerVersions;
|
||||
import ac.grim.grimac.api.platform.Platform;
|
||||
import ac.grim.grimac.api.platform.init.AbstractTickEndEvent;
|
||||
import ac.grim.grimac.api.util.LogUtil;
|
||||
import ac.grim.grimac.platform.bukkit.player.BukkitPlatformPlayer;
|
||||
import ac.grim.grimac.platform.bukkit.utils.list.HookedListWrapper;
|
||||
import ac.grim.grimac.platform.bukkit.utils.reflection.PaperUtils;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.lists.HookedListWrapper;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.util.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -30,11 +29,11 @@ public class BukkitTickEndEvent extends AbstractTickEndEvent implements Listener
|
||||
if (!super.shouldInjectEndTick()) {
|
||||
return;
|
||||
}
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThan(ServerVersion.V_1_11_2) && !Boolean.getBoolean("paper.explicit-flush")) {
|
||||
if (ServerVersions.getServerVersion().isNewerThan(ServerVersions.V_1_11_2) && !Boolean.getBoolean("paper.explicit-flush")) {
|
||||
LogUtil.warn("Reach.enable-post-packet=true but paper.explicit-flush=false, add \"-Dpaper.explicit-flush=true\" to your server's startup flags for fully functional extra reach accuracy.");
|
||||
}
|
||||
// this is necessary for folia
|
||||
if (GrimAPI.INSTANCE.getPlatform() == Platform.FOLIA) {
|
||||
if (GrimAPIProvider.getDirect().getPlatform() == Platform.FOLIA) {
|
||||
PaperUtils.registerTickEndEvent(this, this::tickAllFoliaPlayers);
|
||||
return;
|
||||
}
|
||||
@@ -45,19 +44,19 @@ public class BukkitTickEndEvent extends AbstractTickEndEvent implements Listener
|
||||
}
|
||||
|
||||
private void tickAllPlayers() {
|
||||
for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
if (player.disableGrim) continue;
|
||||
super.onEndOfTick(player);
|
||||
for (GrimUser player : GrimAPIProvider.getDirect().getGrimUsers()) {
|
||||
if (player.isGrimDisabled()) continue;
|
||||
player.onEndOfTick();
|
||||
}
|
||||
}
|
||||
|
||||
private void tickAllFoliaPlayers() {
|
||||
for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
if (player.disableGrim) continue;
|
||||
if (player.platformPlayer == null) continue;
|
||||
Player p = ((BukkitPlatformPlayer) player.platformPlayer).getNative();
|
||||
for (GrimUser player : GrimAPIProvider.getDirect().getGrimUsers()) {
|
||||
if (player.isGrimDisabled()) continue;
|
||||
if (player.getPlatformPlayer() == null) continue;
|
||||
Player p = ((BukkitPlatformPlayer) player.getPlatformPlayer()).getNative();
|
||||
if (!Bukkit.isOwnedByCurrentRegion(p)) continue;
|
||||
super.onEndOfTick(player);
|
||||
player.onEndOfTick();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +85,7 @@ public class BukkitTickEndEvent extends AbstractTickEndEvent implements Listener
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
unsafe.putObject(connection, unsafe.objectFieldOffset(connectionsList), wrapper);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
LogUtil.error("Failed to inject into the end of tick event via reflection", e);
|
||||
LogUtil.exception("Failed to inject into the end of tick event via reflection", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
+80
-197
@@ -1,213 +1,96 @@
|
||||
package ac.grim.grimac.platform.bukkit.manager;
|
||||
|
||||
import ac.grim.grimac.platform.api.manager.ItemResetHandler;
|
||||
import ac.grim.grimac.platform.api.player.PlatformPlayer;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.PacketServerVersion;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.ServerVersions;
|
||||
import ac.grim.grimac.api.platform.manager.ItemResetHandler;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayer;
|
||||
import ac.grim.grimac.platform.bukkit.player.BukkitPlatformPlayer;
|
||||
import ac.grim.grimac.platform.bukkit.utils.reflection.PaperUtils;
|
||||
import ac.grim.grimac.utils.reflection.ReflectionUtils;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.InteractionHand;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class BukkitItemResetHandler implements ItemResetHandler {
|
||||
private static final Consumer<Player> resetItemUsage;
|
||||
private static final Predicate<Player> isUsingItem;
|
||||
private static final Function<Player, InteractionHand> getItemUsageHand;
|
||||
// resets item usage, then returns whether the player was using an item
|
||||
private final @NotNull ItemUsageReset resetItemUsage = createItemUsageResetFunction();
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void resetItemUsage(@Nullable PlatformPlayer player) {
|
||||
if (player != null) resetItemUsage.accept((Player) player.getNative());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable InteractionHand getItemUsageHand(@Nullable PlatformPlayer player) {
|
||||
return player == null ? null : getItemUsageHand.apply((Player) player.getNative());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsingItem(@Nullable PlatformPlayer player) {
|
||||
return player != null && isUsingItem.test((Player) player.getNative());
|
||||
}
|
||||
|
||||
static {
|
||||
final ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
||||
|
||||
boolean legacy = version.isOlderThanOrEquals(ServerVersion.V_1_8_8);
|
||||
|
||||
try {
|
||||
Method getHandle_ = null;
|
||||
|
||||
if (PaperUtils.PAPER && version.isNewerThanOrEquals(ServerVersion.V_1_20_5)) {
|
||||
Class<?> cls = ReflectionUtils.getClass("org.bukkit.craftbukkit.entity.CraftLivingEntity");
|
||||
if (cls != null) getHandle_ = cls.getMethod("getHandle");
|
||||
}
|
||||
|
||||
boolean obfuscated = getHandle_ == null;
|
||||
String nmsPackage = obfuscated ? Bukkit.getServer().getClass().getPackageName().split("\\.")[3] : null;
|
||||
|
||||
if (obfuscated) {
|
||||
String clazzName = legacy ? "CraftHumanEntity" : "CraftLivingEntity";
|
||||
getHandle_ = Class.forName("org.bukkit.craftbukkit." + nmsPackage + ".entity." + clazzName).getMethod("getHandle");
|
||||
}
|
||||
|
||||
final Method getHandle = getHandle_;
|
||||
Class<?> clazz = getHandle_.getReturnType();
|
||||
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_10)) {
|
||||
isUsingItem = Player::isHandRaised;
|
||||
} else {
|
||||
Method method = clazz.getMethod(switch (Objects.requireNonNull(nmsPackage)) {
|
||||
case "v1_8_R3" -> "bS";
|
||||
case "v1_9_R1" -> "cs";
|
||||
case "v1_9_R2" -> "ct";
|
||||
default -> throw new IllegalStateException("You are using an unsupported server version! (" + version.getReleaseName() + ")");
|
||||
});
|
||||
isUsingItem = player -> {
|
||||
try {
|
||||
return (boolean) method.invoke(getHandle.invoke(player));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (legacy) {
|
||||
getItemUsageHand = player -> isUsingItem.test(player) ? InteractionHand.MAIN_HAND : null;
|
||||
} else if (PaperUtils.PAPER && version.isNewerThanOrEquals(ServerVersion.V_1_16_5)) {
|
||||
getItemUsageHand = player -> player.isHandRaised()
|
||||
? player.getHandRaised() == EquipmentSlot.OFF_HAND
|
||||
? InteractionHand.OFF_HAND
|
||||
: InteractionHand.MAIN_HAND
|
||||
: null;
|
||||
} else {
|
||||
Method method = clazz.getMethod(switch (Objects.requireNonNull(nmsPackage)) {
|
||||
case "v1_9_R1" -> "ct";
|
||||
case "v1_9_R2" -> "cu";
|
||||
case "v1_10_R1" -> "cy";
|
||||
case "v1_11_R1" -> "cz";
|
||||
case "v1_12_R1" -> "cH";
|
||||
case "v1_13_R1", "v1_13_R2", "v1_14_R1" -> "cU";
|
||||
case "v1_15_R1", "v1_16_R1", "v1_16_R2", "v1_16_R3", "v1_17_R1" -> "getRaisedHand";
|
||||
case "v1_18_R1" -> "eM";
|
||||
case "v1_18_R2" -> "eN";
|
||||
case "v1_19_R1" -> "eU";
|
||||
case "v1_19_R2" -> "fa";
|
||||
case "v1_19_R3" -> "ff";
|
||||
case "v1_20_R1" -> "fj";
|
||||
case "v1_20_R2" -> "fn";
|
||||
case "v1_20_R3" -> "fo";
|
||||
case "v1_20_R4" -> "fw";
|
||||
case "v1_21_R1" -> "fs";
|
||||
case "v1_21_R2", "v1_21_R3", "v1_21_R4" -> "fA";
|
||||
case "v1_21_R5" -> "fH";
|
||||
case "v1_21_R6" -> "fP";
|
||||
default -> throw new IllegalStateException("You are using an unsupported server version! (" + version.getReleaseName() + ")");
|
||||
});
|
||||
getItemUsageHand = player -> {
|
||||
try {
|
||||
return isUsingItem.test(player)
|
||||
? ((Enum<?>) method.invoke(getHandle.invoke(player))).ordinal() == 0
|
||||
? InteractionHand.MAIN_HAND
|
||||
: InteractionHand.OFF_HAND
|
||||
: null;
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Method setLivingEntityFlag;
|
||||
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_19)) {
|
||||
String name = obfuscated ? "c" : "setLivingEntityFlag";
|
||||
setLivingEntityFlag = clazz.getDeclaredMethod(name, int.class, boolean.class);
|
||||
setLivingEntityFlag.setAccessible(true);
|
||||
} else {
|
||||
setLivingEntityFlag = null;
|
||||
}
|
||||
|
||||
if (PaperUtils.PAPER && version.isNewerThan(ServerVersion.V_1_17)) {
|
||||
resetItemUsage = setLivingEntityFlag == null ? LivingEntity::clearActiveItem : player -> {
|
||||
try {
|
||||
setLivingEntityFlag.invoke(getHandle.invoke(player), 1, false);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
player.clearActiveItem();
|
||||
};
|
||||
} else {
|
||||
Method method = clazz.getMethod(switch (Objects.requireNonNull(nmsPackage)) {
|
||||
case "v1_8_R3" -> "bV";
|
||||
case "v1_9_R1" -> "cz";
|
||||
case "v1_9_R2" -> "cA";
|
||||
case "v1_10_R1" -> "cE";
|
||||
case "v1_11_R1" -> "cF";
|
||||
case "v1_12_R1" -> "cN";
|
||||
case "v1_13_R1", "v1_13_R2" -> "da";
|
||||
case "v1_14_R1" -> "dp";
|
||||
case "v1_15_R1" -> "dH";
|
||||
case "v1_16_R1", "v1_16_R2", "v1_16_R3", "v1_17_R1" -> "clearActiveItem";
|
||||
case "v1_18_R1" -> "eR";
|
||||
case "v1_18_R2" -> "eS";
|
||||
case "v1_19_R1" -> "eZ";
|
||||
case "v1_19_R2" -> "ff";
|
||||
case "v1_19_R3" -> "fk";
|
||||
case "v1_20_R1" -> "fo";
|
||||
case "v1_20_R2" -> "fs";
|
||||
case "v1_20_R3" -> "ft";
|
||||
case "v1_20_R4" -> "fB";
|
||||
case "v1_21_R1" -> "fx";
|
||||
case "v1_21_R2", "v1_21_R3", "v1_21_R4" -> "fF";
|
||||
case "v1_21_R5" -> "fM";
|
||||
case "v1_21_R6" -> "fU";
|
||||
default -> throw new IllegalStateException("You are using an unsupported server version! (" + version.getReleaseName() + ")");
|
||||
});
|
||||
|
||||
if (legacy) { // 1.8.8
|
||||
resetItemUsage = player -> {
|
||||
try {
|
||||
method.invoke(getHandle.invoke(player));
|
||||
|
||||
// in 1.8 we need to resync item usage manually,
|
||||
// only do so if the player is using an item
|
||||
if (isUsingItem.test(player)) player.updateInventory();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
} else if (setLivingEntityFlag == null) { // 1.9-1.18.2
|
||||
resetItemUsage = player -> {
|
||||
try {
|
||||
method.invoke(getHandle.invoke(player));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
} else { // 1.19+
|
||||
resetItemUsage = player -> {
|
||||
try {
|
||||
Object handle = getHandle.invoke(player);
|
||||
setLivingEntityFlag.invoke(handle, 1, false);
|
||||
method.invoke(handle);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw t instanceof RuntimeException e ? e : new RuntimeException(t);
|
||||
if (player != null) {
|
||||
resetItemUsage.accept(((BukkitPlatformPlayer) player).getNative());
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private @NotNull ItemUsageReset createItemUsageResetFunction() {
|
||||
PacketServerVersion version = ServerVersions.getServerVersion();
|
||||
if (version.isNewerThan(ServerVersions.V_1_17) && PaperUtils.PAPER) {
|
||||
if (version.isOlderThan(ServerVersions.V_1_19)) {
|
||||
return LivingEntity::clearActiveItem;
|
||||
}
|
||||
Method setLivingEntityFlag = Class.forName(version.isOlderThan(ServerVersions.V_1_20_5) ? "net.minecraft.world.entity.EntityLiving" : "net.minecraft.world.entity.LivingEntity")
|
||||
.getDeclaredMethod(version.isOlderThan(ServerVersions.V_1_20_5) ? "c" : "setLivingEntityFlag", int.class, boolean.class);
|
||||
Method getHandle = (version.isOlderThan(ServerVersions.V_1_20_5)
|
||||
? Class.forName("org.bukkit.craftbukkit." + Bukkit.getServer().getClass().getPackageName().split("\\.")[3] + ".entity.CraftPlayer")
|
||||
: Class.forName("org.bukkit.craftbukkit.entity.CraftPlayer")
|
||||
).getMethod("getHandle");
|
||||
|
||||
setLivingEntityFlag.setAccessible(true);
|
||||
|
||||
return player -> {
|
||||
// don't trigger gameevents
|
||||
setLivingEntityFlag.invoke(getHandle.invoke(player), 1, false);
|
||||
player.clearActiveItem();
|
||||
};
|
||||
}
|
||||
|
||||
if (version == ServerVersions.V_1_8_8) {
|
||||
Class<?> EntityHuman = Class.forName("net.minecraft.server.v1_8_R3.EntityHuman");
|
||||
Method getHandle = Class.forName("org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer").getMethod("getHandle");
|
||||
Method clearActiveItem = EntityHuman.getMethod("bV");
|
||||
Method isUsingItem = EntityHuman.getMethod("bS");
|
||||
|
||||
return player -> {
|
||||
Object handle = getHandle.invoke(player);
|
||||
clearActiveItem.invoke(handle);
|
||||
|
||||
// in 1.8 we need to resync item usage manually,
|
||||
// only do so if the player was using an item
|
||||
if ((boolean) isUsingItem.invoke(handle)) {
|
||||
player.updateInventory();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
String nmsPackage = Bukkit.getServer().getClass().getPackageName().split("\\.")[3];
|
||||
String livingEntityPackage = version.isNewerThan(ServerVersions.V_1_16_5) ? "net.minecraft.world.entity.EntityLiving" : "net.minecraft.server." + nmsPackage + ".EntityLiving";
|
||||
Method getHandle = Class.forName("org.bukkit.craftbukkit." + nmsPackage + ".entity.CraftPlayer").getMethod("getHandle");
|
||||
Method clearActiveItem = Class.forName(livingEntityPackage).getMethod(
|
||||
switch (nmsPackage) {
|
||||
case "v1_9_R1" -> "cz";
|
||||
case "v1_9_R2" -> "cA";
|
||||
case "v1_10_R1" -> "cE";
|
||||
case "v1_11_R1" -> "cF";
|
||||
case "v1_12_R1" -> "cN";
|
||||
case "v1_13_R1", "v1_13_R2" -> "da";
|
||||
case "v1_14_R1" -> "dp";
|
||||
case "v1_15_R1" -> "dH";
|
||||
case "v1_16_R1", "v1_16_R2", "v1_16_R3", "v1_17_R1" -> "clearActiveItem";
|
||||
case "v1_18_R1" -> "eR";
|
||||
case "v1_18_R2" -> "eS";
|
||||
default -> throw new IllegalStateException("You are using an unsupported server version! (" + version.getReleaseName() + ")");
|
||||
}
|
||||
);
|
||||
|
||||
return player -> clearActiveItem.invoke(getHandle.invoke(player));
|
||||
}
|
||||
|
||||
private interface ItemUsageReset {
|
||||
void accept(@NotNull Player player) throws Throwable;
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,18 +1,18 @@
|
||||
package ac.grim.grimac.platform.bukkit.manager;
|
||||
|
||||
import ac.grim.grimac.platform.api.manager.MessagePlaceHolderManager;
|
||||
import ac.grim.grimac.platform.api.player.PlatformPlayer;
|
||||
import ac.grim.grimac.api.platform.manager.MessagePlaceHolderManager;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayer;
|
||||
import ac.grim.grimac.platform.bukkit.player.BukkitPlatformPlayer;
|
||||
import com.github.retrooper.packetevents.util.reflection.Reflection;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class BukkitMessagePlaceHolderManager implements MessagePlaceHolderManager {
|
||||
public static final boolean hasPlaceholderAPI = Reflection.getClassByNameWithoutException("me.clip.placeholderapi.PlaceholderAPI") != null;
|
||||
|
||||
@Override
|
||||
public @NotNull String replacePlaceholders(@Nullable PlatformPlayer player, @NotNull String string) {
|
||||
public @NonNull String replacePlaceholders(@Nullable PlatformPlayer player, @NonNull String string) {
|
||||
if (!hasPlaceholderAPI) return string;
|
||||
return PlaceholderAPI.setPlaceholders(player instanceof BukkitPlatformPlayer bukkitPlatformPlayer ? bukkitPlatformPlayer.getBukkitPlayer() : null, string);
|
||||
}
|
||||
|
||||
+6
-34
@@ -1,45 +1,17 @@
|
||||
package ac.grim.grimac.platform.bukkit.manager;
|
||||
|
||||
import ac.grim.grimac.platform.api.command.PlayerSelector;
|
||||
import ac.grim.grimac.platform.api.manager.CommandAdapter;
|
||||
import ac.grim.grimac.platform.api.sender.Sender;
|
||||
import ac.grim.grimac.api.platform.command.PlayerSelector;
|
||||
import ac.grim.grimac.api.platform.manager.ParserDescriptorFactory;
|
||||
import ac.grim.grimac.api.platform.sender.Sender;
|
||||
import ac.grim.grimac.platform.bukkit.command.BukkitPlayerSelectorParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.bukkit.BukkitCommandContextKeys;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
public class BukkitParserDescriptorFactory implements ParserDescriptorFactory {
|
||||
|
||||
public class BukkitParserDescriptorFactory implements CommandAdapter {
|
||||
|
||||
// Parser is kept as a field because its stateless
|
||||
private final BukkitPlayerSelectorParser<Sender> bukkitPlayerSelectorParser = new BukkitPlayerSelectorParser<>();
|
||||
BukkitPlayerSelectorParser<Sender> bukkitPlayerSelectorParser = new BukkitPlayerSelectorParser<>();
|
||||
|
||||
@Override
|
||||
public ParserDescriptor<Sender, PlayerSelector> singlePlayerSelectorParser() {
|
||||
public ParserDescriptor<Sender, PlayerSelector> getSinglePlayer() {
|
||||
return bukkitPlayerSelectorParser.descriptor();
|
||||
}
|
||||
|
||||
// TODO (Cross-platform) better + brigadier suggestions
|
||||
@Override
|
||||
public SuggestionProvider<Sender> onlinePlayerSuggestions() {
|
||||
return (context, input) -> {
|
||||
List<Suggestion> suggestions = new ArrayList<>();
|
||||
|
||||
for(Player player : Bukkit.getOnlinePlayers()) {
|
||||
CommandSender bukkit = context.get(BukkitCommandContextKeys.BUKKIT_COMMAND_SENDER);
|
||||
if (!(bukkit instanceof Player) || ((Player)bukkit).canSee(player)) {
|
||||
suggestions.add(Suggestion.suggestion(player.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package ac.grim.grimac.platform.bukkit.manager;
|
||||
|
||||
import ac.grim.grimac.platform.api.manager.PermissionRegistrationManager;
|
||||
import ac.grim.grimac.platform.api.permissions.PermissionDefaultValue;
|
||||
import ac.grim.grimac.api.platform.manager.PermissionRegistrationManager;
|
||||
import ac.grim.grimac.api.platform.permissions.PermissionDefaultValue;
|
||||
import ac.grim.grimac.platform.bukkit.utils.convert.BukkitConversionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package ac.grim.grimac.platform.bukkit.manager;
|
||||
|
||||
import ac.grim.grimac.platform.api.PlatformPlugin;
|
||||
import ac.grim.grimac.platform.api.manager.PlatformPluginManager;
|
||||
import ac.grim.grimac.api.platform.PlatformPlugin;
|
||||
import ac.grim.grimac.api.platform.manager.PlatformPluginManager;
|
||||
import ac.grim.grimac.platform.bukkit.BukkitPlatformPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class BukkitPlatformPluginManager implements PlatformPluginManager {
|
||||
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
package ac.grim.grimac.platform.bukkit.player;
|
||||
|
||||
import ac.grim.grimac.platform.api.player.OfflinePlatformPlayer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BukkitOfflinePlatformPlayer implements OfflinePlatformPlayer {
|
||||
private final OfflinePlayer offlinePlayer;
|
||||
|
||||
@Override
|
||||
public boolean isOnline() {
|
||||
return offlinePlayer.isOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return Objects.requireNonNull(offlinePlayer.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull UUID getUniqueId() {
|
||||
return offlinePlayer.getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof OfflinePlatformPlayer player && this.getUniqueId().equals(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
+16
-14
@@ -1,55 +1,57 @@
|
||||
package ac.grim.grimac.platform.bukkit.player;
|
||||
|
||||
import ac.grim.grimac.platform.api.player.PlatformInventory;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import ac.grim.grimac.api.packet.item.PacketItemStack;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayerInventory;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BukkitPlatformInventory implements PlatformInventory {
|
||||
public class BukkitPlatformInventory implements PlatformPlayerInventory {
|
||||
|
||||
private final Player bukkitPlayer;
|
||||
|
||||
public BukkitPlatformInventory(Player bukkitPlayer) {
|
||||
this.bukkitPlayer = bukkitPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemInHand() {
|
||||
public PacketItemStack getItemInHand() {
|
||||
return SpigotConversionUtil.fromBukkitItemStack(bukkitPlayer.getInventory().getItemInHand());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemInOffHand() {
|
||||
public PacketItemStack getItemInOffHand() {
|
||||
return SpigotConversionUtil.fromBukkitItemStack(bukkitPlayer.getInventory().getItemInOffHand());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack(int bukkitSlot, int vanillaSlot) {
|
||||
public PacketItemStack getStack(int bukkitSlot, int vanillaSlot) {
|
||||
return SpigotConversionUtil.fromBukkitItemStack(bukkitPlayer.getInventory().getItem(bukkitSlot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getHelmet() {
|
||||
public PacketItemStack getHelmet() {
|
||||
return SpigotConversionUtil.fromBukkitItemStack(bukkitPlayer.getInventory().getHelmet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getChestplate() {
|
||||
public PacketItemStack getChestplate() {
|
||||
return SpigotConversionUtil.fromBukkitItemStack(bukkitPlayer.getInventory().getChestplate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getLeggings() {
|
||||
public PacketItemStack getLeggings() {
|
||||
return SpigotConversionUtil.fromBukkitItemStack(bukkitPlayer.getInventory().getLeggings());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getBoots() {
|
||||
public PacketItemStack getBoots() {
|
||||
return SpigotConversionUtil.fromBukkitItemStack(bukkitPlayer.getInventory().getBoots());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack[] getContents() {
|
||||
public PacketItemStack[] getContents() {
|
||||
org.bukkit.inventory.ItemStack[] bukkitItems = bukkitPlayer.getInventory().getContents();
|
||||
ItemStack[] items = new ItemStack[bukkitItems.length];
|
||||
PacketItemStack[] items = new PacketItemStack[bukkitItems.length];
|
||||
for (int i = 0; i < bukkitItems.length; i++) {
|
||||
if (bukkitItems[i] == null) continue;
|
||||
items[i] = SpigotConversionUtil.fromBukkitItemStack(bukkitItems[i]);
|
||||
|
||||
+25
-46
@@ -1,55 +1,41 @@
|
||||
package ac.grim.grimac.platform.bukkit.player;
|
||||
|
||||
import ac.grim.grimac.platform.api.entity.GrimEntity;
|
||||
import ac.grim.grimac.platform.api.player.PlatformInventory;
|
||||
import ac.grim.grimac.platform.api.player.PlatformPlayer;
|
||||
import ac.grim.grimac.platform.api.sender.Sender;
|
||||
import ac.grim.grimac.api.math.Vector3dm;
|
||||
import ac.grim.grimac.api.platform.entity.GrimEntity;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayer;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayerInventory;
|
||||
import ac.grim.grimac.api.platform.sender.Sender;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import ac.grim.grimac.platform.bukkit.entity.BukkitGrimEntity;
|
||||
import ac.grim.grimac.platform.bukkit.utils.anticheat.MultiLibUtil;
|
||||
import ac.grim.grimac.platform.bukkit.utils.convert.BukkitConversionUtils;
|
||||
import ac.grim.grimac.platform.bukkit.utils.reflection.PaperUtils;
|
||||
import ac.grim.grimac.utils.common.arguments.CommonGrimArguments;
|
||||
import ac.grim.grimac.utils.math.Location;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import ac.grim.grimac.api.math.Location;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class BukkitPlatformPlayer extends BukkitGrimEntity implements PlatformPlayer {
|
||||
|
||||
private static final BukkitAudiences audiences = BukkitAudiences.create(GrimACBukkitLoaderPlugin.LOADER);
|
||||
|
||||
@Getter
|
||||
private final Player bukkitPlayer;
|
||||
@Getter
|
||||
private final PlatformInventory inventory;
|
||||
|
||||
private final @Nullable User user;
|
||||
private final PlatformPlayerInventory inventory;
|
||||
|
||||
public BukkitPlatformPlayer(Player bukkitPlayer) {
|
||||
super(bukkitPlayer);
|
||||
this.bukkitPlayer = bukkitPlayer;
|
||||
this.inventory = new BukkitPlatformInventory(bukkitPlayer);
|
||||
if (CommonGrimArguments.USE_CHAT_FAST_BYPASS.value()) {
|
||||
Object channel = PacketEvents.getAPI().getProtocolManager().getChannel(bukkitPlayer.getUniqueId());
|
||||
this.user = PacketEvents.getAPI().getProtocolManager().getUser(channel);
|
||||
} else {
|
||||
this.user = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,20 +65,12 @@ public class BukkitPlatformPlayer extends BukkitGrimEntity implements PlatformPl
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
if (CommonGrimArguments.USE_CHAT_FAST_BYPASS.value() && user != null) {
|
||||
user.sendMessage(message);
|
||||
} else {
|
||||
bukkitPlayer.sendMessage(message);
|
||||
}
|
||||
bukkitPlayer.sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Component message) {
|
||||
if (CommonGrimArguments.USE_CHAT_FAST_BYPASS.value() && user != null) {
|
||||
user.sendMessage(message);
|
||||
} else {
|
||||
audiences.player(bukkitPlayer).sendMessage(message);
|
||||
}
|
||||
audiences.player(bukkitPlayer).sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,13 +89,14 @@ public class BukkitPlatformPlayer extends BukkitGrimEntity implements PlatformPl
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3d getPosition() {
|
||||
if (CAN_USE_DIRECT_GETTERS) {
|
||||
return new Vector3d(this.bukkitPlayer.getX(), this.bukkitPlayer.getY(), this.bukkitPlayer.getZ());
|
||||
} else {
|
||||
org.bukkit.Location location = this.bukkitPlayer.getLocation();
|
||||
return new Vector3d(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
public Vector3dm getPosition() {
|
||||
org.bukkit.Location location = this.bukkitPlayer.getLocation();
|
||||
return new Vector3dm(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformPlayerInventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,13 +105,13 @@ public class BukkitPlatformPlayer extends BukkitGrimEntity implements PlatformPl
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameMode getGameMode() {
|
||||
return SpigotConversionUtil.fromBukkitGameMode(bukkitPlayer.getGameMode());
|
||||
public int getGameModeID() {
|
||||
return bukkitPlayer.getGameMode().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameMode(GameMode gameMode) {
|
||||
bukkitPlayer.setGameMode(SpigotConversionUtil.toBukkitGameMode(gameMode));
|
||||
public void setGameMode(int gameModeID) {
|
||||
bukkitPlayer.setGameMode(GameMode.getByValue(gameModeID));
|
||||
}
|
||||
|
||||
public World getBukkitWorld() {
|
||||
@@ -171,7 +150,7 @@ public class BukkitPlatformPlayer extends BukkitGrimEntity implements PlatformPl
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNull
|
||||
public Player getNative() {
|
||||
return this.bukkitPlayer;
|
||||
}
|
||||
|
||||
+12
-22
@@ -1,10 +1,8 @@
|
||||
package ac.grim.grimac.platform.bukkit.player;
|
||||
|
||||
import ac.grim.grimac.platform.api.player.AbstractPlatformPlayerFactory;
|
||||
import ac.grim.grimac.platform.api.player.OfflinePlatformPlayer;
|
||||
import ac.grim.grimac.platform.api.player.PlatformPlayer;
|
||||
import ac.grim.grimac.api.platform.player.AbstractPlatformPlayerFactory;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -13,27 +11,31 @@ import java.util.UUID;
|
||||
|
||||
|
||||
public class BukkitPlatformPlayerFactory extends AbstractPlatformPlayerFactory<Player> {
|
||||
|
||||
@Override
|
||||
protected Player getNativePlayer(@NotNull UUID uuid) {
|
||||
return Bukkit.getPlayer(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Player getNativePlayer(@NotNull String name) {
|
||||
return Bukkit.getPlayer(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PlatformPlayer createPlatformPlayer(@NotNull Player nativePlayer) {
|
||||
return new BukkitPlatformPlayer(nativePlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNativePlayerType(@NotNull Object playerObject) {
|
||||
return playerObject instanceof Player;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UUID getPlayerUUID(@NotNull Player nativePlayer) {
|
||||
return nativePlayer.getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<Player> getNativePlayerClass() {
|
||||
return Player.class;
|
||||
}
|
||||
|
||||
// The cast is safe because Bukkit.getOnlinePlayers() is guaranteed to contain Player or its subtypes,
|
||||
// and we're only reading from it.
|
||||
@Override
|
||||
@@ -42,16 +44,4 @@ public class BukkitPlatformPlayerFactory extends AbstractPlatformPlayerFactory<P
|
||||
// Cast Collection<? extends Player> to Collection<Player>
|
||||
return (Collection<Player>) Bukkit.getOnlinePlayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflinePlatformPlayer getOfflineFromUUID(@NotNull UUID uuid) {
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
|
||||
return new BukkitOfflinePlatformPlayer(offlinePlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflinePlatformPlayer getOfflineFromName(@NotNull String name) {
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(name);
|
||||
return new BukkitOfflinePlatformPlayer(offlinePlayer);
|
||||
}
|
||||
}
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
package ac.grim.grimac.platform.bukkit.resolver;
|
||||
|
||||
import ac.grim.grimac.api.plugin.BasicGrimPlugin;
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.events.GrimExtensionManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Manages the registration of Bukkit-specific resolvers with the GrimExtensionManager.
|
||||
* This class is designed to be instantiated once during plugin startup.
|
||||
*/
|
||||
public final class BukkitResolverRegistrar {
|
||||
|
||||
private final GrimExtensionManager extensionManager;
|
||||
|
||||
// Cache to ensure we only create one GrimPlugin wrapper per Bukkit Plugin instance.
|
||||
private final Map<Plugin, GrimPlugin> pluginCache = new ConcurrentHashMap<>();
|
||||
|
||||
public BukkitResolverRegistrar(GrimExtensionManager extensionManager) {
|
||||
this.extensionManager = extensionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all the Bukkit-specific resolvers in order of performance (fastest to slowest).
|
||||
*/
|
||||
public void registerAll() {
|
||||
extensionManager.setFailureHandler(this::createFailureException);
|
||||
extensionManager.registerResolver(this::resolvePluginInstance);
|
||||
extensionManager.registerResolver(this::resolveStringName);
|
||||
extensionManager.registerResolver(this::resolveClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* The core logic for converting a Bukkit Plugin into a GrimPlugin, with caching.
|
||||
*/
|
||||
public GrimPlugin resolvePlugin(Plugin bukkitPlugin) {
|
||||
return pluginCache.computeIfAbsent(bukkitPlugin, plugin -> {
|
||||
PluginDescriptionFile desc = plugin.getDescription();
|
||||
return new BasicGrimPlugin(
|
||||
plugin.getLogger(),
|
||||
plugin.getDataFolder(),
|
||||
desc.getVersion(),
|
||||
desc.getDescription(),
|
||||
desc.getAuthors()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Resolver for raw Plugin instances (the most common case).
|
||||
*/
|
||||
private GrimPlugin resolvePluginInstance(Object context) {
|
||||
if (context instanceof Plugin bukkitPlugin) {
|
||||
return resolvePlugin(bukkitPlugin);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 2. Resolver for String plugin names.
|
||||
*/
|
||||
private GrimPlugin resolveStringName(Object context) {
|
||||
if (context instanceof String pluginName) {
|
||||
// Use the Bukkit API to look up the plugin by name. This returns null if not found.
|
||||
Plugin bukkitPlugin = Bukkit.getPluginManager().getPlugin(pluginName);
|
||||
// We must check for null before applying the logic to avoid a NullPointerException.
|
||||
return (bukkitPlugin != null) ? resolvePlugin(bukkitPlugin) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 3. Resolver for Class objects.
|
||||
*/
|
||||
private GrimPlugin resolveClass(Object context) {
|
||||
if (context instanceof Class) {
|
||||
try {
|
||||
// First, resolve the Class to a Plugin instance.
|
||||
JavaPlugin providingPlugin = JavaPlugin.getProvidingPlugin((Class<?>) context);
|
||||
// Then, use our shared logic directly to get the GrimPlugin wrapper.
|
||||
return resolvePlugin(providingPlugin);
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
// This is an expected failure if the class is not from a plugin
|
||||
// or is called from a static initializer. We simply indicate that
|
||||
// this resolver cannot handle this context.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// This resolver only handles Classes.
|
||||
return null;
|
||||
}
|
||||
|
||||
private RuntimeException createFailureException(Object failedContext) {
|
||||
String message = """
|
||||
Failed to resolve GrimPlugin context from the provided object of type '%s'.
|
||||
|
||||
Please ensure you are passing one of the following:
|
||||
- The main instance of your plugin (e.g., 'this' from your class extending JavaPlugin).
|
||||
- The plugin name as a String (e.g., "MyPluginName").
|
||||
- Any Class from your plugin's JAR file (e.g., MyListener.class).
|
||||
- A pre-existing GrimPlugin instance.
|
||||
""".formatted(failedContext.getClass().getName());
|
||||
return new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
+17
-19
@@ -1,9 +1,9 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.bukkit;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.scheduler.AsyncScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.scheduler.AsyncScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
@@ -22,31 +22,29 @@ public class BukkitAsyncScheduler implements AsyncScheduler {
|
||||
|
||||
@Override
|
||||
public TaskHandle runDelayed(@NotNull GrimPlugin plugin, @NotNull Runnable task, long delay, @NotNull TimeUnit timeUnit) {
|
||||
return new BukkitTaskHandle(bukkitScheduler.runTaskLaterAsynchronously(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
return new BukkitTaskHandle(bukkitScheduler.runTaskLaterAsynchronously(GrimACBukkitLoaderPlugin.LOADER,
|
||||
task,
|
||||
PlatformScheduler.convertTimeToTicks(delay, timeUnit)
|
||||
));
|
||||
PlatformScheduler.convertTimeToTicks(delay, timeUnit))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimPlugin plugin, @NotNull Runnable task, long delay, long period, @NotNull TimeUnit timeUnit) {
|
||||
return new BukkitTaskHandle(bukkitScheduler.runTaskTimerAsynchronously(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
task,
|
||||
PlatformScheduler.convertTimeToTicks(delay, timeUnit),
|
||||
PlatformScheduler.convertTimeToTicks(period, timeUnit)
|
||||
));
|
||||
return new BukkitTaskHandle(
|
||||
bukkitScheduler.runTaskTimerAsynchronously(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
task,
|
||||
PlatformScheduler.convertTimeToTicks(delay, timeUnit),
|
||||
PlatformScheduler.convertTimeToTicks(period, timeUnit)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimPlugin plugin, @NotNull Runnable task, long initialDelayTicks, long periodTicks) {
|
||||
return new BukkitTaskHandle(bukkitScheduler.runTaskTimerAsynchronously(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
task,
|
||||
initialDelayTicks,
|
||||
periodTicks
|
||||
));
|
||||
return new BukkitTaskHandle(
|
||||
bukkitScheduler.runTaskTimerAsynchronously(GrimACBukkitLoaderPlugin.LOADER, task, initialDelayTicks, periodTicks)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-8
@@ -1,9 +1,9 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.bukkit;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.entity.GrimEntity;
|
||||
import ac.grim.grimac.platform.api.scheduler.EntityScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.entity.GrimEntity;
|
||||
import ac.grim.grimac.api.platform.scheduler.EntityScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
@@ -11,25 +11,26 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BukkitEntityScheduler implements EntityScheduler {
|
||||
private final BukkitScheduler scheduler = Bukkit.getScheduler();
|
||||
|
||||
private final BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable run, @Nullable Runnable retired, long delay) {
|
||||
scheduler.runTaskLater(GrimACBukkitLoaderPlugin.LOADER, run, delay);
|
||||
bukkitScheduler.runTaskLater(GrimACBukkitLoaderPlugin.LOADER, run, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle run(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable task, @Nullable Runnable retired) {
|
||||
return new BukkitTaskHandle(scheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, task));
|
||||
return new BukkitTaskHandle(bukkitScheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runDelayed(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable task, @Nullable Runnable retired, long delayTicks) {
|
||||
return new BukkitTaskHandle(scheduler.runTaskLater(GrimACBukkitLoaderPlugin.LOADER, task, delayTicks));
|
||||
return new BukkitTaskHandle(bukkitScheduler.runTaskLater(GrimACBukkitLoaderPlugin.LOADER, task, delayTicks));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable task, @Nullable Runnable retired, long initialDelayTicks, long periodTicks) {
|
||||
return new BukkitTaskHandle(scheduler.runTaskTimer(GrimACBukkitLoaderPlugin.LOADER, task, initialDelayTicks, periodTicks));
|
||||
return new BukkitTaskHandle(bukkitScheduler.runTaskTimer(GrimACBukkitLoaderPlugin.LOADER, task, initialDelayTicks, periodTicks));
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.bukkit;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.scheduler.GlobalRegionScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.scheduler.GlobalRegionScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
@@ -13,8 +13,8 @@ public class BukkitGlobalRegionScheduler implements GlobalRegionScheduler {
|
||||
private final BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Runnable task) {
|
||||
bukkitScheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, task);
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Runnable run) {
|
||||
bukkitScheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, run);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+31
-8
@@ -1,13 +1,36 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.bukkit;
|
||||
|
||||
import ac.grim.grimac.platform.api.scheduler.PlatformScheduler;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ac.grim.grimac.api.platform.scheduler.AsyncScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.EntityScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.GlobalRegionScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.RegionScheduler;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@Getter
|
||||
public class BukkitPlatformScheduler implements PlatformScheduler {
|
||||
private final @NotNull BukkitAsyncScheduler asyncScheduler = new BukkitAsyncScheduler();
|
||||
private final @NotNull BukkitGlobalRegionScheduler globalRegionScheduler = new BukkitGlobalRegionScheduler();
|
||||
private final @NotNull BukkitEntityScheduler entityScheduler = new BukkitEntityScheduler();
|
||||
private final @NotNull BukkitRegionScheduler regionScheduler = new BukkitRegionScheduler();
|
||||
|
||||
private final BukkitAsyncScheduler bukkitAsyncScheduler = new BukkitAsyncScheduler();
|
||||
private final BukkitGlobalRegionScheduler bukkitGlobalRegionScheduler = new BukkitGlobalRegionScheduler();
|
||||
private final BukkitEntityScheduler bukkitEntityScheduler = new BukkitEntityScheduler();
|
||||
private final BukkitRegionScheduler bukkitRegionScheduler = new BukkitRegionScheduler();
|
||||
|
||||
@Override
|
||||
public @NonNull AsyncScheduler getAsyncScheduler() {
|
||||
return bukkitAsyncScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull GlobalRegionScheduler getGlobalRegionScheduler() {
|
||||
return bukkitGlobalRegionScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull EntityScheduler getEntityScheduler() {
|
||||
return bukkitEntityScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull RegionScheduler getRegionScheduler() {
|
||||
return bukkitRegionScheduler;
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -1,11 +1,11 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.bukkit;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.scheduler.RegionScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.api.world.PlatformWorld;
|
||||
import ac.grim.grimac.api.platform.scheduler.RegionScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.world.PlatformWorld;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import ac.grim.grimac.utils.math.Location;
|
||||
import ac.grim.grimac.api.math.Location;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -15,13 +15,13 @@ public class BukkitRegionScheduler implements RegionScheduler {
|
||||
private final BukkitScheduler bukkitScheduler = Bukkit.getScheduler();
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull PlatformWorld world, int chunkX, int chunkZ, @NotNull Runnable task) {
|
||||
bukkitScheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, task);
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull PlatformWorld world, int chunkX, int chunkZ, @NotNull Runnable run) {
|
||||
bukkitScheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, run);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Location location, @NotNull Runnable task) {
|
||||
bukkitScheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, task);
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Location location, @NotNull Runnable run) {
|
||||
bukkitScheduler.runTask(GrimACBukkitLoaderPlugin.LOADER, run);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+7
-12
@@ -1,33 +1,28 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.bukkit;
|
||||
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class BukkitTaskHandle implements TaskHandle {
|
||||
|
||||
private final @NotNull BukkitTask task;
|
||||
private final BukkitTask bukkitTask;
|
||||
|
||||
@Contract(pure = true)
|
||||
public BukkitTaskHandle(@NotNull BukkitTask task) {
|
||||
this.task = Objects.requireNonNull(task);
|
||||
public BukkitTaskHandle(BukkitTask bukkitTask) {
|
||||
this.bukkitTask = bukkitTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSync() {
|
||||
return task.isSync();
|
||||
return bukkitTask.isSync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return task.isCancelled();
|
||||
return bukkitTask.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
task.cancel();
|
||||
bukkitTask.cancel();
|
||||
}
|
||||
}
|
||||
+31
-25
@@ -1,8 +1,8 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.folia;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.scheduler.AsyncScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.scheduler.AsyncScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -11,47 +11,53 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FoliaAsyncScheduler implements AsyncScheduler {
|
||||
|
||||
private final io.papermc.paper.threadedregions.scheduler.AsyncScheduler scheduler = Bukkit.getAsyncScheduler();
|
||||
private final io.papermc.paper.threadedregions.scheduler.AsyncScheduler asyncScheduler = Bukkit.getAsyncScheduler();
|
||||
|
||||
@Override
|
||||
public TaskHandle runNow(@NotNull GrimPlugin plugin, @NotNull Runnable task) {
|
||||
return new FoliaTaskHandle(scheduler.runNow(GrimACBukkitLoaderPlugin.LOADER, ignored -> task.run()));
|
||||
return new FoliaTaskHandle(asyncScheduler.runNow(GrimACBukkitLoaderPlugin.LOADER, (ignored) -> task.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runDelayed(@NotNull GrimPlugin plugin, @NotNull Runnable task, long delay, @NotNull TimeUnit timeUnit) {
|
||||
return new FoliaTaskHandle(scheduler.runDelayed(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
ignored -> task.run(),
|
||||
delay,
|
||||
timeUnit
|
||||
));
|
||||
return new FoliaTaskHandle(
|
||||
asyncScheduler.runDelayed(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
(ignored) -> task.run(),
|
||||
delay,
|
||||
timeUnit
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimPlugin plugin, @NotNull Runnable task, long delay, long period, @NotNull TimeUnit timeUnit) {
|
||||
return new FoliaTaskHandle(scheduler.runAtFixedRate(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
ignored -> task.run(),
|
||||
delay,
|
||||
period,
|
||||
timeUnit
|
||||
));
|
||||
return new FoliaTaskHandle(
|
||||
asyncScheduler.runAtFixedRate(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
(ignored) -> task.run(),
|
||||
delay,
|
||||
period,
|
||||
timeUnit
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimPlugin plugin, @NotNull Runnable task, long initialDelayTicks, long periodTicks) {
|
||||
return new FoliaTaskHandle(scheduler.runAtFixedRate(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
ignored -> task.run(),
|
||||
initialDelayTicks * 50,
|
||||
periodTicks * 50,
|
||||
TimeUnit.MILLISECONDS
|
||||
));
|
||||
return new FoliaTaskHandle(
|
||||
asyncScheduler.runAtFixedRate(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
(ignored) -> task.run(),
|
||||
initialDelayTicks * 50,
|
||||
periodTicks * 50,
|
||||
TimeUnit.MILLISECONDS
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@NotNull GrimPlugin plugin) {
|
||||
scheduler.cancelTasks(GrimACBukkitLoaderPlugin.LOADER);
|
||||
asyncScheduler.cancelTasks(GrimACBukkitLoaderPlugin.LOADER);
|
||||
}
|
||||
}
|
||||
+9
-29
@@ -1,55 +1,35 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.folia;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.entity.GrimEntity;
|
||||
import ac.grim.grimac.platform.api.scheduler.EntityScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.entity.GrimEntity;
|
||||
import ac.grim.grimac.api.platform.scheduler.EntityScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import ac.grim.grimac.platform.bukkit.entity.BukkitGrimEntity;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class FoliaEntityScheduler implements EntityScheduler {
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable task, @Nullable Runnable retired, long delay) {
|
||||
((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().execute(GrimACBukkitLoaderPlugin.LOADER, task, retired, delay);
|
||||
public void execute(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable run, @Nullable Runnable retired, long delay) {
|
||||
((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().execute(GrimACBukkitLoaderPlugin.LOADER, run, retired, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle run(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable task, @Nullable Runnable retired) {
|
||||
ScheduledTask scheduled = ((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().run(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
ignored -> task.run(),
|
||||
retired
|
||||
);
|
||||
|
||||
return scheduled == null ? null : new FoliaTaskHandle(scheduled);
|
||||
return new FoliaTaskHandle(((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().run(GrimACBukkitLoaderPlugin.LOADER, (ignored) -> task.run(), retired));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runDelayed(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable task, @Nullable Runnable retired, long delayTicks) {
|
||||
ScheduledTask scheduled = ((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().runDelayed(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
ignored -> task.run(),
|
||||
retired,
|
||||
delayTicks
|
||||
return new FoliaTaskHandle(
|
||||
((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().runDelayed(GrimACBukkitLoaderPlugin.LOADER, (ignored) -> task.run(), retired, delayTicks)
|
||||
);
|
||||
|
||||
return scheduled == null ? null : new FoliaTaskHandle(scheduled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimEntity entity, @NotNull GrimPlugin plugin, @NotNull Runnable task, @Nullable Runnable retired, long initialDelayTicks, long periodTicks) {
|
||||
ScheduledTask scheduled = ((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().runAtFixedRate(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
ignored -> task.run(),
|
||||
retired,
|
||||
initialDelayTicks,
|
||||
periodTicks
|
||||
);
|
||||
|
||||
return scheduled == null ? null : new FoliaTaskHandle(scheduled);
|
||||
return new FoliaTaskHandle(((BukkitGrimEntity) entity).getBukkitEntity().getScheduler().runAtFixedRate(GrimACBukkitLoaderPlugin.LOADER, (ignored) -> task.run(), retired, initialDelayTicks, periodTicks));
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -1,8 +1,8 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.folia;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.scheduler.GlobalRegionScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.scheduler.GlobalRegionScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -12,23 +12,23 @@ public class FoliaGlobalRegionScheduler implements GlobalRegionScheduler {
|
||||
private final io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler globalRegionScheduler = Bukkit.getGlobalRegionScheduler();
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Runnable task) {
|
||||
globalRegionScheduler.execute(GrimACBukkitLoaderPlugin.LOADER, task);
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Runnable run) {
|
||||
globalRegionScheduler.execute(GrimACBukkitLoaderPlugin.LOADER, run);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle run(@NotNull GrimPlugin plugin, @NotNull Runnable task) {
|
||||
return new FoliaTaskHandle(globalRegionScheduler.run(GrimACBukkitLoaderPlugin.LOADER, ignored -> task.run()));
|
||||
return new FoliaTaskHandle(globalRegionScheduler.run(GrimACBukkitLoaderPlugin.LOADER, (ignored) -> task.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runDelayed(@NotNull GrimPlugin plugin, @NotNull Runnable task, long delay) {
|
||||
return new FoliaTaskHandle(globalRegionScheduler.runDelayed(GrimACBukkitLoaderPlugin.LOADER, ignored -> task.run(), delay));
|
||||
return new FoliaTaskHandle(globalRegionScheduler.runDelayed(GrimACBukkitLoaderPlugin.LOADER, (ignored) -> task.run(), delay));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimPlugin plugin, @NotNull Runnable task, long initialDelayTicks, long periodTicks) {
|
||||
return new FoliaTaskHandle(globalRegionScheduler.runAtFixedRate(GrimACBukkitLoaderPlugin.LOADER, ignored -> task.run(), initialDelayTicks, periodTicks));
|
||||
return new FoliaTaskHandle(globalRegionScheduler.runAtFixedRate(GrimACBukkitLoaderPlugin.LOADER, (ignored) -> task.run(), initialDelayTicks, periodTicks));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+31
-8
@@ -1,13 +1,36 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.folia;
|
||||
|
||||
import ac.grim.grimac.platform.api.scheduler.PlatformScheduler;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ac.grim.grimac.api.platform.scheduler.AsyncScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.EntityScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.GlobalRegionScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.RegionScheduler;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@Getter
|
||||
public class FoliaPlatformScheduler implements PlatformScheduler {
|
||||
private final @NotNull FoliaAsyncScheduler asyncScheduler = new FoliaAsyncScheduler();
|
||||
private final @NotNull FoliaGlobalRegionScheduler globalRegionScheduler = new FoliaGlobalRegionScheduler();
|
||||
private final @NotNull FoliaEntityScheduler entityScheduler = new FoliaEntityScheduler();
|
||||
private final @NotNull FoliaRegionScheduler regionScheduler = new FoliaRegionScheduler();
|
||||
|
||||
private final FoliaAsyncScheduler foliaAsyncScheduler = new FoliaAsyncScheduler();
|
||||
private final FoliaGlobalRegionScheduler foliaGlobalRegionScheduler = new FoliaGlobalRegionScheduler();
|
||||
private final FoliaEntityScheduler foliaEntityScheduler = new FoliaEntityScheduler();
|
||||
private final FoliaRegionScheduler foliaRegionScheduler = new FoliaRegionScheduler();
|
||||
|
||||
@Override
|
||||
public @NonNull AsyncScheduler getAsyncScheduler() {
|
||||
return foliaAsyncScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull GlobalRegionScheduler getGlobalRegionScheduler() {
|
||||
return foliaGlobalRegionScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull EntityScheduler getEntityScheduler() {
|
||||
return foliaEntityScheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull RegionScheduler getRegionScheduler() {
|
||||
return foliaRegionScheduler;
|
||||
}
|
||||
}
|
||||
+15
-41
@@ -1,12 +1,12 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.folia;
|
||||
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.platform.api.scheduler.RegionScheduler;
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.platform.api.world.PlatformWorld;
|
||||
import ac.grim.grimac.api.platform.scheduler.RegionScheduler;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.world.PlatformWorld;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import ac.grim.grimac.platform.bukkit.world.BukkitPlatformWorld;
|
||||
import ac.grim.grimac.utils.math.Location;
|
||||
import ac.grim.grimac.api.math.Location;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -15,24 +15,19 @@ public class FoliaRegionScheduler implements RegionScheduler {
|
||||
private final io.papermc.paper.threadedregions.scheduler.RegionScheduler regionScheduler = Bukkit.getRegionScheduler();
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull PlatformWorld world, int chunkX, int chunkZ, @NotNull Runnable task) {
|
||||
regionScheduler.execute(GrimACBukkitLoaderPlugin.LOADER, ((BukkitPlatformWorld) world).getBukkitWorld(), chunkX, chunkZ, task);
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull PlatformWorld world, int chunkX, int chunkZ, @NotNull Runnable run) {
|
||||
regionScheduler.execute(GrimACBukkitLoaderPlugin.LOADER, ((BukkitPlatformWorld) world).getBukkitWorld(), chunkX, chunkZ, run);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Location location, @NotNull Runnable task) {
|
||||
execute(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task);
|
||||
public void execute(@NotNull GrimPlugin plugin, @NotNull Location location, @NotNull Runnable run) {
|
||||
execute(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, run);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle run(@NotNull GrimPlugin plugin, @NotNull PlatformWorld world, int chunkX, int chunkZ, @NotNull Runnable task) {
|
||||
return new FoliaTaskHandle(regionScheduler.run(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
((BukkitPlatformWorld) world).getBukkitWorld(),
|
||||
chunkX,
|
||||
chunkZ,
|
||||
ignored -> task.run()
|
||||
));
|
||||
return new FoliaTaskHandle(regionScheduler.run(GrimACBukkitLoaderPlugin.LOADER, ((BukkitPlatformWorld) world).getBukkitWorld(), chunkX, chunkZ, (ignored) -> task.run()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,14 +37,8 @@ public class FoliaRegionScheduler implements RegionScheduler {
|
||||
|
||||
@Override
|
||||
public TaskHandle runDelayed(@NotNull GrimPlugin plugin, @NotNull PlatformWorld world, int chunkX, int chunkZ, @NotNull Runnable task, long delayTicks) {
|
||||
return new FoliaTaskHandle(regionScheduler.runDelayed(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
((BukkitPlatformWorld) world).getBukkitWorld(),
|
||||
chunkX,
|
||||
chunkZ,
|
||||
ignored -> task.run(),
|
||||
delayTicks
|
||||
));
|
||||
return new FoliaTaskHandle(regionScheduler.runDelayed(GrimACBukkitLoaderPlugin.LOADER,
|
||||
((BukkitPlatformWorld) world).getBukkitWorld(), chunkX, chunkZ, (ignored) -> task.run(), delayTicks));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,27 +48,12 @@ public class FoliaRegionScheduler implements RegionScheduler {
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimPlugin plugin, @NotNull PlatformWorld world, int chunkX, int chunkZ, @NotNull Runnable task, long initialDelayTicks, long periodTicks) {
|
||||
return new FoliaTaskHandle(regionScheduler.runAtFixedRate(
|
||||
GrimACBukkitLoaderPlugin.LOADER,
|
||||
((BukkitPlatformWorld) world).getBukkitWorld(),
|
||||
chunkX,
|
||||
chunkZ,
|
||||
ignored -> task.run(),
|
||||
initialDelayTicks,
|
||||
periodTicks
|
||||
));
|
||||
return new FoliaTaskHandle(regionScheduler.runAtFixedRate(GrimACBukkitLoaderPlugin.LOADER,
|
||||
((BukkitPlatformWorld) world).getBukkitWorld(), chunkX, chunkZ, (ignored) -> task.run(), initialDelayTicks, periodTicks));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskHandle runAtFixedRate(@NotNull GrimPlugin plugin, @NotNull Location location, @NotNull Runnable task, long initialDelayTicks, long periodTicks) {
|
||||
return runAtFixedRate(
|
||||
plugin,
|
||||
location.getWorld(),
|
||||
location.getBlockX() >> 4,
|
||||
location.getBlockZ() >> 4,
|
||||
task,
|
||||
initialDelayTicks,
|
||||
periodTicks
|
||||
);
|
||||
return runAtFixedRate(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, initialDelayTicks, periodTicks);
|
||||
}
|
||||
}
|
||||
+4
-9
@@ -1,19 +1,14 @@
|
||||
package ac.grim.grimac.platform.bukkit.scheduler.folia;
|
||||
|
||||
import ac.grim.grimac.platform.api.scheduler.TaskHandle;
|
||||
import ac.grim.grimac.api.platform.scheduler.TaskHandle;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class FoliaTaskHandle implements TaskHandle {
|
||||
|
||||
private final @NotNull ScheduledTask task;
|
||||
private final ScheduledTask task;
|
||||
|
||||
@Contract(pure = true)
|
||||
public FoliaTaskHandle(@NotNull ScheduledTask task) {
|
||||
this.task = Objects.requireNonNull(task);
|
||||
public FoliaTaskHandle(ScheduledTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package ac.grim.grimac.platform.bukkit.sender;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.platform.api.sender.Sender;
|
||||
import ac.grim.grimac.platform.api.sender.SenderFactory;
|
||||
import ac.grim.grimac.api.GrimAPIProvider;
|
||||
import ac.grim.grimac.api.platform.sender.Sender;
|
||||
import ac.grim.grimac.api.platform.sender.SenderFactory;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -12,8 +12,8 @@ import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.SenderMapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> implements
|
||||
|
||||
@Override
|
||||
protected UUID getUniqueId(CommandSender sender) {
|
||||
return sender instanceof Player player ? player.getUniqueId() : Sender.CONSOLE_UUID;
|
||||
return sender instanceof Player ? ((Player) sender).getUniqueId() : Sender.CONSOLE_UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,8 +45,8 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> implements
|
||||
if (sender instanceof Player || sender instanceof ConsoleCommandSender || sender instanceof RemoteConsoleCommandSender) {
|
||||
this.audiences.sender(sender).sendMessage(message);
|
||||
} else {
|
||||
GrimAPI.INSTANCE.getScheduler().getGlobalRegionScheduler().run(
|
||||
GrimAPI.INSTANCE.getGrimPlugin(),
|
||||
GrimAPIProvider.getDirect().getPlatformLoader().getScheduler().getGlobalRegionScheduler().run(
|
||||
GrimAPIProvider.getDirect().getPlatformLoader().getPlugin(),
|
||||
() -> this.audiences.sender(sender).sendMessage(message)
|
||||
);
|
||||
}
|
||||
@@ -78,12 +78,12 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Sender map(@NotNull CommandSender base) {
|
||||
public @NonNull Sender map(@NonNull CommandSender base) {
|
||||
return this.wrap(base);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CommandSender reverse(@NotNull Sender mapped) {
|
||||
public @NonNull CommandSender reverse(@NonNull Sender mapped) {
|
||||
return this.unwrap(mapped);
|
||||
}
|
||||
}
|
||||
+14
-7
@@ -1,17 +1,22 @@
|
||||
package ac.grim.grimac.platform.bukkit.utils.anticheat;
|
||||
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.reflection.ReflectionUtils;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.ServerVersions;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class MultiLibUtil {
|
||||
|
||||
public final static Method externalPlayerMethod = ReflectionUtils.getMethod(Player.class, "isExternalPlayer");
|
||||
private static final boolean IS_PRE_1_18 = PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_18);
|
||||
public final static Method externalPlayerMethod = getMethod(Player.class, "isExternalPlayer");
|
||||
private static final boolean IS_PRE_1_18 = ServerVersions.getServerVersion().isOlderThan(ServerVersions.V_1_18);
|
||||
|
||||
public static Method getMethod(Class<?> clazz, String methodName) {
|
||||
try {
|
||||
return clazz.getMethod(methodName);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: cache external players for better performance, but this only matters for people using multi-lib
|
||||
public static boolean isExternalPlayer(Player player) {
|
||||
@@ -19,8 +24,10 @@ public class MultiLibUtil {
|
||||
try {
|
||||
return (boolean) externalPlayerMethod.invoke(player);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("Failed to invoke external player method", e);
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+13
-15
@@ -1,17 +1,12 @@
|
||||
package ac.grim.grimac.platform.bukkit.utils.convert;
|
||||
|
||||
import ac.grim.grimac.platform.api.permissions.PermissionDefaultValue;
|
||||
import ac.grim.grimac.api.platform.permissions.PermissionDefaultValue;
|
||||
import ac.grim.grimac.platform.bukkit.world.BukkitPlatformWorld;
|
||||
import ac.grim.grimac.utils.math.Location;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ac.grim.grimac.api.math.Location;
|
||||
import ac.grim.grimac.api.packet.world.enums.BlockFace;
|
||||
|
||||
public class BukkitConversionUtils {
|
||||
@Contract("null -> null; !null -> new")
|
||||
public static org.bukkit.Location toBukkitLocation(Location location) {
|
||||
if (location == null) return null;
|
||||
return new org.bukkit.Location(((BukkitPlatformWorld) location.getWorld()).getBukkitWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
@@ -20,17 +15,20 @@ public class BukkitConversionUtils {
|
||||
*
|
||||
* @return The corresponding Bukkit PermissionDefault.
|
||||
*/
|
||||
@Contract(value = "null -> null; !null -> !null", pure = true)
|
||||
public static @Nullable PermissionDefault toBukkitPermissionDefault(@Nullable PermissionDefaultValue permissionDefaultValue) {
|
||||
if (permissionDefaultValue == null) return null;
|
||||
public static org.bukkit.permissions.PermissionDefault toBukkitPermissionDefault(PermissionDefaultValue permissionDefaultValue) {
|
||||
return switch (permissionDefaultValue) {
|
||||
case TRUE -> PermissionDefault.TRUE;
|
||||
case FALSE -> PermissionDefault.FALSE;
|
||||
case OP -> PermissionDefault.OP;
|
||||
case NOT_OP -> PermissionDefault.NOT_OP;
|
||||
case TRUE -> org.bukkit.permissions.PermissionDefault.TRUE;
|
||||
case FALSE -> org.bukkit.permissions.PermissionDefault.FALSE;
|
||||
case OP -> org.bukkit.permissions.PermissionDefault.OP;
|
||||
case NOT_OP -> org.bukkit.permissions.PermissionDefault.NOT_OP;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* For use with bukkit events only
|
||||
* Grim is not meant to be restrained by bukkit!
|
||||
*/
|
||||
@Deprecated
|
||||
public static BlockFace fromBukkitFace(org.bukkit.block.BlockFace face) {
|
||||
return switch (face) {
|
||||
case NORTH -> BlockFace.NORTH;
|
||||
|
||||
+12
-12
@@ -1,4 +1,4 @@
|
||||
package ac.grim.grimac.utils.lists;
|
||||
package ac.grim.grimac.platform.bukkit.utils.list;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -33,13 +33,13 @@ public abstract class HookedListWrapper<T> extends ListWrapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterator<T> iterator() {
|
||||
public Iterator<T> iterator() {
|
||||
this.onIterator();
|
||||
return this.listIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object @NotNull [] toArray() {
|
||||
public Object[] toArray() {
|
||||
return this.base.toArray();
|
||||
}
|
||||
|
||||
@@ -54,12 +54,12 @@ public abstract class HookedListWrapper<T> extends ListWrapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(@NotNull Collection c) {
|
||||
public boolean addAll(Collection c) {
|
||||
return this.base.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, @NotNull Collection c) {
|
||||
public boolean addAll(int index, Collection c) {
|
||||
return this.base.addAll(index, c);
|
||||
}
|
||||
|
||||
@@ -99,37 +99,37 @@ public abstract class HookedListWrapper<T> extends ListWrapper<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ListIterator<T> listIterator() {
|
||||
public ListIterator<T> listIterator() {
|
||||
return this.base.listIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ListIterator<T> listIterator(int index) {
|
||||
public ListIterator<T> listIterator(int index) {
|
||||
return this.base.listIterator(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<T> subList(int fromIndex, int toIndex) {
|
||||
public List<T> subList(int fromIndex, int toIndex) {
|
||||
return this.base.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(@NotNull Collection c) {
|
||||
public boolean retainAll(Collection c) {
|
||||
return this.base.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(@NotNull Collection c) {
|
||||
public boolean removeAll(Collection c) {
|
||||
return this.base.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(@NotNull Collection c) {
|
||||
public boolean containsAll(Collection c) {
|
||||
return this.base.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object @NotNull [] toArray(Object @NotNull [] a) {
|
||||
public Object @NotNull [] toArray(Object[] a) {
|
||||
return this.base.toArray(a);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package ac.grim.grimac.utils.lists;
|
||||
package ac.grim.grimac.platform.bukkit.utils.list;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
+8
-9
@@ -1,8 +1,7 @@
|
||||
package ac.grim.grimac.platform.bukkit.utils.placeholder;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.GrimAPIProvider;
|
||||
import ac.grim.grimac.api.GrimUser;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -22,12 +21,12 @@ public class PlaceholderAPIExpansion extends PlaceholderExpansion {
|
||||
}
|
||||
|
||||
public @NotNull String getAuthor() {
|
||||
return String.join(", ", GrimAPI.INSTANCE.getGrimPlugin().getDescription().getAuthors());
|
||||
return String.join(", ", GrimAPIProvider.getDirect().getPlatformLoader().getPlugin().getDescription().getAuthors());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getVersion() {
|
||||
return GrimAPI.INSTANCE.getExternalAPI().getGrimVersion();
|
||||
return GrimAPIProvider.getDirect().getGrimVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,8 +36,8 @@ public class PlaceholderAPIExpansion extends PlaceholderExpansion {
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> getPlaceholders() {
|
||||
Set<String> staticReplacements = GrimAPI.INSTANCE.getExternalAPI().getStaticReplacements().keySet();
|
||||
Set<String> variableReplacements = GrimAPI.INSTANCE.getExternalAPI().getVariableReplacements().keySet();
|
||||
Set<String> staticReplacements = GrimAPIProvider.getDirect().getStaticReplacements().keySet();
|
||||
Set<String> variableReplacements = GrimAPIProvider.getDirect().getVariableReplacements().keySet();
|
||||
ArrayList<String> placeholders = new ArrayList<>(staticReplacements.size() + variableReplacements.size());
|
||||
for (String s : staticReplacements) {
|
||||
placeholders.add(s.equals("%grim_version%") ? s : "%grim_" + s.replaceAll("%", "") + "%");
|
||||
@@ -51,7 +50,7 @@ public class PlaceholderAPIExpansion extends PlaceholderExpansion {
|
||||
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer offlinePlayer, @NotNull String params) {
|
||||
for (Map.Entry<String, String> entry : GrimAPI.INSTANCE.getExternalAPI().getStaticReplacements().entrySet()) {
|
||||
for (Map.Entry<String, String> entry : GrimAPIProvider.getDirect().getStaticReplacements().entrySet()) {
|
||||
String key = entry.getKey().equals("%grim_version%")
|
||||
? "version"
|
||||
: entry.getKey().replaceAll("%", "");
|
||||
@@ -61,10 +60,10 @@ public class PlaceholderAPIExpansion extends PlaceholderExpansion {
|
||||
}
|
||||
|
||||
if (offlinePlayer instanceof Player player) {
|
||||
GrimPlayer grimPlayer = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(player.getUniqueId());
|
||||
GrimUser grimPlayer = GrimAPIProvider.getDirect().getGrimUser(player.getUniqueId());
|
||||
if (grimPlayer == null) return null;
|
||||
|
||||
for (Map.Entry<String, Function<GrimUser, String>> entry : GrimAPI.INSTANCE.getExternalAPI().getVariableReplacements().entrySet()) {
|
||||
for (Map.Entry<String, Function<GrimUser, String>> entry : GrimAPIProvider.getDirect().getVariableReplacements().entrySet()) {
|
||||
String key = entry.getKey().equals("%player%")
|
||||
? "player"
|
||||
: "player_" + entry.getKey().replaceAll("%", "");
|
||||
|
||||
+30
-18
@@ -1,8 +1,8 @@
|
||||
package ac.grim.grimac.platform.bukkit.utils.reflection;
|
||||
|
||||
import ac.grim.grimac.api.reflection.ReflectionUtils;
|
||||
import ac.grim.grimac.api.util.LogUtil;
|
||||
import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.reflection.ReflectionUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.Event;
|
||||
@@ -12,29 +12,41 @@ import org.bukkit.event.Listener;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class PaperUtils {
|
||||
public static final boolean PAPER = ReflectionUtils.hasClass("com.destroystokyo.paper.PaperConfig")
|
||||
|| ReflectionUtils.hasClass("io.papermc.paper.configuration.Configuration");
|
||||
|
||||
public static final boolean PAPER;
|
||||
public static final boolean TICK_END_EVENT;
|
||||
public static final boolean ASYNC_TELEPORT;
|
||||
|
||||
static {
|
||||
PAPER = ReflectionUtils.hasClass("com.destroystokyo.paper.PaperConfig") || ReflectionUtils.hasClass("io.papermc.paper.configuration.Configuration");
|
||||
TICK_END_EVENT = ReflectionUtils.hasClass("com.destroystokyo.paper.event.server.ServerTickEndEvent");
|
||||
ASYNC_TELEPORT = ReflectionUtils.hasMethod(Entity.class, "teleportAsync", org.bukkit.Location.class);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Boolean> teleportAsync(final Entity entity, final Location location) {
|
||||
return PAPER ? entity.teleportAsync(location) : CompletableFuture.completedFuture(entity.teleport(location));
|
||||
if (PAPER) {
|
||||
return entity.teleportAsync(location);
|
||||
} else {
|
||||
return CompletableFuture.completedFuture(entity.teleport(location));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static boolean registerTickEndEvent(Listener listener, Runnable runnable) {
|
||||
try {
|
||||
Class<?> clazz = ReflectionUtils.getClass("com.destroystokyo.paper.event.server.ServerTickEndEvent");
|
||||
if (clazz == null) return false;
|
||||
GrimACBukkitLoaderPlugin.LOADER.getServer().getPluginManager().registerEvent(
|
||||
(Class<? extends Event>) clazz,
|
||||
listener,
|
||||
EventPriority.NORMAL,
|
||||
(l, event) -> runnable.run(),
|
||||
GrimACBukkitLoaderPlugin.LOADER
|
||||
);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("Failed to register tick end event", e);
|
||||
if (TICK_END_EVENT) {
|
||||
try {
|
||||
Class<?> clazz = ReflectionUtils.getClass("com.destroystokyo.paper.event.server.ServerTickEndEvent");
|
||||
if (clazz == null) return false;
|
||||
GrimACBukkitLoaderPlugin.LOADER.getServer().getPluginManager().registerEvent((Class<? extends Event>) clazz,
|
||||
listener,
|
||||
EventPriority.NORMAL,
|
||||
(l, event) -> runnable.run(), GrimACBukkitLoaderPlugin.LOADER);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LogUtil.exception("Failed to register tick end event", e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
+12
-19
@@ -1,12 +1,8 @@
|
||||
package ac.grim.grimac.platform.bukkit.world;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.platform.api.Platform;
|
||||
import ac.grim.grimac.platform.api.world.PlatformChunk;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import ac.grim.grimac.api.packet.block.PacketBlockState;
|
||||
import ac.grim.grimac.api.platform.world.PlatformChunk;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.ServerVersions;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -14,25 +10,22 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class BukkitPlatformChunk implements PlatformChunk {
|
||||
private static final Map<BlockData, Integer> blockDataToId = GrimAPI.INSTANCE.getPlatform() == Platform.FOLIA ? new ConcurrentHashMap<>() : new HashMap<>();
|
||||
private static final boolean isFlat = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_13);
|
||||
private final @NotNull Chunk chunk;
|
||||
private static final Map<BlockData, Integer> blockDataToId = new HashMap<>();
|
||||
private static final boolean isFlat = ServerVersions.getServerVersion().isNewerThanOrEquals(ServerVersions.V_1_13);
|
||||
private final Chunk chunk;
|
||||
|
||||
public BukkitPlatformChunk(@NotNull Chunk chunkAt) {
|
||||
this.chunk = chunkAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockID(int x, int y, int z) {
|
||||
Block block = chunk.getBlock(x, y, z);
|
||||
|
||||
return isFlat // Cache blockDataToID because Strings are expensive
|
||||
? blockDataToId.computeIfAbsent(block.getBlockData(), data -> WrappedBlockState.getByString(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), data.getAsString(false)).getGlobalId())
|
||||
: getLegacyBlockID(block);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "deprecation", "UnstableApiUsage" })
|
||||
private static int getLegacyBlockID(@NotNull Block block) {
|
||||
return (block.getType().getId() << 4) | block.getData();
|
||||
? blockDataToId.computeIfAbsent(block.getBlockData(), data -> PacketBlockState.getByString(ServerVersions.getServerVersion().toClientVersion(), data.getAsString(false)).getGlobalId())
|
||||
: (block.getType().getId() << 4) | block.getData();
|
||||
}
|
||||
}
|
||||
+16
-19
@@ -1,43 +1,40 @@
|
||||
package ac.grim.grimac.platform.bukkit.world;
|
||||
|
||||
import ac.grim.grimac.platform.api.world.PlatformChunk;
|
||||
import ac.grim.grimac.platform.api.world.PlatformWorld;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import ac.grim.grimac.api.platform.world.PlatformChunk;
|
||||
import ac.grim.grimac.api.platform.world.PlatformWorld;
|
||||
import ac.grim.grimac.api.packet.block.PacketBlockState;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class BukkitPlatformWorld implements PlatformWorld {
|
||||
|
||||
private static final boolean LEGACY_SERVER_VERSION = PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_12_2);
|
||||
private final @NotNull World bukkitWorld;
|
||||
private final World bukkitWorld;
|
||||
|
||||
public BukkitPlatformWorld(@NotNull World world) {
|
||||
this.bukkitWorld = world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int chunkX, int chunkZ) {
|
||||
return bukkitWorld.isChunkLoaded(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public getBlockAt(int x, int y, int z) {
|
||||
// return fromBukkitBlockData(bukkitWorld.getBlockAt(x, y, z).getBlockData());
|
||||
// }
|
||||
|
||||
@Override
|
||||
public WrappedBlockState getBlockAt(int x, int y, int z) {
|
||||
if (LEGACY_SERVER_VERSION) {
|
||||
Block block = bukkitWorld.getBlockAt(x, y, z);
|
||||
@SuppressWarnings({"deprecation", "UnstableApiUsage"})
|
||||
int blockId = (block.getType().getId() << 4) | block.getData();
|
||||
return WrappedBlockState.getByGlobalId(blockId);
|
||||
} else {
|
||||
return SpigotConversionUtil.fromBukkitBlockData(bukkitWorld.getBlockAt(x, y, z).getBlockData());
|
||||
}
|
||||
public boolean isAirAt(int x, int y, int z) {
|
||||
PacketBlockState wrappedBlockState = SpigotConversionUtil.fromBukkitBlockData(bukkitWorld.getBlockData(x, y , z));
|
||||
return wrappedBlockState.getType().isAir();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
# cliff.toml - DEV BUILDS - Now with Author Info
|
||||
|
||||
[changelog]
|
||||
body = """
|
||||
## Changes in this Build (since previous push)
|
||||
{%- for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group | striptags | upper_first }}
|
||||
{%- for commit in commits %}
|
||||
- {{ commit.message | upper_first }} - *by {{ commit.author.name }}* {% if commit.breaking %}**[BREAKING]**{% endif %} \
|
||||
{%- if commit.remote and commit.remote.url -%}
|
||||
([`{{ commit.id | truncate(length=7, end="") }}`]({{ commit.remote.url }}/commit/{{- commit.id -}}))
|
||||
{%- else -%}
|
||||
(`{{ commit.id | truncate(length=7, end="") }}`)
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
"""
|
||||
trim = true
|
||||
|
||||
[git]
|
||||
# Your previous settings here are perfect, no changes needed
|
||||
filter_unconventional = false
|
||||
skip_unconventional = false
|
||||
remote = "https://github.com/GrimAnticheat/Grim"
|
||||
commit_parsers = [
|
||||
{ message = "^feat", group = "🚀 Features" },
|
||||
{ message = "^fix", group = "🐛 Fixes" },
|
||||
{ message = "^perf", group = "⚡️ Performance" },
|
||||
{ message = "^refactor", group = "♻️ Refactoring" },
|
||||
{ message = "^docs", group = "📖 Documentation" },
|
||||
{ message = "^test", group = "✅ Tests" },
|
||||
{ message = "^chore", group = "🤖 Maintenance & CI" },
|
||||
{ body = ".*BREAKING CHANGE.*", group = "🚨 Breaking Changes" },
|
||||
{ message = ".*", group = "Miscellaneous" } # CHANGED THIS LINE
|
||||
]
|
||||
commit_preprocessors = [
|
||||
{ pattern = 'src/main/java/ac/grim/grimac/checks/.*', group = "✔️ Checks" },
|
||||
{ pattern = 'src/main/java/ac/grim/grimac/api/.*', group = "🔌 API" },
|
||||
{ pattern = 'src/main/java/ac/grim/grimac/platform/.*', group = "🏗️ Platform" },
|
||||
{ pattern = 'src/main/java/ac/grim/grimac/engine/.*', group = "⚙️ Core Engine" },
|
||||
{ pattern = 'src/main/java/ac/grim/grimac/config/.*', group = "⚙️ Configuration" },
|
||||
{ pattern = 'pom.xml', group = "🤖 Maintenance & CI" },
|
||||
{ pattern = '.github/.*', group = "🤖 Maintenance & CI" },
|
||||
{ pattern = 'build.gradle.kts', group = "🤖 Maintenance & CI" },
|
||||
{ pattern = 'src/.*', group = "⚙️ Core Engine" },
|
||||
]
|
||||
sort_commits = "oldest"
|
||||
+19
-68
@@ -9,65 +9,23 @@ repositories {
|
||||
if (BuildConfig.mavenLocalOverride) {
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://repo.grim.ac/snapshots") // Grim API
|
||||
}
|
||||
filter {
|
||||
maven {
|
||||
name = "papermc"
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") // Spigot
|
||||
maven("https://repo.grim.ac/snapshots") { // Grim API
|
||||
content {
|
||||
includeGroup("ac.grim.grimac")
|
||||
includeGroup("com.github.retrooper")
|
||||
}
|
||||
}
|
||||
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://repo.viaversion.com") { // ViaVersion
|
||||
mavenContent { releasesOnly() }
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup("com.viaversion")
|
||||
}
|
||||
}
|
||||
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://nexus.scarsz.me/content/repositories/releases") { // Configuralize
|
||||
mavenContent { releasesOnly() }
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup("github.scarsz")
|
||||
}
|
||||
}
|
||||
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://repo.opencollab.dev/maven-releases/") { // Cumulus (for Floodgate)
|
||||
mavenContent { releasesOnly() }
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup("org.geysermc.api")
|
||||
}
|
||||
}
|
||||
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven("https://repo.opencollab.dev/maven-snapshots/") { // Floodgate
|
||||
mavenContent { snapshotsOnly() }
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup("org.geysermc.floodgate")
|
||||
includeGroup("org.geysermc.cumulus")
|
||||
includeModule("org.geysermc", "common")
|
||||
includeModule("org.geysermc", "geyser-parent")
|
||||
}
|
||||
}
|
||||
|
||||
mavenCentral()
|
||||
maven("https://repo.viaversion.com") // ViaVersion
|
||||
maven("https://nexus.scarsz.me/content/repositories/releases") // Configuralize
|
||||
maven("https://repo.opencollab.dev/maven-snapshots/") // Floodgate
|
||||
maven("https://repo.opencollab.dev/maven-releases/") // Cumulus (for Floodgate)
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
mavenCentral() // FastUtil
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -77,28 +35,21 @@ dependencies {
|
||||
compileOnly(libs.packetevents.api)
|
||||
}
|
||||
api(libs.cloud.core)
|
||||
api(libs.cloud.processors.requirements)
|
||||
api(libs.configuralize) {
|
||||
artifact {
|
||||
classifier = "slim"
|
||||
}
|
||||
api("org.incendo:cloud-processors-requirements:1.0.0-rc.1")
|
||||
api("github.scarsz:configuralize:1.4.1:slim") {
|
||||
exclude(group = "org.yaml", module = "snakeyaml")
|
||||
}
|
||||
// Bump snakeyaml (transitive dep of configuralize) 1.29 -> 2.2+ for geyser-fabric
|
||||
// Bump snakeyaml (transitive dep of configuralize) 1.29 -> 2.2 for geyser-fabric
|
||||
api(libs.snakeyaml)
|
||||
api(libs.fastutil)
|
||||
api(libs.adventure.text.minimessage)
|
||||
api(libs.jetbrains.annotations)
|
||||
api(libs.hikaricp)
|
||||
|
||||
api(libs.grim.api)
|
||||
|
||||
compileOnly(libs.geyser.base.api) {
|
||||
isTransitive = false // messes with guava otherwise
|
||||
}
|
||||
implementation(project(":api"))
|
||||
implementation(project(":api:packetevents"))
|
||||
|
||||
compileOnly(libs.floodgate.api)
|
||||
compileOnly(libs.viaversion)
|
||||
compileOnly(libs.via.version.api)
|
||||
compileOnly(libs.netty)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +1,39 @@
|
||||
package ac.grim.grimac;
|
||||
|
||||
import ac.grim.grimac.api.event.EventBus;
|
||||
import ac.grim.grimac.api.event.OptimizedEventBus;
|
||||
import ac.grim.grimac.api.plugin.GrimPlugin;
|
||||
import ac.grim.grimac.events.GrimExtensionManager;
|
||||
import ac.grim.grimac.events.OptimizedEventBus;
|
||||
import ac.grim.grimac.manager.AlertManagerImpl;
|
||||
import ac.grim.grimac.manager.DiscordManager;
|
||||
import ac.grim.grimac.manager.InitManager;
|
||||
import ac.grim.grimac.manager.SpectateManager;
|
||||
import ac.grim.grimac.manager.TickManager;
|
||||
import ac.grim.grimac.manager.config.BaseConfigManager;
|
||||
import ac.grim.grimac.manager.init.Initable;
|
||||
import ac.grim.grimac.manager.violationdatabase.ViolationDatabaseManager;
|
||||
import ac.grim.grimac.platform.api.Platform;
|
||||
import ac.grim.grimac.platform.api.PlatformLoader;
|
||||
import ac.grim.grimac.platform.api.PlatformServer;
|
||||
import ac.grim.grimac.platform.api.manager.ItemResetHandler;
|
||||
import ac.grim.grimac.platform.api.manager.MessagePlaceHolderManager;
|
||||
import ac.grim.grimac.platform.api.manager.CommandAdapter;
|
||||
import ac.grim.grimac.platform.api.manager.PermissionRegistrationManager;
|
||||
import ac.grim.grimac.platform.api.manager.PlatformPluginManager;
|
||||
import ac.grim.grimac.platform.api.player.PlatformPlayerFactory;
|
||||
import ac.grim.grimac.platform.api.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.platform.api.sender.Sender;
|
||||
import ac.grim.grimac.platform.api.sender.SenderFactory;
|
||||
import ac.grim.grimac.api.platform.init.Initable;
|
||||
import ac.grim.grimac.api.platform.Platform;
|
||||
import ac.grim.grimac.api.platform.PlatformLoader;
|
||||
import ac.grim.grimac.api.platform.PlatformServer;
|
||||
import ac.grim.grimac.api.platform.manager.ItemResetHandler;
|
||||
import ac.grim.grimac.api.platform.manager.MessagePlaceHolderManager;
|
||||
import ac.grim.grimac.api.platform.manager.ParserDescriptorFactory;
|
||||
import ac.grim.grimac.api.platform.manager.PermissionRegistrationManager;
|
||||
import ac.grim.grimac.api.platform.manager.PlatformPluginManager;
|
||||
import ac.grim.grimac.api.platform.player.PlatformPlayerFactory;
|
||||
import ac.grim.grimac.api.platform.scheduler.PlatformScheduler;
|
||||
import ac.grim.grimac.api.platform.sender.Sender;
|
||||
import ac.grim.grimac.api.platform.sender.SenderFactory;
|
||||
import ac.grim.grimac.utils.anticheat.PlayerDataManager;
|
||||
import ac.grim.grimac.utils.common.arguments.CommonGrimArguments;
|
||||
import ac.grim.grimac.utils.reflection.ReflectionUtils;
|
||||
import ac.grim.grimac.api.reflection.ReflectionUtils;
|
||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
||||
import lombok.Getter;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public final class GrimAPI {
|
||||
public static final GrimAPI INSTANCE = new GrimAPI();
|
||||
public final static GrimAPI INSTANCE = new GrimAPI();
|
||||
|
||||
@Getter
|
||||
private final Platform platform = detectPlatform();
|
||||
@@ -44,41 +43,43 @@ public final class GrimAPI {
|
||||
private final DiscordManager discordManager;
|
||||
private final PlayerDataManager playerDataManager;
|
||||
private final TickManager tickManager;
|
||||
private final GrimExtensionManager extensionManager;
|
||||
private final EventBus eventBus;
|
||||
private final GrimExternalAPI externalAPI;
|
||||
private ViolationDatabaseManager violationDatabaseManager;
|
||||
private PlatformLoader loader;
|
||||
@Getter
|
||||
private InitManager initManager;
|
||||
private boolean initialized = false;
|
||||
|
||||
private GrimAPI() {
|
||||
public GrimAPI() {
|
||||
this.configManager = new BaseConfigManager();
|
||||
this.alertManager = new AlertManagerImpl();
|
||||
this.spectateManager = new SpectateManager();
|
||||
this.discordManager = new DiscordManager();
|
||||
this.playerDataManager = new PlayerDataManager();
|
||||
this.alertManager = new AlertManagerImpl(this);
|
||||
this.spectateManager = new SpectateManager(this);
|
||||
this.discordManager = new DiscordManager(this);
|
||||
this.playerDataManager = new PlayerDataManager(this);
|
||||
this.tickManager = new TickManager();
|
||||
this.extensionManager = new GrimExtensionManager();
|
||||
this.eventBus = new OptimizedEventBus(extensionManager);
|
||||
this.eventBus = new OptimizedEventBus();
|
||||
this.externalAPI = new GrimExternalAPI(this);
|
||||
System.out.println("GrimAPI classloader: " + GrimAPI.class.getClassLoader());
|
||||
System.out.println("GrimAPI instance: " + this);
|
||||
}
|
||||
|
||||
// the order matters
|
||||
private static Platform detectPlatform() {
|
||||
Platform override = CommonGrimArguments.PLATFORM_OVERRIDE.value();
|
||||
if (override != null) return override;
|
||||
if (ReflectionUtils.hasClass("io.papermc.paper.threadedregions.RegionizedServer")) return Platform.FOLIA;
|
||||
if (ReflectionUtils.hasClass("org.bukkit.Bukkit")) return Platform.BUKKIT;
|
||||
if (ReflectionUtils.hasClass("net.fabricmc.loader.api.FabricLoader")) return Platform.FABRIC;
|
||||
throw new IllegalStateException("Unknown platform!");
|
||||
final Map<String, Platform> platforms = Map.of(
|
||||
"io.papermc.paper.threadedregions.RegionizedServer", Platform.FOLIA,
|
||||
"org.bukkit.Bukkit", Platform.BUKKIT,
|
||||
"net.fabricmc.loader.api.FabricLoader", Platform.FABRIC
|
||||
);
|
||||
|
||||
return platforms.entrySet().stream()
|
||||
.filter(entry -> ReflectionUtils.hasClass(entry.getKey()))
|
||||
.map(Map.Entry::getValue)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("Unknown platform!"));
|
||||
}
|
||||
|
||||
public void load(PlatformLoader platformLoader, Initable... platformSpecificInitables) {
|
||||
public void bootstrap(@NotNull PlatformLoader platformLoader, Initable... platformSpecificInitables) {
|
||||
this.loader = platformLoader;
|
||||
this.violationDatabaseManager = new ViolationDatabaseManager(getGrimPlugin());
|
||||
this.initManager = new InitManager(loader.getPacketEvents(), loader::getCommandManager, platformSpecificInitables);
|
||||
this.initManager = new InitManager((PacketEventsAPI<?>) loader.getPacketAPI(), loader::getCommandManager, platformSpecificInitables);
|
||||
this.initManager.load();
|
||||
this.initialized = true;
|
||||
}
|
||||
@@ -101,8 +102,8 @@ public final class GrimAPI {
|
||||
return loader.getPlatformPlayerFactory();
|
||||
}
|
||||
|
||||
public CommandAdapter getCommandAdapter() {
|
||||
return loader.getCommandAdapter();
|
||||
public ParserDescriptorFactory getParserDescriptors() {
|
||||
return loader.getParserDescriptorFactory();
|
||||
}
|
||||
|
||||
public GrimPlugin getGrimPlugin() {
|
||||
@@ -143,7 +144,4 @@ public final class GrimAPI {
|
||||
return loader.getPermissionManager();
|
||||
}
|
||||
|
||||
public GrimExtensionManager getExtensionManager() {
|
||||
return extensionManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package ac.grim.grimac;
|
||||
|
||||
import ac.grim.grimac.api.platform.CoreLoader;
|
||||
import ac.grim.grimac.api.platform.PlatformLoader;
|
||||
import ac.grim.grimac.api.platform.init.Initable;
|
||||
|
||||
/**
|
||||
* Service-loader entry that just forwards every call to the
|
||||
* canonical singleton GrimAPI.INSTANCE.
|
||||
* Ensures that ServiceLoader call to clazz.getDeclaredConstructor().newInstance(); will not create two instances
|
||||
*/
|
||||
public final class GrimAPICoreLoader implements CoreLoader {
|
||||
|
||||
@Override
|
||||
public void bootstrap(PlatformLoader platform, Initable... initables) {
|
||||
GrimAPI.INSTANCE.bootstrap(platform, initables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
GrimAPI.INSTANCE.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
GrimAPI.INSTANCE.stop();
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,27 @@
|
||||
package ac.grim.grimac;
|
||||
|
||||
import ac.grim.grimac.api.GrimAbstractAPI;
|
||||
import ac.grim.grimac.api.platform.Platform;
|
||||
import ac.grim.grimac.api.platform.PlatformLoader;
|
||||
import ac.grim.grimac.api.platform.init.LoadableInitable;
|
||||
import ac.grim.grimac.api.plugin.GrimPluginDescription;
|
||||
import ac.grim.grimac.api.GrimUser;
|
||||
import ac.grim.grimac.api.alerts.AlertManager;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.api.event.EventBus;
|
||||
import ac.grim.grimac.api.event.events.GrimReloadEvent;
|
||||
import ac.grim.grimac.manager.config.ConfigManagerFileImpl;
|
||||
import ac.grim.grimac.manager.init.start.StartableInitable;
|
||||
import ac.grim.grimac.api.platform.init.StartableInitable;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.anticheat.MessageUtil;
|
||||
import ac.grim.grimac.api.util.LogUtil;
|
||||
import ac.grim.grimac.api.util.ChatUtil;
|
||||
import ac.grim.grimac.utils.common.ConfigReloadObserver;
|
||||
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -24,7 +30,7 @@ import java.util.function.Function;
|
||||
|
||||
//This is used for grim's external API. It has its own class just for organization.
|
||||
|
||||
public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, StartableInitable {
|
||||
public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, StartableInitable, LoadableInitable {
|
||||
|
||||
private final GrimAPI api;
|
||||
@Getter
|
||||
@@ -32,16 +38,17 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
@Getter
|
||||
private final Map<String, String> staticReplacements = new ConcurrentHashMap<>();
|
||||
private final Map<String, Function<Object, Object>> functions = new ConcurrentHashMap<>();
|
||||
private final ConfigManagerFileImpl configManagerFile = new ConfigManagerFileImpl();
|
||||
private final ConfigManagerFileImpl configManagerFile;
|
||||
private ConfigManager configManager = null;
|
||||
private boolean started = false;
|
||||
|
||||
public GrimExternalAPI(GrimAPI api) {
|
||||
this.api = api;
|
||||
this.configManagerFile = new ConfigManagerFileImpl(api);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull EventBus getEventBus() {
|
||||
public @NonNull EventBus getEventBus() {
|
||||
return api.getEventBus();
|
||||
}
|
||||
|
||||
@@ -50,6 +57,11 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
return api.getPlayerDataManager().getPlayer(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GrimUser> getGrimUsers() {
|
||||
return (Collection) api.getPlayerDataManager().getEntries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerVariable(String string, Function<GrimUser, String> replacement) {
|
||||
if (replacement == null) {
|
||||
@@ -70,7 +82,8 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
|
||||
@Override
|
||||
public String getGrimVersion() {
|
||||
return api.getGrimPlugin().getDescription().getVersion();
|
||||
GrimPluginDescription description = api.getGrimPlugin().getDescription();
|
||||
return description.getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -89,7 +102,7 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
|
||||
@Override
|
||||
public AlertManager getAlertManager() {
|
||||
return GrimAPI.INSTANCE.getAlertManager();
|
||||
return api.getAlertManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,13 +117,23 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
|
||||
@Override
|
||||
public int getCurrentTick() {
|
||||
return GrimAPI.INSTANCE.getTickManager().currentTick;
|
||||
return api.getTickManager().currentTick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlatformLoader getPlatformLoader() {
|
||||
return api.getLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Platform getPlatform() {
|
||||
return api.getPlatform();
|
||||
}
|
||||
|
||||
// on load, load the config & register the service
|
||||
public void load() {
|
||||
reload(configManagerFile);
|
||||
api.getLoader().registerAPIService();
|
||||
api.getLoader().registerAPIService(this);
|
||||
}
|
||||
|
||||
// handles any config loading that's needed to be done after load
|
||||
@@ -118,16 +141,16 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
public void start() {
|
||||
started = true;
|
||||
try {
|
||||
GrimAPI.INSTANCE.getConfigManager().start();
|
||||
api.getConfigManager().start();
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("Failed to start config manager.", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(ConfigManager config) {
|
||||
if (config.isLoadedAsync() && started) {
|
||||
GrimAPI.INSTANCE.getScheduler().getAsyncScheduler().runNow(GrimAPI.INSTANCE.getGrimPlugin(),
|
||||
api.getScheduler().getAsyncScheduler().runNow(api.getGrimPlugin(),
|
||||
() -> successfulReload(config));
|
||||
} else {
|
||||
successfulReload(config);
|
||||
@@ -138,7 +161,7 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
public CompletableFuture<Boolean> reloadAsync(ConfigManager config) {
|
||||
if (config.isLoadedAsync() && started) {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
GrimAPI.INSTANCE.getScheduler().getAsyncScheduler().runNow(GrimAPI.INSTANCE.getGrimPlugin(),
|
||||
api.getScheduler().getAsyncScheduler().runNow(api.getGrimPlugin(),
|
||||
() -> future.complete(successfulReload(config)));
|
||||
return future;
|
||||
}
|
||||
@@ -148,19 +171,19 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
private boolean successfulReload(ConfigManager config) {
|
||||
try {
|
||||
config.reload();
|
||||
GrimAPI.INSTANCE.getConfigManager().load(config);
|
||||
if (started) GrimAPI.INSTANCE.getConfigManager().start();
|
||||
api.getConfigManager().load(config);
|
||||
if (started) api.getConfigManager().start();
|
||||
onReload(config);
|
||||
if (started)
|
||||
GrimAPI.INSTANCE.getScheduler().getAsyncScheduler().runNow(GrimAPI.INSTANCE.getGrimPlugin(),
|
||||
() -> GrimAPI.INSTANCE.getEventBus().post(new GrimReloadEvent(true)));
|
||||
api.getScheduler().getAsyncScheduler().runNow(api.getGrimPlugin(),
|
||||
() -> api.getEventBus().post(new GrimReloadEvent(true)));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("Failed to reload config", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (started)
|
||||
GrimAPI.INSTANCE.getScheduler().getAsyncScheduler().runNow(GrimAPI.INSTANCE.getGrimPlugin(),
|
||||
() -> GrimAPI.INSTANCE.getEventBus().post(new GrimReloadEvent(false)));
|
||||
api.getScheduler().getAsyncScheduler().runNow(api.getGrimPlugin(),
|
||||
() -> api.getEventBus().post(new GrimReloadEvent(false)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -175,15 +198,17 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
// Update variables
|
||||
updateVariables();
|
||||
// Restart
|
||||
GrimAPI.INSTANCE.getAlertManager().reload(configManager);
|
||||
GrimAPI.INSTANCE.getDiscordManager().reload();
|
||||
GrimAPI.INSTANCE.getSpectateManager().reload();
|
||||
GrimAPI.INSTANCE.getViolationDatabaseManager().reload();
|
||||
api.getAlertManager().reload(configManager);
|
||||
api.getDiscordManager().reload();
|
||||
api.getSpectateManager().reload();
|
||||
// Don't reload players if the plugin hasn't started yet
|
||||
if (!started) return;
|
||||
// Reload checks for all players
|
||||
for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
player.runSafely(() -> player.reload(configManager));
|
||||
for (GrimPlayer grimPlayer : api.getPlayerDataManager().getEntries()) {
|
||||
ChannelHelper.runInEventLoop(grimPlayer.user.getChannel(), () -> {
|
||||
grimPlayer.updatePermissions();
|
||||
grimPlayer.reload(configManager);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,10 +220,10 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, S
|
||||
variableReplacements.putIfAbsent("%h_sensitivity%", user -> ((int) Math.round(user.getHorizontalSensitivity() * 200)) + "");
|
||||
variableReplacements.putIfAbsent("%v_sensitivity%", user -> ((int) Math.round(user.getVerticalSensitivity() * 200)) + "");
|
||||
variableReplacements.putIfAbsent("%fast_math%", user -> !user.isVanillaMath() + "");
|
||||
variableReplacements.putIfAbsent("%tps%", user -> String.format("%.2f", GrimAPI.INSTANCE.getPlatformServer().getTPS()));
|
||||
variableReplacements.putIfAbsent("%tps%", user -> String.format("%.2f", api.getPlatformServer().getTPS()));
|
||||
variableReplacements.putIfAbsent("%version%", GrimUser::getVersionName);
|
||||
// static variables
|
||||
staticReplacements.put("%prefix%", MessageUtil.translateAlternateColorCodes('&', GrimAPI.INSTANCE.getConfigManager().getPrefix()));
|
||||
staticReplacements.put("%prefix%", ChatUtil.translateAlternateColorCodes('&', api.getConfigManager().getPrefix()));
|
||||
staticReplacements.putIfAbsent("%grim_version%", getGrimVersion());
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,19 @@ import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.api.event.events.FlagEvent;
|
||||
import ac.grim.grimac.api.packet.MCPacket;
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.api.packet.types.PacketType;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.PacketWrapperFactory;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientPlayerFlyingMetaPacket;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying.isFlying;
|
||||
|
||||
// Class from https://github.com/Tecnio/AntiCheatBase/blob/master/src/main/java/me/tecnio/anticheat/check/Check.java
|
||||
@Getter
|
||||
public class Check extends GrimProcessor implements AbstractCheck {
|
||||
@@ -39,6 +40,8 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
private boolean noModifyPacketPermission;
|
||||
private long lastViolationTime;
|
||||
|
||||
protected PacketWrapperFactory packetFactory = MCPacket.getAPI().packetFactory();
|
||||
|
||||
public Check(final @NotNull GrimPlayer player) {
|
||||
this.player = Objects.requireNonNull(player);
|
||||
|
||||
@@ -63,12 +66,19 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
return isEnabled && !player.disableGrim && !player.noModifyPacketPermission && !exemptPermission;
|
||||
}
|
||||
|
||||
public final void updatePermissions() {
|
||||
if (configName == null || player.platformPlayer == null) return;
|
||||
final String id = configName.toLowerCase();
|
||||
exemptPermission = player.platformPlayer.hasPermission("grim.exempt." + id);
|
||||
noSetbackPermission = player.platformPlayer.hasPermission("grim.nosetback." + id);
|
||||
noModifyPacketPermission = player.platformPlayer.hasPermission("grim.nomodifypacket." + id);
|
||||
public void updatePermissions() {
|
||||
if (player.platformPlayer == null || configName == null) return;
|
||||
GrimAPI.INSTANCE.getScheduler().getEntityScheduler().run(
|
||||
player.platformPlayer,
|
||||
GrimAPI.INSTANCE.getGrimPlugin(),
|
||||
() -> {
|
||||
final String id = configName.toLowerCase();
|
||||
exemptPermission = player.platformPlayer.hasPermission("grim.exempt." + id);
|
||||
noSetbackPermission = player.platformPlayer.hasPermission("grim.nosetback." + id);
|
||||
noModifyPacketPermission = player.platformPlayer.hasPermission("grim.nomodifypacket." + id);
|
||||
},
|
||||
() -> {}
|
||||
);
|
||||
}
|
||||
|
||||
public final boolean flagAndAlert(String verbose) {
|
||||
@@ -96,7 +106,7 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
if (event.isCancelled()) return false;
|
||||
|
||||
player.punishmentManager.handleViolation(this);
|
||||
lastViolationTime = player.now();
|
||||
lastViolationTime = System.currentTimeMillis();
|
||||
violations++;
|
||||
return true;
|
||||
}
|
||||
@@ -130,13 +140,14 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void reload(ConfigManager configuration) {
|
||||
public void reload(ConfigManager configuration) {
|
||||
decay = configuration.getDoubleElse(configName + ".decay", decay);
|
||||
setbackVL = configuration.getDoubleElse(configName + ".setbackvl", setbackVL);
|
||||
displayName = configuration.getStringElse(configName + ".displayname", checkName);
|
||||
description = configuration.getStringElse(configName + ".description", description);
|
||||
|
||||
if (setbackVL == -1) setbackVL = Double.MAX_VALUE;
|
||||
updatePermissions();
|
||||
onReload(configuration);
|
||||
}
|
||||
|
||||
@@ -164,23 +175,22 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
return offset > 0.001 ? String.format("%.5f", offset) : String.format("%.2E", offset);
|
||||
}
|
||||
|
||||
public static boolean isTransaction(PacketTypeCommon packetType) {
|
||||
return packetType == PacketType.Play.Client.PONG ||
|
||||
packetType == PacketType.Play.Client.WINDOW_CONFIRMATION;
|
||||
public boolean isTransaction(PacketType packetType) {
|
||||
return packetType == PacketTypes.Play.Client.PONG ||
|
||||
packetType == PacketTypes.Play.Client.WINDOW_CONFIRMATION;
|
||||
}
|
||||
|
||||
public static boolean isAsync(PacketTypeCommon packetType) {
|
||||
return packetType == PacketType.Play.Client.KEEP_ALIVE
|
||||
|| packetType == PacketType.Play.Client.CHUNK_BATCH_ACK;
|
||||
public boolean isFlying(PacketType type) {
|
||||
return ClientPlayerFlyingMetaPacket.isFlying(type);
|
||||
}
|
||||
|
||||
public boolean isUpdate(PacketTypeCommon packetType) {
|
||||
public boolean isUpdate(PacketType packetType) {
|
||||
return isFlying(packetType)
|
||||
|| packetType == PacketType.Play.Client.CLIENT_TICK_END
|
||||
|| packetType == PacketTypes.Play.Client.CLIENT_TICK_END
|
||||
|| isTransaction(packetType);
|
||||
}
|
||||
|
||||
public boolean isTickPacket(PacketTypeCommon packetType) {
|
||||
public boolean isTickPacket(PacketType packetType) {
|
||||
if (isTickPacketIncludingNonMovement(packetType)) {
|
||||
if (isFlying(packetType)) {
|
||||
return !player.packetStateData.lastPacketWasTeleport && !player.packetStateData.lastPacketWasOnePointSeventeenDuplicate;
|
||||
@@ -190,12 +200,12 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isTickPacketIncludingNonMovement(PacketTypeCommon packetType) {
|
||||
public boolean isTickPacketIncludingNonMovement(PacketType packetType) {
|
||||
// On 1.21.2+ fall back to the TICK_END packet IF the player did not send a movement packet for their tick
|
||||
// TickTimer checks to see if player did not send a tick end packet before new flying packet is sent
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21_2)
|
||||
if (player.getClientVersion().isNewerThanOrEquals(PacketClientVersions.V_1_21_2)
|
||||
&& !player.packetStateData.didSendMovementBeforeTickEnd) {
|
||||
if (packetType == PacketType.Play.Client.CLIENT_TICK_END) {
|
||||
if (packetType == PacketTypes.Play.Client.CLIENT_TICK_END) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -203,4 +213,6 @@ public class Check extends GrimProcessor implements AbstractCheck {
|
||||
return isFlying(packetType);
|
||||
}
|
||||
|
||||
|
||||
public static final PacketType[] POSSIBLE_TICK_PACKET_TYPES = new PacketType[]{PacketTypes.Play.Client.CLIENT_TICK_END, PacketTypes.Play.Client.PLAYER_FLYING, PacketTypes.Play.Client.PLAYER_POSITION, PacketTypes.Play.Client.PLAYER_ROTATION, PacketTypes.Play.Client.PLAYER_POSITION_AND_ROTATION};
|
||||
}
|
||||
@@ -4,8 +4,16 @@ import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
|
||||
public abstract class AbstractDebugHandler extends Check {
|
||||
public AbstractDebugHandler(GrimPlayer player) {
|
||||
super(player);
|
||||
|
||||
protected final GrimPlayer grimPlayer;
|
||||
|
||||
public AbstractDebugHandler(GrimPlayer grimPlayer) {
|
||||
super(grimPlayer);
|
||||
this.grimPlayer = grimPlayer;
|
||||
}
|
||||
|
||||
public GrimPlayer getPlayer() {
|
||||
return grimPlayer;
|
||||
}
|
||||
|
||||
public abstract void toggleListener(GrimPlayer player);
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package ac.grim.grimac.checks.debug;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DebugGrimPlayer extends GrimPlayer {
|
||||
|
||||
private static final long THRESHOLD_NANO = 200_000_000L; // 200ms
|
||||
private static final long THRESHOLD_MILLIS = 200;
|
||||
|
||||
// Global Offsets: Volatile so all threads see the pause adjustment immediately.
|
||||
// When the Netty thread pauses for 60s, it updates this.
|
||||
// The Scheduler thread sees the update and "stops" the timeout check.
|
||||
private volatile long offsetNano = 0;
|
||||
private volatile long offsetMillis = 0;
|
||||
|
||||
// ThreadLocal: Each thread tracks its OWN execution time.
|
||||
// This prevents the Scheduler Thread (pollData) from resetting the timer
|
||||
// while the Netty Thread is sitting at a breakpoint.
|
||||
private final ThreadLocal<Long> packetStartNano = ThreadLocal.withInitial(System::nanoTime);
|
||||
private final ThreadLocal<Long> packetStartMillis = ThreadLocal.withInitial(System::currentTimeMillis);
|
||||
|
||||
public DebugGrimPlayer(@NotNull User user) {
|
||||
super(user, System.currentTimeMillis(), System.nanoTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processingPacket() {
|
||||
// Reset the timer ONLY for the current thread (Netty or Scheduler)
|
||||
this.packetStartNano.set(System.nanoTime());
|
||||
this.packetStartMillis.set(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nano() {
|
||||
// SAFETY CHECK:
|
||||
// If something in the parent constructor calls nano() BEFORE we are fully initialized,
|
||||
// packetStartNano will be null. We must fallback to System time to prevent NPE.
|
||||
if (packetStartNano == null) return System.nanoTime();
|
||||
|
||||
long sysTime = System.nanoTime();
|
||||
|
||||
// 1. Get start time for THIS thread
|
||||
long start = packetStartNano.get();
|
||||
long executionTime = sysTime - start;
|
||||
|
||||
// 2. Check if THIS thread was paused/stuck
|
||||
if (executionTime > THRESHOLD_NANO) {
|
||||
// Update the global offset so ALL threads know to skip this time
|
||||
synchronized (this) {
|
||||
offsetNano += executionTime;
|
||||
}
|
||||
// Reset this thread's timer so we don't loop
|
||||
packetStartNano.set(sysTime);
|
||||
} else if (executionTime < 0) {
|
||||
// Self-healing for rare thread-local init edge cases or system clock jumps
|
||||
packetStartNano.set(sysTime);
|
||||
}
|
||||
|
||||
// 3. Return System Time minus the Global Pause Offset
|
||||
return sysTime - offsetNano;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long now() {
|
||||
if (packetStartMillis == null) return System.currentTimeMillis();
|
||||
|
||||
long sysTime = System.currentTimeMillis();
|
||||
long start = packetStartMillis.get();
|
||||
long executionTime = sysTime - start;
|
||||
|
||||
if (executionTime > THRESHOLD_MILLIS) {
|
||||
synchronized (this) {
|
||||
offsetMillis += executionTime;
|
||||
}
|
||||
packetStartMillis.set(sysTime);
|
||||
}
|
||||
|
||||
return sysTime - offsetMillis;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package ac.grim.grimac.checks.debug;
|
||||
|
||||
import ac.grim.grimac.utils.common.arguments.CommonGrimArguments;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
public class GrimDebugSettings {
|
||||
|
||||
public static boolean shouldEnable() {
|
||||
// 1. If the argument is disabled, never enable debug mode.
|
||||
if (!CommonGrimArguments.DEBUG_BREAKPOINT_MODE.value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Check for Debugger (Startup Agent OR Dynamic Attach)
|
||||
return isDebuggerAttached();
|
||||
}
|
||||
|
||||
private static boolean isDebuggerAttached() {
|
||||
// Fast Path: Check startup arguments for -agentlib:jdwp
|
||||
if (ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("jdwp")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Slow Path (Dynamic Attach): Scan threads for JDWP/Signal Dispatcher
|
||||
try {
|
||||
for (Thread t : Thread.getAllStackTraces().keySet()) {
|
||||
String name = t.getName();
|
||||
if (name.contains("JDWP")) return true;
|
||||
}
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import ac.grim.grimac.utils.anticheat.update.RotationUpdate;
|
||||
|
||||
@CheckData(name = "AimDuplicateLook")
|
||||
public class AimDuplicateLook extends Check implements RotationCheck {
|
||||
private boolean exempt;
|
||||
boolean exempt = false;
|
||||
|
||||
public AimDuplicateLook(GrimPlayer playerData) {
|
||||
super(playerData);
|
||||
|
||||
@@ -28,7 +28,7 @@ public class AimModulo360 extends Check implements RotationCheck {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.yaw < 360 && player.yaw > -360 && Math.abs(rotationUpdate.getDeltaXRot()) > 320 && Math.abs(lastDeltaYaw) < 30) {
|
||||
if (player.xRot < 360 && player.xRot > -360 && Math.abs(rotationUpdate.getDeltaXRot()) > 320 && Math.abs(lastDeltaYaw) < 30) {
|
||||
flagAndAlert();
|
||||
} else {
|
||||
reward();
|
||||
|
||||
@@ -8,6 +8,7 @@ import ac.grim.grimac.utils.data.Pair;
|
||||
import ac.grim.grimac.utils.lists.RunningMode;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
|
||||
|
||||
public class AimProcessor extends Check implements RotationCheck {
|
||||
|
||||
private static final int SIGNIFICANT_SAMPLES_THRESHOLD = 15;
|
||||
@@ -18,10 +19,10 @@ public class AimProcessor extends Check implements RotationCheck {
|
||||
public double divisorY;
|
||||
public double modeX, modeY;
|
||||
public double deltaDotsX, deltaDotsY;
|
||||
private final RunningMode xRotMode = new RunningMode(TOTAL_SAMPLES_THRESHOLD);
|
||||
private final RunningMode yRotMode = new RunningMode(TOTAL_SAMPLES_THRESHOLD);
|
||||
private float lastXRot;
|
||||
private float lastYRot;
|
||||
RunningMode xRotMode = new RunningMode(TOTAL_SAMPLES_THRESHOLD);
|
||||
RunningMode yRotMode = new RunningMode(TOTAL_SAMPLES_THRESHOLD);
|
||||
float lastXRot;
|
||||
float lastYRot;
|
||||
|
||||
public AimProcessor(GrimPlayer playerData) {
|
||||
super(playerData);
|
||||
@@ -37,6 +38,7 @@ public class AimProcessor extends Check implements RotationCheck {
|
||||
public void process(final RotationUpdate rotationUpdate) {
|
||||
rotationUpdate.setProcessor(this);
|
||||
|
||||
|
||||
float deltaXRot = rotationUpdate.getDeltaXRotABS();
|
||||
|
||||
this.divisorX = GrimMath.gcd(deltaXRot, lastXRot);
|
||||
@@ -45,6 +47,7 @@ public class AimProcessor extends Check implements RotationCheck {
|
||||
this.lastXRot = deltaXRot;
|
||||
}
|
||||
|
||||
|
||||
float deltaYRot = rotationUpdate.getDeltaYRotABS();
|
||||
|
||||
this.divisorY = GrimMath.gcd(deltaYRot, lastYRot);
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientHeldItemChange;
|
||||
|
||||
@CheckData(name = "BadPacketsA", description = "Sent duplicate slot id")
|
||||
public class BadPacketsA extends Check implements PacketCheck {
|
||||
private int lastSlot = -1;
|
||||
int lastSlot = -1;
|
||||
|
||||
public BadPacketsA(final GrimPlayer player) {
|
||||
super(player);
|
||||
@@ -18,8 +17,8 @@ public class BadPacketsA extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_CHANGE) {
|
||||
final int slot = new WrapperPlayClientHeldItemChange(event).getSlot();
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.HELD_ITEM_CHANGE) {
|
||||
final int slot = packetFactory.clientHeldItemChange(event).getSlot();
|
||||
|
||||
if (slot == lastSlot && flagAndAlert("slot=" + slot) && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
|
||||
@CheckData(name = "BadPacketsB", description = "Ignored set rotation packet")
|
||||
public class BadPacketsB extends Check implements PacketCheck {
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.player.enums.GameMode;
|
||||
|
||||
@CheckData(name = "BadPacketsC", description = "Interacted with self")
|
||||
public class BadPacketsC extends Check implements PacketCheck {
|
||||
@@ -17,9 +16,9 @@ public class BadPacketsC extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.INTERACT_ENTITY) {
|
||||
if (player.gamemode == GameMode.SPECTATOR) return;
|
||||
if (new WrapperPlayClientInteractEntity(event).getEntityId() == player.entityID) {
|
||||
if (packetFactory.clientInteractEntity(event).getEntityId() == player.entityID) {
|
||||
// Instant ban
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientPlayerFlyingMetaPacket;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
|
||||
@CheckData(name = "BadPacketsD", description = "Impossible pitch")
|
||||
public class BadPacketsD extends Check implements PacketCheck {
|
||||
@@ -18,17 +18,19 @@ public class BadPacketsD extends Check implements PacketCheck {
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (player.packetStateData.lastPacketWasTeleport) return;
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_ROTATION || event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION) {
|
||||
final float pitch = new WrapperPlayClientPlayerFlying(event).getLocation().getPitch();
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.PLAYER_ROTATION || event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION_AND_ROTATION) {
|
||||
final float pitch = ClientPlayerFlyingMetaPacket.from(event).getLocation().getPitch();
|
||||
if (pitch > 90 || pitch < -90) {
|
||||
// Ban.
|
||||
if (flagAndAlert("pitch=" + pitch) && shouldModifyPackets()) {
|
||||
// prevent other checks from using an invalid pitch
|
||||
if (player.pitch > 90) player.pitch = 90;
|
||||
if (player.pitch < -90) player.pitch = -90;
|
||||
if (flagAndAlert("pitch=" + pitch)) {
|
||||
if (shouldModifyPackets()) {
|
||||
// prevent other checks from using an invalid pitch
|
||||
if (player.yRot > 90) player.yRot = 90;
|
||||
if (player.yRot < -90) player.yRot = -90;
|
||||
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.ServerVersions;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
@CheckData(name = "BadPacketsE")
|
||||
public class BadPacketsE extends Check implements PacketCheck {
|
||||
private int noReminderTicks;
|
||||
private final int maxNoReminderTicks = player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) ? 20 : 19;
|
||||
private final boolean isViaPleaseStopUsingProtocolHacksOnYourServer = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21_2) || PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2);
|
||||
|
||||
public BadPacketsE(GrimPlayer player) {
|
||||
super(player);
|
||||
@@ -23,17 +19,20 @@ public class BadPacketsE extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION ||
|
||||
event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION) {
|
||||
final boolean isViaPleaseStopUsingProtocolHacksOnYourServer = player.getClientVersion().isNewerThanOrEquals(PacketClientVersions.V_1_21_2) || ServerVersions.getServerVersion().isNewerThanOrEquals(ServerVersions.V_1_21_2);
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION_AND_ROTATION ||
|
||||
event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION) {
|
||||
noReminderTicks = 0;
|
||||
} else if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
if (++noReminderTicks > maxNoReminderTicks) {
|
||||
flagAndAlert("ticks=" + noReminderTicks);
|
||||
}
|
||||
} else if (event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE
|
||||
} else if (isFlying(event.getPacketType()) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
noReminderTicks++;
|
||||
} else if (event.getPacketType() == PacketTypes.Play.Client.STEER_VEHICLE
|
||||
|| (isViaPleaseStopUsingProtocolHacksOnYourServer && player.inVehicle())) {
|
||||
noReminderTicks = 0; // Exempt vehicles
|
||||
}
|
||||
|
||||
if (noReminderTicks > 20) {
|
||||
flagAndAlert("ticks=" + noReminderTicks); // ban? I don't know how this would false
|
||||
}
|
||||
}
|
||||
|
||||
public void handleRespawn() {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientEntityActionPacket;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
|
||||
@CheckData(name = "BadPacketsF", description = "Sent duplicate sprinting status")
|
||||
public class BadPacketsF extends Check implements PacketCheck {
|
||||
@@ -19,10 +19,10 @@ public class BadPacketsF extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
WrapperPlayClientEntityAction packet = new WrapperPlayClientEntityAction(event);
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.ENTITY_ACTION) {
|
||||
ClientEntityActionPacket packet = packetFactory.clientEntityAction(event);
|
||||
|
||||
if (packet.getAction() == WrapperPlayClientEntityAction.Action.START_SPRINTING) {
|
||||
if (packet.getAction() == ClientEntityActionPacket.Action.START_SPRINTING) {
|
||||
if (lastSprinting) {
|
||||
if (exemptNext) {
|
||||
exemptNext = false;
|
||||
@@ -35,7 +35,7 @@ public class BadPacketsF extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
lastSprinting = true;
|
||||
} else if (packet.getAction() == WrapperPlayClientEntityAction.Action.STOP_SPRINTING) {
|
||||
} else if (packet.getAction() == ClientEntityActionPacket.Action.STOP_SPRINTING) {
|
||||
if (!lastSprinting) {
|
||||
if (exemptNext) {
|
||||
exemptNext = false;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientEntityActionPacket;
|
||||
|
||||
@CheckData(name = "BadPacketsG", description = "Sent duplicate sneaking status")
|
||||
public class BadPacketsG extends Check implements PacketCheck {
|
||||
@@ -18,10 +18,10 @@ public class BadPacketsG extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
WrapperPlayClientEntityAction packet = new WrapperPlayClientEntityAction(event);
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.ENTITY_ACTION) {
|
||||
ClientEntityActionPacket packet = packetFactory.clientEntityAction(event);
|
||||
|
||||
if (packet.getAction() == WrapperPlayClientEntityAction.Action.START_SNEAKING) {
|
||||
if (packet.getAction() == ClientEntityActionPacket.Action.START_SNEAKING) {
|
||||
// The player may send two START_SNEAKING packets if they respawned
|
||||
if (lastSneaking && !respawn) {
|
||||
if (flagAndAlert("state=true") && shouldModifyPackets()) {
|
||||
@@ -32,7 +32,7 @@ public class BadPacketsG extends Check implements PacketCheck {
|
||||
lastSneaking = true;
|
||||
}
|
||||
respawn = false;
|
||||
} else if (packet.getAction() == WrapperPlayClientEntityAction.Action.STOP_SNEAKING) {
|
||||
} else if (packet.getAction() == ClientEntityActionPacket.Action.STOP_SNEAKING) {
|
||||
if (!lastSneaking && !respawn) {
|
||||
if (flagAndAlert("state=false") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.BlockPlaceCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockBreak;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUseItem;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.ServerVersions;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
|
||||
@CheckData(name = "BadPacketsH", description = "Sent unexpected sequence id", experimental = true)
|
||||
public class BadPacketsH extends BlockPlaceCheck {
|
||||
private int lastSequence;
|
||||
private final boolean isSupportedVersion = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_19) && PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_19);
|
||||
private final boolean isSupportedVersion = player.getClientVersion().isNewerThanOrEquals(PacketClientVersions.V_1_19) && ServerVersions.getServerVersion().isNewerThanOrEquals(ServerVersions.V_1_19);
|
||||
|
||||
public BadPacketsH(final GrimPlayer player) {
|
||||
super(player);
|
||||
@@ -23,8 +21,8 @@ public class BadPacketsH extends BlockPlaceCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.USE_ITEM
|
||||
&& shouldCancel(new WrapperPlayClientUseItem(event).getSequence())) {
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.USE_ITEM
|
||||
&& shouldCancel(packetFactory.clientPlayerUseItem(event).getSequence())) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
@@ -54,11 +52,15 @@ public class BadPacketsH extends BlockPlaceCheck {
|
||||
}
|
||||
|
||||
public boolean shouldCancel(int sequence) {
|
||||
int expected = lastSequence + 1;
|
||||
if (isSupportedVersion && sequence != lastSequence + 1) {
|
||||
if (flagAndAlert("expected=" + (lastSequence + 1) + ", id=" + sequence) && shouldModifyPackets()) {
|
||||
lastSequence = sequence;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
lastSequence = sequence;
|
||||
return isSupportedVersion && sequence != expected
|
||||
&& flagAndAlert("expected=" + expected + ", id=" + sequence)
|
||||
&& shouldModifyPackets();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onWorldChange() {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientPlayerAbilitiesPacket;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerAbilities;
|
||||
|
||||
@CheckData(name = "BadPacketsI", description = "Claimed to be flying while unable to fly")
|
||||
public class BadPacketsI extends Check implements PacketCheck {
|
||||
@@ -16,11 +16,13 @@ public class BadPacketsI extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_ABILITIES
|
||||
&& new WrapperPlayClientPlayerAbilities(event).isFlying() && !player.canFly
|
||||
&& flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.PLAYER_ABILITIES) {
|
||||
if (ClientPlayerAbilitiesPacket.from(event).isFlying() && !player.canFly) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,22 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.player.enums.GameMode;
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.api.packet.protocol.version.server.ServerVersions;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.HeadRotation;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUseItem;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientPlayerUseItemPacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@CheckData(name = "BadPacketsJ", description = "Rotation in use item packet did not match tick rotation")
|
||||
public class BadPacketsJ extends Check implements PacketCheck {
|
||||
@CheckData(name = "BadPacketsJ", description = "Rotation in use item packet did not match tick rotation", experimental = true)
|
||||
public class BadPacketsJ extends Check implements PostPredictionCheck {
|
||||
private final List<HeadRotation> rotations = new ArrayList<>();
|
||||
|
||||
public BadPacketsJ(GrimPlayer player) {
|
||||
@@ -31,22 +30,22 @@ public class BadPacketsJ extends Check implements PacketCheck {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.USE_ITEM && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21)
|
||||
&& PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
|
||||
WrapperPlayClientUseItem packet = new WrapperPlayClientUseItem(event);
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.USE_ITEM && player.getClientVersion().isNewerThanOrEquals(PacketClientVersions.V_1_21)
|
||||
&& ServerVersions.getServerVersion().isNewerThanOrEquals(ServerVersions.V_1_21)) {
|
||||
ClientPlayerUseItemPacket packet = packetFactory.clientPlayerUseItem(event);
|
||||
rotations.add(new HeadRotation(packet.getYaw(), packet.getPitch()));
|
||||
}
|
||||
|
||||
if (isTickPacket(event.getPacketType())) {
|
||||
// due to tick skipping, the rotations sent could be last tick's
|
||||
boolean allowLast = player.canSkipTicks() && (event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION || event.getPacketType() == PacketType.Play.Client.PLAYER_ROTATION);
|
||||
boolean allowLast = player.canSkipTicks() && (event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION_AND_ROTATION || event.getPacketType() == PacketTypes.Play.Client.PLAYER_ROTATION);
|
||||
for (HeadRotation rotation : rotations) {
|
||||
if (rotation.yaw() == player.yaw && rotation.pitch() == player.pitch) {
|
||||
if (rotation.getYaw() == player.xRot && rotation.getPitch() == player.yRot) {
|
||||
allowLast = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rotation.yaw() == player.lastYaw && rotation.pitch() == player.lastPitch && allowLast) {
|
||||
if (rotation.getYaw() == player.lastXRot && rotation.getPitch() == player.lastYRot && allowLast) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.player.enums.GameMode;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
|
||||
@CheckData(name = "BadPacketsK", description = "Sent spectate packets while not in spectator mode")
|
||||
public class BadPacketsK extends Check implements PacketCheck {
|
||||
@@ -16,11 +16,13 @@ public class BadPacketsK extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.SPECTATE
|
||||
&& player.gamemode != GameMode.SPECTATOR
|
||||
&& flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.SPECTATE) {
|
||||
if (player.gamemode != GameMode.SPECTATOR) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.player.enums.DiggingAction;
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientPlayerDiggingPacket;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -21,15 +21,15 @@ public class BadPacketsL extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING) {
|
||||
final WrapperPlayClientPlayerDigging packet = new WrapperPlayClientPlayerDigging(event);
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.PLAYER_DIGGING) {
|
||||
final ClientPlayerDiggingPacket packet = packetFactory.clientPlayerDigging(event);
|
||||
|
||||
if (packet.getAction() == DiggingAction.START_DIGGING || packet.getAction() == DiggingAction.FINISHED_DIGGING || packet.getAction() == DiggingAction.CANCELLED_DIGGING)
|
||||
if (packet.getDiggingAction() == DiggingAction.START_DIGGING || packet.getDiggingAction() == DiggingAction.FINISHED_DIGGING || packet.getDiggingAction() == DiggingAction.CANCELLED_DIGGING)
|
||||
return;
|
||||
|
||||
// 1.8 and above clients always send digging packets that aren't used for digging at 0, 0, 0, facing DOWN
|
||||
// 1.7 and below clients do the same, except use SOUTH for RELEASE_USE_ITEM
|
||||
final int expectedFace = player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_7_10) && packet.getAction() == DiggingAction.RELEASE_USE_ITEM
|
||||
final int expectedFace = player.getClientVersion().isOlderThanOrEquals(PacketClientVersions.V_1_7_10) && packet.getDiggingAction() == DiggingAction.RELEASE_USE_ITEM
|
||||
? 255 : 0;
|
||||
|
||||
if (packet.getBlockFaceId() != expectedFace
|
||||
@@ -42,8 +42,8 @@ public class BadPacketsL extends Check implements PacketCheck {
|
||||
+ packet.getBlockPosition().getX() + ", " + packet.getBlockPosition().getY() + ", " + packet.getBlockPosition().getZ()
|
||||
+ ", face=" + packet.getBlockFace()
|
||||
+ ", sequence=" + packet.getSequence()
|
||||
+ ", action=" + packet.getAction().toString().toLowerCase(Locale.ROOT)
|
||||
) && shouldModifyPackets() && packet.getAction() != DiggingAction.RELEASE_USE_ITEM) {
|
||||
+ ", action=" + packet.getDiggingAction().toString().toLowerCase(Locale.ROOT)
|
||||
) && shouldModifyPackets() && packet.getDiggingAction() != DiggingAction.RELEASE_USE_ITEM) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.Combat;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClientStatus;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChangeGameState;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCombatEvent;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDeathCombatEvent;
|
||||
|
||||
@CheckData(name = "BadPacketsM", description = "Tried to respawn while alive", experimental = true)
|
||||
public class BadPacketsM extends Check implements PacketCheck {
|
||||
public BadPacketsM(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
// not a boolean because the server could send packets that cause
|
||||
// the client to send a respawn packet before it receives the first
|
||||
private int exempt;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLIENT_STATUS && new WrapperPlayClientClientStatus(event).getAction() == WrapperPlayClientClientStatus.Action.PERFORM_RESPAWN) {
|
||||
if (exempt > 0) {
|
||||
exempt--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.compensatedEntities.self.isDead) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSend(PacketSendEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.CHANGE_GAME_STATE && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)
|
||||
&& new WrapperPlayServerChangeGameState(event).getReason() == WrapperPlayServerChangeGameState.Reason.WIN_GAME) {
|
||||
player.addRealTimeTaskNow(() -> exempt++);
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Server.DEATH_COMBAT_EVENT && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) {
|
||||
if (new WrapperPlayServerDeathCombatEvent(event).getPlayerId() == player.entityID) {
|
||||
player.addRealTimeTaskNow(() -> exempt++);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Server.COMBAT_EVENT && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) {
|
||||
WrapperPlayServerCombatEvent packet = new WrapperPlayServerCombatEvent(event);
|
||||
if (packet.getCombat() == Combat.ENTITY_DEAD && packet.getPlayerId() == player.entityID) {
|
||||
player.addRealTimeTaskNow(() -> exempt++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,11 @@ package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
|
||||
@CheckData(name = "BadPacketsN", setback = 0)
|
||||
public class BadPacketsN extends Check {
|
||||
public class BadPacketsN extends Check implements PacketCheck {
|
||||
public BadPacketsN(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientKeepAlivePacket;
|
||||
import ac.grim.grimac.api.packet.types.server.play.ServerKeepAlivePacket;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientKeepAlive;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerKeepAlive;
|
||||
import ac.grim.grimac.utils.data.Pair;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketSendEvent;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
@CheckData(name = "BadPacketsO")
|
||||
public class BadPacketsO extends Check implements PacketCheck {
|
||||
private final LinkedList<Long> keepalives = new LinkedList<>();
|
||||
Queue<Pair<Long, Long>> keepaliveMap = new LinkedList<>();
|
||||
|
||||
public BadPacketsO(GrimPlayer player) {
|
||||
super(player);
|
||||
@@ -22,31 +24,38 @@ public class BadPacketsO extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketSend(PacketSendEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.KEEP_ALIVE) {
|
||||
keepalives.add(new WrapperPlayServerKeepAlive(event).getId());
|
||||
if (event.getPacketType() == PacketTypes.Play.Server.KEEP_ALIVE) {
|
||||
ServerKeepAlivePacket packet = ServerKeepAlivePacket.from(event);
|
||||
keepaliveMap.add(new Pair<>(packet.getId(), System.nanoTime()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.KEEP_ALIVE) {
|
||||
final long id = new WrapperPlayClientKeepAlive(event).getId();
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.KEEP_ALIVE) {
|
||||
ClientKeepAlivePacket packet = ClientKeepAlivePacket.from(event);
|
||||
|
||||
for (long keepalive : keepalives) {
|
||||
if (keepalive == id) {
|
||||
// Found the ID, remove stuff until we get to it (to stop very slow memory leaks)
|
||||
Long data;
|
||||
do {
|
||||
data = keepalives.poll();
|
||||
} while (data != null && data != id);
|
||||
long id = packet.getId();
|
||||
boolean hasID = false;
|
||||
|
||||
return;
|
||||
for (Pair<Long, Long> iterator : keepaliveMap) {
|
||||
if (iterator.first() == id) {
|
||||
hasID = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flagAndAlert("id=" + id) && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
if (!hasID) {
|
||||
if (flagAndAlert("id=" + id) && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else { // Found the ID, remove stuff until we get to it (to stop very slow memory leaks)
|
||||
Pair<Long, Long> data;
|
||||
do {
|
||||
data = keepaliveMap.poll();
|
||||
if (data == null) break;
|
||||
} while (data.first() != id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientClickWindowPacket;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketSendEvent;
|
||||
import ac.grim.grimac.api.packet.types.server.play.ServerOpenWindowPacket;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClickWindow;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClickWindow.WindowClickType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerOpenWindow;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientClickWindowPacket.WindowClickType;
|
||||
|
||||
@CheckData(name = "BadPacketsP", description = "Invalid click packets", experimental = true)
|
||||
@CheckData(name = "BadPacketsP", experimental = true)
|
||||
public class BadPacketsP extends Check implements PacketCheck {
|
||||
|
||||
private int containerType = -1;
|
||||
@@ -23,8 +23,8 @@ public class BadPacketsP extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketSend(final PacketSendEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.OPEN_WINDOW) {
|
||||
WrapperPlayServerOpenWindow window = new WrapperPlayServerOpenWindow(event);
|
||||
if (event.getPacketType() == PacketTypes.Play.Server.OPEN_WINDOW) {
|
||||
ServerOpenWindowPacket window = packetFactory.serverOpenWindow(event);
|
||||
this.containerType = window.getType();
|
||||
this.containerId = window.getContainerId();
|
||||
}
|
||||
@@ -32,8 +32,8 @@ public class BadPacketsP extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW) {
|
||||
WrapperPlayClientClickWindow wrapper = new WrapperPlayClientClickWindow(event);
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.CLICK_WINDOW) {
|
||||
ClientClickWindowPacket wrapper = packetFactory.clientClickWindow(event);
|
||||
WindowClickType clickType = wrapper.getWindowClickType();
|
||||
int button = wrapper.getButton();
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientEntityActionPacket;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType.Play.Client;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction.Action;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes.Play.Client;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientEntityActionPacket.Action;
|
||||
|
||||
@CheckData(name = "BadPacketsQ")
|
||||
public class BadPacketsQ extends Check implements PacketCheck {
|
||||
@@ -18,7 +18,7 @@ public class BadPacketsQ extends Check implements PacketCheck {
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == Client.ENTITY_ACTION) {
|
||||
WrapperPlayClientEntityAction wrapper = new WrapperPlayClientEntityAction(event);
|
||||
ClientEntityActionPacket wrapper = packetFactory.clientEntityAction(event);
|
||||
// you are able to send negative jump boost, how and why!?
|
||||
if (Math.abs(wrapper.getJumpBoost()) > 100
|
||||
|| wrapper.getEntityId() != player.entityID
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.player.enums.GameMode;
|
||||
|
||||
@CheckData(name = "BadPacketsR", decay = 0.25, experimental = true)
|
||||
public class BadPacketsR extends Check implements PacketCheck {
|
||||
@@ -23,26 +23,25 @@ public class BadPacketsR extends Check implements PacketCheck {
|
||||
public void onPacketReceive(final PacketReceiveEvent event) {
|
||||
if (isTransaction(event.getPacketType()) && player.packetStateData.lastTransactionPacketWasValid) {
|
||||
long ms = (player.getPlayerClockAtLeast() - clock) / 1000000L;
|
||||
long diff = (player.now() - lastTransTime);
|
||||
long diff = (System.currentTimeMillis() - lastTransTime);
|
||||
if (diff > 2000 && ms > 2000) {
|
||||
if (positions == 0 && clock != 0 && player.gamemode != GameMode.SPECTATOR && !player.compensatedEntities.self.isDead) {
|
||||
flag("time=" + ms + "ms, " + "lst=" + diff + "ms, positions=" + positions);
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
player.compensatedEntities.entitiesRemovedThisTick.clear();
|
||||
player.compensatedWorld.removeInvalidPistonLikeStuff(oldTransId);
|
||||
positions = 0;
|
||||
clock = player.getPlayerClockAtLeast();
|
||||
lastTransTime = player.now();
|
||||
lastTransTime = System.currentTimeMillis();
|
||||
oldTransId = player.lastTransactionSent.get();
|
||||
}
|
||||
}
|
||||
//
|
||||
if ((event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION ||
|
||||
event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION) && !player.inVehicle()) {
|
||||
if ((event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION_AND_ROTATION ||
|
||||
event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION) && !player.inVehicle()) {
|
||||
positions++;
|
||||
} else if ((event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE || event.getPacketType() == PacketType.Play.Client.VEHICLE_MOVE)
|
||||
} else if ((event.getPacketType() == PacketTypes.Play.Client.STEER_VEHICLE || event.getPacketType() == PacketTypes.Play.Client.VEHICLE_MOVE)
|
||||
&& player.inVehicle()) {
|
||||
positions++;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,6 @@ import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientWindowConfirmation;
|
||||
|
||||
@CheckData(name = "BadPacketsS")
|
||||
public class BadPacketsS extends Check implements PacketCheck {
|
||||
@@ -14,13 +11,4 @@ public class BadPacketsS extends Check implements PacketCheck {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.WINDOW_CONFIRMATION
|
||||
&& !new WrapperPlayClientWindowConfirmation(event).isAccepted()
|
||||
&& flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,35 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.api.packet.protocol.attribute.Attributes;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientInteractEntityPacket;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import ac.grim.grimac.api.packet.entity.PacketEntityTypes;
|
||||
|
||||
@CheckData(name = "BadPacketsT")
|
||||
public class BadPacketsT extends Check implements PacketCheck {
|
||||
|
||||
private final double maxHorizontalDisplacement;
|
||||
private final double minVerticalDisplacement;
|
||||
private final double maxVerticalDisplacement;
|
||||
// 1.7 and 1.8 seem to have different hitbox "expansion" values than 1.9+
|
||||
// https://github.com/GrimAnticheat/Grim/pull/1274#issuecomment-1872458702
|
||||
// https://github.com/GrimAnticheat/Grim/pull/1274#issuecomment-1872533497
|
||||
private final boolean hasLegacyExpansion = player.getClientVersion().isOlderThan(PacketClientVersions.V_1_9);
|
||||
private final double maxHorizontalDisplacement = 0.3001 + (hasLegacyExpansion ? 0.1 : 0);
|
||||
private final double minVerticalDisplacement = -0.0001 - (hasLegacyExpansion ? 0.1 : 0);
|
||||
private final double maxVerticalDisplacement = 1.8001 + (hasLegacyExpansion ? 0.1 : 0);
|
||||
|
||||
public BadPacketsT(final GrimPlayer player) {
|
||||
super(player);
|
||||
// 1.7 and 1.8 seem to have different hitbox "expansion" values than 1.9+
|
||||
// https://github.com/GrimAnticheat/Grim/pull/1274#issuecomment-1872458702
|
||||
// https://github.com/GrimAnticheat/Grim/pull/1274#issuecomment-1872533497
|
||||
double expansion = player.getClientVersion().isOlderThan(ClientVersion.V_1_9) ? 0.1 : 0;
|
||||
maxHorizontalDisplacement = 0.3001 + expansion;
|
||||
minVerticalDisplacement = -0.0001 - expansion;
|
||||
maxVerticalDisplacement = 1.8001 + expansion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(final PacketReceiveEvent event) {
|
||||
if (event.getPacketType().equals(PacketType.Play.Client.INTERACT_ENTITY)) {
|
||||
final WrapperPlayClientInteractEntity wrapper = new WrapperPlayClientInteractEntity(event);
|
||||
if (event.getPacketType().equals(PacketTypes.Play.Client.INTERACT_ENTITY)) {
|
||||
final ClientInteractEntityPacket wrapper = packetFactory.clientInteractEntity(event);
|
||||
// Only INTERACT_AT actually has an interaction vector
|
||||
wrapper.getTarget().ifPresent(targetVector -> {
|
||||
final PacketEntity packetEntity = player.compensatedEntities.getEntity(wrapper.getEntityId());
|
||||
@@ -43,7 +39,7 @@ public class BadPacketsT extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
// Make sure our target entity is actually a player (Player NPCs work too)
|
||||
if (!EntityTypes.PLAYER.equals(packetEntity.type)) {
|
||||
if (!PacketEntityTypes.PLAYER.equals(packetEntity.getType())) {
|
||||
// We can't check for any entity that is not a player
|
||||
return;
|
||||
}
|
||||
@@ -54,15 +50,15 @@ public class BadPacketsT extends Check implements PacketCheck {
|
||||
// 28/12/2023 - Player-only is fine
|
||||
// 30/12/2023 - Expansions differ in 1.9+
|
||||
final float scale = (float) packetEntity.getAttributeValue(Attributes.SCALE);
|
||||
if (targetVector.y > (minVerticalDisplacement * scale) && targetVector.y < (maxVerticalDisplacement * scale)
|
||||
&& Math.abs(targetVector.x) < (maxHorizontalDisplacement * scale)
|
||||
&& Math.abs(targetVector.z) < (maxHorizontalDisplacement * scale)) {
|
||||
if (targetVector.getY() > (minVerticalDisplacement * scale) && targetVector.getY() < (maxVerticalDisplacement * scale)
|
||||
&& Math.abs(targetVector.getX()) < (maxHorizontalDisplacement * scale)
|
||||
&& Math.abs(targetVector.getZ()) < (maxHorizontalDisplacement * scale)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Log the vector
|
||||
final String verbose = String.format("%.5f/%.5f/%.5f",
|
||||
targetVector.x, targetVector.y, targetVector.z);
|
||||
targetVector.getX(), targetVector.getY(), targetVector.getZ());
|
||||
// We could pretty much ban the player at this point
|
||||
flagAndAlert(verbose);
|
||||
});
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.item.PacketItemStack;
|
||||
import ac.grim.grimac.api.packet.item.PacketItemTypes;
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientPlayerBlockPlacementPacket;
|
||||
import ac.grim.grimac.api.packet.util.vec.ImmutableVector3f;
|
||||
import ac.grim.grimac.api.packet.world.enums.BlockFace;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.util.vec.ImmutableVector3i;
|
||||
|
||||
@CheckData(name = "BadPacketsU", description = "Sent impossible use item packet")
|
||||
public class BadPacketsU extends Check implements PacketCheck {
|
||||
@@ -22,34 +22,34 @@ public class BadPacketsU extends Check implements PacketCheck {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(final PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT) {
|
||||
final WrapperPlayClientPlayerBlockPlacement packet = new WrapperPlayClientPlayerBlockPlacement(event);
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.PLAYER_BLOCK_PLACEMENT) {
|
||||
final ClientPlayerBlockPlacementPacket packet = packetFactory.clientPlayerBlockPlacement(event);
|
||||
// BlockFace.OTHER is USE_ITEM for pre 1.9
|
||||
if (packet.getFace() == BlockFace.OTHER) {
|
||||
|
||||
// This packet is always sent at (-1, -1, -1) at (0, 0, 0) on the block
|
||||
// except y gets wrapped?
|
||||
final int expectedY = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8) ? 4095 : 255;
|
||||
final int expectedY = player.getClientVersion().isNewerThanOrEquals(PacketClientVersions.V_1_8) ? 4095 : 255;
|
||||
|
||||
final boolean failedItemCheck = packet.getItemStack().isPresent() && isEmpty(packet.getItemStack().get())
|
||||
// ViaVersion can sometimes cause this part of the check to false
|
||||
&& player.getClientVersion().isOlderThan(ClientVersion.V_1_9);
|
||||
&& player.getClientVersion().isOlderThan(PacketClientVersions.V_1_9);
|
||||
|
||||
final Vector3i pos = packet.getBlockPosition();
|
||||
final Vector3f cursor = packet.getCursorPosition();
|
||||
final ImmutableVector3i pos = packet.getBlockPosition();
|
||||
final ImmutableVector3f cursor = packet.getCursorPosition();
|
||||
|
||||
if (failedItemCheck
|
||||
|| pos.x != -1
|
||||
|| pos.y != expectedY
|
||||
|| pos.z != -1
|
||||
|| cursor.x != 0
|
||||
|| cursor.y != 0
|
||||
|| cursor.z != 0
|
||||
|| pos.getX() != -1
|
||||
|| pos.getY() != expectedY
|
||||
|| pos.getZ() != -1
|
||||
|| cursor.getX() != 0
|
||||
|| cursor.getY() != 0
|
||||
|| cursor.getZ() != 0
|
||||
|| packet.getSequence() != 0
|
||||
) {
|
||||
final String verbose = String.format(
|
||||
"xyz=%s, %s, %s, cursor=%s, %s, %s, item=%s, sequence=%s",
|
||||
pos.x, pos.y, pos.z, cursor.x, cursor.y, cursor.z, !failedItemCheck, packet.getSequence()
|
||||
pos.getX(), pos.getY(), pos.getZ(), cursor.getX(), cursor.getY(), cursor.getZ(), !failedItemCheck, packet.getSequence()
|
||||
);
|
||||
if (flagAndAlert(verbose) && shouldModifyPackets()) {
|
||||
player.onPacketCancel();
|
||||
@@ -60,7 +60,7 @@ public class BadPacketsU extends Check implements PacketCheck {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEmpty(ItemStack itemStack) {
|
||||
return itemStack.getType() == null || itemStack.getType() == ItemTypes.AIR;
|
||||
private boolean isEmpty(PacketItemStack itemStack) {
|
||||
return itemStack.getType() == null || itemStack.getType() == PacketItemTypes.AIR;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.api.packet.MCPacket;
|
||||
import ac.grim.grimac.api.packet.protocol.PacketClientVersions;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import ac.grim.grimac.api.packet.types.event.PacketReceiveEvent;
|
||||
import ac.grim.grimac.api.packet.types.PacketTypes;
|
||||
import ac.grim.grimac.api.packet.types.client.play.ClientPlayerFlyingMetaPacket;
|
||||
|
||||
@CheckData(name = "BadPacketsV", description = "Did not move far enough", experimental = true)
|
||||
public class BadPacketsV extends Check implements PacketCheck {
|
||||
@@ -21,12 +21,12 @@ public class BadPacketsV extends Check implements PacketCheck {
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (!player.canSkipTicks() && isTickPacket(event.getPacketType())) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION || event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION) {
|
||||
int positionAtLeastEveryNTicks = player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) ? 20 : 19;
|
||||
if (event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION || event.getPacketType() == PacketTypes.Play.Client.PLAYER_POSITION_AND_ROTATION) {
|
||||
int positionAtLeastEveryNTicks = player.getClientVersion().isOlderThanOrEquals(PacketClientVersions.V_1_8) ? 20 : 19;
|
||||
|
||||
if (noReminderTicks < positionAtLeastEveryNTicks && !player.uncertaintyHandler.lastTeleportTicks.hasOccurredSince(1)) {
|
||||
final double deltaSq = new WrapperPlayClientPlayerFlying(event).getLocation().getPosition()
|
||||
.distanceSquared(new Vector3d(player.lastX, player.lastY, player.lastZ));
|
||||
final double deltaSq = ClientPlayerFlyingMetaPacket.from(event).getLocation().getPosition()
|
||||
.distanceSquared(MCPacket.getAPI().getVectorFactory().getImmutableVec3d(player.lastX, player.lastY, player.lastZ));
|
||||
if (deltaSq <= player.getMovementThreshold() * player.getMovementThreshold()) {
|
||||
flagAndAlert("delta=" + Math.sqrt(deltaSq));
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@ package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
|
||||
@CheckData(name = "BadPacketsW", description = "Interacted with non-existent entity", experimental = true)
|
||||
public class BadPacketsW extends Check {
|
||||
public class BadPacketsW extends Check implements PacketCheck {
|
||||
public BadPacketsW(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
Loaded 100 of 672 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user