Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
007799734f
|
||
|
|
2a2cfd20a5
|
||
|
|
197288a47e | ||
|
|
44e478ebe7 | ||
|
|
ea548dfd91 | ||
|
|
d0561f2e19 | ||
|
|
2c8189a447 | ||
|
|
48c9e45bcf | ||
|
|
ecb4f4bf00 | ||
|
|
6ea9377622 | ||
|
|
b789fdebb7 | ||
|
|
e7b0606e18 | ||
|
|
14991b61e7 | ||
|
|
bf490c3805 | ||
|
|
7ca7078141 | ||
|
|
9c72c68d11 | ||
|
|
91643b8a53 | ||
|
|
170af55f91 | ||
|
|
00d82f9f2f | ||
|
|
79ef613c15 | ||
|
|
e2fcbafc70 | ||
|
|
9ae46145e5 | ||
|
|
76f90b68b8 | ||
|
|
32a2ee6bfa | ||
|
|
04878b7e34 | ||
|
|
45508ddf4d | ||
|
|
adccdc4b41 | ||
|
|
0accea66f2 | ||
|
|
47535748c4 | ||
|
|
65257be3ee | ||
|
|
880e879dce | ||
|
|
0ccc6a0923 | ||
|
|
7bff361e14 | ||
|
|
c2c28473cc | ||
|
|
048d502998 | ||
|
|
e0c1f53115 | ||
|
|
e5313a466b | ||
|
|
e30633e367 | ||
|
|
a443dd5d11 | ||
|
|
3820426bce | ||
|
|
031ae32f27 | ||
|
|
e83616139e | ||
|
|
7325b733d6 | ||
|
|
e64501eae8 | ||
|
|
2d99607c35 | ||
|
|
4d159189c0 | ||
|
|
2076294856 | ||
|
|
49f7bd22be | ||
|
|
298605874d | ||
|
|
35b94f1878 | ||
|
|
37955059c4 | ||
|
|
af4306bc81 | ||
|
|
98ca00f625 | ||
|
|
598804432b | ||
|
|
92bae0a5c4 | ||
|
|
d50b6a2f89 | ||
|
|
54cc085717 | ||
|
|
bd0d4c31b2 | ||
|
|
705c88f4b3 | ||
|
|
7306a795b9 | ||
|
|
dfdfad4bfc | ||
|
|
c87654848d | ||
|
|
08a7077d10 | ||
|
|
73afaaf493 | ||
|
|
f0f8038b18 | ||
|
|
540c0d0d47 | ||
|
|
d00b0c8afe | ||
|
|
b34385c09e | ||
|
|
ff47845df1 | ||
|
|
fc37b9c0ba | ||
|
|
e3baafa2a2 | ||
|
|
11914da37e | ||
|
|
30fa58af81 | ||
|
|
52b6aed005 | ||
|
|
9d74706e84 | ||
|
|
7d5ad45ffc | ||
|
|
bd3593e15a | ||
|
|
835fb5de08 | ||
|
|
8b2769f19b | ||
|
|
4da08b5a35 | ||
|
|
7da8e62a39 | ||
|
|
31c62f96b9 | ||
|
|
0f866d8b50 | ||
|
|
32d265116a | ||
|
|
b7d1197be3 | ||
|
|
d4363b67b6 | ||
|
|
dcdce8ad52 | ||
|
|
af44f88d6e | ||
|
|
1d1d77abfd | ||
|
|
ae800f16be | ||
|
|
f31d731f34 | ||
|
|
2ddd0d8b66 | ||
|
|
f97884158b | ||
|
|
1e2fcb9c58 | ||
|
|
5110326a90 | ||
|
|
6887556b2c | ||
|
|
66cf650d36 | ||
|
|
1426631c97 | ||
|
|
b6a32823cc | ||
|
|
aff88a6ca3 | ||
|
|
0edfd844b9 | ||
|
|
57a64740aa | ||
|
|
f7903050bf | ||
|
|
3a7ac0765b | ||
|
|
48f500a470 | ||
|
|
c3e19b769b | ||
|
|
561829d952 | ||
|
|
6767379526 | ||
|
|
a10ce1f35f | ||
|
|
49f0c673e6 | ||
|
|
fd2c81a6fd | ||
|
|
901463e095 | ||
|
|
227d37b2b9 | ||
|
|
be5bb6e07c | ||
|
|
064dbee920 | ||
|
|
783006baa5 | ||
|
|
ba93a40d22 | ||
|
|
422f81dd2e | ||
|
|
aa47e3c0a5 | ||
|
|
094298771e | ||
|
|
66133d1ccc | ||
|
|
11011d59aa | ||
|
|
691cbf1b2a | ||
|
|
8d8675a891 | ||
|
|
4fa2f10f3a | ||
|
|
c2e516dcd2 | ||
|
|
153eedd5eb | ||
|
|
2d404608ee | ||
|
|
bbc1d77939 | ||
|
|
fa36428391 | ||
|
|
b6dee43620 | ||
|
|
371c25f9d0 | ||
|
|
a41bbc2d67 | ||
|
|
de84a8fffc | ||
|
|
22ff1416c2 | ||
|
|
00b74ef2dd | ||
|
|
8d5b348318 | ||
|
|
51f001ac3e | ||
|
|
e27caba231 | ||
|
|
07aab015ea | ||
|
|
6bcf8d8895 | ||
|
|
43c42f44f6 | ||
|
|
295d87d49f | ||
|
|
ab97e248da | ||
|
|
276b9ba386 | ||
|
|
351ff79187 | ||
|
|
87ed2160c9 | ||
|
|
668ed3c455 | ||
|
|
3a0c742878 | ||
|
|
bc7b33f28a | ||
|
|
657dcaa682 | ||
|
|
3676906fbf | ||
|
|
dc9dbe9900 | ||
|
|
d8924485ac | ||
|
|
b02a257383 | ||
|
|
a4b666724f | ||
|
|
e92b15c19f | ||
|
|
3fd2da9bf8 | ||
|
|
ff4fbe2029 | ||
|
|
c3d32874a7 | ||
|
|
7b9888c758 | ||
|
|
e0c05df633 | ||
|
|
3af661b256 | ||
|
|
74ebb09ebc | ||
|
|
36396c10b0 | ||
|
|
bc9b84464b | ||
|
|
0ee7c1cf16 | ||
|
|
6d35536862 | ||
|
|
8945193a8a | ||
|
|
546f4b14fa | ||
|
|
e8028cf446 | ||
|
|
6a85860132 | ||
|
|
4b11b8e1bb | ||
|
|
724a6b7a4b | ||
|
|
c785df5fc0 | ||
|
|
de92c06dfd | ||
|
|
31f427a1b6 | ||
|
|
fffcae9c0e | ||
|
|
594dbbcbe9 | ||
|
|
8c4efbbb13 | ||
|
|
5b1dcf63d2 | ||
|
|
beead5773c | ||
|
|
60a5c4ae2f | ||
|
|
d707e20b05 | ||
|
|
14bad1d36f | ||
|
|
7a9bf5f465 | ||
|
|
f290af7b81 | ||
|
|
064d0008f5 | ||
|
|
fbe30d9da5 | ||
|
|
31490069ea | ||
|
|
1b8d5eacc0 | ||
|
|
abdb79598b | ||
|
|
1b5b59317c | ||
|
|
6e4ac65983 | ||
|
|
64cce82140 | ||
|
|
cb79316d6a | ||
|
|
7d34c3838a | ||
|
|
c60152532d | ||
|
|
1894bac11b | ||
|
|
a80ca442e5 | ||
|
|
c69ce24d32 | ||
|
|
e937a886ec | ||
|
|
3e261824ef | ||
|
|
43c3bb11dc | ||
|
|
f57ac05bd4 | ||
|
|
a3c623c202 | ||
|
|
481315f1e6 | ||
|
|
21e50421e5 | ||
|
|
233d52281b | ||
|
|
6807a02de7 |
No files matched your search
+14
-2
@@ -1,4 +1,16 @@
|
||||
root = true
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
tab_width = 4
|
||||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
ij_java_class_count_to_use_import_on_demand = 999999
|
||||
ij_java_names_count_to_use_import_on_demand = 999999
|
||||
ij_java_imports_layout = *, |, $*
|
||||
ij_java_generate_final_locals = true
|
||||
ij_java_generate_final_parameters = true
|
||||
|
||||
[{*.json,*.yml}]
|
||||
indent_size = 2
|
||||
@@ -0,0 +1 @@
|
||||
.gitea/CODEOWNERS linguist-detectable=false
|
||||
@@ -0,0 +1,3 @@
|
||||
# Pull requests request review from the eligible staff team(s).
|
||||
# One approval from either an Admin or Developer satisfies branch protection.
|
||||
* @trueog/Admins @trueog/Developers
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
github: FlorianMichael
|
||||
custom: ['https://florianmichael.de/donate', 'https://viaversion.com/donate', 'https://creeper123123321.github.io/#donate']
|
||||
github: florianreuth
|
||||
custom: [ 'https://florianreuth.de/donate', 'https://creeper123123321.github.io/#donate' ]
|
||||
@@ -1,6 +1,6 @@
|
||||
name: Bug report
|
||||
description: Report a bug or console error
|
||||
labels: [Unconfirmed]
|
||||
labels: [ Unconfirmed ]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
@@ -91,4 +91,4 @@ body:
|
||||
- label: I have tried the latest build(s) from https://ci.viaversion.com/ and the issue still persists.
|
||||
required: true
|
||||
- label: I have looked at https://www.spigotmc.org/resources/viarewind-legacy-support.52924/ and it does not offer a fix for my problem
|
||||
required: true
|
||||
required: true
|
||||
@@ -5,34 +5,34 @@ labels: [ Feature Request ]
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Problem Description
|
||||
description: |
|
||||
Describe the issue you are facing or why you need the feature to be added.
|
||||
placeholder: |
|
||||
I am always frustrated with...
|
||||
label: Problem Description
|
||||
description: |
|
||||
Describe the issue you are facing or why you need the feature to be added.
|
||||
placeholder: |
|
||||
I am always frustrated with...
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Solution Description
|
||||
description: |
|
||||
Describe the solution you would like to see.
|
||||
label: Solution Description
|
||||
description: |
|
||||
Describe the solution you would like to see.
|
||||
validations:
|
||||
required: true
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Alternatives
|
||||
description: |
|
||||
Describe alternatives you have considered.
|
||||
label: Alternatives
|
||||
description: |
|
||||
Describe alternatives you have considered.
|
||||
validations:
|
||||
required: false
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Info
|
||||
description: |
|
||||
Does the feature apply to any specific version or environment?
|
||||
label: Additional Info
|
||||
description: |
|
||||
Does the feature apply to any specific version or environment?
|
||||
validations:
|
||||
required: false
|
||||
required: false
|
||||
@@ -0,0 +1,14 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gradle"
|
||||
cooldown:
|
||||
default-days: 7
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
- package-ecosystem: "github-actions"
|
||||
cooldown:
|
||||
default-days: 7
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
+20
-15
@@ -1,28 +1,33 @@
|
||||
name: ViaRewind CI
|
||||
name: Build
|
||||
on: [pull_request, push, workflow_dispatch]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
# Only run on PRs if the source branch is on a different repo. We do not need to run everything twice.
|
||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
|
||||
with:
|
||||
cache-disabled: false
|
||||
cache-provider: basic
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
check-latest: true
|
||||
- name: Cache Dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- name: Upload Artifacts to GitHub
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: Artifacts
|
||||
path: build/libs/
|
||||
@@ -4,24 +4,40 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- dev
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
if: github.repository_owner == 'ViaVersion'
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Gradle
|
||||
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
|
||||
with:
|
||||
cache-disabled: false
|
||||
cache-provider: basic
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
check-latest: true
|
||||
- name: Publish
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- name: Publish to Hangar
|
||||
env:
|
||||
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
|
||||
run: ./gradlew publishAllPublicationsToHangar --stacktrace
|
||||
continue-on-error: true
|
||||
- name: Publish to Modrinth
|
||||
env:
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
run: ./gradlew build modrinth publishAllPublicationsToHangar
|
||||
run: ./gradlew modrinth --stacktrace
|
||||
continue-on-error: true
|
||||
+20
-97
@@ -1,113 +1,36 @@
|
||||
### Java files ###
|
||||
*.class
|
||||
# Gradle
|
||||
|
||||
# Package Files
|
||||
#*.jar
|
||||
*.war
|
||||
*.ear
|
||||
.gradle/
|
||||
build/
|
||||
out/
|
||||
classes/
|
||||
.kotlin/
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
# Eclipse
|
||||
|
||||
*.launch
|
||||
|
||||
# Idea
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
|
||||
# Ignore project files
|
||||
.idea/
|
||||
!.idea/copyright/*
|
||||
!.idea/scopes/*
|
||||
*.iml
|
||||
|
||||
# Ignore IDEA directory
|
||||
.idea/*
|
||||
|
||||
# Include the project's dictionary
|
||||
!.idea/dictionaries/
|
||||
!.idea/dictionaries/*
|
||||
|
||||
# File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
### Plugin-specific files: ###
|
||||
# IntelliJ
|
||||
/out/
|
||||
# VSCode
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
.gradle
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.vscode/
|
||||
bin/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
# macOS
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
DS_Store
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
# Misc
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
|
||||
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
.nb-gradle/
|
||||
|
||||
|
||||
|
||||
### Git ###
|
||||
# Don't exclude the .gitignore itself
|
||||
!/.gitignore
|
||||
run/
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings>
|
||||
<settings default="viarewind-gpl">
|
||||
<module2copyright>
|
||||
<element module="ViaRewind" copyright="viarewind-gpl" />
|
||||
</module2copyright>
|
||||
@@ -1,18 +1,23 @@
|
||||
# ViaRewind
|
||||
|
||||
[](https://github.com/ViaVersion/ViaRewind/releases)
|
||||
[](https://github.com/ViaVersion/ViaRewind/actions)
|
||||
[](https://viaversion.com/discord)
|
||||
|
||||
**ViaBackwards addon to allow 1.8.x and 1.7.x clients on newer server versions.** <br>
|
||||
**ViaVersion addon to allow 1.8.x and 1.7.x clients on newer server versions.** <br>
|
||||
Runs on 1.9-latest servers or 1.8 clients and lower.
|
||||
|
||||
**You can override the included version in [ViaFabric](https://modrinth.com/mod/viafabric) or [ViaProxy](https://github.com/ViaVersion/ViaProxy):**
|
||||
**You can override the included version in [ViaFabric](https://modrinth.com/mod/viafabric)
|
||||
or [ViaProxy](https://github.com/ViaVersion/ViaProxy):**
|
||||
|
||||
- in **ViaFabric**, put ViaRewind into the `mods` folder
|
||||
- in **ViaProxy**, put ViaRewind into the `jars` folder
|
||||
|
||||
Note: when using ViaFabric <= 1.16.5 or J8 ViaProxy builds, you need [J8 ViaRewind](https://ci.viaversion.com/view/ViaRewind/job/ViaRewind-Java8/) builds.
|
||||
Note: when using ViaFabric <= 1.16.5 or J8 ViaProxy builds, you
|
||||
need [J8 ViaRewind](https://ci.viaversion.com/view/ViaRewind/job/ViaRewind-Java8/) builds.
|
||||
|
||||
**Requires [ViaVersion](https://hangar.papermc.io/ViaVersion/ViaVersion) and [ViaBackwards](https://hangar.papermc.io/ViaVersion/ViaBackwards) to be installed..**
|
||||
**Requires [ViaVersion](https://hangar.papermc.io/ViaVersion/ViaVersion)
|
||||
and [ViaBackwards](https://hangar.papermc.io/ViaVersion/ViaBackwards) to be installed..**
|
||||
|
||||
Releases/Dev Builds
|
||||
-
|
||||
@@ -37,7 +42,7 @@ Other Links
|
||||
Building
|
||||
-
|
||||
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out
|
||||
of the `universal/build/libs` directory.
|
||||
of the `build/libs` directory.
|
||||
|
||||
You need JDK 17 or newer to build ViaRewind.
|
||||
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a **security vulnerability**, please **do not** open a public issue. Instead, use one of the following
|
||||
**confidential contact methods**:
|
||||
|
||||
* **Email:** [security@viaversion.com](mailto:security@viaversion.com)
|
||||
* **Discord:** Join our [Discord server](https://discord.gg/viaversion) and visit
|
||||
the [#exploit-report](https://discord.com/channels/316206679014244363/1388847764137316485) channel for further
|
||||
instructions.
|
||||
|
||||
If your issue is **not security-related** (e.g., bug reports, feature requests, or usage questions), please use
|
||||
the [GitHub Issues page](https://github.com/ViaVersion/ViaRewind/issues) or contact us via
|
||||
the [Discord server](https://discord.gg/viaversion).
|
||||
@@ -1,7 +0,0 @@
|
||||
plugins {
|
||||
id "groovy-gradle-plugin"
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
plugins {
|
||||
id "java-library"
|
||||
id "maven-publish"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = uri("https://repo.viaversion.com")
|
||||
}
|
||||
maven {
|
||||
url = uri("https://repo.maven.apache.org/maven2/")
|
||||
}
|
||||
maven {
|
||||
url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||
}
|
||||
maven {
|
||||
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
}
|
||||
maven {
|
||||
url = uri("https://maven.fabricmc.net/")
|
||||
}
|
||||
maven {
|
||||
url = uri("https://repo.spongepowered.org/repository/maven-public/")
|
||||
}
|
||||
maven {
|
||||
url = uri("https://nexus.velocitypowered.com/repository/maven-public/")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly "com.viaversion:viaversion:${project.viaversion_version}"
|
||||
compileOnly "com.viaversion:viabackwards:${project.viabackwards_version}"
|
||||
compileOnly "io.netty:netty-all:${project.netty_version}"
|
||||
compileOnly "com.google.guava:guava:${project.guava_version}"
|
||||
}
|
||||
|
||||
base {
|
||||
archivesName = project.maven_name
|
||||
group = project.maven_group
|
||||
version = project.maven_version
|
||||
description = "ViaBackwards addon to allow 1.8.x and 1.7.x clients on newer server versions."
|
||||
}
|
||||
|
||||
java.sourceCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
tasks {
|
||||
// Variable replacements
|
||||
processResources {
|
||||
for (final def file in ["plugin.yml", "fabric.mod.json"]) {
|
||||
filesMatching(file) {
|
||||
expand(
|
||||
"version": project.version,
|
||||
"description": project.description
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "Via"
|
||||
url = "https://repo.viaversion.com/"
|
||||
|
||||
credentials(PasswordCredentials)
|
||||
authentication {
|
||||
basic(BasicAuthentication)
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
main(MavenPublication) {
|
||||
artifactId = project.maven_name
|
||||
groupId = project.maven_group
|
||||
version = project.maven_version
|
||||
|
||||
from(components.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
tasks.withType(Javadoc) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import de.florianreuth.baseproject.*
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
eclipse
|
||||
id("io.papermc.hangar-publish-plugin")
|
||||
id("com.modrinth.minotaur")
|
||||
id("de.florianreuth.baseproject")
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
||||
setupProject()
|
||||
setupViaPublishing()
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.viaversion.com")
|
||||
maven("https://repo.papermc.io/repository/maven-public")
|
||||
maven("https://maven.fabricmc.net")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
||||
dependencies {
|
||||
compileOnly("com.viaversion:viaversion:5.7.2")
|
||||
compileOnly("com.viaversion:viabackwards:5.7.2")
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
val projectVersion = project.version
|
||||
val projectDescription = project.description
|
||||
filesMatching(listOf("plugin.yml", "fabric.mod.json", "META-INF/sponge_plugins.json")) {
|
||||
expand(mapOf("version" to projectVersion, "description" to projectDescription))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
base {
|
||||
archivesName.set("ViaRewind")
|
||||
}
|
||||
|
||||
val shade = configureShadedDependencies(false) // Only shade, don't add them as dependency
|
||||
|
||||
dependencies {
|
||||
subprojects.forEach {
|
||||
shade(it)
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
jar {
|
||||
manifest {
|
||||
attributes("paperweight-mappings-namespace" to "mojang")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val branch = branchName()
|
||||
val baseVersion = version as String
|
||||
val isRelease = !baseVersion.contains('-')
|
||||
val isMainBranch = branch == "master"
|
||||
if (!isRelease || isMainBranch) { // Only publish releases from the main branch
|
||||
val suffixedVersion = if (isRelease) baseVersion else baseVersion + "+" + System.getenv("GITHUB_RUN_NUMBER")
|
||||
val changelogContent = if (isRelease) {
|
||||
"See [GitHub](https://github.com/ViaVersion/ViaRewind) for release notes."
|
||||
} else {
|
||||
val commitHash = latestCommitHash()
|
||||
"[$commitHash](https://github.com/ViaVersion/ViaRewind/commit/$commitHash) ${latestCommitMessage()}"
|
||||
}
|
||||
|
||||
modrinth {
|
||||
val mcVersions: List<String> = (property("minecraft_versions") as String)
|
||||
.split(",")
|
||||
.map { it.trim() }
|
||||
token.set(System.getenv("MODRINTH_TOKEN"))
|
||||
projectId.set("viarewind")
|
||||
versionType.set(if (isRelease) "release" else if (isMainBranch) "beta" else "alpha")
|
||||
versionNumber.set(suffixedVersion)
|
||||
versionName.set(suffixedVersion)
|
||||
changelog.set(changelogContent)
|
||||
uploadFile.set(tasks.jar.flatMap { it.archiveFile })
|
||||
gameVersions.set(mcVersions)
|
||||
loaders.add("fabric")
|
||||
loaders.add("paper")
|
||||
loaders.add("folia")
|
||||
loaders.add("velocity")
|
||||
autoAddDependsOn.set(false)
|
||||
detectLoaders.set(false)
|
||||
dependencies {
|
||||
required.project("viaversion")
|
||||
required.project("viabackwards")
|
||||
optional.project("viafabric")
|
||||
}
|
||||
}
|
||||
tasks.modrinth {
|
||||
notCompatibleWithConfigurationCache("")
|
||||
}
|
||||
|
||||
hangarPublish {
|
||||
publications.register("plugin") {
|
||||
version.set(suffixedVersion)
|
||||
id.set("ViaRewind")
|
||||
channel.set(if (isRelease) "Release" else if (isMainBranch) "Snapshot" else "Alpha")
|
||||
changelog.set(changelogContent)
|
||||
apiKey.set(System.getenv("HANGAR_TOKEN"))
|
||||
platforms {
|
||||
paper {
|
||||
jar.set(tasks.jar.flatMap { it.archiveFile })
|
||||
platformVersions.set(listOf(property("minecraft_version_range") as String))
|
||||
dependencies {
|
||||
hangar("ViaVersion") {
|
||||
required = true
|
||||
}
|
||||
hangar("ViaBackwards") {
|
||||
required = true
|
||||
}
|
||||
}
|
||||
}
|
||||
velocity {
|
||||
jar.set(tasks.jar.flatMap { it.archiveFile })
|
||||
platformVersions.set(listOf(property("velocity_version") as String))
|
||||
dependencies {
|
||||
hangar("ViaVersion") {
|
||||
required = true
|
||||
}
|
||||
hangar("ViaBackwards") {
|
||||
required = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks.named("publishPluginPublicationToHangar") {
|
||||
notCompatibleWithConfigurationCache("")
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
plugins {
|
||||
id "com.viaversion.java-conventions"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(":viarewind-common")
|
||||
|
||||
compileOnly(annotationProcessor("org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT"))
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
dependencies {
|
||||
compileOnly(project(":viarewind-common"))
|
||||
compileOnly("org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT")
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
maven_name=viarewind-bukkit
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,14 +18,22 @@
|
||||
package com.viaversion.viarewind;
|
||||
|
||||
import com.viaversion.viarewind.api.ViaRewindPlatform;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.provider.InventoryProvider;
|
||||
import com.viaversion.viarewind.provider.BukkitInventoryProvider;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class BukkitPlugin extends JavaPlugin implements ViaRewindPlatform {
|
||||
|
||||
public BukkitPlugin() {
|
||||
Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml")));
|
||||
}
|
||||
public BukkitPlugin() {
|
||||
Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
final ViaProviders providers = Via.getManager().getProviders();
|
||||
providers.use(InventoryProvider.class, new BukkitInventoryProvider());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.provider;
|
||||
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.provider.InventoryProvider;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public final class BukkitInventoryProvider extends InventoryProvider {
|
||||
|
||||
@Override
|
||||
public boolean hasElytra(final UserConnection connection) {
|
||||
final Player player = Bukkit.getPlayer(connection.getProtocolInfo().getUuid());
|
||||
final ItemStack chestplate = player.getInventory().getChestplate();
|
||||
return chestplate != null && chestplate.getType() == Material.ELYTRA;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
name: ViaRewind
|
||||
main: com.viaversion.viarewind.BukkitPlugin
|
||||
authors: [FlorianMichael/EnZaXD, Gerrygames, creeper123321123]
|
||||
authors: [ EnZaXD, Gerrygames, creeper123123321 ]
|
||||
version: ${version}
|
||||
description: ${description}
|
||||
website: https://viaversion.com/rewind
|
||||
api-version: 1.13
|
||||
folia-supported: true
|
||||
load: STARTUP
|
||||
depend: [ViaVersion, ViaBackwards]
|
||||
depend: [ ViaVersion, ViaBackwards ]
|
||||
@@ -1,28 +0,0 @@
|
||||
plugins {
|
||||
id "com.viaversion.java-conventions"
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "net.raphimc.class-token-replacer" version "1.0.0"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
classTokenReplacer {
|
||||
property("\${version}", rootProject.maven_version)
|
||||
property("\${impl_version}", "git-ViaRewind-${rootProject.maven_version}:${project.latestCommitHash()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String latestCommitHash() {
|
||||
def stdout = new ByteArrayOutputStream()
|
||||
exec {
|
||||
commandLine 'git', 'rev-parse', '--short', 'HEAD'
|
||||
standardOutput = stdout
|
||||
}
|
||||
return stdout.toString().trim()
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import de.florianreuth.baseproject.latestCommitHash
|
||||
|
||||
plugins {
|
||||
id("net.raphimc.class-token-replacer")
|
||||
}
|
||||
|
||||
val viaProxy: Configuration by configurations.creating
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.netty:netty-all:4.0.20.Final")
|
||||
compileOnly("com.google.guava:guava:17.0")
|
||||
compileOnly("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT")
|
||||
|
||||
viaProxy("net.raphimc:ViaProxy:[3.0.0,4.0.0)") {
|
||||
isTransitive = false
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets.configureEach {
|
||||
classTokenReplacer {
|
||||
replaceInPlace.set(true)
|
||||
|
||||
property("\${version}", project.version)
|
||||
property("\${impl_version}", "git-ViaRewind-${project.version}:${latestCommitHash()}")
|
||||
}
|
||||
}
|
||||
|
||||
// Task to quickly test/debug code changes using https://github.com/ViaVersion/ViaProxy
|
||||
// For further instructions see the ViaProxy repository README
|
||||
val prepareViaProxyFiles by tasks.registering(Copy::class) {
|
||||
dependsOn(project.tasks.jar)
|
||||
|
||||
from(project.tasks.jar.get().archiveFile.get().asFile)
|
||||
into(layout.projectDirectory.dir("run/jars"))
|
||||
|
||||
val projectName = project.name
|
||||
rename { "${projectName}.jar" }
|
||||
}
|
||||
|
||||
val cleanupViaProxyFiles by tasks.registering(Delete::class) {
|
||||
delete(
|
||||
layout.projectDirectory.file("run/jars/${project.name}.jar"),
|
||||
layout.projectDirectory.dir("run/logs")
|
||||
)
|
||||
}
|
||||
|
||||
tasks.register<JavaExec>("runViaProxy") {
|
||||
dependsOn(prepareViaProxyFiles)
|
||||
finalizedBy(cleanupViaProxyFiles)
|
||||
|
||||
mainClass.set("net.raphimc.viaproxy.ViaProxy")
|
||||
classpath = viaProxy
|
||||
workingDir = layout.projectDirectory.dir("run").asFile
|
||||
jvmArgs = listOf("-DskipUpdateCheck")
|
||||
|
||||
if (System.getProperty("viaproxy.gui.autoStart") != null) {
|
||||
jvmArgs("-Dviaproxy.gui.autoStart")
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
maven_name=viarewind-common
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,21 +23,21 @@ import com.viaversion.viarewind.api.ViaRewindPlatform;
|
||||
|
||||
public class ViaRewind {
|
||||
|
||||
private static ViaRewindPlatform platform;
|
||||
private static ViaRewindConfig config;
|
||||
private static ViaRewindPlatform platform;
|
||||
private static ViaRewindConfig config;
|
||||
|
||||
public static void init(ViaRewindPlatform platform, ViaRewindConfig config) {
|
||||
Preconditions.checkArgument(ViaRewind.platform == null, "ViaRewind is already initialized");
|
||||
public static void init(ViaRewindPlatform platform, ViaRewindConfig config) {
|
||||
Preconditions.checkArgument(ViaRewind.platform == null, "ViaRewind is already initialized");
|
||||
|
||||
ViaRewind.platform = platform;
|
||||
ViaRewind.config = config;
|
||||
}
|
||||
ViaRewind.platform = platform;
|
||||
ViaRewind.config = config;
|
||||
}
|
||||
|
||||
public static ViaRewindPlatform getPlatform() {
|
||||
return ViaRewind.platform;
|
||||
}
|
||||
public static ViaRewindPlatform getPlatform() {
|
||||
return ViaRewind.platform;
|
||||
}
|
||||
|
||||
public static ViaRewindConfig getConfig() {
|
||||
return ViaRewind.config;
|
||||
}
|
||||
public static ViaRewindConfig getConfig() {
|
||||
return ViaRewind.config;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +18,6 @@
|
||||
package com.viaversion.viarewind;
|
||||
|
||||
import com.viaversion.viaversion.util.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
@@ -29,91 +28,105 @@ import java.util.logging.Logger;
|
||||
|
||||
public class ViaRewindConfig extends Config implements com.viaversion.viarewind.api.ViaRewindConfig {
|
||||
|
||||
private CooldownIndicator cooldownIndicator;
|
||||
private boolean replaceAdventureMode;
|
||||
private boolean replaceParticles;
|
||||
private int maxBookPages;
|
||||
private int maxBookPageSize;
|
||||
private boolean emulateWorldBorder;
|
||||
private boolean alwaysShowOriginalMobName;
|
||||
private String worldBorderParticle;
|
||||
private boolean enableOffhand;
|
||||
private String offhandCommand;
|
||||
private CooldownIndicator cooldownIndicator;
|
||||
private boolean replaceAdventureMode;
|
||||
private boolean replaceParticles;
|
||||
private int maxBookPages;
|
||||
private int maxBookPageSize;
|
||||
private boolean emulateWorldBorder;
|
||||
private boolean alwaysShowOriginalMobName;
|
||||
private String worldBorderParticle;
|
||||
private boolean enableOffhand;
|
||||
private String offhandCommand;
|
||||
private boolean emulateLevitationEffect;
|
||||
private boolean handlePlayerCombatPacket;
|
||||
|
||||
public ViaRewindConfig(File configFile, Logger logger) {
|
||||
super(configFile, logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
loadFields();
|
||||
}
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
loadFields();
|
||||
}
|
||||
|
||||
private void loadFields() {
|
||||
cooldownIndicator = CooldownIndicator.valueOf(getString("cooldown-indicator", "TITLE").toUpperCase());
|
||||
replaceAdventureMode = getBoolean("replace-adventure", false);
|
||||
replaceParticles = getBoolean("replace-particles", false);
|
||||
maxBookPages = getInt("max-book-pages", 100);
|
||||
maxBookPageSize = getInt("max-book-page-length", 5000);
|
||||
emulateWorldBorder = getBoolean("emulate-world-border", true);
|
||||
alwaysShowOriginalMobName = getBoolean("always-show-original-mob-name", true);
|
||||
worldBorderParticle = getString("world-border-particle", "fireworksSpark");
|
||||
enableOffhand = getBoolean("enable-offhand", true);
|
||||
offhandCommand = getString("offhand-command", "/offhand");
|
||||
}
|
||||
private void loadFields() {
|
||||
cooldownIndicator = CooldownIndicator.valueOf(getString("cooldown-indicator", "TITLE").toUpperCase());
|
||||
replaceAdventureMode = getBoolean("replace-adventure", false);
|
||||
replaceParticles = getBoolean("replace-particles", false);
|
||||
maxBookPages = getInt("max-book-pages", 100);
|
||||
maxBookPageSize = getInt("max-book-page-length", 5000);
|
||||
emulateWorldBorder = getBoolean("emulate-world-border", true);
|
||||
alwaysShowOriginalMobName = getBoolean("always-show-original-mob-name", true);
|
||||
worldBorderParticle = getString("world-border-particle", "fireworksSpark");
|
||||
enableOffhand = getBoolean("enable-offhand", true);
|
||||
offhandCommand = getString("offhand-command", "/offhand");
|
||||
emulateLevitationEffect = getBoolean("emulate-levitation-effect", true);
|
||||
handlePlayerCombatPacket = getBoolean("handle-player-combat-packet", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public CooldownIndicator getCooldownIndicator() {
|
||||
return cooldownIndicator;
|
||||
return cooldownIndicator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplaceAdventureMode() {
|
||||
return replaceAdventureMode;
|
||||
return replaceAdventureMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplaceParticles() {
|
||||
return replaceParticles;
|
||||
return replaceParticles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxBookPages() {
|
||||
return maxBookPages;
|
||||
return maxBookPages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxBookPageSize() {
|
||||
return maxBookPageSize;
|
||||
return maxBookPageSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmulateWorldBorder() {
|
||||
return emulateWorldBorder;
|
||||
}
|
||||
@Override
|
||||
public boolean isEmulateWorldBorder() {
|
||||
return emulateWorldBorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean alwaysShowOriginalMobName() {
|
||||
return alwaysShowOriginalMobName;
|
||||
}
|
||||
@Override
|
||||
public boolean alwaysShowOriginalMobName() {
|
||||
return alwaysShowOriginalMobName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorldBorderParticle() {
|
||||
return worldBorderParticle;
|
||||
}
|
||||
@Override
|
||||
public String getWorldBorderParticle() {
|
||||
return worldBorderParticle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableOffhand() {
|
||||
return enableOffhand;
|
||||
}
|
||||
@Override
|
||||
public boolean isEnableOffhand() {
|
||||
return enableOffhand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOffhandCommand() {
|
||||
return offhandCommand;
|
||||
}
|
||||
@Override
|
||||
public String getOffhandCommand() {
|
||||
return offhandCommand;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean emulateLevitationEffect() {
|
||||
return emulateLevitationEffect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlePlayerCombatPacket() {
|
||||
return handlePlayerCombatPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getDefaultConfigURL() {
|
||||
return getClass().getClassLoader().getResource("assets/viarewind/config.yml");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind;
|
||||
|
||||
import com.viaversion.viarewind.api.ViaRewindPlatform;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ViaRewindPlatformImpl implements ViaRewindPlatform {
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
public ViaRewindPlatformImpl() {
|
||||
logger = Via.getPlatform().createLogger("ViaRewind");
|
||||
init(new File(getDataFolder(), "viarewind.yml"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDataFolder() {
|
||||
return Via.getPlatform().getDataFolder();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -24,83 +24,97 @@ import com.viaversion.viaversion.api.configuration.Config;
|
||||
*/
|
||||
public interface ViaRewindConfig extends Config {
|
||||
|
||||
enum CooldownIndicator {
|
||||
TITLE, ACTION_BAR, BOSS_BAR, DISABLED
|
||||
}
|
||||
/**
|
||||
* Specifies how 1.8.x clients should see the cooldown indicator
|
||||
* You can choose between TITLE, ACTION_BAR, BOSS_BAR and DISABLED
|
||||
* ONLY DISABLE IF YOU HAVE 1.9 COOLDOWN DISABLED ON YOUR SERVER
|
||||
* 1.8 PLAYERS MAY ASK WHY PVP IS NOT WORKING OTHERWISE
|
||||
*
|
||||
* @return the cooldown indicator
|
||||
*/
|
||||
CooldownIndicator getCooldownIndicator();
|
||||
|
||||
/**
|
||||
* Specifies how 1.8.x clients should see the cooldown indicator
|
||||
* You can choose between TITLE, ACTION_BAR, BOSS_BAR and DISABLED
|
||||
* ONLY DISABLE IF YOU HAVE 1.9 COOLDOWN DISABLED ON YOUR SERVER
|
||||
* 1.8 PLAYERS MAY ASK WHY PVP IS NOT WORKING OTHERWISE
|
||||
*
|
||||
* @return the cooldown indicator
|
||||
*/
|
||||
CooldownIndicator getCooldownIndicator();
|
||||
/**
|
||||
* Replaces Adventure mode with Survival mode for 1.7.x clients
|
||||
* Enable this option if your server is using the 'CanDestroy'
|
||||
* or 'CanPlaceOn' flags on items
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isReplaceAdventureMode();
|
||||
|
||||
/**
|
||||
* Replaces Adventure mode with Survival mode for 1.7.x clients
|
||||
* Enable this option if your server is using the 'CanDestroy'
|
||||
* or 'CanPlaceOn' flags on items
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isReplaceAdventureMode();
|
||||
/**
|
||||
* Whether 1.9 particles should be replaced by similar ones in
|
||||
* 1.8 and lower
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isReplaceParticles();
|
||||
|
||||
/**
|
||||
* Whether 1.9 particles should be replaced by similar ones in
|
||||
* 1.8 and lower
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isReplaceParticles();
|
||||
/**
|
||||
* Max amount of pages for written books before a client gets kicked
|
||||
*
|
||||
* @return the max amount of pages
|
||||
*/
|
||||
int getMaxBookPages();
|
||||
|
||||
/**
|
||||
* Max amount of pages for written books before a client gets kicked
|
||||
*
|
||||
* @return the max amount of pages
|
||||
*/
|
||||
int getMaxBookPages();
|
||||
/**
|
||||
* Max amount of characters in the json (!) string of a book page before a client gets kicked
|
||||
*
|
||||
* @return the max amount of characters
|
||||
*/
|
||||
int getMaxBookPageSize();
|
||||
|
||||
/**
|
||||
* Max amount of characters in the json (!) string of a book page before a client gets kicked
|
||||
*
|
||||
* @return the max amount of characters
|
||||
*/
|
||||
int getMaxBookPageSize();
|
||||
/**
|
||||
* Whether to emulate the 1.8+ world border for 1.7.x clients
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isEmulateWorldBorder();
|
||||
|
||||
/**
|
||||
* Whether to emulate the 1.8+ world border for 1.7.x clients
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isEmulateWorldBorder();
|
||||
/**
|
||||
* Always shows the original mob's name instead of only when hovering over them with the cursor.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean alwaysShowOriginalMobName();
|
||||
|
||||
/**
|
||||
* Always shows the original mob's name instead of only when hovering over them with the cursor.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean alwaysShowOriginalMobName();
|
||||
/**
|
||||
* The particle to show the world border for the 1.8+ world border for 1.7.x clients
|
||||
*
|
||||
* @return the particle name
|
||||
*/
|
||||
String getWorldBorderParticle();
|
||||
|
||||
/**
|
||||
* The particle to show the world border for the 1.8+ world border for 1.7.x clients
|
||||
*
|
||||
* @return the particle name (see <a href="https://wiki.vg/index.php?title=Protocol&oldid=7368#Particle_2">Particle registry for Packet</a>)
|
||||
*/
|
||||
String getWorldBorderParticle();
|
||||
/**
|
||||
* If enabled, 1.8 players on 1.9+ servers can use /offhand to switch items between their main hand and offhand.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isEnableOffhand();
|
||||
|
||||
/**
|
||||
* If enabled, 1.8 players on 1.9+ servers can use /offhand to switch items between their main hand and offhand.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isEnableOffhand();
|
||||
/**
|
||||
* Allows to define the offhand command
|
||||
*
|
||||
* @return the offhand command
|
||||
*/
|
||||
String getOffhandCommand();
|
||||
|
||||
/**
|
||||
* Allows to define the offhand command
|
||||
*
|
||||
* @return the offhand command
|
||||
*/
|
||||
String getOffhandCommand();
|
||||
/**
|
||||
* If enabled, 1.8 players on 1.9+ servers will also experience the levitation effect by sending velocity packets.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean emulateLevitationEffect();
|
||||
|
||||
/**
|
||||
* If enabled, 1.8 players will handle the player combat packet added in 1.9 by showing the custom death message above the hotbar.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean handlePlayerCombatPacket();
|
||||
|
||||
enum CooldownIndicator {
|
||||
TITLE, ACTION_BAR, BOSS_BAR, DISABLED
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,7 +25,6 @@ import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.protocol.ProtocolManager;
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -34,40 +33,62 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public interface ViaRewindPlatform {
|
||||
|
||||
String VERSION = "${version}";
|
||||
String IMPL_VERSION = "${impl_version}";
|
||||
String VERSION = "${version}";
|
||||
String IMPL_VERSION = "${impl_version}";
|
||||
|
||||
/**
|
||||
* Initialize ViaRewind
|
||||
*/
|
||||
default void init(final File configFile) {
|
||||
ViaRewindConfig config = new ViaRewindConfig(configFile, getLogger());
|
||||
config.reload();
|
||||
Via.getManager().getConfigurationProvider().register(config);
|
||||
default void init(final File configFile) {
|
||||
init(new ViaRewindConfig(configFile, getLogger()));
|
||||
}
|
||||
|
||||
ViaRewind.init(this, config);
|
||||
/**
|
||||
* Initialize ViaRewind
|
||||
*/
|
||||
default void init(final com.viaversion.viarewind.api.ViaRewindConfig config) {
|
||||
config.reload();
|
||||
Via.getManager().getConfigurationProvider().register(config);
|
||||
|
||||
Via.getManager().getSubPlatforms().add(IMPL_VERSION);
|
||||
ViaRewind.init(this, config);
|
||||
|
||||
getLogger().info("Registering protocols...");
|
||||
final ProtocolManager protocolManager = Via.getManager().getProtocolManager();
|
||||
protocolManager.registerProtocol(new Protocol1_7_6_10To1_7_2_5(), ProtocolVersion.v1_7_2, ProtocolVersion.v1_7_6);
|
||||
protocolManager.registerProtocol(new Protocol1_8To1_7_6_10(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_8);
|
||||
Via.getManager().getSubPlatforms().add(IMPL_VERSION);
|
||||
|
||||
protocolManager.registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_8, ProtocolVersion.v1_9);
|
||||
}
|
||||
getLogger().info("Registering protocols...");
|
||||
final ProtocolManager protocolManager = Via.getManager().getProtocolManager();
|
||||
protocolManager.registerProtocol(new Protocol1_7_6_10To1_7_2_5(), ProtocolVersion.v1_7_2, ProtocolVersion.v1_7_6);
|
||||
protocolManager.registerProtocol(new Protocol1_8To1_7_6_10(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_8);
|
||||
|
||||
/**
|
||||
* Get the platform logger
|
||||
*
|
||||
* @return the logger
|
||||
*/
|
||||
Logger getLogger();
|
||||
protocolManager.registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_8, ProtocolVersion.v1_9);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform logger
|
||||
*
|
||||
* @return the logger
|
||||
*/
|
||||
Logger getLogger();
|
||||
|
||||
/**
|
||||
* Returns ViaRewind's data folder.
|
||||
*
|
||||
* @return data folder
|
||||
*/
|
||||
File getDataFolder();
|
||||
|
||||
/**
|
||||
* Returns the platform's compression handler name. Only used in the 1.8 -> 1.7 protocol.
|
||||
*
|
||||
* @return the compression handler name
|
||||
*/
|
||||
default String compressHandlerName() {
|
||||
return "compress";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the platform's decompression handler name. Only used in the 1.8 -> 1.7 protocol.
|
||||
*
|
||||
* @return the decompression handler name
|
||||
*/
|
||||
default String decompressHandlerName() {
|
||||
return "decompress";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ViaRewind's data folder.
|
||||
*
|
||||
* @return data folder
|
||||
*/
|
||||
File getDataFolder();
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,25 +17,24 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.api.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viarewind.ViaRewind;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class RewindMappingData extends BackwardsMappingData {
|
||||
|
||||
public RewindMappingData(String unmappedVersion, String mappedVersion) {
|
||||
super(unmappedVersion, mappedVersion);
|
||||
}
|
||||
public RewindMappingData(String unmappedVersion, String mappedVersion) {
|
||||
super(unmappedVersion, mappedVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Logger getLogger() {
|
||||
return ViaRewind.getPlatform().getLogger();
|
||||
}
|
||||
@Override
|
||||
protected Logger getLogger() {
|
||||
return ViaRewind.getPlatform().getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompoundTag readMappingsFile(String name) {
|
||||
return RewindMappingDataLoader.INSTANCE.loadNBTFromDir(name);
|
||||
}
|
||||
@Override
|
||||
protected CompoundTag readMappingsFile(String name) {
|
||||
return RewindMappingDataLoader.INSTANCE.loadNBTFromDir(name);
|
||||
}
|
||||
}
|
||||
+13
-14
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,26 +19,25 @@ package com.viaversion.viarewind.api.data;
|
||||
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
|
||||
import com.viaversion.viarewind.ViaRewind;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class RewindMappingDataLoader extends BackwardsMappingDataLoader {
|
||||
|
||||
public static final RewindMappingDataLoader INSTANCE = new RewindMappingDataLoader();
|
||||
public static final RewindMappingDataLoader INSTANCE = new RewindMappingDataLoader();
|
||||
|
||||
public RewindMappingDataLoader() {
|
||||
super(RewindMappingDataLoader.class, "assets/viarewind/data/");
|
||||
}
|
||||
public RewindMappingDataLoader() {
|
||||
super(RewindMappingDataLoader.class, "assets/viarewind/data/");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return ViaRewind.getPlatform().getLogger();
|
||||
}
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return ViaRewind.getPlatform().getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDataFolder() {
|
||||
return ViaRewind.getPlatform().getDataFolder();
|
||||
}
|
||||
@Override
|
||||
public File getDataFolder() {
|
||||
return ViaRewind.getPlatform().getDataFolder();
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.api.minecraft;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray;
|
||||
|
||||
public class ExtendedBlockStorage {
|
||||
private final byte[] blockLSBArray = new byte[4096];
|
||||
|
||||
private final NibbleArray blockMetadataArray = new NibbleArray(this.blockLSBArray.length);
|
||||
private final NibbleArray blockLightArray = new NibbleArray(this.blockLSBArray.length);
|
||||
|
||||
private NibbleArray blockMSBArray;
|
||||
private NibbleArray skyLightArray;
|
||||
|
||||
public ExtendedBlockStorage(final boolean skylight) {
|
||||
if (skylight) {
|
||||
this.skyLightArray = new NibbleArray(this.blockLSBArray.length);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlockId(final int x, final int y, final int z, final int value) {
|
||||
this.blockLSBArray[ChunkSection.index(x, y, z)] = (byte) (value & 255);
|
||||
if (value > 255) {
|
||||
this.getOrCreateBlockMSBArray().set(x, y, z, (value & 0xF00) >> 8);
|
||||
} else if (this.blockMSBArray != null) {
|
||||
this.blockMSBArray.set(x, y, z, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBlockMetadata(final int x, final int y, final int z, final int value) {
|
||||
this.blockMetadataArray.set(x, y, z, value);
|
||||
}
|
||||
|
||||
public boolean hasBlockMSBArray() {
|
||||
return this.blockMSBArray != null;
|
||||
}
|
||||
|
||||
public byte[] getBlockLSBArray() {
|
||||
return this.blockLSBArray;
|
||||
}
|
||||
|
||||
public NibbleArray getOrCreateBlockMSBArray() {
|
||||
if (this.blockMSBArray == null) {
|
||||
return this.blockMSBArray = new NibbleArray(this.blockLSBArray.length);
|
||||
}
|
||||
return this.blockMSBArray;
|
||||
}
|
||||
|
||||
public NibbleArray getBlockMetadataArray() {
|
||||
return this.blockMetadataArray;
|
||||
}
|
||||
|
||||
public NibbleArray getBlockLightArray() {
|
||||
return this.blockLightArray;
|
||||
}
|
||||
|
||||
public NibbleArray getSkyLightArray() {
|
||||
return this.skyLightArray;
|
||||
}
|
||||
}
|
||||
+25
-25
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,33 +23,33 @@ import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
|
||||
public enum EntityDataTypes1_7_6_10 implements EntityDataType {
|
||||
BYTE(0, Types.BYTE),
|
||||
SHORT(1, Types.SHORT),
|
||||
INT(2, Types.INT),
|
||||
FLOAT(3, Types.FLOAT),
|
||||
STRING(4, Types.STRING),
|
||||
ITEM(5, RewindTypes.COMPRESSED_NBT_ITEM),
|
||||
POSITION(6, Types.VECTOR);
|
||||
BYTE(0, Types.BYTE),
|
||||
SHORT(1, Types.SHORT),
|
||||
INT(2, Types.INT),
|
||||
FLOAT(3, Types.FLOAT),
|
||||
STRING(4, Types.STRING),
|
||||
ITEM(5, RewindTypes.COMPRESSED_NBT_ITEM),
|
||||
POSITION(6, Types.VECTOR);
|
||||
|
||||
private final int typeID;
|
||||
private final Type<?> type;
|
||||
private final int typeID;
|
||||
private final Type<?> type;
|
||||
|
||||
EntityDataTypes1_7_6_10(int typeID, Type<?> type) {
|
||||
this.typeID = typeID;
|
||||
this.type = type;
|
||||
}
|
||||
EntityDataTypes1_7_6_10(int typeID, Type<?> type) {
|
||||
this.typeID = typeID;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static EntityDataTypes1_7_6_10 byId(int id) {
|
||||
return values()[id];
|
||||
}
|
||||
public static EntityDataTypes1_7_6_10 byId(int id) {
|
||||
return values()[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int typeId() {
|
||||
return this.typeID;
|
||||
}
|
||||
@Override
|
||||
public int typeId() {
|
||||
return this.typeID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type<?> type() {
|
||||
return this.type;
|
||||
}
|
||||
@Override
|
||||
public Type<?> type() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,19 +18,19 @@
|
||||
package com.viaversion.viarewind.api.minecraft.math;
|
||||
|
||||
public class AABB {
|
||||
Vector3d min;
|
||||
Vector3d max;
|
||||
Vector3d min;
|
||||
Vector3d max;
|
||||
|
||||
public AABB(Vector3d min, Vector3d max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
public AABB(Vector3d min, Vector3d max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public Vector3d getMin() {
|
||||
return this.min;
|
||||
}
|
||||
public Vector3d getMin() {
|
||||
return this.min;
|
||||
}
|
||||
|
||||
public Vector3d getMax() {
|
||||
return this.max;
|
||||
}
|
||||
public Vector3d getMax() {
|
||||
return this.max;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,19 +18,19 @@
|
||||
package com.viaversion.viarewind.api.minecraft.math;
|
||||
|
||||
public class Ray3d {
|
||||
Vector3d start;
|
||||
Vector3d dir;
|
||||
Vector3d start;
|
||||
Vector3d dir;
|
||||
|
||||
public Ray3d(Vector3d start, Vector3d dir) {
|
||||
this.start = start;
|
||||
this.dir = dir;
|
||||
}
|
||||
public Ray3d(Vector3d start, Vector3d dir) {
|
||||
this.start = start;
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
public Vector3d getStart() {
|
||||
return this.start;
|
||||
}
|
||||
public Vector3d getStart() {
|
||||
return this.start;
|
||||
}
|
||||
|
||||
public Vector3d getDir() {
|
||||
return this.dir;
|
||||
}
|
||||
public Vector3d getDir() {
|
||||
return this.dir;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,40 +19,40 @@ package com.viaversion.viarewind.api.minecraft.math;
|
||||
|
||||
public class RayTracing {
|
||||
|
||||
public static Vector3d trace(Ray3d ray, AABB aabb, double distance) {
|
||||
Vector3d invDir = new Vector3d(1f / ray.dir.x, 1f / ray.dir.y, 1f / ray.dir.z);
|
||||
public static Vector3d trace(Ray3d ray, AABB aabb, double distance) {
|
||||
Vector3d invDir = new Vector3d(1f / ray.dir.x, 1f / ray.dir.y, 1f / ray.dir.z);
|
||||
|
||||
boolean signDirX = invDir.x < 0;
|
||||
boolean signDirY = invDir.y < 0;
|
||||
boolean signDirZ = invDir.z < 0;
|
||||
boolean signDirX = invDir.x < 0;
|
||||
boolean signDirY = invDir.y < 0;
|
||||
boolean signDirZ = invDir.z < 0;
|
||||
|
||||
Vector3d bbox = signDirX ? aabb.max : aabb.min;
|
||||
double tmin = (bbox.x - ray.start.x) * invDir.x;
|
||||
bbox = signDirX ? aabb.min : aabb.max;
|
||||
double tmax = (bbox.x - ray.start.x) * invDir.x;
|
||||
bbox = signDirY ? aabb.max : aabb.min;
|
||||
double tymin = (bbox.y - ray.start.y) * invDir.y;
|
||||
bbox = signDirY ? aabb.min : aabb.max;
|
||||
double tymax = (bbox.y - ray.start.y) * invDir.y;
|
||||
Vector3d bbox = signDirX ? aabb.max : aabb.min;
|
||||
double tmin = (bbox.x - ray.start.x) * invDir.x;
|
||||
bbox = signDirX ? aabb.min : aabb.max;
|
||||
double tmax = (bbox.x - ray.start.x) * invDir.x;
|
||||
bbox = signDirY ? aabb.max : aabb.min;
|
||||
double tymin = (bbox.y - ray.start.y) * invDir.y;
|
||||
bbox = signDirY ? aabb.min : aabb.max;
|
||||
double tymax = (bbox.y - ray.start.y) * invDir.y;
|
||||
|
||||
if (tmin > tymax || tymin > tmax) return null;
|
||||
if (tmin > tymax || tymin > tmax) return null;
|
||||
|
||||
if (tymin > tmin) tmin = tymin;
|
||||
if (tymin > tmin) tmin = tymin;
|
||||
|
||||
if (tymax < tmax) tmax = tymax;
|
||||
if (tymax < tmax) tmax = tymax;
|
||||
|
||||
bbox = signDirZ ? aabb.max : aabb.min;
|
||||
double tzmin = (bbox.z - ray.start.z) * invDir.z;
|
||||
bbox = signDirZ ? aabb.min : aabb.max;
|
||||
double tzmax = (bbox.z - ray.start.z) * invDir.z;
|
||||
bbox = signDirZ ? aabb.max : aabb.min;
|
||||
double tzmin = (bbox.z - ray.start.z) * invDir.z;
|
||||
bbox = signDirZ ? aabb.min : aabb.max;
|
||||
double tzmax = (bbox.z - ray.start.z) * invDir.z;
|
||||
|
||||
if (tmin > tzmax || tzmin > tmax) return null;
|
||||
if (tmin > tzmax || tzmin > tmax) return null;
|
||||
|
||||
if (tzmin > tmin) tmin = tzmin;
|
||||
if (tzmin > tmin) tmin = tzmin;
|
||||
|
||||
if (tzmax < tmax) tmax = tzmax;
|
||||
if (tzmax < tmax) tmax = tzmax;
|
||||
|
||||
return tmin <= distance && tmax > 0 ? ray.start.clone().add(ray.dir.clone().normalize().multiply(tmin)) : null;
|
||||
}
|
||||
return tmin <= distance && tmax > 0 ? ray.start.clone().add(ray.dir.clone().normalize().multiply(tmin)) : null;
|
||||
}
|
||||
|
||||
}
|
||||
+64
-64
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,79 +25,79 @@ import com.viaversion.viaversion.api.minecraft.Vector;
|
||||
@Deprecated // ?????????
|
||||
public class RelativeMoveUtil {
|
||||
|
||||
public static Vector[] calculateRelativeMoves(UserConnection user, int entityId, int relX, int relY, int relZ) {
|
||||
EntityTracker1_9 tracker = user.getEntityTracker(Protocol1_9To1_8.class);
|
||||
public static Vector[] calculateRelativeMoves(UserConnection user, int entityId, int relX, int relY, int relZ) {
|
||||
EntityTracker1_9 tracker = user.getEntityTracker(Protocol1_9To1_8.class);
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
Vector offset = tracker.getEntityOffset(entityId);
|
||||
if (offset != null) {
|
||||
relX += offset.blockX();
|
||||
relY += offset.blockY();
|
||||
relZ += offset.blockZ();
|
||||
}
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
Vector offset = tracker.getEntityOffset(entityId);
|
||||
if (offset != null) {
|
||||
relX += offset.blockX();
|
||||
relY += offset.blockY();
|
||||
relZ += offset.blockZ();
|
||||
}
|
||||
|
||||
if (relX > Short.MAX_VALUE) {
|
||||
x = relX - Short.MAX_VALUE;
|
||||
relX = Short.MAX_VALUE;
|
||||
} else if (relX < Short.MIN_VALUE) {
|
||||
x = relX - Short.MIN_VALUE;
|
||||
relX = Short.MIN_VALUE;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
if (relX > Short.MAX_VALUE) {
|
||||
x = relX - Short.MAX_VALUE;
|
||||
relX = Short.MAX_VALUE;
|
||||
} else if (relX < Short.MIN_VALUE) {
|
||||
x = relX - Short.MIN_VALUE;
|
||||
relX = Short.MIN_VALUE;
|
||||
} else {
|
||||
x = 0;
|
||||
}
|
||||
|
||||
if (relY > Short.MAX_VALUE) {
|
||||
y = relY - Short.MAX_VALUE;
|
||||
relY = Short.MAX_VALUE;
|
||||
} else if (relY < Short.MIN_VALUE) {
|
||||
y = relY - Short.MIN_VALUE;
|
||||
relY = Short.MIN_VALUE;
|
||||
} else {
|
||||
y = 0;
|
||||
}
|
||||
if (relY > Short.MAX_VALUE) {
|
||||
y = relY - Short.MAX_VALUE;
|
||||
relY = Short.MAX_VALUE;
|
||||
} else if (relY < Short.MIN_VALUE) {
|
||||
y = relY - Short.MIN_VALUE;
|
||||
relY = Short.MIN_VALUE;
|
||||
} else {
|
||||
y = 0;
|
||||
}
|
||||
|
||||
if (relZ > Short.MAX_VALUE) {
|
||||
z = relZ - Short.MAX_VALUE;
|
||||
relZ = Short.MAX_VALUE;
|
||||
} else if (relZ < Short.MIN_VALUE) {
|
||||
z = relZ - Short.MIN_VALUE;
|
||||
relZ = Short.MIN_VALUE;
|
||||
} else {
|
||||
z = 0;
|
||||
}
|
||||
if (relZ > Short.MAX_VALUE) {
|
||||
z = relZ - Short.MAX_VALUE;
|
||||
relZ = Short.MAX_VALUE;
|
||||
} else if (relZ < Short.MIN_VALUE) {
|
||||
z = relZ - Short.MIN_VALUE;
|
||||
relZ = Short.MIN_VALUE;
|
||||
} else {
|
||||
z = 0;
|
||||
}
|
||||
|
||||
int sentRelX, sentRelY, sentRelZ;
|
||||
Vector[] moves;
|
||||
int sentRelX, sentRelY, sentRelZ;
|
||||
Vector[] moves;
|
||||
|
||||
if (relX > Byte.MAX_VALUE * 128 || relX < Byte.MIN_VALUE * 128 || relY > Byte.MAX_VALUE * 128 || relY < Byte.MIN_VALUE * 128 || relZ > Byte.MAX_VALUE * 128 || relZ < Byte.MIN_VALUE * 128) {
|
||||
byte relX1 = (byte) (relX / 256);
|
||||
byte relX2 = (byte) (Math.round((relX - relX1 * 128) / 128f));
|
||||
byte relY1 = (byte) (relY / 256);
|
||||
byte relY2 = (byte) (Math.round((relY - relY1 * 128) / 128f));
|
||||
byte relZ1 = (byte) (relZ / 256);
|
||||
byte relZ2 = (byte) (Math.round((relZ - relZ1 * 128) / 128f));
|
||||
if (relX > Byte.MAX_VALUE * 128 || relX < Byte.MIN_VALUE * 128 || relY > Byte.MAX_VALUE * 128 || relY < Byte.MIN_VALUE * 128 || relZ > Byte.MAX_VALUE * 128 || relZ < Byte.MIN_VALUE * 128) {
|
||||
byte relX1 = (byte) (relX / 256);
|
||||
byte relX2 = (byte) (Math.round((relX - relX1 * 128) / 128f));
|
||||
byte relY1 = (byte) (relY / 256);
|
||||
byte relY2 = (byte) (Math.round((relY - relY1 * 128) / 128f));
|
||||
byte relZ1 = (byte) (relZ / 256);
|
||||
byte relZ2 = (byte) (Math.round((relZ - relZ1 * 128) / 128f));
|
||||
|
||||
sentRelX = relX1 + relX2;
|
||||
sentRelY = relY1 + relY2;
|
||||
sentRelZ = relZ1 + relZ2;
|
||||
sentRelX = relX1 + relX2;
|
||||
sentRelY = relY1 + relY2;
|
||||
sentRelZ = relZ1 + relZ2;
|
||||
|
||||
moves = new Vector[]{new Vector(relX1, relY1, relZ1), new Vector(relX2, relY2, relZ2)};
|
||||
} else {
|
||||
sentRelX = Math.round(relX / 128f);
|
||||
sentRelY = Math.round(relY / 128f);
|
||||
sentRelZ = Math.round(relZ / 128f);
|
||||
moves = new Vector[]{new Vector(relX1, relY1, relZ1), new Vector(relX2, relY2, relZ2)};
|
||||
} else {
|
||||
sentRelX = Math.round(relX / 128f);
|
||||
sentRelY = Math.round(relY / 128f);
|
||||
sentRelZ = Math.round(relZ / 128f);
|
||||
|
||||
moves = new Vector[]{new Vector(sentRelX, sentRelY, sentRelZ)};
|
||||
}
|
||||
moves = new Vector[]{new Vector(sentRelX, sentRelY, sentRelZ)};
|
||||
}
|
||||
|
||||
x = x + relX - sentRelX * 128;
|
||||
y = y + relY - sentRelY * 128;
|
||||
z = z + relZ - sentRelZ * 128;
|
||||
x = x + relX - sentRelX * 128;
|
||||
y = y + relY - sentRelY * 128;
|
||||
z = z + relZ - sentRelZ * 128;
|
||||
|
||||
tracker.setEntityOffset(entityId, new Vector(x, y, z));
|
||||
tracker.setEntityOffset(entityId, new Vector(x, y, z));
|
||||
|
||||
return moves;
|
||||
}
|
||||
return moves;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,109 +20,109 @@ package com.viaversion.viarewind.api.minecraft.math;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Vector3d {
|
||||
double x, y, z;
|
||||
double x, y, z;
|
||||
|
||||
public Vector3d(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
public Vector3d(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public Vector3d() {
|
||||
}
|
||||
public Vector3d() {
|
||||
}
|
||||
|
||||
public void set(Vector3d vec) {
|
||||
this.x = vec.x;
|
||||
this.y = vec.y;
|
||||
this.z = vec.z;
|
||||
}
|
||||
public void set(Vector3d vec) {
|
||||
this.x = vec.x;
|
||||
this.y = vec.y;
|
||||
this.z = vec.z;
|
||||
}
|
||||
|
||||
public Vector3d set(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
public Vector3d set(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3d multiply(double a) {
|
||||
this.x *= a;
|
||||
this.y *= a;
|
||||
this.z *= a;
|
||||
return this;
|
||||
}
|
||||
public Vector3d multiply(double a) {
|
||||
this.x *= a;
|
||||
this.y *= a;
|
||||
this.z *= a;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3d add(Vector3d vec) {
|
||||
this.x += vec.x;
|
||||
this.y += vec.y;
|
||||
this.z += vec.z;
|
||||
return this;
|
||||
}
|
||||
public Vector3d add(Vector3d vec) {
|
||||
this.x += vec.x;
|
||||
this.y += vec.y;
|
||||
this.z += vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3d substract(Vector3d vec) {
|
||||
this.x -= vec.x;
|
||||
this.y -= vec.y;
|
||||
this.z -= vec.z;
|
||||
return this;
|
||||
}
|
||||
public Vector3d substract(Vector3d vec) {
|
||||
this.x -= vec.x;
|
||||
this.y -= vec.y;
|
||||
this.z -= vec.z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double length() {
|
||||
return Math.sqrt(lengthSquared());
|
||||
}
|
||||
public double length() {
|
||||
return Math.sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
public double lengthSquared() {
|
||||
return this.x * this.x + this.y * this.y + this.z * this.z;
|
||||
}
|
||||
public double lengthSquared() {
|
||||
return this.x * this.x + this.y * this.y + this.z * this.z;
|
||||
}
|
||||
|
||||
public Vector3d normalize() {
|
||||
double length = length();
|
||||
multiply(1.0 / length);
|
||||
return this;
|
||||
}
|
||||
public Vector3d normalize() {
|
||||
double length = length();
|
||||
multiply(1.0 / length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3d clone() {
|
||||
return new Vector3d(this.x, this.y, this.z);
|
||||
}
|
||||
@Override
|
||||
public Vector3d clone() {
|
||||
return new Vector3d(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Vector3d vector3d = (Vector3d) o;
|
||||
return Double.compare(vector3d.x, x) == 0 && Double.compare(vector3d.y, y) == 0 && Double.compare(vector3d.z, z) == 0;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Vector3d vector3d = (Vector3d) o;
|
||||
return Double.compare(vector3d.x, x) == 0 && Double.compare(vector3d.y, y) == 0 && Double.compare(vector3d.z, z) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y, z);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Vector3d{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Vector3d{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return this.z;
|
||||
}
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
this.y = y;
|
||||
}
|
||||
public double getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,8 +23,8 @@ import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
public class ForwardMessageToByteEncoder extends MessageToByteEncoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
|
||||
out.writeBytes(msg);
|
||||
}
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
|
||||
out.writeBytes(msg);
|
||||
}
|
||||
}
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -26,17 +26,17 @@ import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
|
||||
public class VRBlockItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType, T extends BackwardsProtocol<C, ?, ?, S>> extends LegacyBlockItemRewriter<C, S, T> {
|
||||
|
||||
protected VRBlockItemRewriter(T protocol, String name) {
|
||||
super(protocol, name);
|
||||
}
|
||||
protected VRBlockItemRewriter(T protocol, String name) {
|
||||
super(protocol, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject readMappingsFile(String name) {
|
||||
return RewindMappingDataLoader.INSTANCE.loadFromDataDir(name);
|
||||
}
|
||||
@Override
|
||||
protected JsonObject readMappingsFile(String name) {
|
||||
return RewindMappingDataLoader.INSTANCE.loadFromDataDir(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nbtTagName() {
|
||||
return "VR|" + protocol.getClass().getSimpleName();
|
||||
}
|
||||
@Override
|
||||
public String nbtTagName() {
|
||||
return "VR|" + protocol.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,47 +25,42 @@ import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
|
||||
public abstract class VREntityRewriter<C extends ClientboundPacketType, T extends BackwardsProtocol<C, ?, ?, ?>> extends LegacyEntityRewriter<C, T> {
|
||||
|
||||
public VREntityRewriter(T protocol) {
|
||||
super(protocol, EntityDataTypes1_8.STRING, EntityDataTypes1_8.BYTE);
|
||||
}
|
||||
public VREntityRewriter(T protocol) {
|
||||
super(protocol, EntityDataTypes1_8.STRING, EntityDataTypes1_8.BYTE);
|
||||
}
|
||||
|
||||
public VREntityRewriter(T protocol, EntityDataType displayType, EntityDataType displayVisibilityType) {
|
||||
super(protocol, displayType, displayVisibilityType);
|
||||
}
|
||||
public VREntityRewriter(T protocol, EntityDataType displayType, EntityDataType displayVisibilityType) {
|
||||
super(protocol, displayType, displayVisibilityType);
|
||||
}
|
||||
|
||||
protected void registerJoinGame1_8(final C packetType) {
|
||||
protocol.registerClientbound(packetType, new PacketHandlers() {
|
||||
@Override
|
||||
protected void register() {
|
||||
map(Types.INT); // Entity id
|
||||
map(Types.UNSIGNED_BYTE); // Game mode
|
||||
map(Types.BYTE); // Dimension
|
||||
handler(playerTrackerHandler());
|
||||
handler(wrapper -> wrapper.user().get(ClientWorld.class).setEnvironment(wrapper.get(Types.BYTE, 0)));
|
||||
}
|
||||
});
|
||||
}
|
||||
protected void removeEntities(final UserConnection connection, final int[] entities) {
|
||||
final EntityTrackerBase tracker = tracker(connection);
|
||||
for (int entityId : entities) {
|
||||
tracker.removeEntity(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void untrackEntities(final UserConnection connection, final int[] entities) {
|
||||
final EntityTrackerBase tracker = tracker(connection);
|
||||
for (int entityId : entities) {
|
||||
tracker.removeEntity(entityId);
|
||||
}
|
||||
}
|
||||
protected PacketHandler getDimensionHandler() {
|
||||
return wrapper -> {
|
||||
final int dimension = wrapper.get(Types.BYTE, 0);
|
||||
final ClientWorld clientWorld = wrapper.user().getClientWorld(protocol.getClass());
|
||||
clientWorld.setEnvironment(dimension);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getDisplayVisibilityMetaValue() {
|
||||
return (byte) 1;
|
||||
}
|
||||
@Override
|
||||
protected Object getDisplayVisibilityDataValue() {
|
||||
return (byte) 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean alwaysShowOriginalMobName() {
|
||||
return ViaRewind.getConfig().alwaysShowOriginalMobName();
|
||||
}
|
||||
@Override
|
||||
protected boolean alwaysShowOriginalMobName() {
|
||||
return ViaRewind.getConfig().alwaysShowOriginalMobName();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,23 +22,23 @@ import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class IntArrayType extends Type<int[]> {
|
||||
|
||||
public IntArrayType() {
|
||||
super(int[].class);
|
||||
}
|
||||
public IntArrayType() {
|
||||
super(int[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] read(ByteBuf byteBuf) {
|
||||
byte size = byteBuf.readByte();
|
||||
int[] array = new int[size];
|
||||
for (byte i = 0; i < size; i++) {
|
||||
array[i] = byteBuf.readInt();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
@Override
|
||||
public int[] read(ByteBuf byteBuf) {
|
||||
byte size = byteBuf.readByte();
|
||||
int[] array = new int[size];
|
||||
for (byte i = 0; i < size; i++) {
|
||||
array[i] = byteBuf.readInt();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf byteBuf, int[] array) {
|
||||
byteBuf.writeByte(array.length);
|
||||
for (int i : array) byteBuf.writeInt(i);
|
||||
}
|
||||
@Override
|
||||
public void write(ByteBuf byteBuf, int[] array) {
|
||||
byteBuf.writeByte(array.length);
|
||||
for (int i : array) byteBuf.writeInt(i);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,34 +20,33 @@ package com.viaversion.viarewind.api.type;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
public class PositionVarYType<T extends Number> extends Type<BlockPosition> {
|
||||
|
||||
private final Type<T> yType;
|
||||
private final IntFunction<T> toY;
|
||||
private final Type<T> yType;
|
||||
private final IntFunction<T> toY;
|
||||
|
||||
public PositionVarYType(final Type<T> yType, final IntFunction<T> toY) {
|
||||
super(BlockPosition.class);
|
||||
public PositionVarYType(final Type<T> yType, final IntFunction<T> toY) {
|
||||
super(BlockPosition.class);
|
||||
|
||||
this.yType = yType;
|
||||
this.toY = toY;
|
||||
}
|
||||
this.yType = yType;
|
||||
this.toY = toY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosition read(ByteBuf buffer) {
|
||||
final int x = buffer.readInt();
|
||||
final int y = yType.read(buffer).intValue();
|
||||
final int z = buffer.readInt();
|
||||
@Override
|
||||
public BlockPosition read(ByteBuf buffer) {
|
||||
final int x = buffer.readInt();
|
||||
final int y = yType.read(buffer).intValue();
|
||||
final int z = buffer.readInt();
|
||||
|
||||
return new BlockPosition(x, y, z);
|
||||
}
|
||||
return new BlockPosition(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, BlockPosition value) {
|
||||
buffer.writeInt(value.x());
|
||||
yType.write(buffer, this.toY.apply(value.y()));
|
||||
buffer.writeInt(value.z());
|
||||
}
|
||||
@Override
|
||||
public void write(ByteBuf buffer, BlockPosition value) {
|
||||
buffer.writeInt(value.x());
|
||||
yType.write(buffer, this.toY.apply(value.y()));
|
||||
buffer.writeInt(value.z());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,18 +17,17 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.api.type;
|
||||
|
||||
import com.viaversion.viarewind.api.type.item.NBTType;
|
||||
import com.viaversion.viarewind.api.type.item.ItemArrayType;
|
||||
import com.viaversion.viarewind.api.type.item.ItemType;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viarewind.api.type.entitydata.EntityDataListType;
|
||||
import com.viaversion.viarewind.api.type.entitydata.EntityDataType;
|
||||
import com.viaversion.viarewind.api.type.item.ItemArrayType;
|
||||
import com.viaversion.viarewind.api.type.item.ItemType;
|
||||
import com.viaversion.viarewind.api.type.item.NBTType;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -36,15 +35,18 @@ import java.util.List;
|
||||
*/
|
||||
public class RewindTypes {
|
||||
|
||||
public static final Type<int[]> INT_ARRAY = new IntArrayType(); // Integer array with byte as length indicator
|
||||
public static final Type<int[]> INT_ARRAY = new IntArrayType(); // Integer array with byte as length indicator
|
||||
|
||||
public static final Type<BlockPosition> SHORT_POSITION = new PositionVarYType<>(Types.SHORT, value -> (short) value);
|
||||
public static final Type<BlockPosition> INT_POSITION = new PositionVarYType<>(Types.INT, value -> value);
|
||||
public static final Type<BlockPosition> BYTE_POSITION = new PositionVarYType<>(Types.BYTE, value -> (byte) value);
|
||||
public static final Type<BlockPosition> U_BYTE_POSITION = new PositionVarYType<>(Types.UNSIGNED_BYTE, value -> (short) value);
|
||||
public static final Type<BlockPosition> SHORT_POSITION = new PositionVarYType<>(Types.SHORT, value -> (short) value);
|
||||
public static final Type<BlockPosition> INT_POSITION = new PositionVarYType<>(Types.INT, value -> value);
|
||||
public static final Type<BlockPosition> BYTE_POSITION = new PositionVarYType<>(Types.BYTE, value -> (byte) value);
|
||||
public static final Type<BlockPosition> U_BYTE_POSITION = new PositionVarYType<>(Types.UNSIGNED_BYTE, value -> (short) value);
|
||||
|
||||
public static final Type<CompoundTag> COMPRESSED_NBT = new NBTType();
|
||||
public static final Type<Item> COMPRESSED_NBT_ITEM = new ItemType();
|
||||
public static final Type<Item[]> COMPRESSED_NBT_ITEM_ARRAY = new ItemArrayType();
|
||||
public static final Type<CompoundTag> COMPRESSED_NBT = new NBTType();
|
||||
public static final Type<Item> COMPRESSED_NBT_ITEM = new ItemType();
|
||||
public static final Type<Item[]> COMPRESSED_NBT_ITEM_ARRAY = new ItemArrayType();
|
||||
|
||||
public static final Type<EntityData> ENTITY_DATA1_7 = new EntityDataType();
|
||||
public static final Type<List<EntityData>> ENTITY_DATA_LIST1_7 = new EntityDataListType(ENTITY_DATA1_7);
|
||||
|
||||
}
|
||||
+73
-66
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,85 +18,92 @@
|
||||
package com.viaversion.viarewind.api.type.chunk;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.util.Pair;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
public class BulkChunkType1_7_6 extends Type<Chunk[]> {
|
||||
|
||||
public static final BulkChunkType1_7_6 TYPE = new BulkChunkType1_7_6();
|
||||
public static final BulkChunkType1_7_6 TYPE = new BulkChunkType1_7_6();
|
||||
|
||||
public BulkChunkType1_7_6() {
|
||||
super(Chunk[].class);
|
||||
}
|
||||
public BulkChunkType1_7_6() {
|
||||
super(Chunk[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk[] read(ByteBuf byteBuf) {
|
||||
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/ChunkBulk1_7_6Type.java
|
||||
}
|
||||
@Override
|
||||
public Chunk[] read(ByteBuf byteBuf) {
|
||||
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/ChunkBulk1_7_6Type.java
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf byteBuf, Chunk[] chunks) {
|
||||
final int chunkCount = chunks.length;
|
||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
final int[] chunkX = new int[chunkCount];
|
||||
final int[] chunkZ = new int[chunkCount];
|
||||
final short[] primaryBitMask = new short[chunkCount];
|
||||
final short[] additionalBitMask = new short[chunkCount];
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Chunk[] chunks) {
|
||||
final int chunkCount = chunks.length;
|
||||
final int[] addBitMasks = new int[chunkCount];
|
||||
int totalSize = 0;
|
||||
boolean anySkyLight = false;
|
||||
|
||||
for (int i = 0; i < chunkCount; i++) {
|
||||
final Chunk chunk = chunks[i];
|
||||
Pair<byte[], Short> chunkData;
|
||||
try {
|
||||
chunkData = ChunkType1_7_6.serialize(chunk);
|
||||
output.write(chunkData.key());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to serialize chunk", e);
|
||||
}
|
||||
chunkX[i] = chunk.getX();
|
||||
chunkZ[i] = chunk.getZ();
|
||||
primaryBitMask[i] = (short) chunk.getBitmask();
|
||||
additionalBitMask[i] = chunkData.value();
|
||||
}
|
||||
final byte[] data = output.toByteArray();
|
||||
for (Chunk chunk : chunks) {
|
||||
if (ChunkType1_7_6.hasSkyLight(chunk)) {
|
||||
anySkyLight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final Deflater deflater = new Deflater();
|
||||
byte[] compressedData;
|
||||
int compressedSize;
|
||||
try {
|
||||
deflater.setInput(data, 0, data.length);
|
||||
deflater.finish();
|
||||
compressedData = new byte[data.length];
|
||||
compressedSize = deflater.deflate(compressedData);
|
||||
} finally {
|
||||
deflater.end();
|
||||
}
|
||||
for (int i = 0; i < chunkCount; i++) {
|
||||
Chunk chunk = chunks[i];
|
||||
addBitMasks[i] = ChunkType1_7_6.getAddBitMask(chunk);
|
||||
boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null;
|
||||
|
||||
byteBuf.writeShort(chunkCount);
|
||||
byteBuf.writeInt(compressedSize);
|
||||
totalSize += ChunkType1_7_6.calcSize(
|
||||
chunk.getBitmask(),
|
||||
addBitMasks[i],
|
||||
anySkyLight,
|
||||
biomes
|
||||
);
|
||||
}
|
||||
|
||||
boolean skyLight = false;
|
||||
for (Chunk chunk : chunks) {
|
||||
for (ChunkSection section : chunk.getSections()) {
|
||||
if (section != null && section.getLight().hasSkyLight()) {
|
||||
skyLight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
final byte[] data = new byte[totalSize];
|
||||
int offset = 0;
|
||||
|
||||
byteBuf.writeBoolean(skyLight); // hasSkyLight
|
||||
byteBuf.writeBytes(compressedData, 0, compressedSize);
|
||||
for (int i = 0; i < chunkCount; i++) {
|
||||
Chunk chunk = chunks[i];
|
||||
boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null;
|
||||
|
||||
for (int i = 0; i < chunkCount; i++) {
|
||||
byteBuf.writeInt(chunkX[i]);
|
||||
byteBuf.writeInt(chunkZ[i]);
|
||||
byteBuf.writeShort(primaryBitMask[i]);
|
||||
byteBuf.writeShort(additionalBitMask[i]);
|
||||
}
|
||||
}
|
||||
offset = ChunkType1_7_6.serialize(
|
||||
chunk,
|
||||
data,
|
||||
offset,
|
||||
addBitMasks[i],
|
||||
anySkyLight,
|
||||
biomes
|
||||
);
|
||||
}
|
||||
|
||||
buffer.writeShort(chunkCount);
|
||||
|
||||
final Deflater deflater = new Deflater();
|
||||
byte[] compressedData;
|
||||
int compressedSize;
|
||||
try {
|
||||
deflater.setInput(data, 0, data.length);
|
||||
deflater.finish();
|
||||
compressedData = new byte[data.length];
|
||||
compressedSize = deflater.deflate(compressedData);
|
||||
} finally {
|
||||
deflater.end();
|
||||
}
|
||||
|
||||
buffer.writeInt(compressedSize);
|
||||
buffer.writeBoolean(anySkyLight);
|
||||
buffer.writeBytes(compressedData, 0, compressedSize);
|
||||
|
||||
for (int i = 0; i < chunkCount; i++) {
|
||||
Chunk chunk = chunks[i];
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeShort(chunk.getBitmask());
|
||||
buffer.writeShort(addBitMasks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+159
-100
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,123 +17,182 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.api.type.chunk;
|
||||
|
||||
import com.viaversion.viarewind.api.minecraft.ExtendedBlockStorage;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.*;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.util.Pair;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
import static com.viaversion.viaversion.api.minecraft.chunks.ChunkSection.SIZE;
|
||||
import static com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionLight.LIGHT_LENGTH;
|
||||
|
||||
public class ChunkType1_7_6 extends Type<Chunk> {
|
||||
|
||||
public static final ChunkType1_7_6 TYPE = new ChunkType1_7_6();
|
||||
public static final ChunkType1_7_6 TYPE = new ChunkType1_7_6();
|
||||
|
||||
public ChunkType1_7_6() {
|
||||
super(Chunk.class);
|
||||
}
|
||||
public ChunkType1_7_6() {
|
||||
super(Chunk.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk read(ByteBuf byteBuf) {
|
||||
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/Chunk1_7_6Type.java
|
||||
}
|
||||
@Override
|
||||
public Chunk read(ByteBuf byteBuf) {
|
||||
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/Chunk1_7_6Type.java
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf output, Chunk chunk) {
|
||||
Pair<byte[], Short> chunkData;
|
||||
try {
|
||||
chunkData = serialize(chunk);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unable to serialize chunk", e);
|
||||
}
|
||||
final byte[] data = chunkData.key();
|
||||
final short additionalBitMask = chunkData.value();
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Chunk chunk) {
|
||||
final int bitmask = chunk.getBitmask();
|
||||
final int addBitmask = getAddBitMask(chunk);
|
||||
final boolean hasSkyLight = hasSkyLight(chunk);
|
||||
final boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null;
|
||||
|
||||
final Deflater deflater = new Deflater();
|
||||
byte[] compressedData;
|
||||
int compressedSize;
|
||||
try {
|
||||
deflater.setInput(data, 0, data.length);
|
||||
deflater.finish();
|
||||
compressedData = new byte[data.length];
|
||||
compressedSize = deflater.deflate(compressedData);
|
||||
} finally {
|
||||
deflater.end();
|
||||
}
|
||||
final int size = calcSize(bitmask, addBitmask, hasSkyLight, biomes);
|
||||
final byte[] data = new byte[size];
|
||||
|
||||
output.writeInt(chunk.getX());
|
||||
output.writeInt(chunk.getZ());
|
||||
output.writeBoolean(chunk.isFullChunk());
|
||||
output.writeShort(chunk.getBitmask());
|
||||
output.writeShort(additionalBitMask);
|
||||
output.writeInt(compressedSize);
|
||||
output.writeBytes(compressedData, 0, compressedSize);
|
||||
}
|
||||
serialize(chunk, data, 0, addBitmask, hasSkyLight, biomes);
|
||||
|
||||
public static Pair<byte[], Short> serialize(final Chunk chunk) throws IOException {
|
||||
final ExtendedBlockStorage[] storageArrays = new ExtendedBlockStorage[16];
|
||||
for (int i = 0; i < storageArrays.length; i++) {
|
||||
final ChunkSection section = chunk.getSections()[i];
|
||||
if (section != null) {
|
||||
final ExtendedBlockStorage storage = storageArrays[i] = new ExtendedBlockStorage(section.getLight().hasSkyLight());
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
final int flatBlock = section.palette(PaletteType.BLOCKS).idAt(x, y, z);
|
||||
storage.setBlockId(x, y, z, flatBlock >> 4);
|
||||
storage.setBlockMetadata(x, y, z, flatBlock & 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
storage.getBlockLightArray().setHandle(section.getLight().getBlockLight());
|
||||
if (section.getLight().hasSkyLight()) {
|
||||
storage.getSkyLightArray().setHandle(section.getLight().getSkyLight());
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.writeInt(chunk.getX());
|
||||
buffer.writeInt(chunk.getZ());
|
||||
buffer.writeBoolean(chunk.isFullChunk());
|
||||
buffer.writeShort(bitmask);
|
||||
buffer.writeShort(addBitmask);
|
||||
|
||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
final Deflater deflater = new Deflater();
|
||||
byte[] compressedData;
|
||||
int compressedSize;
|
||||
try {
|
||||
deflater.setInput(data, 0, data.length);
|
||||
deflater.finish();
|
||||
compressedData = new byte[data.length];
|
||||
compressedSize = deflater.deflate(compressedData);
|
||||
} finally {
|
||||
deflater.end();
|
||||
}
|
||||
|
||||
for (int i = 0; i < storageArrays.length; i++) {
|
||||
if ((chunk.getBitmask() & 1 << i) != 0) {
|
||||
output.write(storageArrays[i].getBlockLSBArray());
|
||||
}
|
||||
}
|
||||
buffer.writeInt(compressedSize);
|
||||
buffer.writeBytes(compressedData, 0, compressedSize);
|
||||
}
|
||||
|
||||
for (int i = 0; i < storageArrays.length; i++) {
|
||||
if ((chunk.getBitmask() & 1 << i) != 0) {
|
||||
output.write(storageArrays[i].getBlockMetadataArray().getHandle());
|
||||
}
|
||||
}
|
||||
public static int serialize(Chunk chunk, byte[] output, int offset, int addBitmask, boolean writeSkyLight, boolean biomes) {
|
||||
final ChunkSection[] sections = chunk.getSections();
|
||||
final int bitmask = chunk.getBitmask();
|
||||
|
||||
for (int i = 0; i < storageArrays.length; i++) {
|
||||
if ((chunk.getBitmask() & 1 << i) != 0) {
|
||||
output.write(storageArrays[i].getBlockLightArray().getHandle());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((bitmask & (1 << i)) != 0) {
|
||||
final ChunkSection section = sections[i];
|
||||
final DataPalette palette = section.palette(PaletteType.BLOCKS);
|
||||
for (int j = 0; j < SIZE; j++) {
|
||||
final int block = palette.idAt(j);
|
||||
output[offset++] = (byte) ((block >> 4) & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < storageArrays.length; i++) {
|
||||
if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].getSkyLightArray() != null) {
|
||||
output.write(storageArrays[i].getSkyLightArray().getHandle());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((bitmask & (1 << i)) != 0) {
|
||||
final ChunkSection section = sections[i];
|
||||
final DataPalette palette = section.palette(PaletteType.BLOCKS);
|
||||
for (int j = 0; j < ChunkSection.SIZE; j += 2) {
|
||||
final int meta1 = palette.idAt(j) & 0xF;
|
||||
final int meta2 = palette.idAt(j + 1) & 0xF;
|
||||
output[offset++] = (byte) (meta1 | (meta2 << 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
short additionalBitMask = 0;
|
||||
for (int i = 0; i < storageArrays.length; i++) {
|
||||
if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].hasBlockMSBArray()) {
|
||||
additionalBitMask |= (short) (1 << i);
|
||||
output.write(storageArrays[i].getOrCreateBlockMSBArray().getHandle());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((bitmask & (1 << i)) != 0) {
|
||||
final byte[] blockLight = sections[i].getLight().getBlockLight();
|
||||
System.arraycopy(blockLight, 0, output, offset, LIGHT_LENGTH);
|
||||
offset += LIGHT_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk.isFullChunk() && chunk.getBiomeData() != null) {
|
||||
for (int biome : chunk.getBiomeData()) {
|
||||
output.write(biome);
|
||||
}
|
||||
}
|
||||
if (writeSkyLight) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((bitmask & (1 << i)) != 0) {
|
||||
if (sections[i].getLight().hasSkyLight()) {
|
||||
final byte[] skyLight = sections[i].getLight().getSkyLight();
|
||||
System.arraycopy(skyLight, 0, output, offset, LIGHT_LENGTH);
|
||||
}
|
||||
offset += LIGHT_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Pair<>(output.toByteArray(), additionalBitMask);
|
||||
}
|
||||
if (addBitmask != 0) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((bitmask & (1 << i)) != 0 && (addBitmask & (1 << i)) != 0) {
|
||||
final ChunkSection section = sections[i];
|
||||
final DataPalette palette = section.palette(PaletteType.BLOCKS);
|
||||
for (int j = 0; j < SIZE; j += 2) {
|
||||
final int add1 = (palette.idAt(j) >> 12) & 0xF;
|
||||
final int add2 = (palette.idAt(j + 1) >> 12) & 0xF;
|
||||
output[offset++] = (byte) (add1 | (add2 << 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (biomes && chunk.getBiomeData() != null) {
|
||||
final int[] biomeData = chunk.getBiomeData();
|
||||
for (int biome : biomeData) {
|
||||
output[offset++] = (byte) biome;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static int calcSize(int bitmask, int addBitmask, boolean hasSkyLight, boolean biomes) {
|
||||
int size = 0;
|
||||
int sections = Integer.bitCount(bitmask);
|
||||
|
||||
size += sections * SIZE;
|
||||
size += sections * (SIZE / 2);
|
||||
size += sections * LIGHT_LENGTH;
|
||||
|
||||
if (hasSkyLight) {
|
||||
size += sections * LIGHT_LENGTH;
|
||||
}
|
||||
|
||||
if (addBitmask != 0) {
|
||||
size += Integer.bitCount(addBitmask) * (SIZE / 2);
|
||||
}
|
||||
|
||||
if (biomes) {
|
||||
size += 256;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
public static int getAddBitMask(Chunk chunk) {
|
||||
int addBitMask = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((chunk.getBitmask() & (1 << i)) != 0) {
|
||||
final ChunkSection section = chunk.getSections()[i];
|
||||
final DataPalette palette = section.palette(PaletteType.BLOCKS);
|
||||
for (int j = 0; j < SIZE; j++) {
|
||||
final int id = palette.idAt(j);
|
||||
if ((id >> 12) != 0) {
|
||||
addBitMask |= (1 << i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return addBitMask;
|
||||
}
|
||||
|
||||
public static boolean hasSkyLight(Chunk chunk) {
|
||||
for (ChunkSection section : chunk.getSections()) {
|
||||
if (section != null && section.getLight().hasSkyLight()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+28
-29
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,41 +22,40 @@ import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListTypeTemplate;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EntityDataListType extends EntityDataListTypeTemplate {
|
||||
|
||||
private final Type<EntityData> type;
|
||||
private final Type<EntityData> type;
|
||||
|
||||
public EntityDataListType(Type<EntityData> type) {
|
||||
this.type = type;
|
||||
}
|
||||
public EntityDataListType(Type<EntityData> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntityData> read(ByteBuf buffer) {
|
||||
ArrayList<EntityData> entityData = new ArrayList<>();
|
||||
@Override
|
||||
public List<EntityData> read(ByteBuf buffer) {
|
||||
ArrayList<EntityData> entityData = new ArrayList<>();
|
||||
|
||||
EntityData data;
|
||||
do {
|
||||
data = type.read(buffer);
|
||||
if (data != null) {
|
||||
entityData.add(data);
|
||||
}
|
||||
} while (data != null);
|
||||
EntityData data;
|
||||
do {
|
||||
data = type.read(buffer);
|
||||
if (data != null) {
|
||||
entityData.add(data);
|
||||
}
|
||||
} while (data != null);
|
||||
|
||||
return entityData;
|
||||
}
|
||||
return entityData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, List<EntityData> entityData) {
|
||||
for (EntityData meta : entityData) {
|
||||
type.write(buffer, meta);
|
||||
}
|
||||
if (entityData.isEmpty()) {
|
||||
type.write(buffer, new EntityData(0, EntityDataTypes1_7_6_10.BYTE, (byte) 0));
|
||||
}
|
||||
buffer.writeByte(127);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void write(ByteBuf buffer, List<EntityData> entityData) {
|
||||
for (EntityData meta : entityData) {
|
||||
type.write(buffer, meta);
|
||||
}
|
||||
if (entityData.isEmpty()) {
|
||||
type.write(buffer, new EntityData(0, EntityDataTypes1_7_6_10.BYTE, (byte) 0));
|
||||
}
|
||||
buffer.writeByte(127);
|
||||
}
|
||||
}
|
||||
+19
-19
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,23 +23,23 @@ import com.viaversion.viaversion.api.type.types.entitydata.EntityDataTypeTemplat
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class EntityDataType extends EntityDataTypeTemplate {
|
||||
@Override
|
||||
public EntityData read(ByteBuf buffer) {
|
||||
byte item = buffer.readByte();
|
||||
if (item == 127) {
|
||||
return null;
|
||||
} else {
|
||||
int typeID = (item & 224) >> 5;
|
||||
EntityDataTypes1_7_6_10 type = EntityDataTypes1_7_6_10.byId(typeID);
|
||||
int id = item & 31;
|
||||
return new EntityData(id, type, type.type().read(buffer));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public EntityData read(ByteBuf buffer) {
|
||||
byte item = buffer.readByte();
|
||||
if (item == 127) {
|
||||
return null;
|
||||
} else {
|
||||
int typeID = (item & 224) >> 5;
|
||||
EntityDataTypes1_7_6_10 type = EntityDataTypes1_7_6_10.byId(typeID);
|
||||
int id = item & 31;
|
||||
return new EntityData(id, type, type.type().read(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, EntityData meta) {
|
||||
int item = (meta.dataType().typeId() << 5 | meta.id() & 31) & 255;
|
||||
buffer.writeByte(item);
|
||||
meta.dataType().type().write(buffer, meta.getValue());
|
||||
}
|
||||
@Override
|
||||
public void write(ByteBuf buffer, EntityData meta) {
|
||||
int item = (meta.dataType().typeId() << 5 | meta.id() & 31) & 255;
|
||||
buffer.writeByte(item);
|
||||
meta.dataType().type().write(buffer, meta.getValue());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,26 +25,26 @@ import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class ItemArrayType extends Type<Item[]> {
|
||||
|
||||
public ItemArrayType() {
|
||||
super(Item[].class);
|
||||
}
|
||||
public ItemArrayType() {
|
||||
super(Item[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item[] read(ByteBuf buffer) {
|
||||
int amount = Types.SHORT.readPrimitive(buffer);
|
||||
Item[] items = new Item[amount];
|
||||
@Override
|
||||
public Item[] read(ByteBuf buffer) {
|
||||
int amount = Types.SHORT.readPrimitive(buffer);
|
||||
Item[] items = new Item[amount];
|
||||
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
items[i] = RewindTypes.COMPRESSED_NBT_ITEM.read(buffer);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
items[i] = RewindTypes.COMPRESSED_NBT_ITEM.read(buffer);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Item[] items) {
|
||||
Types.SHORT.writePrimitive(buffer, (short) items.length);
|
||||
for (Item item : items) {
|
||||
RewindTypes.COMPRESSED_NBT_ITEM.write(buffer, item);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Item[] items) {
|
||||
Types.SHORT.writePrimitive(buffer, (short) items.length);
|
||||
for (Item item : items) {
|
||||
RewindTypes.COMPRESSED_NBT_ITEM.write(buffer, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,33 +25,33 @@ import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class ItemType extends Type<Item> {
|
||||
|
||||
public ItemType() {
|
||||
super(Item.class);
|
||||
}
|
||||
public ItemType() {
|
||||
super(Item.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item read(ByteBuf buffer) {
|
||||
short id = buffer.readShort();
|
||||
if (id < 0) {
|
||||
return null;
|
||||
}
|
||||
Item item = new DataItem();
|
||||
item.setIdentifier(id);
|
||||
item.setAmount(buffer.readByte());
|
||||
item.setData(buffer.readShort());
|
||||
item.setTag(RewindTypes.COMPRESSED_NBT.read(buffer));
|
||||
return item;
|
||||
}
|
||||
@Override
|
||||
public Item read(ByteBuf buffer) {
|
||||
short id = buffer.readShort();
|
||||
if (id < 0) {
|
||||
return null;
|
||||
}
|
||||
Item item = new DataItem();
|
||||
item.setIdentifier(id);
|
||||
item.setAmount(buffer.readByte());
|
||||
item.setData(buffer.readShort());
|
||||
item.setTag(RewindTypes.COMPRESSED_NBT.read(buffer));
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Item item) {
|
||||
if (item == null) {
|
||||
buffer.writeShort(-1);
|
||||
} else {
|
||||
buffer.writeShort(item.identifier());
|
||||
buffer.writeByte(item.amount());
|
||||
buffer.writeShort(item.data());
|
||||
RewindTypes.COMPRESSED_NBT.write(buffer, item.tag());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void write(ByteBuf buffer, Item item) {
|
||||
if (item == null) {
|
||||
buffer.writeShort(-1);
|
||||
} else {
|
||||
buffer.writeShort(item.identifier());
|
||||
buffer.writeByte(item.amount());
|
||||
buffer.writeShort(item.data());
|
||||
RewindTypes.COMPRESSED_NBT.write(buffer, item.tag());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,57 +17,56 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.api.type.item;
|
||||
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.io.NBTIO;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class NBTType extends Type<CompoundTag> {
|
||||
public NBTType() {
|
||||
super(CompoundTag.class);
|
||||
}
|
||||
public NBTType() {
|
||||
super(CompoundTag.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag read(ByteBuf buffer) {
|
||||
short length = buffer.readShort();
|
||||
if (length <= 0) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public CompoundTag read(ByteBuf buffer) {
|
||||
short length = buffer.readShort();
|
||||
if (length <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ByteBuf compressed = buffer.readSlice(length);
|
||||
ByteBuf compressed = buffer.readSlice(length);
|
||||
|
||||
try (GZIPInputStream gzipStream = new GZIPInputStream(new ByteBufInputStream(compressed))) {
|
||||
return NBTIO.reader(CompoundTag.class).named().read(gzipStream);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
try (GZIPInputStream gzipStream = new GZIPInputStream(new ByteBufInputStream(compressed))) {
|
||||
return NBTIO.reader(CompoundTag.class).named().read(gzipStream);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buffer, CompoundTag nbt) {
|
||||
if (nbt == null) {
|
||||
buffer.writeShort(-1);
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void write(ByteBuf buffer, CompoundTag nbt) {
|
||||
if (nbt == null) {
|
||||
buffer.writeShort(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuf compressedBuf = buffer.alloc().buffer();
|
||||
try {
|
||||
try (GZIPOutputStream gzipStream = new GZIPOutputStream(new ByteBufOutputStream(compressedBuf))) {
|
||||
NBTIO.writer().named().write(gzipStream, nbt);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ByteBuf compressedBuf = buffer.alloc().buffer();
|
||||
try {
|
||||
try (GZIPOutputStream gzipStream = new GZIPOutputStream(new ByteBufOutputStream(compressedBuf))) {
|
||||
NBTIO.writer().named().write(gzipStream, nbt);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
buffer.writeShort(compressedBuf.readableBytes());
|
||||
buffer.writeBytes(compressedBuf);
|
||||
} finally {
|
||||
compressedBuf.release();
|
||||
}
|
||||
}
|
||||
buffer.writeShort(compressedBuf.readableBytes());
|
||||
buffer.writeBytes(compressedBuf);
|
||||
} finally {
|
||||
compressedBuf.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.viaversion.viarewind.api.type.version;
|
||||
|
||||
import com.viaversion.viarewind.api.type.entitydata.EntityDataListType;
|
||||
import com.viaversion.viarewind.api.type.entitydata.EntityDataType;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Types1_7_6_10 {
|
||||
|
||||
public static final Type<EntityData> ENTITY_DATA = new EntityDataType();
|
||||
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
|
||||
|
||||
}
|
||||
+75
-76
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5;
|
||||
|
||||
import com.viaversion.viarewind.api.type.version.Types1_7_6_10;
|
||||
import com.viaversion.viarewind.api.type.RewindTypes;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ServerboundPackets1_7_2_5;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
@@ -27,90 +27,89 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Protocol1_7_6_10To1_7_2_5 extends AbstractProtocol<ClientboundPackets1_7_2_5, ClientboundPackets1_7_2_5, ServerboundPackets1_7_2_5, ServerboundPackets1_7_2_5> {
|
||||
|
||||
public static final ValueTransformer<String, String> REMOVE_DASHES = new ValueTransformer<>(Types.STRING) {
|
||||
@Override
|
||||
public String transform(PacketWrapper wrapper, String s) {
|
||||
return s.replace("-", "");
|
||||
}
|
||||
};
|
||||
public static final ValueTransformer<String, String> REMOVE_DASHES = new ValueTransformer<>(Types.STRING) {
|
||||
@Override
|
||||
public String transform(PacketWrapper wrapper, String s) {
|
||||
return s.replace("-", "");
|
||||
}
|
||||
};
|
||||
|
||||
public Protocol1_7_6_10To1_7_2_5() {
|
||||
super(ClientboundPackets1_7_2_5.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class);
|
||||
}
|
||||
public Protocol1_7_6_10To1_7_2_5() {
|
||||
super(ClientboundPackets1_7_2_5.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING, REMOVE_DASHES); // Uuid
|
||||
map(Types.STRING); // Name
|
||||
}
|
||||
});
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING, REMOVE_DASHES); // Uuid
|
||||
map(Types.STRING); // Name
|
||||
}
|
||||
});
|
||||
|
||||
this.registerClientbound(ClientboundPackets1_7_2_5.ADD_PLAYER, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Entity id
|
||||
map(Types.STRING, REMOVE_DASHES); // Uuid
|
||||
map(Types.STRING); // Name
|
||||
handler(wrapper -> {
|
||||
final int size = wrapper.read(Types.VAR_INT); // Data count
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.read(Types.STRING); // Data name
|
||||
wrapper.read(Types.STRING); // Data value
|
||||
wrapper.read(Types.STRING); // Data signature
|
||||
}
|
||||
});
|
||||
map(Types.INT); // X
|
||||
map(Types.INT); // Y
|
||||
map(Types.INT); // Z
|
||||
map(Types.BYTE); // Yaw
|
||||
map(Types.BYTE); // Pitch
|
||||
map(Types.SHORT); // Item in hand
|
||||
map(Types1_7_6_10.ENTITY_DATA_LIST); // Entity data
|
||||
}
|
||||
});
|
||||
this.registerClientbound(ClientboundPackets1_7_2_5.ADD_PLAYER, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Entity id
|
||||
map(Types.STRING, REMOVE_DASHES); // Uuid
|
||||
map(Types.STRING); // Name
|
||||
handler(wrapper -> {
|
||||
final int size = wrapper.read(Types.VAR_INT); // Data count
|
||||
for (int i = 0; i < size; i++) {
|
||||
wrapper.read(Types.STRING); // Data name
|
||||
wrapper.read(Types.STRING); // Data value
|
||||
wrapper.read(Types.STRING); // Data signature
|
||||
}
|
||||
});
|
||||
map(Types.INT); // X
|
||||
map(Types.INT); // Y
|
||||
map(Types.INT); // Z
|
||||
map(Types.BYTE); // Yaw
|
||||
map(Types.BYTE); // Pitch
|
||||
map(Types.SHORT); // Item in hand
|
||||
map(RewindTypes.ENTITY_DATA_LIST1_7); // Entity data
|
||||
}
|
||||
});
|
||||
|
||||
this.registerClientbound(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Team name
|
||||
map(Types.BYTE); // Mode
|
||||
handler(wrapper -> {
|
||||
final byte mode = wrapper.get(Types.BYTE, 0);
|
||||
if (mode == 0 || mode == 2) { // Team is created or information is updated
|
||||
wrapper.passthrough(Types.STRING); // Team display name
|
||||
wrapper.passthrough(Types.STRING); // Team prefix
|
||||
wrapper.passthrough(Types.STRING); // Team suffix
|
||||
wrapper.passthrough(Types.BYTE); // Friendly fire
|
||||
}
|
||||
if (mode == 0 || mode == 3 || mode == 4) { // Team is created, player is added or player is removed
|
||||
List<String> entryList = new ArrayList<>();
|
||||
final int size = wrapper.read(Types.SHORT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
entryList.add(wrapper.read(Types.STRING));
|
||||
}
|
||||
this.registerClientbound(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Team name
|
||||
map(Types.BYTE); // Mode
|
||||
handler(wrapper -> {
|
||||
final byte mode = wrapper.get(Types.BYTE, 0);
|
||||
if (mode == 0 || mode == 2) { // Team is created or information is updated
|
||||
wrapper.passthrough(Types.STRING); // Team display name
|
||||
wrapper.passthrough(Types.STRING); // Team prefix
|
||||
wrapper.passthrough(Types.STRING); // Team suffix
|
||||
wrapper.passthrough(Types.BYTE); // Friendly fire
|
||||
}
|
||||
if (mode == 0 || mode == 3 || mode == 4) { // Team is created, player is added or player is removed
|
||||
List<String> entryList = new ArrayList<>();
|
||||
final int size = wrapper.read(Types.SHORT);
|
||||
for (int i = 0; i < size; i++) {
|
||||
entryList.add(wrapper.read(Types.STRING));
|
||||
}
|
||||
|
||||
entryList = entryList.stream()
|
||||
.map(it -> it.length() > 16 ? it.substring(0, 16) : it) // trim to 16 characters
|
||||
.distinct() // remove duplicates
|
||||
.collect(Collectors.toList());
|
||||
entryList = entryList.stream()
|
||||
.map(it -> it.length() > 16 ? it.substring(0, 16) : it) // trim to 16 characters
|
||||
.distinct() // remove duplicates
|
||||
.collect(Collectors.toList());
|
||||
|
||||
wrapper.write(Types.SHORT, (short) entryList.size());
|
||||
for (String entry : entryList) {
|
||||
wrapper.write(Types.STRING, entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
wrapper.write(Types.SHORT, (short) entryList.size());
|
||||
for (String entry : entryList) {
|
||||
wrapper.write(Types.STRING, entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+74
-74
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,79 +20,79 @@ package com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
|
||||
public enum ClientboundPackets1_7_2_5 implements ClientboundPacketType {
|
||||
KEEP_ALIVE, // 0x00
|
||||
LOGIN, // 0x01
|
||||
CHAT, // 0x02
|
||||
SET_TIME, // 0x03
|
||||
SET_EQUIPPED_ITEM, // 0x04
|
||||
SET_DEFAULT_SPAWN_POSITION, // 0x05
|
||||
SET_HEALTH, // 0x06
|
||||
RESPAWN, // 0x07
|
||||
PLAYER_POSITION, // 0x08
|
||||
SET_CARRIED_ITEM, // 0x09
|
||||
PLAYER_SLEEP, // 0x0A
|
||||
ANIMATE, // 0x0B
|
||||
ADD_PLAYER, // 0x0C
|
||||
TAKE_ITEM_ENTITY, // 0x0D
|
||||
ADD_ENTITY, // 0x0E
|
||||
ADD_MOB, // 0x0F
|
||||
ADD_PAINTING, // 0x10
|
||||
ADD_EXPERIENCE_ORB, // 0x11
|
||||
SET_ENTITY_MOTION, // 0x12
|
||||
REMOVE_ENTITIES, // 0x13
|
||||
MOVE_ENTITY, // 0x14
|
||||
MOVE_ENTITY_POS, // 0x15
|
||||
MOVE_ENTITY_ROT, // 0x16
|
||||
MOVE_ENTITY_POS_ROT, // 0x17
|
||||
TELEPORT_ENTITY, // 0x18
|
||||
ROTATE_HEAD, // 0x19
|
||||
ENTITY_EVENT, // 0x1A
|
||||
SET_ENTITY_LINK, // 0x1B
|
||||
SET_ENTITY_DATA, // 0x1C
|
||||
UPDATE_MOB_EFFECT, // 0x1D
|
||||
REMOVE_MOB_EFFECT, // 0x1E
|
||||
SET_EXPERIENCE, // 0x1F
|
||||
UPDATE_ATTRIBUTES, // 0x20
|
||||
LEVEL_CHUNK, // 0x21
|
||||
CHUNK_BLOCKS_UPDATE, // 0x22
|
||||
BLOCK_UPDATE, // 0x23
|
||||
BLOCK_EVENT, // 0x24
|
||||
BLOCK_DESTRUCTION, // 0x25
|
||||
MAP_BULK_CHUNK, // 0x26
|
||||
EXPLODE, // 0x27
|
||||
LEVEL_EVENT, // 0x28
|
||||
CUSTOM_SOUND, // 0x29
|
||||
LEVEL_PARTICLES, // 0x2A
|
||||
GAME_EVENT, // 0x2B
|
||||
ADD_GLOBAL_ENTITY, // 0x2C
|
||||
OPEN_SCREEN, // 0x2D
|
||||
CONTAINER_CLOSE, // 0x2E
|
||||
CONTAINER_SET_SLOT, // 0x2F
|
||||
CONTAINER_SET_CONTENT, // 0x30
|
||||
CONTAINER_SET_DATA, // 0x31
|
||||
CONTAINER_ACK, // 0x32
|
||||
UPDATE_SIGN, // 0x33
|
||||
MAP_ITEM_DATA, // 0x34
|
||||
BLOCK_ENTITY_DATA, // 0x35
|
||||
OPEN_SIGN_EDITOR, // 0x36
|
||||
AWARD_STATS, // 0x37
|
||||
PLAYER_INFO, // 0x38
|
||||
PLAYER_ABILITIES, // 0x39
|
||||
COMMAND_SUGGESTIONS, // 0x3A
|
||||
SET_OBJECTIVE, // 0x3B
|
||||
SET_SCORE, // 0x3C
|
||||
SET_DISPLAY_OBJECTIVE, // 0x3D
|
||||
SET_PLAYER_TEAM, // 0x3E
|
||||
CUSTOM_PAYLOAD, // 0x3F
|
||||
DISCONNECT; // 0x40
|
||||
KEEP_ALIVE, // 0x00
|
||||
LOGIN, // 0x01
|
||||
CHAT, // 0x02
|
||||
SET_TIME, // 0x03
|
||||
SET_EQUIPPED_ITEM, // 0x04
|
||||
SET_DEFAULT_SPAWN_POSITION, // 0x05
|
||||
SET_HEALTH, // 0x06
|
||||
RESPAWN, // 0x07
|
||||
PLAYER_POSITION, // 0x08
|
||||
SET_CARRIED_ITEM, // 0x09
|
||||
PLAYER_SLEEP, // 0x0A
|
||||
ANIMATE, // 0x0B
|
||||
ADD_PLAYER, // 0x0C
|
||||
TAKE_ITEM_ENTITY, // 0x0D
|
||||
ADD_ENTITY, // 0x0E
|
||||
ADD_MOB, // 0x0F
|
||||
ADD_PAINTING, // 0x10
|
||||
ADD_EXPERIENCE_ORB, // 0x11
|
||||
SET_ENTITY_MOTION, // 0x12
|
||||
REMOVE_ENTITIES, // 0x13
|
||||
MOVE_ENTITY, // 0x14
|
||||
MOVE_ENTITY_POS, // 0x15
|
||||
MOVE_ENTITY_ROT, // 0x16
|
||||
MOVE_ENTITY_POS_ROT, // 0x17
|
||||
TELEPORT_ENTITY, // 0x18
|
||||
ROTATE_HEAD, // 0x19
|
||||
ENTITY_EVENT, // 0x1A
|
||||
SET_ENTITY_LINK, // 0x1B
|
||||
SET_ENTITY_DATA, // 0x1C
|
||||
UPDATE_MOB_EFFECT, // 0x1D
|
||||
REMOVE_MOB_EFFECT, // 0x1E
|
||||
SET_EXPERIENCE, // 0x1F
|
||||
UPDATE_ATTRIBUTES, // 0x20
|
||||
LEVEL_CHUNK, // 0x21
|
||||
CHUNK_BLOCKS_UPDATE, // 0x22
|
||||
BLOCK_UPDATE, // 0x23
|
||||
BLOCK_EVENT, // 0x24
|
||||
BLOCK_DESTRUCTION, // 0x25
|
||||
MAP_BULK_CHUNK, // 0x26
|
||||
EXPLODE, // 0x27
|
||||
LEVEL_EVENT, // 0x28
|
||||
CUSTOM_SOUND, // 0x29
|
||||
LEVEL_PARTICLES, // 0x2A
|
||||
GAME_EVENT, // 0x2B
|
||||
ADD_GLOBAL_ENTITY, // 0x2C
|
||||
OPEN_SCREEN, // 0x2D
|
||||
CONTAINER_CLOSE, // 0x2E
|
||||
CONTAINER_SET_SLOT, // 0x2F
|
||||
CONTAINER_SET_CONTENT, // 0x30
|
||||
CONTAINER_SET_DATA, // 0x31
|
||||
CONTAINER_ACK, // 0x32
|
||||
UPDATE_SIGN, // 0x33
|
||||
MAP_ITEM_DATA, // 0x34
|
||||
BLOCK_ENTITY_DATA, // 0x35
|
||||
OPEN_SIGN_EDITOR, // 0x36
|
||||
AWARD_STATS, // 0x37
|
||||
PLAYER_INFO, // 0x38
|
||||
PLAYER_ABILITIES, // 0x39
|
||||
COMMAND_SUGGESTIONS, // 0x3A
|
||||
SET_OBJECTIVE, // 0x3B
|
||||
SET_SCORE, // 0x3C
|
||||
SET_DISPLAY_OBJECTIVE, // 0x3D
|
||||
SET_PLAYER_TEAM, // 0x3E
|
||||
CUSTOM_PAYLOAD, // 0x3F
|
||||
DISCONNECT; // 0x40
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
+33
-33
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,38 +20,38 @@ package com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
|
||||
public enum ServerboundPackets1_7_2_5 implements ServerboundPacketType {
|
||||
KEEP_ALIVE, // 0x00
|
||||
CHAT, // 0x01
|
||||
INTERACT, // 0x02
|
||||
MOVE_PLAYER_STATUS_ONLY, // 0x03
|
||||
MOVE_PLAYER_POS, // 0x04
|
||||
MOVE_PLAYER_ROT, // 0x05
|
||||
MOVE_PLAYER_POS_ROT, // 0x06
|
||||
PLAYER_ACTION, // 0x07
|
||||
USE_ITEM_ON, // 0x08
|
||||
SET_CARRIED_ITEM, // 0x09
|
||||
SWING, // 0x0A
|
||||
PLAYER_COMMAND, // 0x0B
|
||||
PLAYER_INPUT, // 0x0C
|
||||
CONTAINER_CLOSE, // 0x0D
|
||||
CONTAINER_CLICK, // 0x0E
|
||||
CONTAINER_ACK, // 0x0F
|
||||
SET_CREATIVE_MODE_SLOT, // 0x10
|
||||
CONTAINER_BUTTON_CLICK, // 0x11
|
||||
SIGN_UPDATE, // 0x12
|
||||
PLAYER_ABILITIES, // 0x13
|
||||
COMMAND_SUGGESTION, // 0x14
|
||||
CLIENT_INFORMATION, // 0x15
|
||||
CLIENT_COMMAND, // 0x16
|
||||
CUSTOM_PAYLOAD; // 0x17
|
||||
KEEP_ALIVE, // 0x00
|
||||
CHAT, // 0x01
|
||||
INTERACT, // 0x02
|
||||
MOVE_PLAYER_STATUS_ONLY, // 0x03
|
||||
MOVE_PLAYER_POS, // 0x04
|
||||
MOVE_PLAYER_ROT, // 0x05
|
||||
MOVE_PLAYER_POS_ROT, // 0x06
|
||||
PLAYER_ACTION, // 0x07
|
||||
USE_ITEM_ON, // 0x08
|
||||
SET_CARRIED_ITEM, // 0x09
|
||||
SWING, // 0x0A
|
||||
PLAYER_COMMAND, // 0x0B
|
||||
PLAYER_INPUT, // 0x0C
|
||||
CONTAINER_CLOSE, // 0x0D
|
||||
CONTAINER_CLICK, // 0x0E
|
||||
CONTAINER_ACK, // 0x0F
|
||||
SET_CREATIVE_MODE_SLOT, // 0x10
|
||||
CONTAINER_BUTTON_CLICK, // 0x11
|
||||
SIGN_UPDATE, // 0x12
|
||||
PLAYER_ABILITIES, // 0x13
|
||||
COMMAND_SUGGESTION, // 0x14
|
||||
CLIENT_INFORMATION, // 0x15
|
||||
CLIENT_COMMAND, // 0x16
|
||||
CUSTOM_PAYLOAD; // 0x17
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
@Override
|
||||
public int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
@Override
|
||||
public String getName() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
+100
-98
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,11 +22,20 @@ import com.viaversion.viarewind.ViaRewind;
|
||||
import com.viaversion.viarewind.api.data.RewindMappingData;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ServerboundPackets1_7_2_5;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.EntityPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.*;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.CompressionHandlerProvider;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.TrackingCompressionHandlerProvider;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.*;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.BlockItemPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.EntityPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.PlayerPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.ScoreboardPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.WorldPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.CompressionStatusTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.EntityTracker1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.GameProfileStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.InventoryTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.PlayerSessionStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.ScoreboardTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.WorldBorderEmulator;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.task.WorldBorderUpdateTask;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
@@ -42,121 +51,114 @@ import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_8;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Protocol1_8To1_7_6_10 extends BackwardsProtocol<ClientboundPackets1_8, ClientboundPackets1_7_2_5, ServerboundPackets1_8, ServerboundPackets1_7_2_5> {
|
||||
|
||||
public static final RewindMappingData MAPPINGS = new RewindMappingData("1.8", "1.7.10");
|
||||
public static final RewindMappingData MAPPINGS = new RewindMappingData("1.8", "1.7.10");
|
||||
|
||||
private final BlockItemPacketRewriter1_8 itemRewriter = new BlockItemPacketRewriter1_8(this);
|
||||
private final EntityPacketRewriter1_8 entityRewriter = new EntityPacketRewriter1_8(this);
|
||||
private final BlockItemPacketRewriter1_8 itemRewriter = new BlockItemPacketRewriter1_8(this);
|
||||
private final EntityPacketRewriter1_8 entityRewriter = new EntityPacketRewriter1_8(this);
|
||||
|
||||
public Protocol1_8To1_7_6_10() {
|
||||
super(ClientboundPackets1_8.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_8.class, ServerboundPackets1_7_2_5.class);
|
||||
}
|
||||
public Protocol1_8To1_7_6_10() {
|
||||
super(ClientboundPackets1_8.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_8.class, ServerboundPackets1_7_2_5.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
itemRewriter.register();
|
||||
entityRewriter.register();
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
itemRewriter.register();
|
||||
entityRewriter.register();
|
||||
|
||||
PlayerPacketRewriter1_8.register(this);
|
||||
ScoreboardPacketRewriter1_8.register(this);
|
||||
WorldPacketRewriter1_8.register(this);
|
||||
new PlayerPacketRewriter1_8(this).register();
|
||||
new ScoreboardPacketRewriter1_8(this).register();
|
||||
new WorldPacketRewriter1_8(this).register();
|
||||
|
||||
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO.getId(), ClientboundLoginPackets.HELLO.getId(), new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // server hash
|
||||
map(Types.BYTE_ARRAY_PRIMITIVE, Types.SHORT_BYTE_ARRAY); // public key
|
||||
map(Types.BYTE_ARRAY_PRIMITIVE, Types.SHORT_BYTE_ARRAY); // verification token
|
||||
}
|
||||
});
|
||||
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_COMPRESSION.getId(), ClientboundLoginPackets.LOGIN_COMPRESSION.getId(), new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final int threshold = wrapper.read(Types.VAR_INT);
|
||||
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // server hash
|
||||
map(Types.BYTE_ARRAY_PRIMITIVE, Types.SHORT_BYTE_ARRAY); // public key
|
||||
map(Types.BYTE_ARRAY_PRIMITIVE, Types.SHORT_BYTE_ARRAY); // verification token
|
||||
}
|
||||
});
|
||||
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_COMPRESSION, this::handleCompression);
|
||||
this.registerClientbound(ClientboundPackets1_8.SET_COMPRESSION, null, this::handleCompression);
|
||||
this.registerClientbound(ClientboundPackets1_8.KEEP_ALIVE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT, Types.INT); // id
|
||||
}
|
||||
});
|
||||
|
||||
Via.getManager().getProviders().get(CompressionHandlerProvider.class).onHandleLoginCompressionPacket(wrapper.user(), threshold);
|
||||
wrapper.cancel();
|
||||
});
|
||||
}
|
||||
});
|
||||
this.cancelClientbound(ClientboundPackets1_8.SET_COMPRESSION); // unused
|
||||
this.registerClientbound(ClientboundPackets1_8.KEEP_ALIVE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT, Types.INT); // id
|
||||
}
|
||||
});
|
||||
this.registerServerbound(State.LOGIN, ServerboundLoginPackets.ENCRYPTION_KEY, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.SHORT_BYTE_ARRAY, Types.BYTE_ARRAY_PRIMITIVE); // shared secret
|
||||
map(Types.SHORT_BYTE_ARRAY, Types.BYTE_ARRAY_PRIMITIVE); // verification token
|
||||
}
|
||||
});
|
||||
|
||||
this.registerServerbound(State.LOGIN, ServerboundLoginPackets.ENCRYPTION_KEY.getId(), ServerboundLoginPackets.ENCRYPTION_KEY.getId(), new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.SHORT_BYTE_ARRAY, Types.BYTE_ARRAY_PRIMITIVE); // shared secret
|
||||
map(Types.SHORT_BYTE_ARRAY, Types.BYTE_ARRAY_PRIMITIVE); // verification token
|
||||
}
|
||||
});
|
||||
this.registerServerbound(ServerboundPackets1_7_2_5.KEEP_ALIVE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT, Types.VAR_INT); // id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.registerServerbound(ServerboundPackets1_7_2_5.KEEP_ALIVE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT, Types.VAR_INT); // id
|
||||
}
|
||||
});
|
||||
}
|
||||
private void handleCompression(final PacketWrapper wrapper) {
|
||||
wrapper.cancel();
|
||||
final int threshold = wrapper.read(Types.VAR_INT);
|
||||
|
||||
@Override
|
||||
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws CancelException {
|
||||
Via.getManager().getProviders().get(CompressionHandlerProvider.class).onTransformPacket(packetWrapper.user());
|
||||
Via.getManager().getProviders().get(CompressionHandlerProvider.class).setCompressionThreshold(wrapper.user(), threshold);
|
||||
}
|
||||
|
||||
super.transform(direction, state, packetWrapper);
|
||||
}
|
||||
@Override
|
||||
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws CancelException {
|
||||
Via.getManager().getProviders().get(CompressionHandlerProvider.class).onTransformPacket(packetWrapper.user());
|
||||
|
||||
@Override
|
||||
public void init(UserConnection connection) {
|
||||
connection.addEntityTracker(this.getClass(), new EntityTracker1_8(connection));
|
||||
super.transform(direction, state, packetWrapper);
|
||||
}
|
||||
|
||||
connection.put(new InventoryTracker(connection));
|
||||
connection.put(new PlayerSessionStorage(connection));
|
||||
connection.put(new GameProfileStorage(connection));
|
||||
connection.put(new ScoreboardTracker(connection));
|
||||
connection.put(new CompressionStatusTracker(connection));
|
||||
connection.put(new WorldBorderEmulator(connection));
|
||||
@Override
|
||||
public void init(UserConnection connection) {
|
||||
connection.addEntityTracker(this.getClass(), new EntityTracker1_8(connection));
|
||||
connection.addClientWorld(this.getClass(), new ClientWorld());
|
||||
|
||||
if (!connection.has(ClientWorld.class)) {
|
||||
connection.put(new ClientWorld());
|
||||
}
|
||||
}
|
||||
connection.put(new InventoryTracker(connection));
|
||||
connection.put(new PlayerSessionStorage(connection));
|
||||
connection.put(new GameProfileStorage(connection));
|
||||
connection.put(new ScoreboardTracker(connection));
|
||||
connection.put(new CompressionStatusTracker(connection));
|
||||
connection.put(new WorldBorderEmulator(connection));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(ViaProviders providers) {
|
||||
providers.register(CompressionHandlerProvider.class, new TrackingCompressionHandlerProvider());
|
||||
@Override
|
||||
public void register(ViaProviders providers) {
|
||||
providers.register(CompressionHandlerProvider.class, new TrackingCompressionHandlerProvider());
|
||||
|
||||
if (ViaRewind.getConfig().isEmulateWorldBorder()) {
|
||||
Via.getManager().getScheduler().scheduleRepeating(new WorldBorderUpdateTask(), 0L, 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
if (ViaRewind.getConfig().isEmulateWorldBorder()) {
|
||||
Via.getManager().getScheduler().scheduleRepeating(new WorldBorderUpdateTask(), 0L, 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RewindMappingData getMappingData() {
|
||||
return MAPPINGS;
|
||||
}
|
||||
@Override
|
||||
public RewindMappingData getMappingData() {
|
||||
return MAPPINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockItemPacketRewriter1_8 getItemRewriter() {
|
||||
return itemRewriter;
|
||||
}
|
||||
@Override
|
||||
public BlockItemPacketRewriter1_8 getItemRewriter() {
|
||||
return itemRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPacketRewriter1_8 getEntityRewriter() {
|
||||
return entityRewriter;
|
||||
}
|
||||
@Override
|
||||
public EntityPacketRewriter1_8 getEntityRewriter() {
|
||||
return entityRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMappingDataToLoad() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean hasMappingDataToLoad() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+425
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.DataItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.gson.JsonArray;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
|
||||
// TODO move this into a ComponentRewriter
|
||||
@Deprecated
|
||||
public final class ChatItemRewriter {
|
||||
|
||||
private static final Object2IntMap<String> NAME_TO_ID = new Object2IntOpenHashMap<>(336);
|
||||
|
||||
static {
|
||||
NAME_TO_ID.put("stone", 1);
|
||||
NAME_TO_ID.put("grass", 2);
|
||||
NAME_TO_ID.put("dirt", 3);
|
||||
NAME_TO_ID.put("cobblestone", 4);
|
||||
NAME_TO_ID.put("planks", 5);
|
||||
NAME_TO_ID.put("sapling", 6);
|
||||
NAME_TO_ID.put("bedrock", 7);
|
||||
NAME_TO_ID.put("sand", 12);
|
||||
NAME_TO_ID.put("gravel", 13);
|
||||
NAME_TO_ID.put("gold_ore", 14);
|
||||
NAME_TO_ID.put("iron_ore", 15);
|
||||
NAME_TO_ID.put("coal_ore", 16);
|
||||
NAME_TO_ID.put("log", 17);
|
||||
NAME_TO_ID.put("leaves", 18);
|
||||
NAME_TO_ID.put("sponge", 19);
|
||||
NAME_TO_ID.put("glass", 20);
|
||||
NAME_TO_ID.put("lapis_ore", 21);
|
||||
NAME_TO_ID.put("lapis_block", 22);
|
||||
NAME_TO_ID.put("dispenser", 23);
|
||||
NAME_TO_ID.put("sandstone", 24);
|
||||
NAME_TO_ID.put("noteblock", 25);
|
||||
NAME_TO_ID.put("golden_rail", 27);
|
||||
NAME_TO_ID.put("detector_rail", 28);
|
||||
NAME_TO_ID.put("sticky_piston", 29);
|
||||
NAME_TO_ID.put("web", 30);
|
||||
NAME_TO_ID.put("tallgrass", 31);
|
||||
NAME_TO_ID.put("deadbush", 32);
|
||||
NAME_TO_ID.put("piston", 33);
|
||||
NAME_TO_ID.put("wool", 35);
|
||||
NAME_TO_ID.put("yellow_flower", 37);
|
||||
NAME_TO_ID.put("red_flower", 38);
|
||||
NAME_TO_ID.put("brown_mushroom", 39);
|
||||
NAME_TO_ID.put("red_mushroom", 40);
|
||||
NAME_TO_ID.put("gold_block", 41);
|
||||
NAME_TO_ID.put("iron_block", 42);
|
||||
NAME_TO_ID.put("stone_slab", 44);
|
||||
NAME_TO_ID.put("brick_block", 45);
|
||||
NAME_TO_ID.put("tnt", 46);
|
||||
NAME_TO_ID.put("bookshelf", 47);
|
||||
NAME_TO_ID.put("mossy_cobblestone", 48);
|
||||
NAME_TO_ID.put("obsidian", 49);
|
||||
NAME_TO_ID.put("torch", 50);
|
||||
NAME_TO_ID.put("mob_spawner", 52);
|
||||
NAME_TO_ID.put("oak_stairs", 53);
|
||||
NAME_TO_ID.put("chest", 54);
|
||||
NAME_TO_ID.put("diamond_ore", 56);
|
||||
NAME_TO_ID.put("diamond_block", 57);
|
||||
NAME_TO_ID.put("crafting_table", 58);
|
||||
NAME_TO_ID.put("farmland", 60);
|
||||
NAME_TO_ID.put("furnace", 61);
|
||||
NAME_TO_ID.put("ladder", 65);
|
||||
NAME_TO_ID.put("rail", 66);
|
||||
NAME_TO_ID.put("stone_stairs", 67);
|
||||
NAME_TO_ID.put("lever", 69);
|
||||
NAME_TO_ID.put("stone_pressure_plate", 70);
|
||||
NAME_TO_ID.put("wooden_pressure_plate", 72);
|
||||
NAME_TO_ID.put("redstone_ore", 73);
|
||||
NAME_TO_ID.put("redstone_torch", 76);
|
||||
NAME_TO_ID.put("stone_button", 77);
|
||||
NAME_TO_ID.put("snow_layer", 78);
|
||||
NAME_TO_ID.put("ice", 79);
|
||||
NAME_TO_ID.put("snow", 80);
|
||||
NAME_TO_ID.put("cactus", 81);
|
||||
NAME_TO_ID.put("clay", 82);
|
||||
NAME_TO_ID.put("jukebox", 84);
|
||||
NAME_TO_ID.put("fence", 85);
|
||||
NAME_TO_ID.put("pumpkin", 86);
|
||||
NAME_TO_ID.put("netherrack", 87);
|
||||
NAME_TO_ID.put("soul_sand", 88);
|
||||
NAME_TO_ID.put("glowstone", 89);
|
||||
NAME_TO_ID.put("lit_pumpkin", 91);
|
||||
NAME_TO_ID.put("stained_glass", 95);
|
||||
NAME_TO_ID.put("trapdoor", 96);
|
||||
NAME_TO_ID.put("monster_egg", 97);
|
||||
NAME_TO_ID.put("stonebrick", 98);
|
||||
NAME_TO_ID.put("brown_mushroom_block", 99);
|
||||
NAME_TO_ID.put("red_mushroom_block", 100);
|
||||
NAME_TO_ID.put("iron_bars", 101);
|
||||
NAME_TO_ID.put("glass_pane", 102);
|
||||
NAME_TO_ID.put("melon_block", 103);
|
||||
NAME_TO_ID.put("vine", 106);
|
||||
NAME_TO_ID.put("fence_gate", 107);
|
||||
NAME_TO_ID.put("brick_stairs", 108);
|
||||
NAME_TO_ID.put("stone_brick_stairs", 109);
|
||||
NAME_TO_ID.put("mycelium", 110);
|
||||
NAME_TO_ID.put("waterlily", 111);
|
||||
NAME_TO_ID.put("nether_brick", 112);
|
||||
NAME_TO_ID.put("nether_brick_fence", 113);
|
||||
NAME_TO_ID.put("nether_brick_stairs", 114);
|
||||
NAME_TO_ID.put("enchanting_table", 116);
|
||||
NAME_TO_ID.put("end_portal_frame", 120);
|
||||
NAME_TO_ID.put("end_stone", 121);
|
||||
NAME_TO_ID.put("dragon_egg", 122);
|
||||
NAME_TO_ID.put("redstone_lamp", 123);
|
||||
NAME_TO_ID.put("wooden_slab", 126);
|
||||
NAME_TO_ID.put("sandstone_stairs", 128);
|
||||
NAME_TO_ID.put("emerald_ore", 129);
|
||||
NAME_TO_ID.put("ender_chest", 130);
|
||||
NAME_TO_ID.put("tripwire_hook", 131);
|
||||
NAME_TO_ID.put("emerald_block", 133);
|
||||
NAME_TO_ID.put("spruce_stairs", 134);
|
||||
NAME_TO_ID.put("birch_stairs", 135);
|
||||
NAME_TO_ID.put("jungle_stairs", 136);
|
||||
NAME_TO_ID.put("command_block", 137);
|
||||
NAME_TO_ID.put("beacon", 138);
|
||||
NAME_TO_ID.put("cobblestone_wall", 139);
|
||||
NAME_TO_ID.put("wooden_button", 143);
|
||||
NAME_TO_ID.put("anvil", 145);
|
||||
NAME_TO_ID.put("trapped_chest", 146);
|
||||
NAME_TO_ID.put("light_weighted_pressure_plate", 147);
|
||||
NAME_TO_ID.put("heavy_weighted_pressure_plate", 148);
|
||||
NAME_TO_ID.put("daylight_detector", 151);
|
||||
NAME_TO_ID.put("redstone_block", 152);
|
||||
NAME_TO_ID.put("quartz_ore", 153);
|
||||
NAME_TO_ID.put("hopper", 154);
|
||||
NAME_TO_ID.put("quartz_block", 155);
|
||||
NAME_TO_ID.put("quartz_stairs", 156);
|
||||
NAME_TO_ID.put("activator_rail", 157);
|
||||
NAME_TO_ID.put("dropper", 158);
|
||||
NAME_TO_ID.put("stained_hardened_clay", 159);
|
||||
NAME_TO_ID.put("stained_glass_pane", 160);
|
||||
NAME_TO_ID.put("leaves2", 161);
|
||||
NAME_TO_ID.put("log2", 162);
|
||||
NAME_TO_ID.put("acacia_stairs", 163);
|
||||
NAME_TO_ID.put("dark_oak_stairs", 164);
|
||||
NAME_TO_ID.put("slime", 165);
|
||||
NAME_TO_ID.put("barrier", 166);
|
||||
NAME_TO_ID.put("iron_trapdoor", 167);
|
||||
NAME_TO_ID.put("prismarine", 168);
|
||||
NAME_TO_ID.put("sea_lantern", 169);
|
||||
NAME_TO_ID.put("hay_block", 170);
|
||||
NAME_TO_ID.put("carpet", 171);
|
||||
NAME_TO_ID.put("hardened_clay", 172);
|
||||
NAME_TO_ID.put("coal_block", 173);
|
||||
NAME_TO_ID.put("packed_ice", 174);
|
||||
NAME_TO_ID.put("double_plant", 175);
|
||||
NAME_TO_ID.put("red_sandstone", 179);
|
||||
NAME_TO_ID.put("red_sandstone_stairs", 180);
|
||||
NAME_TO_ID.put("stone_slab2", 182);
|
||||
NAME_TO_ID.put("spruce_fence_gate", 183);
|
||||
NAME_TO_ID.put("birch_fence_gate", 184);
|
||||
NAME_TO_ID.put("jungle_fence_gate", 185);
|
||||
NAME_TO_ID.put("dark_oak_fence_gate", 186);
|
||||
NAME_TO_ID.put("acacia_fence_gate", 187);
|
||||
NAME_TO_ID.put("spruce_fence", 188);
|
||||
NAME_TO_ID.put("birch_fence", 189);
|
||||
NAME_TO_ID.put("jungle_fence", 190);
|
||||
NAME_TO_ID.put("dark_oak_fence", 191);
|
||||
NAME_TO_ID.put("acacia_fence", 192);
|
||||
NAME_TO_ID.put("iron_shovel", 256);
|
||||
NAME_TO_ID.put("iron_pickaxe", 257);
|
||||
NAME_TO_ID.put("iron_axe", 258);
|
||||
NAME_TO_ID.put("flint_and_steel", 259);
|
||||
NAME_TO_ID.put("apple", 260);
|
||||
NAME_TO_ID.put("bow", 261);
|
||||
NAME_TO_ID.put("arrow", 262);
|
||||
NAME_TO_ID.put("coal", 263);
|
||||
NAME_TO_ID.put("diamond", 264);
|
||||
NAME_TO_ID.put("iron_ingot", 265);
|
||||
NAME_TO_ID.put("gold_ingot", 266);
|
||||
NAME_TO_ID.put("iron_sword", 267);
|
||||
NAME_TO_ID.put("wooden_sword", 268);
|
||||
NAME_TO_ID.put("wooden_shovel", 269);
|
||||
NAME_TO_ID.put("wooden_pickaxe", 270);
|
||||
NAME_TO_ID.put("wooden_axe", 271);
|
||||
NAME_TO_ID.put("stone_sword", 272);
|
||||
NAME_TO_ID.put("stone_shovel", 273);
|
||||
NAME_TO_ID.put("stone_pickaxe", 274);
|
||||
NAME_TO_ID.put("stone_axe", 275);
|
||||
NAME_TO_ID.put("diamond_sword", 276);
|
||||
NAME_TO_ID.put("diamond_shovel", 277);
|
||||
NAME_TO_ID.put("diamond_pickaxe", 278);
|
||||
NAME_TO_ID.put("diamond_axe", 279);
|
||||
NAME_TO_ID.put("stick", 280);
|
||||
NAME_TO_ID.put("bowl", 281);
|
||||
NAME_TO_ID.put("mushroom_stew", 282);
|
||||
NAME_TO_ID.put("golden_sword", 283);
|
||||
NAME_TO_ID.put("golden_shovel", 284);
|
||||
NAME_TO_ID.put("golden_pickaxe", 285);
|
||||
NAME_TO_ID.put("golden_axe", 286);
|
||||
NAME_TO_ID.put("string", 287);
|
||||
NAME_TO_ID.put("feather", 288);
|
||||
NAME_TO_ID.put("gunpowder", 289);
|
||||
NAME_TO_ID.put("wooden_hoe", 290);
|
||||
NAME_TO_ID.put("stone_hoe", 291);
|
||||
NAME_TO_ID.put("iron_hoe", 292);
|
||||
NAME_TO_ID.put("diamond_hoe", 293);
|
||||
NAME_TO_ID.put("golden_hoe", 294);
|
||||
NAME_TO_ID.put("wheat_seeds", 295);
|
||||
NAME_TO_ID.put("wheat", 296);
|
||||
NAME_TO_ID.put("bread", 297);
|
||||
NAME_TO_ID.put("leather_helmet", 298);
|
||||
NAME_TO_ID.put("leather_chestplate", 299);
|
||||
NAME_TO_ID.put("leather_leggings", 300);
|
||||
NAME_TO_ID.put("leather_boots", 301);
|
||||
NAME_TO_ID.put("chainmail_helmet", 302);
|
||||
NAME_TO_ID.put("chainmail_chestplate", 303);
|
||||
NAME_TO_ID.put("chainmail_leggings", 304);
|
||||
NAME_TO_ID.put("chainmail_boots", 305);
|
||||
NAME_TO_ID.put("iron_helmet", 306);
|
||||
NAME_TO_ID.put("iron_chestplate", 307);
|
||||
NAME_TO_ID.put("iron_leggings", 308);
|
||||
NAME_TO_ID.put("iron_boots", 309);
|
||||
NAME_TO_ID.put("diamond_helmet", 310);
|
||||
NAME_TO_ID.put("diamond_chestplate", 311);
|
||||
NAME_TO_ID.put("diamond_leggings", 312);
|
||||
NAME_TO_ID.put("diamond_boots", 313);
|
||||
NAME_TO_ID.put("golden_helmet", 314);
|
||||
NAME_TO_ID.put("golden_chestplate", 315);
|
||||
NAME_TO_ID.put("golden_leggings", 316);
|
||||
NAME_TO_ID.put("golden_boots", 317);
|
||||
NAME_TO_ID.put("flint", 318);
|
||||
NAME_TO_ID.put("porkchop", 319);
|
||||
NAME_TO_ID.put("cooked_porkchop", 320);
|
||||
NAME_TO_ID.put("painting", 321);
|
||||
NAME_TO_ID.put("golden_apple", 322);
|
||||
NAME_TO_ID.put("sign", 323);
|
||||
NAME_TO_ID.put("wooden_door", 324);
|
||||
NAME_TO_ID.put("bucket", 325);
|
||||
NAME_TO_ID.put("water_bucket", 326);
|
||||
NAME_TO_ID.put("lava_bucket", 327);
|
||||
NAME_TO_ID.put("minecart", 328);
|
||||
NAME_TO_ID.put("saddle", 329);
|
||||
NAME_TO_ID.put("iron_door", 330);
|
||||
NAME_TO_ID.put("redstone", 331);
|
||||
NAME_TO_ID.put("snowball", 332);
|
||||
NAME_TO_ID.put("boat", 333);
|
||||
NAME_TO_ID.put("leather", 334);
|
||||
NAME_TO_ID.put("milk_bucket", 335);
|
||||
NAME_TO_ID.put("brick", 336);
|
||||
NAME_TO_ID.put("clay_ball", 337);
|
||||
NAME_TO_ID.put("reeds", 338);
|
||||
NAME_TO_ID.put("paper", 339);
|
||||
NAME_TO_ID.put("book", 340);
|
||||
NAME_TO_ID.put("slime_ball", 341);
|
||||
NAME_TO_ID.put("chest_minecart", 342);
|
||||
NAME_TO_ID.put("furnace_minecart", 343);
|
||||
NAME_TO_ID.put("egg", 344);
|
||||
NAME_TO_ID.put("compass", 345);
|
||||
NAME_TO_ID.put("fishing_rod", 346);
|
||||
NAME_TO_ID.put("clock", 347);
|
||||
NAME_TO_ID.put("glowstone_dust", 348);
|
||||
NAME_TO_ID.put("fish", 349);
|
||||
NAME_TO_ID.put("cooked_fish", 350);
|
||||
NAME_TO_ID.put("dye", 351);
|
||||
NAME_TO_ID.put("bone", 352);
|
||||
NAME_TO_ID.put("sugar", 353);
|
||||
NAME_TO_ID.put("cake", 354);
|
||||
NAME_TO_ID.put("bed", 355);
|
||||
NAME_TO_ID.put("repeater", 356);
|
||||
NAME_TO_ID.put("cookie", 357);
|
||||
NAME_TO_ID.put("filled_map", 358);
|
||||
NAME_TO_ID.put("shears", 359);
|
||||
NAME_TO_ID.put("melon", 360);
|
||||
NAME_TO_ID.put("pumpkin_seeds", 361);
|
||||
NAME_TO_ID.put("melon_seeds", 362);
|
||||
NAME_TO_ID.put("beef", 363);
|
||||
NAME_TO_ID.put("cooked_beef", 364);
|
||||
NAME_TO_ID.put("chicken", 365);
|
||||
NAME_TO_ID.put("cooked_chicken", 366);
|
||||
NAME_TO_ID.put("rotten_flesh", 367);
|
||||
NAME_TO_ID.put("ender_pearl", 368);
|
||||
NAME_TO_ID.put("blaze_rod", 369);
|
||||
NAME_TO_ID.put("ghast_tear", 370);
|
||||
NAME_TO_ID.put("gold_nugget", 371);
|
||||
NAME_TO_ID.put("nether_wart", 372);
|
||||
NAME_TO_ID.put("potion", 373);
|
||||
NAME_TO_ID.put("glass_bottle", 374);
|
||||
NAME_TO_ID.put("spider_eye", 375);
|
||||
NAME_TO_ID.put("fermented_spider_eye", 376);
|
||||
NAME_TO_ID.put("blaze_powder", 377);
|
||||
NAME_TO_ID.put("magma_cream", 378);
|
||||
NAME_TO_ID.put("brewing_stand", 379);
|
||||
NAME_TO_ID.put("cauldron", 380);
|
||||
NAME_TO_ID.put("ender_eye", 381);
|
||||
NAME_TO_ID.put("speckled_melon", 382);
|
||||
NAME_TO_ID.put("spawn_egg", 383);
|
||||
NAME_TO_ID.put("experience_bottle", 384);
|
||||
NAME_TO_ID.put("fire_charge", 385);
|
||||
NAME_TO_ID.put("writable_book", 386);
|
||||
NAME_TO_ID.put("written_book", 387);
|
||||
NAME_TO_ID.put("emerald", 388);
|
||||
NAME_TO_ID.put("item_frame", 389);
|
||||
NAME_TO_ID.put("flower_pot", 390);
|
||||
NAME_TO_ID.put("carrot", 391);
|
||||
NAME_TO_ID.put("potato", 392);
|
||||
NAME_TO_ID.put("baked_potato", 393);
|
||||
NAME_TO_ID.put("poisonous_potato", 394);
|
||||
NAME_TO_ID.put("map", 395);
|
||||
NAME_TO_ID.put("golden_carrot", 396);
|
||||
NAME_TO_ID.put("skull", 397);
|
||||
NAME_TO_ID.put("carrot_on_a_stick", 398);
|
||||
NAME_TO_ID.put("nether_star", 399);
|
||||
NAME_TO_ID.put("pumpkin_pie", 400);
|
||||
NAME_TO_ID.put("fireworks", 401);
|
||||
NAME_TO_ID.put("firework_charge", 402);
|
||||
NAME_TO_ID.put("enchanted_book", 403);
|
||||
NAME_TO_ID.put("comparator", 404);
|
||||
NAME_TO_ID.put("netherbrick", 405);
|
||||
NAME_TO_ID.put("quartz", 406);
|
||||
NAME_TO_ID.put("tnt_minecart", 407);
|
||||
NAME_TO_ID.put("hopper_minecart", 408);
|
||||
NAME_TO_ID.put("prismarine_shard", 409);
|
||||
NAME_TO_ID.put("prismarine_crystals", 410);
|
||||
NAME_TO_ID.put("rabbit", 411);
|
||||
NAME_TO_ID.put("cooked_rabbit", 412);
|
||||
NAME_TO_ID.put("rabbit_stew", 413);
|
||||
NAME_TO_ID.put("rabbit_foot", 414);
|
||||
NAME_TO_ID.put("rabbit_hide", 415);
|
||||
NAME_TO_ID.put("armor_stand", 416);
|
||||
NAME_TO_ID.put("iron_horse_armor", 417);
|
||||
NAME_TO_ID.put("golden_horse_armor", 418);
|
||||
NAME_TO_ID.put("diamond_horse_armor", 419);
|
||||
NAME_TO_ID.put("lead", 420);
|
||||
NAME_TO_ID.put("name_tag", 421);
|
||||
NAME_TO_ID.put("command_block_minecart", 422);
|
||||
NAME_TO_ID.put("mutton", 423);
|
||||
NAME_TO_ID.put("cooked_mutton", 424);
|
||||
NAME_TO_ID.put("banner", 425);
|
||||
NAME_TO_ID.put("spruce_door", 427);
|
||||
NAME_TO_ID.put("birch_door", 428);
|
||||
NAME_TO_ID.put("jungle_door", 429);
|
||||
NAME_TO_ID.put("acacia_door", 430);
|
||||
NAME_TO_ID.put("dark_oak_door", 431);
|
||||
NAME_TO_ID.put("record_13", 2256);
|
||||
NAME_TO_ID.put("record_cat", 2257);
|
||||
NAME_TO_ID.put("record_blocks", 2258);
|
||||
NAME_TO_ID.put("record_chirp", 2259);
|
||||
NAME_TO_ID.put("record_far", 2260);
|
||||
NAME_TO_ID.put("record_mall", 2261);
|
||||
NAME_TO_ID.put("record_mellohi", 2262);
|
||||
NAME_TO_ID.put("record_stal", 2263);
|
||||
NAME_TO_ID.put("record_strad", 2264);
|
||||
NAME_TO_ID.put("record_ward", 2265);
|
||||
NAME_TO_ID.put("record_11", 2266);
|
||||
NAME_TO_ID.put("record_wait", 2267);
|
||||
}
|
||||
|
||||
public static void toClient(final Protocol1_8To1_7_6_10 protocol, final UserConnection connection, JsonElement element) {
|
||||
if (element instanceof final JsonObject obj) {
|
||||
if (obj.has("hoverEvent")) {
|
||||
if (!(obj.get("hoverEvent") instanceof final JsonObject hoverEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hoverEvent.has("action") || !hoverEvent.has("value")) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String type = hoverEvent.get("action").getAsString();
|
||||
if (!type.equals("show_item")) {
|
||||
return;
|
||||
}
|
||||
|
||||
final CompoundTag compound = ComponentUtil.deserializeLegacyShowItem(hoverEvent.get("value"), SerializerVersion.V1_8);
|
||||
final int identifier;
|
||||
final String stringId = compound.getString("id");
|
||||
if (stringId != null) {
|
||||
identifier = NAME_TO_ID.getOrDefault(Key.stripMinecraftNamespace(stringId), compound.getShort("id"));
|
||||
} else {
|
||||
identifier = compound.getShort("id");
|
||||
}
|
||||
final CompoundTag itemTag = compound.getCompoundTag("tag");
|
||||
|
||||
final Item dataItem = new DataItem(identifier, (byte) 1, (short) 0, itemTag);
|
||||
protocol.getItemRewriter().handleItemToClient(connection, dataItem);
|
||||
|
||||
compound.putInt("id", dataItem.identifier());
|
||||
if (dataItem.tag() != itemTag) {
|
||||
compound.put("tag", dataItem.tag());
|
||||
}
|
||||
hoverEvent.addProperty("value", SerializerVersion.V1_7.toSNBT(compound));
|
||||
} else if (obj.has("extra")) {
|
||||
toClient(protocol, connection, obj.get("extra"));
|
||||
} else if (obj.has("translate") && obj.has("with")) {
|
||||
toClient(protocol, connection, obj.get("with"));
|
||||
}
|
||||
} else if (element instanceof final JsonArray array) {
|
||||
for (JsonElement value : array) {
|
||||
toClient(protocol, connection, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data;
|
||||
|
||||
import com.viaversion.viaversion.libs.gson.JsonArray;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChatNewlineRewriter {
|
||||
public static List<JsonObject> splitChatComponentByNewline(JsonElement element) {
|
||||
return splitChatComponentByNewline(element, new JsonObject());
|
||||
}
|
||||
|
||||
private static List<JsonObject> splitChatComponentByNewline(JsonElement element, JsonObject inheritedStyle) {
|
||||
List<JsonObject> results = new ArrayList<>();
|
||||
if (element == null || element.isJsonNull()) {
|
||||
return results;
|
||||
}
|
||||
|
||||
if (element.isJsonPrimitive()) {
|
||||
String text = element.getAsString();
|
||||
for (String part : text.split("\n", -1)) {
|
||||
JsonObject obj = inheritedStyle.deepCopy();
|
||||
obj.addProperty("text", part);
|
||||
results.add(obj);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
if (element.isJsonArray()) {
|
||||
for (JsonElement child : element.getAsJsonArray()) {
|
||||
results.addAll(splitChatComponentByNewline(child, inheritedStyle));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
if (!element.isJsonObject()) {
|
||||
return results;
|
||||
}
|
||||
|
||||
JsonObject obj = element.getAsJsonObject();
|
||||
|
||||
// Build the style for this node: inherit first, then override with this object's style
|
||||
JsonObject currentStyle = inheritedStyle.deepCopy();
|
||||
for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!"text".equals(key) && !"extra".equals(key)) {
|
||||
currentStyle.add(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// Gather components in order: base text then extra array
|
||||
List<JsonElement> ordered = new ArrayList<>();
|
||||
if (obj.has("text")) {
|
||||
ordered.add(obj.get("text"));
|
||||
}
|
||||
if (obj.has("extra") && obj.get("extra").isJsonArray()) {
|
||||
for (JsonElement extra : obj.getAsJsonArray("extra")) {
|
||||
ordered.add(extra);
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no text/extra, return a single object with the style
|
||||
if (ordered.isEmpty()) {
|
||||
results.add(currentStyle);
|
||||
return results;
|
||||
}
|
||||
|
||||
// Build lines by concatenating split pieces
|
||||
List<JsonObject> currentLine = new ArrayList<>();
|
||||
for (JsonElement part : ordered) {
|
||||
if (part == null || part.isJsonNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part.isJsonPrimitive()) {
|
||||
String text = part.getAsString();
|
||||
String[] split = text.split("\n", -1);
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
JsonObject piece = currentStyle.deepCopy();
|
||||
piece.addProperty("text", split[i]);
|
||||
currentLine.add(piece);
|
||||
|
||||
if (i < split.length - 1) {
|
||||
results.add(mergeLine(currentLine));
|
||||
currentLine.clear();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part.isJsonObject() || part.isJsonArray()) {
|
||||
List<JsonObject> splitParts = splitChatComponentByNewline(part, currentStyle);
|
||||
for (int i = 0; i < splitParts.size(); i++) {
|
||||
currentLine.add(splitParts.get(i));
|
||||
if (i < splitParts.size() - 1) {
|
||||
results.add(mergeLine(currentLine));
|
||||
currentLine.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentLine.isEmpty()) {
|
||||
results.add(mergeLine(currentLine));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static JsonObject mergeLine(List<JsonObject> lineParts) {
|
||||
if (lineParts.isEmpty()) {
|
||||
JsonObject empty = new JsonObject();
|
||||
empty.addProperty("text", "");
|
||||
return empty;
|
||||
}
|
||||
|
||||
JsonObject first = lineParts.get(0);
|
||||
if (lineParts.size() == 1) {
|
||||
return first;
|
||||
}
|
||||
|
||||
JsonArray extra = new JsonArray();
|
||||
for (int i = 1; i < lineParts.size(); i++) {
|
||||
extra.add(lineParts.get(i));
|
||||
}
|
||||
first.add("extra", extra);
|
||||
return first;
|
||||
}
|
||||
}
|
||||
+170
-142
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,198 +22,226 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
|
||||
import com.viaversion.viaversion.util.Pair;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.*;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ABSTRACT_AGEABLE;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ABSTRACT_MINECART;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ARMOR_STAND;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ARROW;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.BAT;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.BLAZE;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.BOAT;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.CREEPER;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ENDERMAN;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.END_CRYSTAL;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ENTITY;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.FIREWORK_ROCKET;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.FURNACE_MINECART;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.GHAST;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.GUARDIAN;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.HORSE;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.IRON_GOLEM;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ITEM;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ITEM_FRAME;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.LIVING_ENTITY;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.LIVING_ENTITY_BASE;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.OCELOT;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.PIG;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.PLAYER;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.SHEEP;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.SKELETON;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.SLIME;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.SPIDER;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.TAMABLE_ANIMAL;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.VILLAGER;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.WITCH;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.WITHER;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.WOLF;
|
||||
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.ZOMBIE;
|
||||
|
||||
public enum EntityDataIndex1_7_6_10 {
|
||||
|
||||
ENTITY_FLAGS(ENTITY, 0, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ENTITY_AIR(ENTITY, 1, EntityDataTypes1_7_6_10.SHORT, EntityDataTypes1_8.SHORT),
|
||||
ENTITY_NAME_TAG(ENTITY, -1, null, 2, EntityDataTypes1_8.STRING),
|
||||
ENTITY_NAME_TAG_VISIBILITY(ENTITY, -1, null, 3, EntityDataTypes1_8.BYTE),
|
||||
ENTITY_SILENT(ENTITY, -1, null, 4, EntityDataTypes1_8.BYTE),
|
||||
ENTITY_FLAGS(ENTITY, 0, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ENTITY_AIR(ENTITY, 1, EntityDataTypes1_7_6_10.SHORT, EntityDataTypes1_8.SHORT),
|
||||
ENTITY_NAME_TAG(ENTITY, -1, null, 2, EntityDataTypes1_8.STRING),
|
||||
ENTITY_NAME_TAG_VISIBILITY(ENTITY, -1, null, 3, EntityDataTypes1_8.BYTE),
|
||||
ENTITY_SILENT(ENTITY, -1, null, 4, EntityDataTypes1_8.BYTE),
|
||||
|
||||
LIVING_ENTITY_BASE_HEALTH(LIVING_ENTITY_BASE, 6, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
LIVING_ENTITY_BASE_POTION_EFFECT_COLOR(LIVING_ENTITY_BASE, 7, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
LIVING_ENTITY_BASE_IS_POTION_EFFECT_AMBIENT(LIVING_ENTITY_BASE, 8, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
LIVING_ENTITY_BASE_ARROWS(LIVING_ENTITY_BASE, 9, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
LIVING_ENTITY_BASE_NAME_TAG(LIVING_ENTITY_BASE, 10, EntityDataTypes1_7_6_10.STRING, 2, EntityDataTypes1_8.STRING),
|
||||
LIVING_ENTITY_BASE_NAME_TAG_VISIBILITY(LIVING_ENTITY_BASE, 11, EntityDataTypes1_7_6_10.BYTE, 3, EntityDataTypes1_8.BYTE),
|
||||
LIVING_ENTITY_BASE_HEALTH(LIVING_ENTITY_BASE, 6, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
LIVING_ENTITY_BASE_POTION_EFFECT_COLOR(LIVING_ENTITY_BASE, 7, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
LIVING_ENTITY_BASE_IS_POTION_EFFECT_AMBIENT(LIVING_ENTITY_BASE, 8, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
LIVING_ENTITY_BASE_ARROWS(LIVING_ENTITY_BASE, 9, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
LIVING_ENTITY_BASE_NAME_TAG(LIVING_ENTITY_BASE, 10, EntityDataTypes1_7_6_10.STRING, 2, EntityDataTypes1_8.STRING),
|
||||
LIVING_ENTITY_BASE_NAME_TAG_VISIBILITY(LIVING_ENTITY_BASE, 11, EntityDataTypes1_7_6_10.BYTE, 3, EntityDataTypes1_8.BYTE),
|
||||
|
||||
LIVING_ENTITY_AI(LIVING_ENTITY, -1, null, 15, EntityDataTypes1_8.BYTE),
|
||||
LIVING_ENTITY_AI(LIVING_ENTITY, -1, null, 15, EntityDataTypes1_8.BYTE),
|
||||
|
||||
ABSTRACT_AGEABLE_AGE(ABSTRACT_AGEABLE, 12, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.BYTE),
|
||||
ABSTRACT_AGEABLE_AGE(ABSTRACT_AGEABLE, 12, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.BYTE),
|
||||
|
||||
ARMOR_STAND_FLAGS(ARMOR_STAND, -1, null, 10, EntityDataTypes1_8.BYTE),
|
||||
ARMOR_STAND_HEAD_POSITION(ARMOR_STAND, -1, null, 11, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_BODY_POSITION(ARMOR_STAND, -1, null, 12, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_LEFT_ARM_POSITION(ARMOR_STAND, -1, null, 13, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_RIGHT_ARM_POSITION(ARMOR_STAND, -1, null, 14, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_LEFT_LEG_POSITION(ARMOR_STAND, -1, null, 15, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_RIGHT_LEG_POSITION(ARMOR_STAND, -1, null, 16, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_FLAGS(ARMOR_STAND, -1, null, 10, EntityDataTypes1_8.BYTE),
|
||||
ARMOR_STAND_HEAD_POSITION(ARMOR_STAND, -1, null, 11, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_BODY_POSITION(ARMOR_STAND, -1, null, 12, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_LEFT_ARM_POSITION(ARMOR_STAND, -1, null, 13, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_RIGHT_ARM_POSITION(ARMOR_STAND, -1, null, 14, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_LEFT_LEG_POSITION(ARMOR_STAND, -1, null, 15, EntityDataTypes1_8.ROTATIONS),
|
||||
ARMOR_STAND_RIGHT_LEG_POSITION(ARMOR_STAND, -1, null, 16, EntityDataTypes1_8.ROTATIONS),
|
||||
|
||||
PLAYER_SKIN_FLAGS(PLAYER, 16, EntityDataTypes1_7_6_10.BYTE, 10, EntityDataTypes1_8.BYTE),
|
||||
PLAYER_UNUSED(PLAYER, -1, null, 16, EntityDataTypes1_8.BYTE),
|
||||
PLAYER_ABSORPTION_HEATS(PLAYER, 17, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
PLAYER_SCORE(PLAYER, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
PLAYER_SKIN_FLAGS(PLAYER, 16, EntityDataTypes1_7_6_10.BYTE, 10, EntityDataTypes1_8.BYTE),
|
||||
PLAYER_UNUSED(PLAYER, -1, null, 16, EntityDataTypes1_8.BYTE),
|
||||
PLAYER_ABSORPTION_HEATS(PLAYER, 17, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
PLAYER_SCORE(PLAYER, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
|
||||
HORSE_FLAGS(HORSE, 16, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
HORSE_TYPE(HORSE, 19, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
HORSE_COLOR(HORSE, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
HORSE_OWNER(HORSE, 21, EntityDataTypes1_7_6_10.STRING, EntityDataTypes1_8.STRING),
|
||||
HORSE_ARMOR(HORSE, 22, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
HORSE_FLAGS(HORSE, 16, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
HORSE_TYPE(HORSE, 19, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
HORSE_COLOR(HORSE, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
HORSE_OWNER(HORSE, 21, EntityDataTypes1_7_6_10.STRING, EntityDataTypes1_8.STRING),
|
||||
HORSE_ARMOR(HORSE, 22, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
|
||||
BAT_HANGING(BAT, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
BAT_HANGING(BAT, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
TAMABLE_ANIMAL_FLAGS(TAMABLE_ANIMAL, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
TAMABLE_ANIMAL_OWNER(TAMABLE_ANIMAL, 17, EntityDataTypes1_7_6_10.STRING, EntityDataTypes1_8.STRING),
|
||||
TAMABLE_ANIMAL_FLAGS(TAMABLE_ANIMAL, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
TAMABLE_ANIMAL_OWNER(TAMABLE_ANIMAL, 17, EntityDataTypes1_7_6_10.STRING, EntityDataTypes1_8.STRING),
|
||||
|
||||
OCELOT_TYPE(OCELOT, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
OCELOT_TYPE(OCELOT, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
WOLF_FLAGS(WOLF, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
WOLF_HEALTH(WOLF, 18, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
WOLF_BEGGING(WOLF, 19, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
WOLF_COLLAR_COLOR(WOLF, 20, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
WOLF_FLAGS(WOLF, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
WOLF_HEALTH(WOLF, 18, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
WOLF_BEGGING(WOLF, 19, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
WOLF_COLLAR_COLOR(WOLF, 20, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
PIG_SADDLE(PIG, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
PIG_SADDLE(PIG, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
SHEEP_COLOR_OR_SHEARED(SHEEP, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
SHEEP_COLOR_OR_SHEARED(SHEEP, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
VILLAGER_TYPE(VILLAGER, 16, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
VILLAGER_TYPE(VILLAGER, 16, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
|
||||
ENDERMAN_CARRIED_BLOCK(ENDERMAN, 16, null, EntityDataTypes1_8.SHORT),
|
||||
ENDERMAN_CARRIED_BLOCK_DATA(ENDERMAN, 17, null, EntityDataTypes1_8.BYTE),
|
||||
ENDERMAN_IS_SCREAMING(ENDERMAN, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ENDERMAN_CARRIED_BLOCK(ENDERMAN, 16, null, EntityDataTypes1_8.SHORT),
|
||||
ENDERMAN_CARRIED_BLOCK_DATA(ENDERMAN, 17, null, EntityDataTypes1_8.BYTE),
|
||||
ENDERMAN_IS_SCREAMING(ENDERMAN, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
ZOMBIE_CHILD(ZOMBIE, 12, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ZOMBIE_VILLAGER(ZOMBIE, 13, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ZOMBIE_CONVERTING(ZOMBIE, 14, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ZOMBIE_CHILD(ZOMBIE, 12, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ZOMBIE_VILLAGER(ZOMBIE, 13, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ZOMBIE_CONVERTING(ZOMBIE, 14, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
BLAZE_ON_FIRE(BLAZE, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
BLAZE_ON_FIRE(BLAZE, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
SPIDER_CLIMBING(SPIDER, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
SPIDER_CLIMBING(SPIDER, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
CREEPER_STATE(CREEPER, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
CREEPER_POWERED(CREEPER, 17, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
CREEPER_IGNITED(CREEPER, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
CREEPER_STATE(CREEPER, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
CREEPER_POWERED(CREEPER, 17, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
CREEPER_IGNITED(CREEPER, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
GHAST_STATE(GHAST, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
GHAST_IS_POWERED(GHAST, 17, null, EntityDataTypes1_8.BYTE),
|
||||
GHAST_STATE(GHAST, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
GHAST_IS_POWERED(GHAST, 17, null, EntityDataTypes1_8.BYTE),
|
||||
|
||||
SLIME_SIZE(SLIME, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
SLIME_SIZE(SLIME, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
SKELETON_TYPE(SKELETON, 13, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
SKELETON_TYPE(SKELETON, 13, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
WITCH_AGGRESSIVE(WITCH, 21, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
WITCH_AGGRESSIVE(WITCH, 21, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
IRON_GOLEM_IS_PLAYER_CREATED(IRON_GOLEM, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
IRON_GOLEM_IS_PLAYER_CREATED(IRON_GOLEM, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
WITHER_WATCHED_TARGET_1(WITHER, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
WITHER_WATCHED_TARGET_2(WITHER, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
WITHER_WATCHED_TARGET_3(WITHER, 19, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
WITHER_INVULNERABLE_TIME(WITHER, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
WITHER_WATCHED_TARGET_1(WITHER, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
WITHER_WATCHED_TARGET_2(WITHER, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
WITHER_WATCHED_TARGET_3(WITHER, 19, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
WITHER_INVULNERABLE_TIME(WITHER, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
|
||||
GUARDIAN_FLAGS(GUARDIAN, 16, null, EntityDataTypes1_8.BYTE),
|
||||
GUARDIAN_TARGET(GUARDIAN, 17, null, EntityDataTypes1_8.INT),
|
||||
GUARDIAN_FLAGS(GUARDIAN, 16, null, EntityDataTypes1_8.BYTE),
|
||||
GUARDIAN_TARGET(GUARDIAN, 17, null, EntityDataTypes1_8.INT),
|
||||
|
||||
BOAT_TIME_SINCE_HIT(BOAT, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
BOAT_FORWARD_DIRECTION(BOAT, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
BOAT_DAMAGE_TAKEN(BOAT, 19, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
BOAT_TIME_SINCE_HIT(BOAT, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
BOAT_FORWARD_DIRECTION(BOAT, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
BOAT_DAMAGE_TAKEN(BOAT, 19, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
|
||||
ABSTRACT_MINECART_SHAKING_POWER(ABSTRACT_MINECART, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_SHAKING_DIRECTION(ABSTRACT_MINECART, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_DAMAGE_TAKEN(ABSTRACT_MINECART, 19, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
ABSTRACT_MINECART_BLOCK_INSIDE(ABSTRACT_MINECART, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_BLOCK_Y(ABSTRACT_MINECART, 21, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_SHOW_BLOCK(ABSTRACT_MINECART, 22, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ABSTRACT_MINECART_SHAKING_POWER(ABSTRACT_MINECART, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_SHAKING_DIRECTION(ABSTRACT_MINECART, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_DAMAGE_TAKEN(ABSTRACT_MINECART, 19, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
|
||||
ABSTRACT_MINECART_BLOCK_INSIDE(ABSTRACT_MINECART, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_BLOCK_Y(ABSTRACT_MINECART, 21, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
|
||||
ABSTRACT_MINECART_SHOW_BLOCK(ABSTRACT_MINECART, 22, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
FURNACE_MINECART_IS_POWERED(FURNACE_MINECART, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
FURNACE_MINECART_IS_POWERED(FURNACE_MINECART, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
ITEM_ITEM(ITEM, 10, EntityDataTypes1_7_6_10.ITEM, EntityDataTypes1_8.ITEM),
|
||||
ITEM_ITEM(ITEM, 10, EntityDataTypes1_7_6_10.ITEM, EntityDataTypes1_8.ITEM),
|
||||
|
||||
ARROW_IS_CRITICAL(ARROW, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
ARROW_IS_CRITICAL(ARROW, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
|
||||
|
||||
FIREWORK_ROCKET_INFO(FIREWORK_ROCKET, 8, EntityDataTypes1_7_6_10.ITEM, EntityDataTypes1_8.ITEM),
|
||||
FIREWORK_ROCKET_INFO(FIREWORK_ROCKET, 8, EntityDataTypes1_7_6_10.ITEM, EntityDataTypes1_8.ITEM),
|
||||
|
||||
ITEM_FRAME_ITEM(ITEM_FRAME, 2, EntityDataTypes1_7_6_10.ITEM, 8, EntityDataTypes1_8.ITEM),
|
||||
ITEM_FRAME_ROTATION(ITEM_FRAME, 3, EntityDataTypes1_7_6_10.BYTE, 9, EntityDataTypes1_8.BYTE),
|
||||
ITEM_FRAME_ITEM(ITEM_FRAME, 2, EntityDataTypes1_7_6_10.ITEM, 8, EntityDataTypes1_8.ITEM),
|
||||
ITEM_FRAME_ROTATION(ITEM_FRAME, 3, EntityDataTypes1_7_6_10.BYTE, 9, EntityDataTypes1_8.BYTE),
|
||||
|
||||
END_CRYSTAL_HEALTH(END_CRYSTAL, 8, EntityDataTypes1_7_6_10.INT, 9, EntityDataTypes1_8.INT);
|
||||
END_CRYSTAL_HEALTH(END_CRYSTAL, 8, EntityDataTypes1_7_6_10.INT, 9, EntityDataTypes1_8.INT);
|
||||
|
||||
private static final HashMap<Pair<EntityTypes1_8.EntityType, Integer>, EntityDataIndex1_7_6_10> ENTITY_DATA_REWRITES = new HashMap<>();
|
||||
private static final HashMap<Pair<EntityTypes1_8.EntityType, Integer>, EntityDataIndex1_7_6_10> ENTITY_DATA_REWRITES = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (EntityDataIndex1_7_6_10 index : EntityDataIndex1_7_6_10.values()) {
|
||||
ENTITY_DATA_REWRITES.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
|
||||
}
|
||||
}
|
||||
static {
|
||||
for (EntityDataIndex1_7_6_10 index : EntityDataIndex1_7_6_10.values()) {
|
||||
ENTITY_DATA_REWRITES.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
|
||||
}
|
||||
}
|
||||
|
||||
private final EntityTypes1_8.EntityType clazz;
|
||||
private final int newIndex;
|
||||
private final EntityDataTypes1_8 newType;
|
||||
private final EntityDataTypes1_7_6_10 oldType;
|
||||
private final int index;
|
||||
private final EntityTypes1_8.EntityType clazz;
|
||||
private final int newIndex;
|
||||
private final EntityDataTypes1_8 newType;
|
||||
private final EntityDataTypes1_7_6_10 oldType;
|
||||
private final int index;
|
||||
|
||||
EntityDataIndex1_7_6_10(EntityTypes1_8.EntityType type, int index, EntityDataTypes1_7_6_10 oldType, EntityDataTypes1_8 newType) {
|
||||
this.clazz = type;
|
||||
this.index = index;
|
||||
this.newIndex = index;
|
||||
this.oldType = oldType;
|
||||
this.newType = newType;
|
||||
}
|
||||
EntityDataIndex1_7_6_10(EntityTypes1_8.EntityType type, int index, EntityDataTypes1_7_6_10 oldType, EntityDataTypes1_8 newType) {
|
||||
this.clazz = type;
|
||||
this.index = index;
|
||||
this.newIndex = index;
|
||||
this.oldType = oldType;
|
||||
this.newType = newType;
|
||||
}
|
||||
|
||||
EntityDataIndex1_7_6_10(EntityTypes1_8.EntityType type, int index, EntityDataTypes1_7_6_10 oldType, int newIndex, EntityDataTypes1_8 newType) {
|
||||
this.clazz = type;
|
||||
this.index = index;
|
||||
this.oldType = oldType;
|
||||
this.newIndex = newIndex;
|
||||
this.newType = newType;
|
||||
}
|
||||
EntityDataIndex1_7_6_10(EntityTypes1_8.EntityType type, int index, EntityDataTypes1_7_6_10 oldType, int newIndex, EntityDataTypes1_8 newType) {
|
||||
this.clazz = type;
|
||||
this.index = index;
|
||||
this.oldType = oldType;
|
||||
this.newIndex = newIndex;
|
||||
this.newType = newType;
|
||||
}
|
||||
|
||||
private static Optional<EntityDataIndex1_7_6_10> getIndex(EntityType type, int index) {
|
||||
Pair<EntityType, Integer> pair = new Pair<>(type, index);
|
||||
if (ENTITY_DATA_REWRITES.containsKey(pair)) {
|
||||
return Optional.of(ENTITY_DATA_REWRITES.get(pair));
|
||||
}
|
||||
private static Optional<EntityDataIndex1_7_6_10> getIndex(EntityType type, int index) {
|
||||
final Pair<EntityType, Integer> pair = new Pair<>(type, index);
|
||||
return Optional.ofNullable(ENTITY_DATA_REWRITES.get(pair));
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
public static EntityDataIndex1_7_6_10 searchIndex(EntityType type, int index) {
|
||||
EntityType currentType = type;
|
||||
do {
|
||||
Optional<EntityDataIndex1_7_6_10> optMeta = getIndex(currentType, index);
|
||||
|
||||
public EntityTypes1_8.EntityType getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
if (optMeta.isPresent()) {
|
||||
return optMeta.get();
|
||||
}
|
||||
|
||||
public int getNewIndex() {
|
||||
return newIndex;
|
||||
}
|
||||
currentType = currentType.getParent();
|
||||
} while (currentType != null);
|
||||
|
||||
public EntityDataTypes1_8 getNewType() {
|
||||
return newType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public EntityDataTypes1_7_6_10 getOldType() {
|
||||
return oldType;
|
||||
}
|
||||
public EntityTypes1_8.EntityType getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
public int getNewIndex() {
|
||||
return newIndex;
|
||||
}
|
||||
|
||||
public static EntityDataIndex1_7_6_10 searchIndex(EntityType type, int index) {
|
||||
EntityType currentType = type;
|
||||
do {
|
||||
Optional<EntityDataIndex1_7_6_10> optMeta = getIndex(currentType, index);
|
||||
public EntityDataTypes1_8 getNewType() {
|
||||
return newType;
|
||||
}
|
||||
|
||||
if (optMeta.isPresent()) {
|
||||
return optMeta.get();
|
||||
}
|
||||
public EntityDataTypes1_7_6_10 getOldType() {
|
||||
return oldType;
|
||||
}
|
||||
|
||||
currentType = currentType.getParent();
|
||||
} while (currentType != null);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
+69
-68
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,77 +20,78 @@ package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data;
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum Particles1_8 {
|
||||
EXPLOSION_NORMAL("explode"),
|
||||
EXPLOSION_LARGE("largeexplode"),
|
||||
EXPLOSION_HUGE("hugeexplosion"),
|
||||
FIREWORKS_SPARK("fireworksSpark"),
|
||||
WATER_BUBBLE("bubble"),
|
||||
WATER_SPLASH("splash"),
|
||||
WATER_WAKE("wake"),
|
||||
SUSPENDED("suspended"),
|
||||
SUSPENDED_DEPTH("depthsuspend"),
|
||||
CRIT("crit"),
|
||||
CRIT_MAGIC("magicCrit"),
|
||||
SMOKE_NORMAL("smoke"),
|
||||
SMOKE_LARGE("largesmoke"),
|
||||
SPELL("spell"),
|
||||
SPELL_INSTANT("instantSpell"),
|
||||
SPELL_MOB("mobSpell"),
|
||||
SPELL_MOB_AMBIENT("mobSpellAmbient"),
|
||||
SPELL_WITCH("witchMagic"),
|
||||
DRIP_WATER("dripWater"),
|
||||
DRIP_LAVA("dripLava"),
|
||||
VILLAGER_ANGRY("angryVillager"),
|
||||
VILLAGER_HAPPY("happyVillager"),
|
||||
TOWN_AURA("townaura"),
|
||||
NOTE("note"),
|
||||
PORTAL("portal"),
|
||||
ENCHANTMENT_TABLE("enchantmenttable"),
|
||||
FLAME("flame"),
|
||||
LAVA("lava"),
|
||||
FOOTSTEP("footstep"),
|
||||
CLOUD("cloud"),
|
||||
REDSTONE("reddust"),
|
||||
SNOWBALL("snowballpoof"),
|
||||
SNOW_SHOVEL("snowshovel"),
|
||||
SLIME("slime"),
|
||||
HEART("heart"),
|
||||
BARRIER("barrier"),
|
||||
ICON_CRACK("iconcrack", 2),
|
||||
BLOCK_CRACK("blockcrack", 1),
|
||||
BLOCK_DUST("blockdust", 1),
|
||||
WATER_DROP("droplet"),
|
||||
ITEM_TAKE("take"),
|
||||
MOB_APPEARANCE("mobappearance");
|
||||
EXPLOSION_NORMAL("explode"),
|
||||
EXPLOSION_LARGE("largeexplode"),
|
||||
EXPLOSION_HUGE("hugeexplosion"),
|
||||
FIREWORKS_SPARK("fireworksSpark"),
|
||||
WATER_BUBBLE("bubble"),
|
||||
WATER_SPLASH("splash"),
|
||||
WATER_WAKE("wake"),
|
||||
SUSPENDED("suspended"),
|
||||
SUSPENDED_DEPTH("depthsuspend"),
|
||||
CRIT("crit"),
|
||||
CRIT_MAGIC("magicCrit"),
|
||||
SMOKE_NORMAL("smoke"),
|
||||
SMOKE_LARGE("largesmoke"),
|
||||
SPELL("spell"),
|
||||
SPELL_INSTANT("instantSpell"),
|
||||
SPELL_MOB("mobSpell"),
|
||||
SPELL_MOB_AMBIENT("mobSpellAmbient"),
|
||||
SPELL_WITCH("witchMagic"),
|
||||
DRIP_WATER("dripWater"),
|
||||
DRIP_LAVA("dripLava"),
|
||||
VILLAGER_ANGRY("angryVillager"),
|
||||
VILLAGER_HAPPY("happyVillager"),
|
||||
TOWN_AURA("townaura"),
|
||||
NOTE("note"),
|
||||
PORTAL("portal"),
|
||||
ENCHANTMENT_TABLE("enchantmenttable"),
|
||||
FLAME("flame"),
|
||||
LAVA("lava"),
|
||||
FOOTSTEP("footstep"),
|
||||
CLOUD("cloud"),
|
||||
REDSTONE("reddust"),
|
||||
SNOWBALL("snowballpoof"),
|
||||
SNOW_SHOVEL("snowshovel"),
|
||||
SLIME("slime"),
|
||||
HEART("heart"),
|
||||
BARRIER("barrier"),
|
||||
ICON_CRACK("iconcrack", 2),
|
||||
BLOCK_CRACK("blockcrack", 1),
|
||||
BLOCK_DUST("blockdust", 1),
|
||||
WATER_DROP("droplet"),
|
||||
ITEM_TAKE("take"),
|
||||
MOB_APPEARANCE("mobappearance");
|
||||
|
||||
public final String name;
|
||||
public final int extra;
|
||||
private static final HashMap<String, Particles1_8> particleMap = new HashMap<>();
|
||||
private static final HashMap<String, Particles1_8> particleMap = new HashMap<>();
|
||||
|
||||
Particles1_8(String name) {
|
||||
this(name, 0);
|
||||
}
|
||||
static {
|
||||
Particles1_8[] particles = values();
|
||||
|
||||
Particles1_8(String name, int extra) {
|
||||
this.name = name;
|
||||
this.extra = extra;
|
||||
}
|
||||
for (Particles1_8 particle : particles) {
|
||||
particleMap.put(particle.name, particle);
|
||||
}
|
||||
}
|
||||
|
||||
public static Particles1_8 find(String part) {
|
||||
return particleMap.get(part);
|
||||
}
|
||||
public final String name;
|
||||
public final int extra;
|
||||
|
||||
public static Particles1_8 find(int id) {
|
||||
if (id < 0) return null;
|
||||
Particles1_8[] values = Particles1_8.values();
|
||||
return id >= values.length ? null : values[id];
|
||||
}
|
||||
Particles1_8(String name) {
|
||||
this(name, 0);
|
||||
}
|
||||
|
||||
static {
|
||||
Particles1_8[] particles = values();
|
||||
Particles1_8(String name, int extra) {
|
||||
this.name = name;
|
||||
this.extra = extra;
|
||||
}
|
||||
|
||||
for (Particles1_8 particle : particles) {
|
||||
particleMap.put(particle.name, particle);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static Particles1_8 find(String part) {
|
||||
return particleMap.get(part);
|
||||
}
|
||||
|
||||
public static Particles1_8 find(int id) {
|
||||
if (id < 0) return null;
|
||||
Particles1_8[] values = Particles1_8.values();
|
||||
return id >= values.length ? null : values[id];
|
||||
}
|
||||
}
|
||||
+285
-242
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,13 +17,14 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data;
|
||||
|
||||
import com.viaversion.viarewind.api.type.version.Types1_7_6_10;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
|
||||
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.EntityPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.api.minecraft.math.AABB;
|
||||
import com.viaversion.viarewind.api.minecraft.math.Vector3d;
|
||||
import com.viaversion.viarewind.api.type.RewindTypes;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.EntityPacketRewriter1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.EntityTracker1_8;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
@@ -33,293 +34,335 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.data.entity.TrackedEntityImpl;
|
||||
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEvent;
|
||||
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEventImpl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VirtualHologramEntity {
|
||||
private final List<EntityData> entityDataTracker = new ArrayList<>();
|
||||
private double locX, locY, locZ;
|
||||
private final List<EntityData> entityDataTracker = new ArrayList<>();
|
||||
private final UserConnection user;
|
||||
private final int entityId;
|
||||
private double locX, locY, locZ;
|
||||
private int[] entityIds = null;
|
||||
private State currentState = null;
|
||||
private String name = null;
|
||||
private float yaw, pitch;
|
||||
private float headYaw;
|
||||
private byte flags = 0;
|
||||
private byte armorStandFlags = 0;
|
||||
private boolean small = false;
|
||||
private boolean marker = false;
|
||||
private boolean sneaking = false;
|
||||
private boolean gravity = false;
|
||||
private byte alwaysShowNametag;
|
||||
|
||||
private final UserConnection user;
|
||||
private final int entityId;
|
||||
public VirtualHologramEntity(final UserConnection user, final int entityId) {
|
||||
this.user = user;
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
private int[] entityIds = null;
|
||||
private State currentState = null;
|
||||
private String name = null;
|
||||
private float yaw, pitch;
|
||||
private float headYaw;
|
||||
private boolean small = false;
|
||||
private boolean marker = false;
|
||||
public void setPosition(final double x, final double y, final double z) {
|
||||
if (x == this.locX && y == this.locY && z == this.locZ) return;
|
||||
this.locX = x;
|
||||
this.locY = y;
|
||||
this.locZ = z;
|
||||
|
||||
public VirtualHologramEntity(final UserConnection user, final int entityId) {
|
||||
this.user = user;
|
||||
this.entityId = entityId;
|
||||
}
|
||||
updateLocation();
|
||||
}
|
||||
|
||||
public void setPosition(final double x, final double y, final double z) {
|
||||
if (x == this.locX && y == this.locY && z == this.locZ) return;
|
||||
this.locX = x;
|
||||
this.locY = y;
|
||||
this.locZ = z;
|
||||
public void setRelativePosition(final double x, final double y, final double z) {
|
||||
if (x == 0.0 && y == 0.0 && z == 0.0) return;
|
||||
this.locX += x;
|
||||
this.locY += y;
|
||||
this.locZ += z;
|
||||
|
||||
updateLocation(false);
|
||||
}
|
||||
updateLocation();
|
||||
}
|
||||
|
||||
public void setRelativePosition(final double x, final double y, final double z) {
|
||||
if (x == 0.0 && y == 0.0 && z == 0.0) return;
|
||||
this.locX += x;
|
||||
this.locY += y;
|
||||
this.locZ += z;
|
||||
public void setRotation(final float yaw, final float pitch) {
|
||||
if (this.yaw == yaw || this.headYaw == yaw || this.pitch == pitch) return;
|
||||
this.yaw = yaw;
|
||||
this.headYaw = yaw;
|
||||
this.pitch = pitch;
|
||||
|
||||
updateLocation(false);
|
||||
}
|
||||
updateLocation();
|
||||
}
|
||||
|
||||
public void setRotation(final float yaw, final float pitch) {
|
||||
if (this.yaw == yaw || this.headYaw == yaw || this.pitch == pitch) return;
|
||||
this.yaw = yaw;
|
||||
this.headYaw = yaw;
|
||||
this.pitch = pitch;
|
||||
public void setHeadYaw(float yaw) {
|
||||
if (this.headYaw == yaw) return;
|
||||
this.headYaw = yaw;
|
||||
|
||||
updateLocation(false);
|
||||
}
|
||||
updateLocation();
|
||||
}
|
||||
|
||||
public void setHeadYaw(float yaw) {
|
||||
if (this.headYaw == yaw) return;
|
||||
this.headYaw = yaw;
|
||||
public void syncState(final EntityPacketRewriter1_8 entityRewriter, final List<EntityData> entityDataList) {
|
||||
// Merge entity data updates into current tracker
|
||||
for (EntityData entityData : entityDataList) {
|
||||
entityDataTracker.removeIf(m -> m.id() == entityData.id());
|
||||
entityDataTracker.add(entityData);
|
||||
}
|
||||
|
||||
updateLocation(false);
|
||||
}
|
||||
// Filter armor stand data to calculate emulation
|
||||
for (EntityData entityData : entityDataTracker) {
|
||||
if (entityData.id() == 0 && entityData.dataType() == EntityDataTypes1_8.BYTE) {
|
||||
flags = ((Number) entityData.getValue()).byteValue();
|
||||
} else if (entityData.id() == 2 && entityData.dataType() == EntityDataTypes1_8.STRING) {
|
||||
name = entityData.getValue().toString();
|
||||
if (name != null && name.isEmpty()) name = null;
|
||||
} else if (entityData.id() == 3 && entityData.dataType() == EntityDataTypes1_8.BYTE) {
|
||||
alwaysShowNametag = ((Number) entityData.getValue()).byteValue();
|
||||
} else if (entityData.id() == 10 && entityData.dataType() == EntityDataTypes1_8.BYTE) {
|
||||
armorStandFlags = ((Number) entityData.getValue()).byteValue();
|
||||
}
|
||||
}
|
||||
final boolean invisible = (flags & 0x20) != 0;
|
||||
sneaking = (flags & 0x02) != 0;
|
||||
small = (armorStandFlags & 0x01) != 0;
|
||||
marker = (armorStandFlags & 0x10) != 0;
|
||||
gravity = (armorStandFlags & 0x02) == 0;
|
||||
|
||||
public void syncState(final EntityPacketRewriter1_8 entityRewriter, final List<EntityData> entityDataList) {
|
||||
// Merge entity data updates into current tracker
|
||||
for (EntityData entityData : entityDataList) {
|
||||
entityDataTracker.removeIf(m -> m.id() == entityData.id());
|
||||
entityDataTracker.add(entityData);
|
||||
}
|
||||
State prevState = currentState;
|
||||
if (invisible && name != null && alwaysShowNametag == 1) {
|
||||
currentState = State.HOLOGRAM;
|
||||
} else if (gravity) {
|
||||
currentState = State.ZOMBIE;
|
||||
} else {
|
||||
currentState = State.ZOMBIE_NO_GRAVITY;
|
||||
}
|
||||
|
||||
// Filter armor stand data to calculate emulation
|
||||
byte flags = 0;
|
||||
byte armorStandFlags = 0;
|
||||
for (EntityData entityData : entityDataTracker) {
|
||||
if (entityData.id() == 0 && entityData.dataType() == EntityDataTypes1_8.BYTE) {
|
||||
flags = ((Number) entityData.getValue()).byteValue();
|
||||
} else if (entityData.id() == 2 && entityData.dataType() == EntityDataTypes1_8.STRING) {
|
||||
name = entityData.getValue().toString();
|
||||
if (name != null && name.isEmpty()) name = null;
|
||||
} else if (entityData.id() == 10 && entityData.dataType() == EntityDataTypes1_8.BYTE) {
|
||||
armorStandFlags = ((Number) entityData.getValue()).byteValue();
|
||||
}
|
||||
}
|
||||
final boolean invisible = (flags & 0x20) != 0;
|
||||
small = (armorStandFlags & 0x01) != 0;
|
||||
marker = (armorStandFlags & 0x10) != 0;
|
||||
if (currentState != prevState) {
|
||||
deleteEntity();
|
||||
sendSpawnPacket(entityRewriter);
|
||||
} else {
|
||||
sendEntityDataUpdate(entityRewriter);
|
||||
updateLocation();
|
||||
}
|
||||
}
|
||||
|
||||
State prevState = currentState;
|
||||
if (invisible && name != null) {
|
||||
currentState = State.HOLOGRAM;
|
||||
} else {
|
||||
currentState = State.ZOMBIE;
|
||||
}
|
||||
private void updateLocation() {
|
||||
if (entityIds == null) {
|
||||
return;
|
||||
}
|
||||
if (currentState == State.ZOMBIE) {
|
||||
teleportEntity(entityId, locX, locY, locZ, yaw, pitch);
|
||||
|
||||
if (currentState != prevState) {
|
||||
deleteEntity();
|
||||
sendSpawnPacket(entityRewriter);
|
||||
} else {
|
||||
sendEntityDataUpdate(entityRewriter);
|
||||
updateLocation(false);
|
||||
}
|
||||
}
|
||||
final PacketWrapper entityHeadLook = PacketWrapper.create(ClientboundPackets1_7_2_5.ROTATE_HEAD, user);
|
||||
|
||||
private void updateLocation(final boolean remount) {
|
||||
if (entityIds == null) {
|
||||
return;
|
||||
}
|
||||
if (currentState == State.ZOMBIE) {
|
||||
teleportEntity(entityId, locX, locY, locZ, yaw, pitch);
|
||||
entityHeadLook.write(Types.INT, entityId);
|
||||
entityHeadLook.write(Types.BYTE, (byte) ((headYaw / 360f) * 256));
|
||||
|
||||
final PacketWrapper entityHeadLook = PacketWrapper.create(ClientboundPackets1_7_2_5.ROTATE_HEAD, user);
|
||||
entityHeadLook.send(Protocol1_8To1_7_6_10.class);
|
||||
} else if (currentState == State.HOLOGRAM || currentState == State.ZOMBIE_NO_GRAVITY) {
|
||||
// Don't ask me where this offset is coming from
|
||||
teleportEntity(entityIds[1], locX, (locY + getOffset()), locZ, 0, 0); // Squid
|
||||
}
|
||||
}
|
||||
|
||||
entityHeadLook.write(Types.INT, entityId);
|
||||
entityHeadLook.write(Types.BYTE, (byte) ((headYaw / 360f) * 256));
|
||||
private double getOffset() {
|
||||
if (currentState == State.HOLOGRAM) {
|
||||
double baseOffset = 54.35;
|
||||
|
||||
entityHeadLook.send(Protocol1_8To1_7_6_10.class);
|
||||
} else if (currentState == State.HOLOGRAM) {
|
||||
if (remount) {
|
||||
PacketWrapper detach = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_LINK, user);
|
||||
detach.write(Types.INT, entityIds[1]);
|
||||
detach.write(Types.INT, -1);
|
||||
detach.write(Types.BOOLEAN, false);
|
||||
detach.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
if (marker) {
|
||||
return baseOffset;
|
||||
} else if (small) {
|
||||
return baseOffset + 0.9875;
|
||||
} else {
|
||||
return baseOffset + (0.9875 * 2);
|
||||
}
|
||||
} else if (currentState == State.ZOMBIE_NO_GRAVITY) {
|
||||
// 1.7 ride stack offset sum: Squid (0.95 * 0.75) + Zombie (1.8 * 0.75) = 2.0625
|
||||
// By starting at -2.0625, we zero out the 1.7 passenger height so we can apply 1.8's offsets.
|
||||
double baseOffset = -2.0625;
|
||||
|
||||
// Don't ask me where this offset is coming from
|
||||
teleportEntity(entityIds[0], locX, (locY + (marker ? 54.85 : small ? 56 : 57) - 0.16), locZ, 0, 0); // Skull
|
||||
if (marker) {
|
||||
// 1.8 Marker ArmorStand height is 0.0 -> mounted offset 0.0
|
||||
return baseOffset;
|
||||
} else {
|
||||
// 1.8 Normal ArmorStand height is 1.975 -> mounted offset 1.975 * 0.75 = 1.48125
|
||||
return baseOffset + 1.48125;
|
||||
}
|
||||
} else {
|
||||
return -0.4;
|
||||
}
|
||||
}
|
||||
|
||||
if (remount) {
|
||||
teleportEntity(entityIds[1], locX, locY + 56.75, locZ, 0, 0); // Horse
|
||||
protected void teleportEntity(final int entityId, final double x, final double y, final double z, final float yaw, final float pitch) {
|
||||
final PacketWrapper entityTeleport = PacketWrapper.create(ClientboundPackets1_7_2_5.TELEPORT_ENTITY, user);
|
||||
|
||||
PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_LINK, null, user);
|
||||
attach.write(Types.INT, entityIds[1]);
|
||||
attach.write(Types.INT, entityIds[0]);
|
||||
attach.write(Types.BOOLEAN, false);
|
||||
attach.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
entityTeleport.write(Types.INT, entityId); // entity id
|
||||
entityTeleport.write(Types.INT, (int) (x * 32.0)); // x
|
||||
entityTeleport.write(Types.INT, (int) (y * 32.0)); // y
|
||||
entityTeleport.write(Types.INT, (int) (z * 32.0)); // z
|
||||
entityTeleport.write(Types.BYTE, (byte) ((yaw / 360f) * 256)); // yaw
|
||||
entityTeleport.write(Types.BYTE, (byte) ((pitch / 360f) * 256)); // pitch
|
||||
|
||||
protected void teleportEntity(final int entityId, final double x, final double y, final double z, final float yaw, final float pitch) {
|
||||
final PacketWrapper entityTeleport = PacketWrapper.create(ClientboundPackets1_7_2_5.TELEPORT_ENTITY, user);
|
||||
entityTeleport.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
entityTeleport.write(Types.INT, entityId); // entity id
|
||||
entityTeleport.write(Types.INT, (int) (x * 32.0)); // x
|
||||
entityTeleport.write(Types.INT, (int) (y * 32.0)); // y
|
||||
entityTeleport.write(Types.INT, (int) (z * 32.0)); // z
|
||||
entityTeleport.write(Types.BYTE, (byte) ((yaw / 360f) * 256)); // yaw
|
||||
entityTeleport.write(Types.BYTE, (byte) ((pitch / 360f) * 256)); // pitch
|
||||
protected void spawnEntity(final int entityId, final int type, final double locX, final double locY, final double locZ, final List<EntityData> entityData) {
|
||||
final PacketWrapper addMob = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_MOB, user);
|
||||
|
||||
entityTeleport.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
addMob.write(Types.VAR_INT, entityId); // Entity id
|
||||
addMob.write(Types.UNSIGNED_BYTE, (short) type); // Entity type
|
||||
addMob.write(Types.INT, (int) (locX * 32.0)); // X
|
||||
addMob.write(Types.INT, (int) (locY * 32.0)); // Y
|
||||
addMob.write(Types.INT, (int) (locZ * 32.0)); // Z
|
||||
addMob.write(Types.BYTE, (byte) 0); // Yaw
|
||||
addMob.write(Types.BYTE, (byte) 0); // Pitch
|
||||
addMob.write(Types.BYTE, (byte) 0); // Head pitch
|
||||
addMob.write(Types.SHORT, (short) 0); // Velocity x
|
||||
addMob.write(Types.SHORT, (short) 0); // Velocity y
|
||||
addMob.write(Types.SHORT, (short) 0); // Velocity z
|
||||
addMob.write(RewindTypes.ENTITY_DATA_LIST1_7, entityData); // Entity data
|
||||
|
||||
protected void spawnEntity(final int entityId, final int type, final double locX, final double locY, final double locZ) {
|
||||
final PacketWrapper addMob = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_MOB, user);
|
||||
addMob.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
addMob.write(Types.VAR_INT, entityId); // Entity id
|
||||
addMob.write(Types.UNSIGNED_BYTE, (short) type); // Entity type
|
||||
addMob.write(Types.INT, (int) (locX * 32.0)); // X
|
||||
addMob.write(Types.INT, (int) (locY * 32.0)); // Y
|
||||
addMob.write(Types.INT, (int) (locZ * 32.0)); // Z
|
||||
addMob.write(Types.BYTE, (byte) 0); // Yaw
|
||||
addMob.write(Types.BYTE, (byte) 0); // Pitch
|
||||
addMob.write(Types.BYTE, (byte) 0); // Head pitch
|
||||
addMob.write(Types.SHORT, (short) 0); // Velocity x
|
||||
addMob.write(Types.SHORT, (short) 0); // Velocity y
|
||||
addMob.write(Types.SHORT, (short) 0); // Velocity z
|
||||
addMob.write(Types1_7_6_10.ENTITY_DATA_LIST, new ArrayList<>()); // Entity data
|
||||
public void sendEntityDataUpdate(final EntityPacketRewriter1_8 entityRewriter) {
|
||||
if (entityIds == null) {
|
||||
return;
|
||||
}
|
||||
final PacketWrapper setEntityData = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_DATA, user);
|
||||
|
||||
addMob.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
if (currentState == State.ZOMBIE || currentState == State.ZOMBIE_NO_GRAVITY) {
|
||||
writeZombieMeta(entityRewriter, setEntityData);
|
||||
} else if (currentState == State.HOLOGRAM) {
|
||||
writeHologramMeta(setEntityData);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
setEntityData.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
public void sendEntityDataUpdate(final EntityPacketRewriter1_8 entityRewriter) {
|
||||
if (entityIds == null) {
|
||||
return;
|
||||
}
|
||||
final PacketWrapper setEntityData = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_DATA, user);
|
||||
private void writeZombieMeta(final EntityPacketRewriter1_8 entityRewriter, final PacketWrapper wrapper) {
|
||||
wrapper.write(Types.INT, entityIds[0]);
|
||||
|
||||
if (currentState == State.ZOMBIE) {
|
||||
writeZombieMeta(entityRewriter, setEntityData);
|
||||
} else if (currentState == State.HOLOGRAM) {
|
||||
writeHologramMeta(setEntityData);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
setEntityData.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
// Filter entity data sent by the server and convert them together with our custom entity data
|
||||
final List<EntityData> entityDataList = new ArrayList<>();
|
||||
for (EntityData entityData : entityDataTracker) {
|
||||
// Remove non existent entityData
|
||||
if (entityData.id() < 0 || entityData.id() > 9) {
|
||||
continue;
|
||||
}
|
||||
entityDataList.add(new EntityData(entityData.id(), entityData.dataType(), entityData.getValue()));
|
||||
}
|
||||
if (small) {
|
||||
entityDataList.add(new EntityData(12, EntityDataTypes1_8.BYTE, (byte) 1));
|
||||
}
|
||||
|
||||
private void writeZombieMeta(final EntityPacketRewriter1_8 entityRewriter, PacketWrapper wrapper) {
|
||||
wrapper.write(Types.INT, entityIds[0]);
|
||||
// Push entity data from the server through entity data conversion 1.7->1.8
|
||||
for (EntityData entityData : entityDataList.toArray(new EntityData[0])) {
|
||||
final EntityDataHandlerEvent event = new EntityDataHandlerEventImpl(wrapper.user(), new TrackedEntityImpl(EntityTypes1_8.EntityType.ZOMBIE), -1, entityData, entityDataList);
|
||||
try {
|
||||
entityRewriter.handleEntityData(event, entityData);
|
||||
} catch (Exception e) {
|
||||
entityDataList.remove(entityData);
|
||||
break;
|
||||
}
|
||||
if (event.cancelled()) {
|
||||
entityDataList.remove(entityData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
wrapper.write(RewindTypes.ENTITY_DATA_LIST1_7, entityDataList);
|
||||
}
|
||||
|
||||
// Filter entity data sent by the server and convert them together with our custom entity data
|
||||
final List<EntityData> entityDataList = new ArrayList<>();
|
||||
for (EntityData entityData : entityDataTracker) {
|
||||
// Remove non existent entityData
|
||||
if (entityData.id() < 0 || entityData.id() > 9) {
|
||||
continue;
|
||||
}
|
||||
entityDataList.add(new EntityData(entityData.id(), entityData.dataType(), entityData.getValue()));
|
||||
}
|
||||
if (small) {
|
||||
entityDataList.add(new EntityData(12, EntityDataTypes1_8.BYTE, (byte) 1));
|
||||
}
|
||||
private void writeHologramMeta(PacketWrapper wrapper) {
|
||||
wrapper.write(Types.INT, entityIds[0]);
|
||||
|
||||
// Push entity data from the server through entity data conversion 1.7->1.8
|
||||
for (EntityData entityData : entityDataList.toArray(new EntityData[0])) {
|
||||
final EntityDataHandlerEvent event = new EntityDataHandlerEventImpl(wrapper.user(), new TrackedEntityImpl(EntityTypes1_8.EntityType.ZOMBIE), -1, entityData, entityDataList);
|
||||
try {
|
||||
entityRewriter.handleEntityData(event, entityData);
|
||||
} catch (Exception e) {
|
||||
entityDataList.remove(entityData);
|
||||
break;
|
||||
}
|
||||
if (event.cancelled()) {
|
||||
entityDataList.remove(entityData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
wrapper.write(Types1_7_6_10.ENTITY_DATA_LIST, entityDataList);
|
||||
}
|
||||
// Directly write 1.7 entity data here since we are making them up
|
||||
final List<EntityData> entityDataList = new ArrayList<>();
|
||||
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.ENTITY_FLAGS.getIndex(), EntityDataTypes1_7_6_10.BYTE, (byte) (sneaking ? 2 : 0)));
|
||||
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.ABSTRACT_AGEABLE_AGE.getIndex(), EntityDataTypes1_7_6_10.INT, -1700000));
|
||||
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.LIVING_ENTITY_BASE_NAME_TAG.getIndex(), EntityDataTypes1_7_6_10.STRING, name));
|
||||
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.LIVING_ENTITY_BASE_NAME_TAG_VISIBILITY.getIndex(), EntityDataTypes1_7_6_10.BYTE, alwaysShowNametag));
|
||||
|
||||
private void writeHologramMeta(PacketWrapper wrapper) {
|
||||
wrapper.write(Types.INT, entityIds[1]);
|
||||
wrapper.write(RewindTypes.ENTITY_DATA_LIST1_7, entityDataList);
|
||||
}
|
||||
|
||||
// Directly write 1.7 entity data here since we are making them up
|
||||
final List<EntityData> entityDataList = new ArrayList<>();
|
||||
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.ABSTRACT_AGEABLE_AGE.getIndex(), EntityDataTypes1_7_6_10.INT, -1700000));
|
||||
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.LIVING_ENTITY_BASE_NAME_TAG.getIndex(), EntityDataTypes1_7_6_10.STRING, name));
|
||||
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.LIVING_ENTITY_BASE_NAME_TAG_VISIBILITY.getIndex(), EntityDataTypes1_7_6_10.BYTE, (byte) 1));
|
||||
public void sendSpawnPacket(final EntityPacketRewriter1_8 entityRewriter) {
|
||||
if (entityIds != null) {
|
||||
deleteEntity();
|
||||
}
|
||||
if (currentState == State.ZOMBIE) {
|
||||
spawnEntity(entityId, EntityTypes1_8.EntityType.ZOMBIE.getId(), locX, locY, locZ, new ArrayList<>());
|
||||
|
||||
wrapper.write(Types1_7_6_10.ENTITY_DATA_LIST, entityDataList);
|
||||
}
|
||||
entityIds = new int[]{entityId};
|
||||
} else if (currentState == State.ZOMBIE_NO_GRAVITY || currentState == State.HOLOGRAM) {
|
||||
final int[] entityIds = {entityId, additionalEntityId()};
|
||||
|
||||
public void sendSpawnPacket(final EntityPacketRewriter1_8 entityRewriter) {
|
||||
if (entityIds != null) {
|
||||
deleteEntity();
|
||||
}
|
||||
if (currentState == State.ZOMBIE) {
|
||||
spawnEntity(entityId, EntityTypes1_8.EntityType.ZOMBIE.getId(), locX, locY, locZ);
|
||||
final List<EntityData> squidEntityData = new ArrayList<>();
|
||||
squidEntityData.add(new EntityData(0, EntityDataTypes1_8.BYTE, (byte) 32));
|
||||
|
||||
entityIds = new int[]{entityId};
|
||||
} else if (currentState == State.HOLOGRAM) {
|
||||
final int[] entityIds = { entityId, additionalEntityId() };
|
||||
if (currentState == State.HOLOGRAM) {
|
||||
spawnEntity(entityIds[0], EntityTypes1_8.EntityType.HORSE.getId(), locX, locY + (getOffset() + 0.68), locZ, new ArrayList<>());
|
||||
} else {
|
||||
spawnEntity(entityIds[0], EntityTypes1_8.EntityType.ZOMBIE.getId(), locX, locY, locZ, new ArrayList<>());
|
||||
}
|
||||
|
||||
final PacketWrapper spawnSkull = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_ENTITY, user);
|
||||
spawnSkull.write(Types.VAR_INT, entityIds[0]);
|
||||
spawnSkull.write(Types.BYTE, (byte) 66);
|
||||
spawnSkull.write(Types.INT, (int) (locX * 32.0));
|
||||
spawnSkull.write(Types.INT, (int) (locY * 32.0));
|
||||
spawnSkull.write(Types.INT, (int) (locZ * 32.0));
|
||||
spawnSkull.write(Types.BYTE, (byte) 0);
|
||||
spawnSkull.write(Types.BYTE, (byte) 0);
|
||||
spawnSkull.write(Types.INT, 0);
|
||||
spawnSkull.send(Protocol1_8To1_7_6_10.class);
|
||||
spawnEntity(entityIds[1], EntityTypes1_8.EntityType.SQUID.getId(), locX, locY + getOffset(), locZ, squidEntityData);
|
||||
|
||||
spawnEntity(entityIds[1], EntityTypes1_8.EntityType.HORSE.getId(), locX, locY, locZ); // Horse
|
||||
this.entityIds = entityIds;
|
||||
}
|
||||
|
||||
this.entityIds = entityIds;
|
||||
}
|
||||
for (int extraId : entityIds) {
|
||||
if (extraId != entityId) {
|
||||
((EntityTracker1_8) user.getEntityTracker(Protocol1_8To1_7_6_10.class)).setExtraHologramId(entityId, extraId);
|
||||
}
|
||||
}
|
||||
|
||||
sendEntityDataUpdate(entityRewriter);
|
||||
updateLocation(true);
|
||||
}
|
||||
|
||||
public AABB getBoundingBox() {
|
||||
final double width = this.small ? 0.25 : 0.5;
|
||||
final double height = this.small ? 0.9875 : 1.975;
|
||||
sendEntityDataUpdate(entityRewriter);
|
||||
if (entityIds == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Vector3d min = new Vector3d(this.locX - width / 2, this.locY, this.locZ - width / 2);
|
||||
final Vector3d max = new Vector3d(this.locX + width / 2, this.locY + height, this.locZ + width / 2);
|
||||
if (currentState == State.ZOMBIE) {
|
||||
updateLocation();
|
||||
} else {
|
||||
final PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_LINK, user);
|
||||
attach.write(Types.INT, entityIds[0]);
|
||||
attach.write(Types.INT, entityIds[1]);
|
||||
attach.write(Types.BOOLEAN, false);
|
||||
|
||||
return new AABB(min, max);
|
||||
}
|
||||
attach.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
|
||||
private int additionalEntityId() {
|
||||
return Integer.MAX_VALUE - 16000 - entityId;
|
||||
}
|
||||
public AABB getBoundingBox() {
|
||||
final double width = this.small ? 0.25 : 0.5;
|
||||
final double height = this.small ? 0.9875 : 1.975;
|
||||
|
||||
public void deleteEntity() {
|
||||
if (entityIds == null) {
|
||||
return;
|
||||
}
|
||||
final PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7_2_5.REMOVE_ENTITIES, user);
|
||||
despawn.write(Types.BYTE, (byte) entityIds.length);
|
||||
for (int id : entityIds) {
|
||||
despawn.write(Types.INT, id);
|
||||
}
|
||||
entityIds = null;
|
||||
despawn.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
final Vector3d min = new Vector3d(this.locX - width / 2, this.locY, this.locZ - width / 2);
|
||||
final Vector3d max = new Vector3d(this.locX + width / 2, this.locY + height, this.locZ + width / 2);
|
||||
|
||||
private enum State {
|
||||
HOLOGRAM, ZOMBIE
|
||||
}
|
||||
return new AABB(min, max);
|
||||
}
|
||||
|
||||
private int additionalEntityId() {
|
||||
return Integer.MAX_VALUE - 16000 - entityId;
|
||||
}
|
||||
|
||||
public void deleteEntity() {
|
||||
if (entityIds == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int extraId : entityIds) {
|
||||
if (extraId != entityId) {
|
||||
((EntityTracker1_8) user.getEntityTracker(Protocol1_8To1_7_6_10.class)).removeExtraHologramId(extraId);
|
||||
}
|
||||
}
|
||||
|
||||
final PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7_2_5.REMOVE_ENTITIES, user);
|
||||
despawn.write(Types.BYTE, (byte) entityIds.length);
|
||||
for (int id : entityIds) {
|
||||
despawn.write(Types.INT, id);
|
||||
}
|
||||
entityIds = null;
|
||||
despawn.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
private enum State {
|
||||
HOLOGRAM, ZOMBIE, ZOMBIE_NO_GRAVITY
|
||||
}
|
||||
}
|
||||
+27
-11
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -24,17 +24,33 @@ import io.netty.channel.ChannelHandler;
|
||||
|
||||
public abstract class CompressionHandlerProvider implements Provider {
|
||||
|
||||
public abstract void onHandleLoginCompressionPacket(UserConnection user, int threshold);
|
||||
public abstract void onTransformPacket(UserConnection user);
|
||||
public abstract void setCompressionThreshold(UserConnection user, int threshold);
|
||||
|
||||
public abstract ChannelHandler getEncoder(int threshold);
|
||||
public abstract ChannelHandler getDecoder(int threshold);
|
||||
public abstract void onTransformPacket(UserConnection user);
|
||||
|
||||
public boolean isCompressionEnabled(UserConnection user) {
|
||||
return user.get(CompressionStatusTracker.class).removeCompression;
|
||||
}
|
||||
/**
|
||||
* Creates the compression encoder
|
||||
*
|
||||
* @param compressor A nullable object that may present a native backend for compression (if available)
|
||||
* @param threshold The compression threshold
|
||||
* @return The encoder
|
||||
*/
|
||||
public abstract ChannelHandler getEncoder(Object compressor, int threshold);
|
||||
|
||||
public void setCompressionEnabled(UserConnection user, boolean enabled) {
|
||||
user.get(CompressionStatusTracker.class).removeCompression = enabled;
|
||||
}
|
||||
/**
|
||||
* Creates the compression decoder
|
||||
*
|
||||
* @param compressor A nullable object that may present a native backend for compression (if available)
|
||||
* @param threshold The compression threshold
|
||||
* @return The decoder
|
||||
*/
|
||||
public abstract ChannelHandler getDecoder(Object compressor, int threshold);
|
||||
|
||||
public boolean isRemoveCompression(UserConnection user) {
|
||||
return user.get(CompressionStatusTracker.class).removeCompression;
|
||||
}
|
||||
|
||||
public void setRemoveCompression(UserConnection user, boolean enabled) {
|
||||
user.get(CompressionStatusTracker.class).removeCompression = enabled;
|
||||
}
|
||||
}
|
||||
+58
-59
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,7 +18,6 @@
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider;
|
||||
|
||||
import com.viaversion.viaversion.api.platform.providers.Provider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@@ -26,74 +25,74 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
// TODO I believe this should be a storage?
|
||||
public abstract class TitleRenderProvider implements Provider {
|
||||
protected Map<UUID, Integer> fadeIn = new HashMap<>();
|
||||
protected Map<UUID, Integer> stay = new HashMap<>();
|
||||
protected Map<UUID, Integer> fadeOut = new HashMap<>();
|
||||
protected Map<UUID, String> titles = new HashMap<>();
|
||||
protected Map<UUID, String> subTitles = new HashMap<>();
|
||||
protected Map<UUID, AtomicInteger> times = new HashMap<>();
|
||||
protected Map<UUID, Integer> fadeIn = new HashMap<>();
|
||||
protected Map<UUID, Integer> stay = new HashMap<>();
|
||||
protected Map<UUID, Integer> fadeOut = new HashMap<>();
|
||||
protected Map<UUID, String> titles = new HashMap<>();
|
||||
protected Map<UUID, String> subTitles = new HashMap<>();
|
||||
protected Map<UUID, AtomicInteger> times = new HashMap<>();
|
||||
|
||||
public void setTimings(UUID uuid, int fadeIn, int stay, int fadeOut) {
|
||||
setFadeIn(uuid, fadeIn);
|
||||
setStay(uuid, stay);
|
||||
setFadeOut(uuid, fadeOut);
|
||||
public void setTimings(UUID uuid, int fadeIn, int stay, int fadeOut) {
|
||||
setFadeIn(uuid, fadeIn);
|
||||
setStay(uuid, stay);
|
||||
setFadeOut(uuid, fadeOut);
|
||||
|
||||
AtomicInteger time = getTime(uuid);
|
||||
if (time.get() > 0) time.set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
|
||||
}
|
||||
AtomicInteger time = getTime(uuid);
|
||||
if (time.get() > 0) time.set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
|
||||
}
|
||||
|
||||
public void reset(UUID uuid) {
|
||||
this.titles.remove(uuid);
|
||||
this.subTitles.remove(uuid);
|
||||
getTime(uuid).set(0);
|
||||
fadeIn.remove(uuid);
|
||||
stay.remove(uuid);
|
||||
fadeOut.remove(uuid);
|
||||
}
|
||||
public void reset(UUID uuid) {
|
||||
this.titles.remove(uuid);
|
||||
this.subTitles.remove(uuid);
|
||||
getTime(uuid).set(0);
|
||||
fadeIn.remove(uuid);
|
||||
stay.remove(uuid);
|
||||
fadeOut.remove(uuid);
|
||||
}
|
||||
|
||||
public void setTitle(UUID uuid, String title) {
|
||||
this.titles.put(uuid, title);
|
||||
getTime(uuid).set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
|
||||
}
|
||||
public void setTitle(UUID uuid, String title) {
|
||||
this.titles.put(uuid, title);
|
||||
getTime(uuid).set(getFadeIn(uuid) + getStay(uuid) + getFadeOut(uuid));
|
||||
}
|
||||
|
||||
public void setSubTitle(UUID uuid, String subTitle) {
|
||||
this.subTitles.put(uuid, subTitle);
|
||||
}
|
||||
public void setSubTitle(UUID uuid, String subTitle) {
|
||||
this.subTitles.put(uuid, subTitle);
|
||||
}
|
||||
|
||||
public void clear(UUID uuid) {
|
||||
this.titles.remove(uuid);
|
||||
this.subTitles.remove(uuid);
|
||||
getTime(uuid).set(0);
|
||||
}
|
||||
public void clear(UUID uuid) {
|
||||
this.titles.remove(uuid);
|
||||
this.subTitles.remove(uuid);
|
||||
getTime(uuid).set(0);
|
||||
}
|
||||
|
||||
public AtomicInteger getTime(UUID uuid) {
|
||||
return times.computeIfAbsent(uuid, key -> new AtomicInteger(0));
|
||||
}
|
||||
public AtomicInteger getTime(UUID uuid) {
|
||||
return times.computeIfAbsent(uuid, key -> new AtomicInteger(0));
|
||||
}
|
||||
|
||||
public int getFadeIn(UUID uuid) {
|
||||
return fadeIn.getOrDefault(uuid, 10);
|
||||
}
|
||||
public int getFadeIn(UUID uuid) {
|
||||
return fadeIn.getOrDefault(uuid, 10);
|
||||
}
|
||||
|
||||
public int getStay(UUID uuid) {
|
||||
return stay.getOrDefault(uuid, 70);
|
||||
}
|
||||
public int getStay(UUID uuid) {
|
||||
return stay.getOrDefault(uuid, 70);
|
||||
}
|
||||
|
||||
public int getFadeOut(UUID uuid) {
|
||||
return fadeOut.getOrDefault(uuid, 20);
|
||||
}
|
||||
public int getFadeOut(UUID uuid) {
|
||||
return fadeOut.getOrDefault(uuid, 20);
|
||||
}
|
||||
|
||||
public void setFadeIn(UUID uuid, int fadeIn) {
|
||||
if (fadeIn >= 0) this.fadeIn.put(uuid, fadeIn);
|
||||
else this.fadeIn.remove(uuid);
|
||||
}
|
||||
public void setFadeIn(UUID uuid, int fadeIn) {
|
||||
if (fadeIn >= 0) this.fadeIn.put(uuid, fadeIn);
|
||||
else this.fadeIn.remove(uuid);
|
||||
}
|
||||
|
||||
public void setStay(UUID uuid, int stay) {
|
||||
if (stay >= 0) this.stay.put(uuid, stay);
|
||||
else this.stay.remove(uuid);
|
||||
}
|
||||
public void setStay(UUID uuid, int stay) {
|
||||
if (stay >= 0) this.stay.put(uuid, stay);
|
||||
else this.stay.remove(uuid);
|
||||
}
|
||||
|
||||
public void setFadeOut(UUID uuid, int fadeOut) {
|
||||
if (fadeOut >= 0) this.fadeOut.put(uuid, fadeOut);
|
||||
else this.fadeOut.remove(uuid);
|
||||
}
|
||||
public void setFadeOut(UUID uuid, int fadeOut) {
|
||||
if (fadeOut >= 0) this.fadeOut.put(uuid, fadeOut);
|
||||
else this.fadeOut.remove(uuid);
|
||||
}
|
||||
}
|
||||
+48
-37
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,50 +23,61 @@ import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.DecoderException;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
public class CompressionDecoder extends MessageToMessageDecoder<ByteBuf> {
|
||||
private final Inflater inflater = new Inflater();
|
||||
private final Inflater inflater = new Inflater();
|
||||
|
||||
private final int threshold;
|
||||
private int threshold;
|
||||
|
||||
public CompressionDecoder(final int threshold) {
|
||||
this.threshold = threshold;
|
||||
}
|
||||
public CompressionDecoder(final int threshold) {
|
||||
this.threshold = threshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||
if (!in.isReadable()) return;
|
||||
public void setThreshold(final int threshold) {
|
||||
this.threshold = threshold;
|
||||
}
|
||||
|
||||
int outLength = Types.VAR_INT.readPrimitive(in);
|
||||
if (outLength == 0) {
|
||||
out.add(in.readBytes(in.readableBytes()));
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||
if (!in.isReadable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (outLength < this.threshold) {
|
||||
throw new DecoderException("Badly compressed packet - size of " + outLength + " is below server threshold of " + this.threshold);
|
||||
} else if (outLength > 2097152) {
|
||||
throw new DecoderException("Badly compressed packet - size of " + outLength + " is larger than protocol maximum of " + 2097152);
|
||||
}
|
||||
int outLength = Types.VAR_INT.readPrimitive(in);
|
||||
if (outLength == 0) {
|
||||
out.add(in.readBytes(in.readableBytes()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (outLength < this.threshold) {
|
||||
throw new DecoderException("Badly compressed packet - size of " + outLength + " is below server threshold of " + this.threshold);
|
||||
} else if (outLength > 2097152) {
|
||||
throw new DecoderException("Badly compressed packet - size of " + outLength + " is larger than protocol maximum of " + 2097152);
|
||||
}
|
||||
|
||||
inflate(ctx, in, outLength, out);
|
||||
}
|
||||
|
||||
protected void inflate(final ChannelHandlerContext ctx, final ByteBuf source, final int outLength, final List<Object> out) throws DataFormatException {
|
||||
ByteBuf temp = source;
|
||||
if (!source.hasArray()) {
|
||||
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(source);
|
||||
} else {
|
||||
source.retain();
|
||||
}
|
||||
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer(outLength, outLength);
|
||||
try {
|
||||
this.inflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
|
||||
output.writerIndex(output.writerIndex() + this.inflater.inflate(output.array(), output.arrayOffset(), outLength));
|
||||
out.add(output.retain());
|
||||
} finally {
|
||||
output.release();
|
||||
temp.release();
|
||||
this.inflater.reset();
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuf temp = in;
|
||||
if (!in.hasArray()) {
|
||||
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
|
||||
} else {
|
||||
in.retain();
|
||||
}
|
||||
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer(outLength, outLength);
|
||||
try {
|
||||
this.inflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
|
||||
output.writerIndex(output.writerIndex() + this.inflater.inflate(output.array(), output.arrayOffset(), outLength));
|
||||
out.add(output.retain());
|
||||
} finally {
|
||||
output.release();
|
||||
temp.release();
|
||||
this.inflater.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
-38
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,49 +22,58 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
public class CompressionEncoder extends MessageToByteEncoder<ByteBuf> {
|
||||
private final Deflater deflater = new Deflater();
|
||||
private final Deflater deflater = new Deflater();
|
||||
|
||||
private final int threshold;
|
||||
private int threshold;
|
||||
|
||||
public CompressionEncoder(final int threshold) {
|
||||
this.threshold = threshold;
|
||||
}
|
||||
public CompressionEncoder(final int threshold) {
|
||||
this.threshold = threshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception {
|
||||
int frameLength = in.readableBytes();
|
||||
if (frameLength < this.threshold) {
|
||||
out.writeByte(0); // VarInt
|
||||
out.writeBytes(in);
|
||||
return;
|
||||
}
|
||||
public void setThreshold(final int threshold) {
|
||||
this.threshold = threshold;
|
||||
}
|
||||
|
||||
Types.VAR_INT.writePrimitive(out, frameLength);
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception {
|
||||
int frameLength = in.readableBytes();
|
||||
if (frameLength < this.threshold) {
|
||||
out.writeByte(0); // VarInt
|
||||
out.writeBytes(in);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuf temp = in;
|
||||
if (!in.hasArray()) {
|
||||
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
|
||||
} else {
|
||||
in.retain();
|
||||
}
|
||||
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer();
|
||||
try {
|
||||
this.deflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
|
||||
deflater.finish();
|
||||
Types.VAR_INT.writePrimitive(out, frameLength);
|
||||
|
||||
while (!deflater.finished()) {
|
||||
output.ensureWritable(4096);
|
||||
output.writerIndex(output.writerIndex() + this.deflater.deflate(output.array(), output.arrayOffset() + output.writerIndex(), output.writableBytes()));
|
||||
}
|
||||
out.writeBytes(output);
|
||||
} finally {
|
||||
output.release();
|
||||
temp.release();
|
||||
this.deflater.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
deflate(in, out);
|
||||
}
|
||||
|
||||
protected void deflate(final ByteBuf source, final ByteBuf destination) throws DataFormatException {
|
||||
ByteBuf temp = source;
|
||||
if (!source.hasArray()) {
|
||||
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(source);
|
||||
} else {
|
||||
source.retain();
|
||||
}
|
||||
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer();
|
||||
try {
|
||||
this.deflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
|
||||
deflater.finish();
|
||||
|
||||
while (!deflater.finished()) {
|
||||
output.ensureWritable(4096);
|
||||
output.writerIndex(output.writerIndex() + this.deflater.deflate(output.array(), output.arrayOffset() + output.writerIndex(), output.writableBytes()));
|
||||
}
|
||||
destination.writeBytes(output);
|
||||
} finally {
|
||||
output.release();
|
||||
temp.release();
|
||||
this.deflater.reset();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+82
-43
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,62 +17,101 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression;
|
||||
|
||||
import com.viaversion.viarewind.ViaRewind;
|
||||
import com.viaversion.viarewind.api.minecraft.netty.EmptyChannelHandler;
|
||||
import com.viaversion.viarewind.api.minecraft.netty.ForwardMessageToByteEncoder;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.CompressionHandlerProvider;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.velocity.VelocityCompressionDecoder;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.velocity.VelocityCompressionEncoder;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
|
||||
public class TrackingCompressionHandlerProvider extends CompressionHandlerProvider {
|
||||
public static final String COMPRESS_HANDLER_NAME = "compress";
|
||||
public static final String DECOMPRESS_HANDLER_NAME = "decompress";
|
||||
|
||||
@Override
|
||||
public void onHandleLoginCompressionPacket(UserConnection user, int threshold) {
|
||||
final ChannelPipeline pipeline = user.getChannel().pipeline();
|
||||
if (user.isClientSide()) {
|
||||
pipeline.addBefore(Via.getManager().getInjector().getEncoderName(), COMPRESS_HANDLER_NAME, getEncoder(threshold));
|
||||
pipeline.addBefore(Via.getManager().getInjector().getDecoderName(), DECOMPRESS_HANDLER_NAME, getDecoder(threshold));
|
||||
} else {
|
||||
setCompressionEnabled(user, true); // We need to remove compression for 1.7 clients
|
||||
}
|
||||
}
|
||||
// Use Velocity's compression backend if ViaRewind is loaded on a Velocity server or a custom server software
|
||||
// is shipping them in the classpath.
|
||||
private static boolean velocityNatives;
|
||||
|
||||
@Override
|
||||
public void onTransformPacket(UserConnection user) {
|
||||
if (isCompressionEnabled(user)) {
|
||||
final ChannelPipeline pipeline = user.getChannel().pipeline();
|
||||
static {
|
||||
try {
|
||||
Class.forName("com.velocitypowered.natives.compression.VelocityCompressor");
|
||||
velocityNatives = true;
|
||||
} catch (final ClassNotFoundException ignored) {
|
||||
velocityNatives = false;
|
||||
}
|
||||
}
|
||||
|
||||
String compressor = null;
|
||||
String decompressor = null;
|
||||
if (pipeline.get(COMPRESS_HANDLER_NAME) != null) { // ViaVersion
|
||||
compressor = COMPRESS_HANDLER_NAME;
|
||||
decompressor = DECOMPRESS_HANDLER_NAME;
|
||||
} else if (pipeline.get("compression-encoder") != null) { // Velocity
|
||||
compressor = "compression-encoder";
|
||||
decompressor = "compression-decoder";
|
||||
}
|
||||
@Override
|
||||
public void setCompressionThreshold(UserConnection user, int threshold) {
|
||||
final ChannelPipeline pipeline = user.getChannel().pipeline();
|
||||
if (!user.isClientSide() || threshold < 0) {
|
||||
setRemoveCompression(user, true); // We need to remove compression for 1.7 clients
|
||||
return;
|
||||
}
|
||||
|
||||
if (compressor != null) { // We can neutralize the effect of compressor to the client
|
||||
pipeline.replace(decompressor, decompressor, new EmptyChannelHandler());
|
||||
pipeline.replace(compressor, compressor, new ForwardMessageToByteEncoder());
|
||||
} else {
|
||||
throw new IllegalStateException("Couldn't remove compression for 1.7!");
|
||||
}
|
||||
Object compressor = null;
|
||||
if (velocityNatives) {
|
||||
compressor = com.velocitypowered.natives.util.Natives.compress.get().create(-1);
|
||||
}
|
||||
|
||||
setCompressionEnabled(user, false);
|
||||
}
|
||||
}
|
||||
final String compressHandlerName = ViaRewind.getPlatform().compressHandlerName();
|
||||
final CompressionEncoder encoder = (CompressionEncoder) pipeline.get(compressHandlerName);
|
||||
if (encoder != null) {
|
||||
encoder.setThreshold(threshold);
|
||||
} else {
|
||||
pipeline.addBefore(Via.getManager().getInjector().getEncoderName(), compressHandlerName, getEncoder(compressor, threshold));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler getEncoder(int threshold) {
|
||||
return new CompressionEncoder(threshold);
|
||||
}
|
||||
final String decompressHandlerName = ViaRewind.getPlatform().decompressHandlerName();
|
||||
final CompressionDecoder decoder = (CompressionDecoder) pipeline.get(decompressHandlerName);
|
||||
if (decoder != null) {
|
||||
decoder.setThreshold(threshold);
|
||||
} else {
|
||||
pipeline.addBefore(Via.getManager().getInjector().getDecoderName(), decompressHandlerName, getDecoder(compressor, threshold));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransformPacket(UserConnection user) {
|
||||
if (isRemoveCompression(user)) {
|
||||
final ChannelPipeline pipeline = user.getChannel().pipeline();
|
||||
|
||||
String compressor = null;
|
||||
String decompressor = null;
|
||||
if (pipeline.get(ViaRewind.getPlatform().compressHandlerName()) != null) {
|
||||
compressor = ViaRewind.getPlatform().compressHandlerName();
|
||||
decompressor = ViaRewind.getPlatform().decompressHandlerName();
|
||||
}
|
||||
|
||||
if (compressor != null) { // We can neutralize the effect of compressor to the client
|
||||
pipeline.replace(decompressor, decompressor, new EmptyChannelHandler());
|
||||
pipeline.replace(compressor, compressor, new ForwardMessageToByteEncoder());
|
||||
} else {
|
||||
throw new IllegalStateException("Couldn't remove compression for 1.7!");
|
||||
}
|
||||
|
||||
setRemoveCompression(user, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler getEncoder(final Object compressor, int threshold) {
|
||||
if (velocityNatives) {
|
||||
return new VelocityCompressionEncoder(threshold, (com.velocitypowered.natives.compression.VelocityCompressor) compressor);
|
||||
} else {
|
||||
return new CompressionEncoder(threshold);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler getDecoder(final Object compressor, int threshold) {
|
||||
if (velocityNatives) {
|
||||
return new VelocityCompressionDecoder(threshold, (com.velocitypowered.natives.compression.VelocityCompressor) compressor);
|
||||
} else {
|
||||
return new CompressionDecoder(threshold);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler getDecoder(int threshold) {
|
||||
return new CompressionDecoder(threshold);
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.velocity;
|
||||
|
||||
import com.velocitypowered.natives.compression.VelocityCompressor;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.CompressionDecoder;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.util.List;
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
public final class VelocityCompressionDecoder extends CompressionDecoder {
|
||||
|
||||
private final VelocityCompressor compressor;
|
||||
|
||||
public VelocityCompressionDecoder(final int threshold, final VelocityCompressor compressor) {
|
||||
super(threshold);
|
||||
this.compressor = compressor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void inflate(final ChannelHandlerContext ctx, final ByteBuf source, final int outLength, final List<Object> out) throws DataFormatException {
|
||||
ByteBuf output = ctx.alloc().buffer(outLength);
|
||||
try {
|
||||
this.compressor.inflate(source, output, outLength);
|
||||
out.add(output.retain());
|
||||
} finally {
|
||||
output.release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.velocity;
|
||||
|
||||
import com.velocitypowered.natives.compression.VelocityCompressor;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.CompressionEncoder;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
public final class VelocityCompressionEncoder extends CompressionEncoder {
|
||||
|
||||
private final VelocityCompressor compressor;
|
||||
|
||||
public VelocityCompressionEncoder(final int threshold, final VelocityCompressor compressor) {
|
||||
super(threshold);
|
||||
this.compressor = compressor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deflate(final ByteBuf source, final ByteBuf destination) throws DataFormatException {
|
||||
this.compressor.deflate(source, destination);
|
||||
}
|
||||
|
||||
}
|
||||
+241
-241
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,305 +17,305 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.api.rewriters.LegacyEnchantmentRewriter;
|
||||
import com.viaversion.viarewind.api.rewriter.VRBlockItemRewriter;
|
||||
import com.viaversion.viarewind.api.type.RewindTypes;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ServerboundPackets1_7_2_5;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.EntityTracker1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.GameProfileStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.InventoryTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.PlayerSessionStorage;
|
||||
import com.viaversion.viarewind.api.type.RewindTypes;
|
||||
import com.viaversion.viarewind.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.*;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BlockItemPacketRewriter1_8 extends VRBlockItemRewriter<ClientboundPackets1_8, ServerboundPackets1_7_2_5, Protocol1_8To1_7_6_10> {
|
||||
|
||||
private LegacyEnchantmentRewriter enchantmentRewriter;
|
||||
private LegacyEnchantmentRewriter enchantmentRewriter;
|
||||
|
||||
public BlockItemPacketRewriter1_8(Protocol1_8To1_7_6_10 protocol) {
|
||||
super(protocol, "1.8");
|
||||
}
|
||||
public BlockItemPacketRewriter1_8(Protocol1_8To1_7_6_10 protocol) {
|
||||
super(protocol, "1.8");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
protocol.registerClientbound(ClientboundPackets1_8.OPEN_SCREEN, wrapper -> {
|
||||
final InventoryTracker windowTracker = wrapper.user().get(InventoryTracker.class);
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
protocol.registerClientbound(ClientboundPackets1_8.OPEN_SCREEN, wrapper -> {
|
||||
final InventoryTracker windowTracker = wrapper.user().get(InventoryTracker.class);
|
||||
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE); // Window id
|
||||
final short windowTypeId = InventoryTracker.getInventoryType(wrapper.read(Types.STRING)); // Window type
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE); // Window id
|
||||
final short windowTypeId = InventoryTracker.getInventoryType(wrapper.read(Types.STRING)); // Window type
|
||||
|
||||
windowTracker.getWindowTypeMap().put(windowId, windowTypeId);
|
||||
wrapper.write(Types.UNSIGNED_BYTE, windowTypeId); // Window type id
|
||||
windowTracker.getWindowTypeMap().put(windowId, windowTypeId);
|
||||
wrapper.write(Types.UNSIGNED_BYTE, windowTypeId); // Window type id
|
||||
|
||||
final JsonElement titleComponent = wrapper.read(Types.COMPONENT); // Title
|
||||
String title = ChatUtil.jsonToLegacy(wrapper.user(), titleComponent);
|
||||
title = ChatUtil.removeUnusedColor(title, '8');
|
||||
if (title.length() > 32) {
|
||||
title = title.substring(0, 32);
|
||||
}
|
||||
wrapper.write(Types.STRING, title); // Window title
|
||||
final JsonElement titleComponent = wrapper.read(Types.COMPONENT); // Title
|
||||
String title = ChatUtil.jsonToLegacy(titleComponent);
|
||||
title = ChatUtil.removeUnusedColor(title, '8');
|
||||
if (title.length() > 32) {
|
||||
title = title.substring(0, 32);
|
||||
}
|
||||
wrapper.write(Types.STRING, title); // Window title
|
||||
|
||||
wrapper.passthrough(Types.UNSIGNED_BYTE); // Slots
|
||||
wrapper.write(Types.BOOLEAN, true); // Use provided window title
|
||||
wrapper.passthrough(Types.UNSIGNED_BYTE); // Slots
|
||||
wrapper.write(Types.BOOLEAN, true); // Use provided window title
|
||||
|
||||
if (windowTypeId == 11) { // Horse
|
||||
wrapper.passthrough(Types.INT); // Entity id
|
||||
}
|
||||
});
|
||||
if (windowTypeId == 11) { // Horse
|
||||
wrapper.passthrough(Types.INT); // Entity id
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_CLOSE, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE); // Window id
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_CLOSE, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE); // Window id
|
||||
|
||||
wrapper.user().get(InventoryTracker.class).remove(windowId);
|
||||
});
|
||||
wrapper.user().get(InventoryTracker.class).remove(windowId);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_SLOT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.SHORT); // Slot
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_SLOT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Window id
|
||||
map(Types.SHORT); // Slot
|
||||
|
||||
handler(wrapper -> {
|
||||
final short windowType = wrapper.user().get(InventoryTracker.class).get(wrapper.get(Types.UNSIGNED_BYTE, 0));
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
if (windowType == 4) { // Enchantment Table
|
||||
if (slot == 1) {
|
||||
wrapper.cancel();
|
||||
} else if (slot >= 2) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot - 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
handler(wrapper -> {
|
||||
final short windowType = wrapper.user().get(InventoryTracker.class).get(wrapper.get(Types.BYTE, 0));
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
if (windowType == 4) { // Enchantment Table
|
||||
if (slot == 1) {
|
||||
wrapper.cancel();
|
||||
} else if (slot >= 2) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot - 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
map(Types.ITEM1_8, RewindTypes.COMPRESSED_NBT_ITEM); // item
|
||||
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(RewindTypes.COMPRESSED_NBT_ITEM, 0)));
|
||||
map(Types.ITEM1_8, RewindTypes.COMPRESSED_NBT_ITEM); // item
|
||||
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(RewindTypes.COMPRESSED_NBT_ITEM, 0)));
|
||||
|
||||
handler(wrapper -> {
|
||||
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
if (windowId != 0) {
|
||||
return;
|
||||
}
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
if (slot < 5 || slot > 8) {
|
||||
return;
|
||||
}
|
||||
final PlayerSessionStorage playerSession = wrapper.user().get(PlayerSessionStorage.class);
|
||||
final Item item = wrapper.get(RewindTypes.COMPRESSED_NBT_ITEM, 0);
|
||||
playerSession.setPlayerEquipment(wrapper.user().getProtocolInfo().getUuid(), item, 8 - slot);
|
||||
handler(wrapper -> {
|
||||
final byte windowId = wrapper.get(Types.BYTE, 0);
|
||||
if (windowId != 0) {
|
||||
return;
|
||||
}
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
if (slot < 5 || slot > 8) {
|
||||
return;
|
||||
}
|
||||
final PlayerSessionStorage playerSession = wrapper.user().get(PlayerSessionStorage.class);
|
||||
final Item item = wrapper.get(RewindTypes.COMPRESSED_NBT_ITEM, 0);
|
||||
playerSession.setPlayerEquipment(wrapper.user().getProtocolInfo().getUuid(), item, 8 - slot);
|
||||
|
||||
final EntityTracker1_8 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_7_6_10.class);
|
||||
if (tracker.isSpectator()) { // Spectator mode didn't exist in 1.7.10
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
final EntityTracker1_8 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_7_6_10.class);
|
||||
if (tracker.isSpectator()) { // Spectator mode didn't exist in 1.7.10
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_CONTENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_CONTENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
|
||||
// remap enchantment table items
|
||||
handler(wrapper -> {
|
||||
final short windowType = wrapper.user().get(InventoryTracker.class).get(wrapper.get(Types.UNSIGNED_BYTE, 0));
|
||||
// remap enchantment table items
|
||||
handler(wrapper -> {
|
||||
final short windowType = wrapper.user().get(InventoryTracker.class).get(wrapper.get(Types.UNSIGNED_BYTE, 0));
|
||||
|
||||
Item[] items = wrapper.read(Types.ITEM1_8_SHORT_ARRAY);
|
||||
if (windowType == 4) { // Enchantment Table
|
||||
Item[] old = items;
|
||||
items = new Item[old.length - 1];
|
||||
items[0] = old[0];
|
||||
System.arraycopy(old, 2, items, 1, old.length - 3);
|
||||
}
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
wrapper.write(RewindTypes.COMPRESSED_NBT_ITEM_ARRAY, items); // Items
|
||||
});
|
||||
Item[] items = wrapper.read(Types.ITEM1_8_SHORT_ARRAY);
|
||||
if (windowType == 4) { // Enchantment Table
|
||||
Item[] old = items;
|
||||
items = new Item[old.length - 1];
|
||||
items[0] = old[0];
|
||||
System.arraycopy(old, 2, items, 1, old.length - 2);
|
||||
}
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
wrapper.write(RewindTypes.COMPRESSED_NBT_ITEM_ARRAY, items); // Items
|
||||
});
|
||||
|
||||
handler(wrapper -> {
|
||||
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
if (windowId != 0) {
|
||||
return;
|
||||
}
|
||||
final EntityTracker1_8 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_7_6_10.class);
|
||||
final UUID userId = wrapper.user().getProtocolInfo().getUuid();
|
||||
handler(wrapper -> {
|
||||
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
if (windowId != 0) {
|
||||
return;
|
||||
}
|
||||
final EntityTracker1_8 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_7_6_10.class);
|
||||
final UUID userId = wrapper.user().getProtocolInfo().getUuid();
|
||||
|
||||
final Item[] items = wrapper.get(RewindTypes.COMPRESSED_NBT_ITEM_ARRAY, 0);
|
||||
for (int i = 5; i < 9; i++) {
|
||||
wrapper.user().get(PlayerSessionStorage.class).setPlayerEquipment(userId, items[i], 8 - i);
|
||||
if (tracker.isSpectator()) {
|
||||
items[i] = null;
|
||||
}
|
||||
}
|
||||
if (tracker.isSpectator()) {
|
||||
final GameProfileStorage.GameProfile profile = wrapper.user().get(GameProfileStorage.class).get(userId);
|
||||
if (profile != null) {
|
||||
items[5] = profile.getSkull();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
final Item[] items = wrapper.get(RewindTypes.COMPRESSED_NBT_ITEM_ARRAY, 0);
|
||||
for (int i = 5; i < 9; i++) {
|
||||
wrapper.user().get(PlayerSessionStorage.class).setPlayerEquipment(userId, items[i], 8 - i);
|
||||
if (tracker.isSpectator()) {
|
||||
items[i] = null;
|
||||
}
|
||||
}
|
||||
if (tracker.isSpectator()) {
|
||||
final GameProfileStorage.GameProfile profile = wrapper.user().get(GameProfileStorage.class).get(userId);
|
||||
if (profile != null) {
|
||||
items[5] = profile.getSkull();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.SHORT); // Progress bar id
|
||||
map(Types.SHORT); // Progress bar value
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.SHORT); // Progress bar id
|
||||
map(Types.SHORT); // Progress bar value
|
||||
|
||||
handler(wrapper -> {
|
||||
final InventoryTracker windowTracker = wrapper.user().get(InventoryTracker.class);
|
||||
handler(wrapper -> {
|
||||
final InventoryTracker windowTracker = wrapper.user().get(InventoryTracker.class);
|
||||
|
||||
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
final short windowType = windowTracker.get(windowId);
|
||||
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
final short windowType = windowTracker.get(windowId);
|
||||
|
||||
final short progressBarId = wrapper.get(Types.SHORT, 0);
|
||||
short progress = wrapper.get(Types.SHORT, 1);
|
||||
final short progressBarId = wrapper.get(Types.SHORT, 0);
|
||||
short progress = wrapper.get(Types.SHORT, 1);
|
||||
|
||||
if (windowType == 2) { // Furnace
|
||||
// TODO | Proper methods (getOrCreate)=
|
||||
final InventoryTracker.FurnaceData furnace = windowTracker.getFurnaceData().computeIfAbsent(windowId, x -> new InventoryTracker.FurnaceData());
|
||||
if (progressBarId == 0 || progressBarId == 1) {
|
||||
if (progressBarId == 0) {
|
||||
furnace.fuelLeft = progress;
|
||||
} else {
|
||||
furnace.maxFuel = progress;
|
||||
}
|
||||
if (furnace.maxFuel == 0) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
progress = (short) (200 * furnace.fuelLeft / furnace.maxFuel);
|
||||
wrapper.set(Types.SHORT, 0, (short) 1);
|
||||
wrapper.set(Types.SHORT, 1, progress);
|
||||
} else if (progressBarId == 2 || progressBarId == 3) {
|
||||
if (progressBarId == 2) {
|
||||
furnace.progress = progress;
|
||||
} else {
|
||||
furnace.maxProgress = progress;
|
||||
}
|
||||
if (furnace.maxProgress == 0) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
progress = (short) (200 * furnace.progress / furnace.maxProgress);
|
||||
wrapper.set(Types.SHORT, 0, (short) 0);
|
||||
wrapper.set(Types.SHORT, 1, progress);
|
||||
}
|
||||
} else if (windowType == 4 && progressBarId > 2) { // Enchanting Table
|
||||
wrapper.cancel();
|
||||
} else if (windowType == 8) { // Anvil
|
||||
windowTracker.levelCost = progress;
|
||||
windowTracker.anvilId = windowId;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (windowType == 2) { // Furnace
|
||||
// TODO | Proper methods (getOrCreate)=
|
||||
final InventoryTracker.FurnaceData furnace = windowTracker.getFurnaceData().computeIfAbsent(windowId, x -> new InventoryTracker.FurnaceData());
|
||||
if (progressBarId == 0 || progressBarId == 1) {
|
||||
if (progressBarId == 0) {
|
||||
furnace.fuelLeft = progress;
|
||||
} else {
|
||||
furnace.maxFuel = progress;
|
||||
}
|
||||
if (furnace.maxFuel == 0) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
progress = (short) (200 * furnace.fuelLeft / furnace.maxFuel);
|
||||
wrapper.set(Types.SHORT, 0, (short) 1);
|
||||
wrapper.set(Types.SHORT, 1, progress);
|
||||
} else if (progressBarId == 2 || progressBarId == 3) {
|
||||
if (progressBarId == 2) {
|
||||
furnace.progress = progress;
|
||||
} else {
|
||||
furnace.maxProgress = progress;
|
||||
}
|
||||
if (furnace.maxProgress == 0) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
progress = (short) (200 * furnace.progress / furnace.maxProgress);
|
||||
wrapper.set(Types.SHORT, 0, (short) 0);
|
||||
wrapper.set(Types.SHORT, 1, progress);
|
||||
}
|
||||
} else if (windowType == 4 && progressBarId > 2) { // Enchanting Table
|
||||
wrapper.cancel();
|
||||
} else if (windowType == 8) { // Anvil
|
||||
windowTracker.levelCost = progress;
|
||||
windowTracker.anvilId = windowId;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_7_2_5.CONTAINER_CLOSE, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
protocol.registerServerbound(ServerboundPackets1_7_2_5.CONTAINER_CLOSE, wrapper -> {
|
||||
final byte windowId = wrapper.passthrough(Types.BYTE);
|
||||
|
||||
wrapper.user().get(InventoryTracker.class).remove(windowId);
|
||||
});
|
||||
wrapper.user().get(InventoryTracker.class).remove(windowId);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_7_2_5.CONTAINER_CLICK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE, Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.SHORT); // Slot
|
||||
handler(wrapper -> {
|
||||
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0); // Window id
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
protocol.registerServerbound(ServerboundPackets1_7_2_5.CONTAINER_CLICK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Window id
|
||||
map(Types.SHORT); // Slot
|
||||
handler(wrapper -> {
|
||||
final byte windowId = wrapper.get(Types.BYTE, 0); // Window id
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
|
||||
final short windowType = wrapper.user().get(InventoryTracker.class).get(windowId);
|
||||
if (windowType == 4) { // Enchantment Table
|
||||
if (slot > 0) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot + 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
map(Types.BYTE); // Button
|
||||
map(Types.SHORT); // Action number
|
||||
map(Types.BYTE); // Mode
|
||||
map(RewindTypes.COMPRESSED_NBT_ITEM, Types.ITEM1_8); // Clicked item
|
||||
final short windowType = wrapper.user().get(InventoryTracker.class).get(windowId);
|
||||
if (windowType == 4) { // Enchantment Table
|
||||
if (slot > 0) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot + 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
map(Types.BYTE); // Button
|
||||
map(Types.SHORT); // Action number
|
||||
map(Types.BYTE); // Mode
|
||||
map(RewindTypes.COMPRESSED_NBT_ITEM, Types.ITEM1_8); // Clicked item
|
||||
|
||||
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
|
||||
}
|
||||
});
|
||||
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_7_2_5.SET_CREATIVE_MODE_SLOT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.SHORT); // Slot
|
||||
map(RewindTypes.COMPRESSED_NBT_ITEM, Types.ITEM1_8); // Item
|
||||
protocol.registerServerbound(ServerboundPackets1_7_2_5.SET_CREATIVE_MODE_SLOT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.SHORT); // Slot
|
||||
map(RewindTypes.COMPRESSED_NBT_ITEM, Types.ITEM1_8); // Item
|
||||
|
||||
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
|
||||
}
|
||||
});
|
||||
}
|
||||
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName(), false);
|
||||
enchantmentRewriter.registerEnchantment(8, "§7Depth Strider");
|
||||
}
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName(), false);
|
||||
enchantmentRewriter.registerEnchantment(8, "§7Depth Strider");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item handleItemToClient(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToClient(connection, item);
|
||||
@Override
|
||||
public Item handleItemToClient(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToClient(connection, item);
|
||||
|
||||
CompoundTag tag = item.tag();
|
||||
if (tag == null) {
|
||||
item.setTag(tag = new CompoundTag());
|
||||
}
|
||||
enchantmentRewriter.handleToClient(item);
|
||||
CompoundTag tag = item.tag();
|
||||
if (tag == null) return item;
|
||||
|
||||
if (item.identifier() == 387) {
|
||||
final ListTag<StringTag> pages = tag.getListTag("pages", StringTag.class);
|
||||
if (pages == null) return item;
|
||||
enchantmentRewriter.handleToClient(item);
|
||||
|
||||
final ListTag<StringTag> oldPages = new ListTag<>(StringTag.class);
|
||||
tag.put(nbtTagName() + "|pages", oldPages);
|
||||
if (item.identifier() == 387) {
|
||||
final ListTag<StringTag> pages = tag.getListTag("pages", StringTag.class);
|
||||
if (pages == null) return item;
|
||||
|
||||
for (StringTag page : pages) {
|
||||
final String value = page.getValue();
|
||||
oldPages.add(new StringTag(value));
|
||||
page.setValue(ChatUtil.jsonToLegacy(connection, value));
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
final ListTag<StringTag> oldPages = new ListTag<>(StringTag.class);
|
||||
tag.put(nbtTagName() + "|pages", oldPages);
|
||||
|
||||
@Override
|
||||
public Item handleItemToServer(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToServer(connection, item);
|
||||
for (StringTag page : pages) {
|
||||
final String value = page.getValue();
|
||||
oldPages.add(new StringTag(value));
|
||||
page.setValue(ChatUtil.jsonToLegacy(value));
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
final CompoundTag tag = item.tag();
|
||||
if (tag == null) return item;
|
||||
@Override
|
||||
public Item handleItemToServer(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToServer(connection, item);
|
||||
|
||||
enchantmentRewriter.handleToServer(item);
|
||||
final CompoundTag tag = item.tag();
|
||||
if (tag == null) return item;
|
||||
|
||||
if (item.identifier() == 387) {
|
||||
final ListTag<StringTag> oldPages = tag.getListTag(nbtTagName() + "|pages", StringTag.class);
|
||||
if (oldPages != null) {
|
||||
tag.remove("pages");
|
||||
tag.put("pages", oldPages);
|
||||
}
|
||||
}
|
||||
enchantmentRewriter.handleToServer(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
if (item.identifier() == 387) {
|
||||
final ListTag<StringTag> oldPages = tag.getListTag(nbtTagName() + "|pages", StringTag.class);
|
||||
if (oldPages != null) {
|
||||
tag.remove("pages");
|
||||
tag.put("pages", oldPages);
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
+661
-653
File diff suppressed because it is too large.
Load diff
+801
-741
File diff suppressed because it is too large.
Load diff
+219
-195
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,228 +19,252 @@ package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter;
|
||||
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.EntityTracker1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.ScoreboardTracker;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.rewriter.RewriterBase;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
import com.viaversion.viaversion.util.ChatColorUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ScoreboardPacketRewriter1_8 {
|
||||
public class ScoreboardPacketRewriter1_8 extends RewriterBase<Protocol1_8To1_7_6_10> {
|
||||
|
||||
public static void register(Protocol1_8To1_7_6_10 protocol) {
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_OBJECTIVE, wrapper -> {
|
||||
String name = wrapper.passthrough(Types.STRING);
|
||||
if (name.length() > 16) {
|
||||
wrapper.set(Types.STRING, 0, name = name.substring(0, 16));
|
||||
}
|
||||
public ScoreboardPacketRewriter1_8(Protocol1_8To1_7_6_10 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
final byte mode = wrapper.read(Types.BYTE);
|
||||
ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
if (mode == 0) {
|
||||
if (scoreboard.objectiveExists(name)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
scoreboard.addObjective(name);
|
||||
} else if (mode == 1) {
|
||||
if (!scoreboard.objectiveExists(name)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
if (scoreboard.getColorIndependentSidebar() != null) {
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||
if (color.isPresent()) {
|
||||
String sidebar = scoreboard.getColorDependentSidebar().get(color.get());
|
||||
if (name.equals(sidebar)) {
|
||||
final PacketWrapper sidebarPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
sidebarPacket.write(Types.BYTE, (byte) 1);
|
||||
sidebarPacket.write(Types.STRING, scoreboard.getColorIndependentSidebar());
|
||||
sidebarPacket.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
scoreboard.removeObjective(name);
|
||||
} else if (mode == 2) {
|
||||
if (!scoreboard.objectiveExists(name)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_OBJECTIVE, wrapper -> {
|
||||
String name = wrapper.passthrough(Types.STRING);
|
||||
if (name.length() > 16) {
|
||||
wrapper.set(Types.STRING, 0, name = name.substring(0, 16));
|
||||
}
|
||||
|
||||
if (mode == 0 || mode == 2) {
|
||||
String displayName = wrapper.passthrough(Types.STRING);
|
||||
if (displayName.length() > 32) {
|
||||
wrapper.set(Types.STRING, 1, displayName.substring(0, 32));
|
||||
}
|
||||
wrapper.read(Types.STRING);
|
||||
} else {
|
||||
wrapper.write(Types.STRING, "");
|
||||
}
|
||||
wrapper.write(Types.BYTE, mode);
|
||||
});
|
||||
final byte mode = wrapper.read(Types.BYTE);
|
||||
ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
if (mode == 0) {
|
||||
if (scoreboard.objectiveExists(name)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
scoreboard.addObjective(name);
|
||||
} else if (mode == 1) {
|
||||
if (!scoreboard.objectiveExists(name)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
if (scoreboard.getColorIndependentSidebar() != null) {
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||
if (color.isPresent()) {
|
||||
String sidebar = scoreboard.getColorDependentSidebar().get(color.get());
|
||||
if (name.equals(sidebar)) {
|
||||
final PacketWrapper sidebarPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
sidebarPacket.write(Types.BYTE, (byte) 1);
|
||||
sidebarPacket.write(Types.STRING, scoreboard.getColorIndependentSidebar());
|
||||
sidebarPacket.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
scoreboard.removeObjective(name);
|
||||
} else if (mode == 2) {
|
||||
if (!scoreboard.objectiveExists(name)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_SCORE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Name
|
||||
map(Types.VAR_INT, Types.BYTE); // Mode
|
||||
handler(wrapper -> {
|
||||
ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
byte mode = wrapper.get(Types.BYTE, 0);
|
||||
if (mode == 0 || mode == 2) {
|
||||
String displayName = wrapper.passthrough(Types.STRING);
|
||||
if (displayName.length() > 32) {
|
||||
wrapper.set(Types.STRING, 1, displayName.substring(0, 32));
|
||||
}
|
||||
wrapper.read(Types.STRING);
|
||||
} else {
|
||||
wrapper.write(Types.STRING, "");
|
||||
}
|
||||
wrapper.write(Types.BYTE, mode);
|
||||
});
|
||||
|
||||
if (mode == 1) {
|
||||
name = scoreboard.removeTeamForScore(name);
|
||||
} else {
|
||||
name = scoreboard.sendTeamForScore(name);
|
||||
}
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_SCORE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Name
|
||||
map(Types.VAR_INT, Types.BYTE); // Mode
|
||||
handler(wrapper -> {
|
||||
ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
byte mode = wrapper.get(Types.BYTE, 0);
|
||||
|
||||
if (name.length() > 16) {
|
||||
name = ChatColorUtil.stripColor(name);
|
||||
if (name.length() > 16) {
|
||||
name = name.substring(0, 16);
|
||||
}
|
||||
}
|
||||
wrapper.set(Types.STRING, 0, name);
|
||||
if (mode == 1) {
|
||||
name = scoreboard.removeTeamForScore(name);
|
||||
} else {
|
||||
name = scoreboard.sendTeamForScore(name);
|
||||
}
|
||||
|
||||
String objective = wrapper.read(Types.STRING);
|
||||
if (objective.length() > 16) {
|
||||
objective = objective.substring(0, 16);
|
||||
}
|
||||
if (name.length() > 16) {
|
||||
name = ChatColorUtil.stripColor(name);
|
||||
if (name.length() > 16) {
|
||||
name = name.substring(0, 16);
|
||||
}
|
||||
}
|
||||
wrapper.set(Types.STRING, 0, name);
|
||||
|
||||
if (mode != 1) {
|
||||
int score = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(Types.STRING, objective);
|
||||
wrapper.write(Types.INT, score);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
String objective = wrapper.read(Types.STRING);
|
||||
if (objective.length() > 16) {
|
||||
objective = objective.substring(0, 16);
|
||||
}
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_DISPLAY_OBJECTIVE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Position
|
||||
map(Types.STRING); // Score name
|
||||
handler(wrapper -> {
|
||||
byte position = wrapper.get(Types.BYTE, 0);
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
if (position > 2) { // team specific sidebar
|
||||
byte receiverTeamColor = (byte) (position - 3);
|
||||
scoreboard.getColorDependentSidebar().put(receiverTeamColor, name);
|
||||
if (mode != 1) {
|
||||
int score = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(Types.STRING, objective);
|
||||
wrapper.write(Types.INT, score);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||
if (color.isPresent() && color.get() == receiverTeamColor) {
|
||||
position = 1;
|
||||
} else {
|
||||
position = -1;
|
||||
}
|
||||
} else if (position == 1) { // team independent sidebar
|
||||
scoreboard.setColorIndependentSidebar(name);
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||
if (color.isPresent() && scoreboard.getColorDependentSidebar().containsKey(color.get())) {
|
||||
position = -1;
|
||||
}
|
||||
}
|
||||
if (position == -1) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
wrapper.set(Types.BYTE, 0, position);
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_DISPLAY_OBJECTIVE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Position
|
||||
map(Types.STRING); // Score name
|
||||
handler(wrapper -> {
|
||||
byte position = wrapper.get(Types.BYTE, 0);
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
if (position > 2) { // team specific sidebar
|
||||
byte receiverTeamColor = (byte) (position - 3);
|
||||
scoreboard.getColorDependentSidebar().put(receiverTeamColor, name);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_PLAYER_TEAM, wrapper -> {
|
||||
final String team = wrapper.passthrough(Types.STRING);
|
||||
if (team == null) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||
if (color.isPresent() && color.get() == receiverTeamColor) {
|
||||
position = 1;
|
||||
} else {
|
||||
position = -1;
|
||||
}
|
||||
} else if (position == 1) { // team independent sidebar
|
||||
scoreboard.setColorIndependentSidebar(name);
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
|
||||
if (color.isPresent() && scoreboard.getColorDependentSidebar().containsKey(color.get())) {
|
||||
position = -1;
|
||||
}
|
||||
}
|
||||
if (position == -1) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
wrapper.set(Types.BYTE, 0, position);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
final ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_PLAYER_TEAM, wrapper -> {
|
||||
final String team = wrapper.passthrough(Types.STRING);
|
||||
if (team == null) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
final byte mode = wrapper.passthrough(Types.BYTE);
|
||||
if (mode != 0 && !scoreboard.teamExists(team)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
} else if (mode == 0 && scoreboard.teamExists(team)) {
|
||||
scoreboard.removeTeam(team);
|
||||
final ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
|
||||
final EntityTracker1_8 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_7_6_10.class);
|
||||
|
||||
final PacketWrapper removeTeam = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, wrapper.user());
|
||||
removeTeam.write(Types.STRING, team);
|
||||
removeTeam.write(Types.BYTE, (byte) 1);
|
||||
removeTeam.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
final byte mode = wrapper.passthrough(Types.BYTE);
|
||||
if (mode != 0 && !scoreboard.teamExists(team)) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
} else if (mode == 0 && scoreboard.teamExists(team)) {
|
||||
scoreboard.removeTeam(team);
|
||||
|
||||
if (mode == 0) {
|
||||
scoreboard.addTeam(team);
|
||||
} else if (mode == 1) {
|
||||
scoreboard.removeTeam(team);
|
||||
}
|
||||
final PacketWrapper removeTeam = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, wrapper.user());
|
||||
removeTeam.write(Types.STRING, team);
|
||||
removeTeam.write(Types.BYTE, (byte) 1);
|
||||
removeTeam.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
if (mode == 0 || mode == 2) {
|
||||
wrapper.passthrough(Types.STRING); // Display name
|
||||
wrapper.passthrough(Types.STRING); // Prefix
|
||||
wrapper.passthrough(Types.STRING); // Suffix
|
||||
wrapper.passthrough(Types.BYTE); // Friendly fire
|
||||
wrapper.read(Types.STRING); // Name tag visibility
|
||||
byte color = wrapper.read(Types.BYTE);
|
||||
if (mode == 2 && scoreboard.getTeamColor(team).get() != color) {
|
||||
final String sidebar = scoreboard.getColorDependentSidebar().get(color);
|
||||
if (mode == 0) {
|
||||
scoreboard.addTeam(team);
|
||||
} else if (mode == 1) {
|
||||
// Team removed, nametag visibility might have changed
|
||||
for (final String member : scoreboard.getTeamMembers(team)) {
|
||||
tracker.checkNametagVisbility(member);
|
||||
}
|
||||
scoreboard.removeTeam(team);
|
||||
}
|
||||
|
||||
final PacketWrapper sidebarPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
sidebarPacket.write(Types.BYTE, (byte) 1);
|
||||
sidebarPacket.write(Types.STRING, sidebar == null ? "" : sidebar);
|
||||
sidebarPacket.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
scoreboard.setTeamColor(team, color);
|
||||
}
|
||||
if (mode == 0 || mode == 3 || mode == 4) {
|
||||
byte color = scoreboard.getTeamColor(team).get();
|
||||
String[] entries = wrapper.read(Types.STRING_ARRAY);
|
||||
List<String> entryList = new ArrayList<>();
|
||||
if (mode == 0 || mode == 2) {
|
||||
wrapper.passthrough(Types.STRING); // Display name
|
||||
wrapper.passthrough(Types.STRING); // Prefix
|
||||
wrapper.passthrough(Types.STRING); // Suffix
|
||||
wrapper.passthrough(Types.BYTE); // Friendly fire
|
||||
final String nameTagVisibility = wrapper.read(Types.STRING);
|
||||
final String previousVisibility = scoreboard.getTeamNameTagVisibility(team);
|
||||
scoreboard.setTeamNameTagVisibility(team, nameTagVisibility);
|
||||
byte color = wrapper.read(Types.BYTE);
|
||||
if (mode == 2 && scoreboard.getTeamColor(team).get() != color) {
|
||||
final String sidebar = scoreboard.getColorDependentSidebar().get(color);
|
||||
|
||||
for (String entry : entries) {
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
final PacketWrapper sidebarPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
sidebarPacket.write(Types.BYTE, (byte) 1);
|
||||
sidebarPacket.write(Types.STRING, sidebar == null ? "" : sidebar);
|
||||
sidebarPacket.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
scoreboard.setTeamColor(team, color);
|
||||
|
||||
if (mode == 4) {
|
||||
if (!scoreboard.isPlayerInTeam(entry, team)) {
|
||||
continue;
|
||||
}
|
||||
scoreboard.removePlayerFromTeam(entry, team);
|
||||
if (entry.equals(username)) {
|
||||
final PacketWrapper sidebarPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
sidebarPacket.write(Types.BYTE, (byte) 1);
|
||||
sidebarPacket.write(Types.STRING, scoreboard.getColorIndependentSidebar() == null ? "" : scoreboard.getColorIndependentSidebar());
|
||||
sidebarPacket.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
} else {
|
||||
scoreboard.addPlayerToTeam(entry, team);
|
||||
if (entry.equals(username) && scoreboard.getColorDependentSidebar().containsKey(color)) {
|
||||
final PacketWrapper displayObjective = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
displayObjective.write(Types.BYTE, (byte) 1);
|
||||
displayObjective.write(Types.STRING, scoreboard.getColorDependentSidebar().get(color));
|
||||
displayObjective.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
entryList.add(entry);
|
||||
}
|
||||
// Re-evaluate nametag visibility for all team members when visibility changes
|
||||
if (mode == 2 && !nameTagVisibility.equals(previousVisibility)) {
|
||||
for (final String member : scoreboard.getTeamMembers(team)) {
|
||||
tracker.checkNametagVisbility(member);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mode == 0 || mode == 3 || mode == 4) {
|
||||
byte color = scoreboard.getTeamColor(team).get();
|
||||
String[] entries = wrapper.read(Types.STRING_ARRAY);
|
||||
List<String> entryList = new ArrayList<>();
|
||||
|
||||
wrapper.write(Types.SHORT, (short) entryList.size());
|
||||
for (String entry : entryList) {
|
||||
wrapper.write(Types.STRING, entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
for (String entry : entries) {
|
||||
String username = wrapper.user().getProtocolInfo().getUsername();
|
||||
|
||||
if (mode == 4) {
|
||||
if (!scoreboard.isPlayerInTeam(entry, team)) {
|
||||
continue;
|
||||
}
|
||||
scoreboard.removePlayerFromTeam(entry, team);
|
||||
// Player left team, nametag visibility may change
|
||||
tracker.checkNametagVisbility(entry);
|
||||
if (entry.equals(username)) {
|
||||
final PacketWrapper sidebarPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
sidebarPacket.write(Types.BYTE, (byte) 1);
|
||||
sidebarPacket.write(Types.STRING, scoreboard.getColorIndependentSidebar() == null ? "" : scoreboard.getColorIndependentSidebar());
|
||||
sidebarPacket.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
} else {
|
||||
scoreboard.addPlayerToTeam(entry, team);
|
||||
// Player joined team, nametag visibility may change
|
||||
tracker.checkNametagVisbility(entry);
|
||||
if (entry.equals(username) && scoreboard.getColorDependentSidebar().containsKey(color)) {
|
||||
final PacketWrapper displayObjective = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
|
||||
displayObjective.write(Types.BYTE, (byte) 1);
|
||||
displayObjective.write(Types.STRING, scoreboard.getColorDependentSidebar().get(color));
|
||||
displayObjective.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
entryList.add(entry);
|
||||
}
|
||||
|
||||
wrapper.write(Types.SHORT, (short) entryList.size());
|
||||
for (String entry : entryList) {
|
||||
wrapper.write(Types.STRING, entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+225
-220
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,272 +17,277 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter;
|
||||
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.WorldBorderEmulator;
|
||||
import com.viaversion.viarewind.api.type.chunk.ChunkType1_7_6;
|
||||
import com.viaversion.viarewind.api.type.chunk.BulkChunkType1_7_6;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data.Particles1_8;
|
||||
import com.viaversion.viarewind.api.type.RewindTypes;
|
||||
import com.viaversion.viarewind.api.type.chunk.BulkChunkType1_7_6;
|
||||
import com.viaversion.viarewind.api.type.chunk.ChunkType1_7_6;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data.Particles1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.WorldBorderEmulator;
|
||||
import com.viaversion.viarewind.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.rewriter.RewriterBase;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.FixedByteArrayType;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.BulkChunkType1_8;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_8;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
import com.viaversion.viaversion.util.ChatColorUtil;
|
||||
import com.viaversion.viaversion.util.IdAndData;
|
||||
|
||||
public class WorldPacketRewriter1_8 {
|
||||
public class WorldPacketRewriter1_8 extends RewriterBase<Protocol1_8To1_7_6_10> {
|
||||
|
||||
public static void register(Protocol1_8To1_7_6_10 protocol) {
|
||||
protocol.registerClientbound(ClientboundPackets1_8.LEVEL_CHUNK, wrapper -> {
|
||||
final ClientWorld world = wrapper.user().get(ClientWorld.class);
|
||||
final Chunk chunk = wrapper.read(ChunkType1_8.forEnvironment(world.getEnvironment()));
|
||||
protocol.getItemRewriter().handleChunk(chunk);
|
||||
public WorldPacketRewriter1_8(Protocol1_8To1_7_6_10 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
wrapper.write(ChunkType1_7_6.TYPE, chunk);
|
||||
});
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
protocol.registerClientbound(ClientboundPackets1_8.LEVEL_CHUNK, wrapper -> {
|
||||
final ClientWorld world = wrapper.user().getClientWorld(Protocol1_8To1_7_6_10.class);
|
||||
final Chunk chunk = wrapper.read(ChunkType1_8.forEnvironment(world.getEnvironment()));
|
||||
protocol.getItemRewriter().handleChunk(chunk);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_UPDATE, new PacketHandlers() {
|
||||
@Override
|
||||
protected void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.U_BYTE_POSITION); // Position
|
||||
handler(wrapper -> {
|
||||
int data = wrapper.read(Types.VAR_INT); // Block data
|
||||
data = protocol.getItemRewriter().handleBlockId(data);
|
||||
wrapper.write(ChunkType1_7_6.TYPE, chunk);
|
||||
});
|
||||
|
||||
wrapper.write(Types.VAR_INT, IdAndData.getId(data)); // Block id
|
||||
wrapper.write(Types.UNSIGNED_BYTE, (short) IdAndData.getData(data)); // Block data
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_UPDATE, new PacketHandlers() {
|
||||
@Override
|
||||
protected void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.U_BYTE_POSITION); // Position
|
||||
handler(wrapper -> {
|
||||
int data = wrapper.read(Types.VAR_INT); // Block data
|
||||
data = protocol.getItemRewriter().handleBlockId(data);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CHUNK_BLOCKS_UPDATE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Chunk x
|
||||
map(Types.INT); // Chunk z
|
||||
wrapper.write(Types.VAR_INT, IdAndData.getId(data)); // Block id
|
||||
wrapper.write(Types.UNSIGNED_BYTE, (short) IdAndData.getData(data)); // Block data
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
handler(wrapper -> {
|
||||
final BlockChangeRecord[] records = wrapper.read(Types.BLOCK_CHANGE_ARRAY);
|
||||
protocol.registerClientbound(ClientboundPackets1_8.CHUNK_BLOCKS_UPDATE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Chunk x
|
||||
map(Types.INT); // Chunk z
|
||||
|
||||
wrapper.write(Types.SHORT, (short) records.length); // Record count
|
||||
wrapper.write(Types.INT, records.length * 4); // Data array length (position + block id)
|
||||
handler(wrapper -> {
|
||||
final BlockChangeRecord[] records = wrapper.read(Types.BLOCK_CHANGE_ARRAY);
|
||||
|
||||
for (BlockChangeRecord record : records) {
|
||||
wrapper.write(Types.SHORT, (short) (record.getSectionX() << 12 | record.getSectionZ() << 8 | record.getY())); // Position
|
||||
wrapper.write(Types.SHORT, (short) protocol.getItemRewriter().handleBlockId(record.getBlockId())); // Block id
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
wrapper.write(Types.SHORT, (short) records.length); // Record count
|
||||
wrapper.write(Types.INT, records.length * 4); // Data array length (position + block id)
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.SHORT_POSITION); // Position
|
||||
map(Types.UNSIGNED_BYTE); // Type
|
||||
map(Types.UNSIGNED_BYTE); // Data
|
||||
map(Types.VAR_INT); // Block id
|
||||
}
|
||||
});
|
||||
for (BlockChangeRecord record : records) {
|
||||
wrapper.write(Types.SHORT, (short) (record.getSectionX() << 12 | record.getSectionZ() << 8 | record.getY())); // Position
|
||||
wrapper.write(Types.SHORT, (short) protocol.getItemRewriter().handleBlockId(record.getBlockId())); // Block id
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_DESTRUCTION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Entity id
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.INT_POSITION); // Position
|
||||
map(Types.BYTE); // Progress
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.SHORT_POSITION); // Position
|
||||
map(Types.UNSIGNED_BYTE); // Type
|
||||
map(Types.UNSIGNED_BYTE); // Data
|
||||
map(Types.VAR_INT); // Block id
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, wrapper -> {
|
||||
final Chunk[] chunks = wrapper.read(BulkChunkType1_8.TYPE);
|
||||
for (Chunk chunk : chunks) {
|
||||
protocol.getItemRewriter().handleChunk(chunk);
|
||||
}
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_DESTRUCTION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Entity id
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.INT_POSITION); // Position
|
||||
map(Types.BYTE); // Progress
|
||||
}
|
||||
});
|
||||
|
||||
wrapper.write(BulkChunkType1_7_6.TYPE, chunks);
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, wrapper -> {
|
||||
final Chunk[] chunks = wrapper.read(BulkChunkType1_8.TYPE);
|
||||
for (Chunk chunk : chunks) {
|
||||
protocol.getItemRewriter().handleChunk(chunk);
|
||||
}
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.LEVEL_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Effect id
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.BYTE_POSITION); // Position
|
||||
map(Types.INT); // Data
|
||||
map(Types.BOOLEAN); // Disable relative volume
|
||||
}
|
||||
});
|
||||
wrapper.write(BulkChunkType1_7_6.TYPE, chunks);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.LEVEL_PARTICLES, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final int particleId = wrapper.read(Types.INT); // Particle id
|
||||
Particles1_8 particle = Particles1_8.find(particleId);
|
||||
if (particle == null) {
|
||||
particle = Particles1_8.CRIT;
|
||||
}
|
||||
wrapper.write(Types.STRING, particle.name); // Particle name
|
||||
protocol.registerClientbound(ClientboundPackets1_8.LEVEL_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Effect id
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.BYTE_POSITION); // Position
|
||||
map(Types.INT); // Data
|
||||
map(Types.BOOLEAN); // Disable relative volume
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
read(Types.BOOLEAN); // Long distance
|
||||
map(Types.FLOAT); // X
|
||||
map(Types.FLOAT); // Y
|
||||
map(Types.FLOAT); // Z
|
||||
map(Types.FLOAT); // Offset x
|
||||
map(Types.FLOAT); // Offset y
|
||||
map(Types.FLOAT); // Offset z
|
||||
map(Types.FLOAT); // Particle data
|
||||
map(Types.INT); // Particle count
|
||||
handler(wrapper -> {
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
Particles1_8 particle = Particles1_8.find(name);
|
||||
protocol.registerClientbound(ClientboundPackets1_8.LEVEL_PARTICLES, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final int particleId = wrapper.read(Types.INT); // Particle id
|
||||
Particles1_8 particle = Particles1_8.find(particleId);
|
||||
if (particle == null) {
|
||||
particle = Particles1_8.CRIT;
|
||||
}
|
||||
wrapper.write(Types.STRING, particle.name); // Particle name
|
||||
|
||||
if (particle == Particles1_8.ICON_CRACK || particle == Particles1_8.BLOCK_CRACK || particle == Particles1_8.BLOCK_DUST) {
|
||||
int id = wrapper.read(Types.VAR_INT);
|
||||
int data = particle == Particles1_8.ICON_CRACK ? wrapper.read(Types.VAR_INT) : id / 4096;
|
||||
id %= 4096;
|
||||
if (id >= 256 && id <= 422 || id >= 2256 && id <= 2267) { //item
|
||||
particle = Particles1_8.ICON_CRACK;
|
||||
} else if (id >= 0 && id <= 164 || id >= 170 && id <= 175) {
|
||||
if (particle == Particles1_8.ICON_CRACK)
|
||||
particle = Particles1_8.BLOCK_CRACK;
|
||||
} else {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
name = particle.name + "_" + id + "_" + data;
|
||||
}
|
||||
});
|
||||
read(Types.BOOLEAN); // Long distance
|
||||
map(Types.FLOAT); // X
|
||||
map(Types.FLOAT); // Y
|
||||
map(Types.FLOAT); // Z
|
||||
map(Types.FLOAT); // Offset x
|
||||
map(Types.FLOAT); // Offset y
|
||||
map(Types.FLOAT); // Offset z
|
||||
map(Types.FLOAT); // Particle data
|
||||
map(Types.INT); // Particle count
|
||||
handler(wrapper -> {
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
Particles1_8 particle = Particles1_8.find(name);
|
||||
|
||||
wrapper.set(Types.STRING, 0, name);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (particle == Particles1_8.ICON_CRACK || particle == Particles1_8.BLOCK_CRACK || particle == Particles1_8.BLOCK_DUST) {
|
||||
int id = wrapper.read(Types.VAR_INT);
|
||||
int data = particle == Particles1_8.ICON_CRACK ? wrapper.read(Types.VAR_INT) : id / 4096;
|
||||
id %= 4096;
|
||||
if (id >= 256 && id <= 422 || id >= 2256 && id <= 2267) { //item
|
||||
particle = Particles1_8.ICON_CRACK;
|
||||
} else if (id >= 0 && id <= 164 || id >= 170 && id <= 175) {
|
||||
if (particle == Particles1_8.ICON_CRACK)
|
||||
particle = Particles1_8.BLOCK_CRACK;
|
||||
} else {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
name = particle.name + "_" + id + "_" + data;
|
||||
}
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SIGN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.SHORT_POSITION); // position
|
||||
handler(wrapper -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
String line = wrapper.read(Types.STRING);
|
||||
line = ChatUtil.jsonToLegacy(wrapper.user(), line);
|
||||
line = ChatUtil.removeUnusedColor(line, '0');
|
||||
wrapper.set(Types.STRING, 0, name);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (line.length() > 15) {
|
||||
line = ChatColorUtil.stripColor(line);
|
||||
if (line.length() > 15) line = line.substring(0, 15);
|
||||
}
|
||||
wrapper.write(Types.STRING, line);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SIGN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.SHORT_POSITION); // position
|
||||
handler(wrapper -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
String line = wrapper.read(Types.STRING);
|
||||
line = ChatUtil.jsonToLegacy(line);
|
||||
line = ChatUtil.removeUnusedColor(line, '0');
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper -> {
|
||||
wrapper.cancel();
|
||||
final int id = wrapper.read(Types.VAR_INT);
|
||||
final byte scale = wrapper.read(Types.BYTE);
|
||||
if (line.length() > 15) {
|
||||
line = ChatColorUtil.stripColor(line);
|
||||
if (line.length() > 15) line = line.substring(0, 15);
|
||||
}
|
||||
wrapper.write(Types.STRING, line);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
final int iconCount = wrapper.read(Types.VAR_INT);
|
||||
byte[] icons = new byte[iconCount * 4];
|
||||
for (int i = 0; i < iconCount; i++) {
|
||||
final int directionAndType = wrapper.read(Types.BYTE);
|
||||
protocol.registerClientbound(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper -> {
|
||||
wrapper.cancel();
|
||||
final int id = wrapper.read(Types.VAR_INT);
|
||||
final byte scale = wrapper.read(Types.BYTE);
|
||||
|
||||
icons[i * 4] = (byte) (directionAndType >> 4 & 0xF);
|
||||
icons[i * 4 + 1] = wrapper.read(Types.BYTE); // x
|
||||
icons[i * 4 + 2] = wrapper.read(Types.BYTE); // z
|
||||
icons[i * 4 + 3] = (byte) (directionAndType & 0xF);
|
||||
}
|
||||
final short columns = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
if (columns > 0) {
|
||||
final short rows = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
final short x = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
final short z = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
final int iconCount = wrapper.read(Types.VAR_INT);
|
||||
byte[] icons = new byte[iconCount * 4];
|
||||
for (int i = 0; i < iconCount; i++) {
|
||||
final int directionAndType = wrapper.read(Types.BYTE);
|
||||
|
||||
final byte[] data = wrapper.read(Types.BYTE_ARRAY_PRIMITIVE);
|
||||
for (int column = 0; column < columns; column++) {
|
||||
byte[] columnData = new byte[rows + 3];
|
||||
columnData[0] = 0;
|
||||
columnData[1] = (byte) (x + column);
|
||||
columnData[2] = (byte) z;
|
||||
icons[i * 4] = (byte) (directionAndType >> 4 & 0xF);
|
||||
icons[i * 4 + 1] = wrapper.read(Types.BYTE); // x
|
||||
icons[i * 4 + 2] = wrapper.read(Types.BYTE); // z
|
||||
icons[i * 4 + 3] = (byte) (directionAndType & 0xF);
|
||||
}
|
||||
final short columns = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
if (columns > 0) {
|
||||
final short rows = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
final short x = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
final short z = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
|
||||
for (int i = 0; i < rows; i++) {
|
||||
columnData[i + 3] = data[column + i * columns];
|
||||
}
|
||||
final byte[] data = wrapper.read(Types.BYTE_ARRAY_PRIMITIVE);
|
||||
for (int column = 0; column < columns; column++) {
|
||||
byte[] columnData = new byte[rows + 3];
|
||||
columnData[0] = 0;
|
||||
columnData[1] = (byte) (x + column);
|
||||
columnData[2] = (byte) z;
|
||||
|
||||
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper.user());
|
||||
mapData.write(Types.VAR_INT, id); // map id
|
||||
mapData.write(Types.SHORT, (short) columnData.length); // data length
|
||||
mapData.write(new FixedByteArrayType(columnData.length), columnData); // data
|
||||
for (int i = 0; i < rows; i++) {
|
||||
columnData[i + 3] = data[column + i * columns];
|
||||
}
|
||||
|
||||
mapData.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper.user());
|
||||
mapData.write(Types.VAR_INT, id); // map id
|
||||
mapData.write(Types.SHORT, (short) columnData.length); // data length
|
||||
mapData.write(new FixedByteArrayType(columnData.length), columnData); // data
|
||||
|
||||
if (iconCount > 0) {
|
||||
final byte[] iconData = new byte[iconCount * 3 + 1];
|
||||
iconData[0] = 1;
|
||||
for (int i = 0; i < iconCount; i++) {
|
||||
iconData[i * 3 + 1] = (byte) (icons[i * 4] << 4 | icons[i * 4 + 3] & 0xF);
|
||||
iconData[i * 3 + 2] = icons[i * 4 + 1];
|
||||
iconData[i * 3 + 3] = icons[i * 4 + 2];
|
||||
}
|
||||
mapData.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
}
|
||||
|
||||
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper.user());
|
||||
mapData.write(Types.VAR_INT, id); // map id
|
||||
mapData.write(Types.SHORT, (short) iconData.length); // data length
|
||||
mapData.write(new FixedByteArrayType(iconData.length), iconData); // data
|
||||
if (iconCount > 0) {
|
||||
final byte[] iconData = new byte[iconCount * 3 + 1];
|
||||
iconData[0] = 1;
|
||||
for (int i = 0; i < iconCount; i++) {
|
||||
iconData[i * 3 + 1] = (byte) (icons[i * 4] << 4 | icons[i * 4 + 3] & 0xF);
|
||||
iconData[i * 3 + 2] = icons[i * 4 + 1];
|
||||
iconData[i * 3 + 3] = icons[i * 4 + 2];
|
||||
}
|
||||
|
||||
mapData.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper.user());
|
||||
mapData.write(Types.VAR_INT, id); // map id
|
||||
mapData.write(Types.SHORT, (short) iconData.length); // data length
|
||||
mapData.write(new FixedByteArrayType(iconData.length), iconData); // data
|
||||
|
||||
// Update scale
|
||||
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper.user());
|
||||
mapData.write(Types.VAR_INT, id); // map id
|
||||
mapData.write(Types.SHORT, (short) 2); // data length
|
||||
mapData.write(new FixedByteArrayType(2), new byte[]{2, scale}); // data
|
||||
mapData.send(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
mapData.send(Protocol1_8To1_7_6_10.class);
|
||||
});
|
||||
// Update scale
|
||||
final PacketWrapper mapData = PacketWrapper.create(ClientboundPackets1_8.MAP_ITEM_DATA, wrapper.user());
|
||||
mapData.write(Types.VAR_INT, id); // map id
|
||||
mapData.write(Types.SHORT, (short) 2); // data length
|
||||
mapData.write(new FixedByteArrayType(2), new byte[]{2, scale}); // data
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ENTITY_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.SHORT_POSITION); // position
|
||||
map(Types.UNSIGNED_BYTE); // action
|
||||
map(Types.NAMED_COMPOUND_TAG, RewindTypes.COMPRESSED_NBT); // nbt
|
||||
}
|
||||
});
|
||||
mapData.send(Protocol1_8To1_7_6_10.class);
|
||||
});
|
||||
|
||||
protocol.cancelClientbound(ClientboundPackets1_8.CHANGE_DIFFICULTY);
|
||||
protocol.cancelClientbound(ClientboundPackets1_8.PLAYER_COMBAT);
|
||||
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ENTITY_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8, RewindTypes.SHORT_POSITION); // position
|
||||
map(Types.UNSIGNED_BYTE); // action
|
||||
map(Types.NAMED_COMPOUND_TAG, RewindTypes.COMPRESSED_NBT); // nbt
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_BORDER, null, wrapper -> {
|
||||
final WorldBorderEmulator emulator = wrapper.user().get(WorldBorderEmulator.class);
|
||||
wrapper.cancel();
|
||||
protocol.cancelClientbound(ClientboundPackets1_8.CHANGE_DIFFICULTY);
|
||||
|
||||
final int action = wrapper.read(Types.VAR_INT);
|
||||
if (action == 0) { // set size
|
||||
emulator.setSize(wrapper.read(Types.DOUBLE)); // radius
|
||||
} else if (action == 1) { // lerp size
|
||||
emulator.lerpSize(wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE), wrapper.read(Types.VAR_LONG)); // old radius, new radius, speed
|
||||
} else if (action == 2) { // set center
|
||||
emulator.setCenter(wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE)); // x, z
|
||||
} else if (action == 3) { // initialize
|
||||
emulator.init(
|
||||
wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE), // x, z
|
||||
wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE), // old radius, new radius
|
||||
wrapper.read(Types.VAR_LONG) // speed
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
protocol.registerClientbound(ClientboundPackets1_8.SET_BORDER, null, wrapper -> {
|
||||
final WorldBorderEmulator emulator = wrapper.user().get(WorldBorderEmulator.class);
|
||||
wrapper.cancel();
|
||||
|
||||
final int action = wrapper.read(Types.VAR_INT);
|
||||
if (action == 0) { // set size
|
||||
emulator.setSize(wrapper.read(Types.DOUBLE)); // radius
|
||||
} else if (action == 1) { // lerp size
|
||||
emulator.lerpSize(wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE), wrapper.read(Types.VAR_LONG)); // old radius, new radius, speed
|
||||
} else if (action == 2) { // set center
|
||||
emulator.setCenter(wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE)); // x, z
|
||||
} else if (action == 3) { // initialize
|
||||
emulator.init(
|
||||
wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE), // x, z
|
||||
wrapper.read(Types.DOUBLE), wrapper.read(Types.DOUBLE), // old radius, new radius
|
||||
wrapper.read(Types.VAR_LONG) // speed
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -24,9 +24,9 @@ import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
* @see com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.CompressionHandlerProvider
|
||||
*/
|
||||
public class CompressionStatusTracker extends StoredObject {
|
||||
public boolean removeCompression = false;
|
||||
public boolean removeCompression = false;
|
||||
|
||||
public CompressionStatusTracker(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
public CompressionStatusTracker(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
}
|
||||
+272
-118
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -24,6 +24,8 @@ import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data.VirtualHologramEnti
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
@@ -34,150 +36,302 @@ import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
|
||||
import com.viaversion.viarewind.api.type.RewindTypes;
|
||||
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
|
||||
|
||||
public class EntityTracker1_8 extends EntityTrackerBase {
|
||||
|
||||
private final Int2ObjectMap<VirtualHologramEntity> holograms = new Int2ObjectArrayMap<>();
|
||||
private final Int2IntMap vehicles = new Int2IntArrayMap();
|
||||
private final Int2ObjectMap<UUID> entityIdToUUID = new Int2ObjectArrayMap<>();
|
||||
private final Object2IntMap<UUID> entityUUIDToId = new Object2IntOpenHashMap<>();
|
||||
private final Int2ObjectMap<VirtualHologramEntity> holograms = new Int2ObjectArrayMap<>();
|
||||
private final Int2IntMap extraHologramIds = new Int2IntArrayMap();
|
||||
private final Int2IntMap vehicles = new Int2IntArrayMap();
|
||||
private final Int2ObjectMap<UUID> entityIdToUUID = new Int2ObjectArrayMap<>();
|
||||
private final Object2IntMap<UUID> entityUUIDToId = new Object2IntOpenHashMap<>();
|
||||
private final Int2IntMap playerNametagHiderEntities = new Int2IntArrayMap();
|
||||
|
||||
public int spectatingClientEntityId = -1;
|
||||
private int clientEntityGameMode;
|
||||
private final List<EntityData> entityData = new ArrayList<>();
|
||||
|
||||
public EntityTracker1_8(UserConnection connection) {
|
||||
super(connection, EntityTypes1_8.EntityType.PLAYER);
|
||||
}
|
||||
public Integer spectatingClientEntityId;
|
||||
private int clientEntityGameMode;
|
||||
|
||||
@Override
|
||||
public void addEntity(int id, EntityType type) {
|
||||
super.addEntity(id, type);
|
||||
if (type == EntityTypes1_8.EntityType.ARMOR_STAND) {
|
||||
holograms.put(id, new VirtualHologramEntity(user(), id));
|
||||
}
|
||||
}
|
||||
public EntityTracker1_8(UserConnection connection) {
|
||||
super(connection, EntityTypes1_8.EntityType.PLAYER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntity(int entityId) {
|
||||
super.removeEntity(entityId);
|
||||
@Override
|
||||
public void addEntity(int id, EntityType type) {
|
||||
super.addEntity(id, type);
|
||||
if (type == EntityTypes1_8.EntityType.ARMOR_STAND) {
|
||||
holograms.put(id, new VirtualHologramEntity(user(), id));
|
||||
}
|
||||
}
|
||||
|
||||
if (entityIdToUUID.containsKey(entityId)) {
|
||||
final UUID playerId = entityIdToUUID.remove(entityId);
|
||||
@Override
|
||||
public void removeEntity(int entityId) {
|
||||
super.removeEntity(entityId);
|
||||
|
||||
entityUUIDToId.removeInt(playerId);
|
||||
user().get(PlayerSessionStorage.class).getPlayerEquipment().remove(playerId);
|
||||
}
|
||||
}
|
||||
final VirtualHologramEntity hologram = holograms.get(entityId);
|
||||
if (hologram != null) {
|
||||
hologram.deleteEntity();
|
||||
holograms.remove(entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearEntities() {
|
||||
super.clearEntities();
|
||||
vehicles.clear();
|
||||
}
|
||||
if (playerNametagHiderEntities.containsKey(entityId)) {
|
||||
despawnNametagHiderEntity(entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientEntityId(int entityId) {
|
||||
if (this.spectatingClientEntityId == this.clientEntityId()) {
|
||||
this.spectatingClientEntityId = entityId;
|
||||
}
|
||||
super.setClientEntityId(entityId);
|
||||
}
|
||||
if (entityIdToUUID.containsKey(entityId)) {
|
||||
final UUID playerId = entityIdToUUID.remove(entityId);
|
||||
|
||||
public void addPlayer(final int entityId, final UUID uuid) {
|
||||
entityUUIDToId.put(uuid, entityId);
|
||||
entityIdToUUID.put(entityId, uuid);
|
||||
}
|
||||
entityUUIDToId.removeInt(playerId);
|
||||
user().get(PlayerSessionStorage.class).getPlayerEquipment().remove(playerId);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getPlayerUUID(final int entityId) {
|
||||
return entityIdToUUID.get(entityId);
|
||||
}
|
||||
@Override
|
||||
public void clearEntities() {
|
||||
super.clearEntities();
|
||||
holograms.clear();
|
||||
extraHologramIds.clear();
|
||||
vehicles.clear();
|
||||
playerNametagHiderEntities.clear();
|
||||
}
|
||||
|
||||
public int getPlayerEntityId(final UUID uuid) {
|
||||
return entityUUIDToId.getOrDefault(uuid, -1);
|
||||
}
|
||||
@Override
|
||||
public void setClientEntityId(int entityId) {
|
||||
if (Objects.equals(this.spectatingClientEntityId, clientEntityIdOrNull())) {
|
||||
this.spectatingClientEntityId = entityId;
|
||||
}
|
||||
super.setClientEntityId(entityId);
|
||||
}
|
||||
|
||||
public int getVehicle(final int passengerId) {
|
||||
for (Map.Entry<Integer, Integer> vehicle : vehicles.entrySet()) {
|
||||
if (vehicle.getValue() == passengerId) {
|
||||
return vehicle.getValue();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public Integer clientEntityIdOrNull() {
|
||||
return this.hasClientEntityId() ? this.clientEntityId() : null;
|
||||
}
|
||||
|
||||
public int getPassenger(int vehicleId) {
|
||||
return vehicles.getOrDefault(vehicleId, -1);
|
||||
}
|
||||
public void addPlayer(final int entityId, final UUID uuid) {
|
||||
entityUUIDToId.put(uuid, entityId);
|
||||
entityIdToUUID.put(entityId, uuid);
|
||||
}
|
||||
|
||||
protected void startSneaking() {
|
||||
try {
|
||||
final PacketWrapper entityAction = PacketWrapper.create(ServerboundPackets1_7_2_5.PLAYER_COMMAND, user());
|
||||
entityAction.write(Types.VAR_INT, this.clientEntityId()); // Entity id
|
||||
entityAction.write(Types.VAR_INT, 0); // Action id
|
||||
entityAction.write(Types.VAR_INT, 0); // Jump boost
|
||||
public UUID getPlayerUUID(final int entityId) {
|
||||
return entityIdToUUID.get(entityId);
|
||||
}
|
||||
|
||||
entityAction.sendToServer(Protocol1_8To1_7_6_10.class);
|
||||
} catch (Exception e) {
|
||||
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send sneak packet", e);
|
||||
}
|
||||
}
|
||||
public int getPlayerEntityId(final UUID uuid) {
|
||||
return entityUUIDToId.getOrDefault(uuid, -1);
|
||||
}
|
||||
|
||||
public void setPassenger(final int vehicleId, final int passengerId) {
|
||||
if (vehicleId == this.spectatingClientEntityId && this.spectatingClientEntityId != this.clientEntityId()) {
|
||||
startSneaking();
|
||||
setSpectating(this.clientEntityId());
|
||||
}
|
||||
public int getVehicle(final int passengerId) {
|
||||
for (Map.Entry<Integer, Integer> vehicle : vehicles.int2IntEntrySet()) {
|
||||
if (vehicle.getValue() == passengerId) {
|
||||
return vehicle.getValue();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vehicleId == -1) {
|
||||
vehicles.remove(getVehicle(passengerId));
|
||||
} else if (passengerId == -1) {
|
||||
vehicles.remove(vehicleId);
|
||||
} else {
|
||||
vehicles.put(vehicleId, passengerId);
|
||||
}
|
||||
}
|
||||
public int getPassenger(int vehicleId) {
|
||||
return vehicles.getOrDefault(vehicleId, -1);
|
||||
}
|
||||
|
||||
protected void attachEntity(final int target) {
|
||||
try {
|
||||
final PacketWrapper attachEntity = PacketWrapper.create(ClientboundPackets1_8.SET_ENTITY_LINK, user());
|
||||
attachEntity.write(Types.INT, this.clientEntityId()); // vehicle id
|
||||
attachEntity.write(Types.INT, target); // passenger id
|
||||
attachEntity.write(Types.BOOLEAN, false); // leash
|
||||
protected void startSneaking() {
|
||||
try {
|
||||
final PacketWrapper entityAction = PacketWrapper.create(ServerboundPackets1_7_2_5.PLAYER_COMMAND, user());
|
||||
entityAction.write(Types.VAR_INT, this.clientEntityId()); // Entity id
|
||||
entityAction.write(Types.VAR_INT, 0); // Action id
|
||||
entityAction.write(Types.VAR_INT, 0); // Jump boost
|
||||
|
||||
attachEntity.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
} catch (Exception e) {
|
||||
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send attach packet", e);
|
||||
}
|
||||
}
|
||||
entityAction.sendToServer(Protocol1_8To1_7_6_10.class);
|
||||
} catch (Exception e) {
|
||||
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send sneak packet", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpectating(int spectating) {
|
||||
if (spectating != this.clientEntityId() && getPassenger(spectating) != -1) {
|
||||
startSneaking();
|
||||
setSpectating(this.clientEntityId());
|
||||
return;
|
||||
}
|
||||
if (this.spectatingClientEntityId != spectating && this.spectatingClientEntityId != this.clientEntityId()) {
|
||||
attachEntity(-1);
|
||||
}
|
||||
this.spectatingClientEntityId = spectating;
|
||||
if (spectating != this.clientEntityId()) {
|
||||
attachEntity(this.spectatingClientEntityId);
|
||||
}
|
||||
}
|
||||
public void setPassenger(final int vehicleId, final int passengerId) {
|
||||
if (vehicleId == this.spectatingClientEntityId && this.spectatingClientEntityId != this.clientEntityId()) {
|
||||
startSneaking();
|
||||
setSpectating(this.clientEntityId());
|
||||
}
|
||||
|
||||
public Int2ObjectMap<VirtualHologramEntity> getHolograms() {
|
||||
return holograms;
|
||||
}
|
||||
if (vehicleId == -1) {
|
||||
vehicles.remove(getVehicle(passengerId));
|
||||
} else if (passengerId == -1) {
|
||||
vehicles.remove(vehicleId);
|
||||
} else {
|
||||
vehicles.put(vehicleId, passengerId);
|
||||
}
|
||||
|
||||
public boolean isSpectator() {
|
||||
return clientEntityGameMode == 3;
|
||||
}
|
||||
// Re-evaluate nametag visibility when a player entity's passenger changes
|
||||
if (vehicleId != -1 && entityIdToUUID.containsKey(vehicleId)) {
|
||||
checkNametagVisibility(vehicleId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void attachEntity(final int target) {
|
||||
try {
|
||||
final PacketWrapper attachEntity = PacketWrapper.create(ClientboundPackets1_8.SET_ENTITY_LINK, user());
|
||||
attachEntity.write(Types.INT, this.clientEntityId()); // vehicle id
|
||||
attachEntity.write(Types.INT, target); // passenger id
|
||||
attachEntity.write(Types.BOOLEAN, false); // leash
|
||||
|
||||
attachEntity.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
} catch (Exception e) {
|
||||
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send attach packet", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpectating(int spectating) {
|
||||
if (spectating != this.clientEntityId() && getPassenger(spectating) != -1) {
|
||||
startSneaking();
|
||||
setSpectating(this.clientEntityId());
|
||||
return;
|
||||
}
|
||||
if (this.spectatingClientEntityId != spectating && this.spectatingClientEntityId != this.clientEntityId()) {
|
||||
attachEntity(-1);
|
||||
}
|
||||
this.spectatingClientEntityId = spectating;
|
||||
if (spectating != this.clientEntityId()) {
|
||||
attachEntity(this.spectatingClientEntityId);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkNametagVisibility(final int entityId) {
|
||||
if (!entityIdToUUID.containsKey(entityId)) {
|
||||
return;
|
||||
}
|
||||
final boolean shouldHide = isPlayerNametagHidden(entityId);
|
||||
final boolean hasServerPassenger = getPassenger(entityId) != -1;
|
||||
final boolean hasSkull = playerNametagHiderEntities.containsKey(entityId);
|
||||
|
||||
if (shouldHide && !hasServerPassenger && !hasSkull) {
|
||||
spawnNametagHiderEntity(entityId);
|
||||
} else if ((!shouldHide || hasServerPassenger) && hasSkull) {
|
||||
despawnNametagHiderEntity(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkNametagVisbility(final String username) {
|
||||
final GameProfileStorage profileStorage = user().get(GameProfileStorage.class);
|
||||
final List<GameProfileStorage.GameProfile> profiles = profileStorage.get(username, false);
|
||||
|
||||
for (GameProfileStorage.GameProfile profile : profiles) {
|
||||
final int entityId = getPlayerEntityId(profile.uuid);
|
||||
if (entityId == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkNametagVisibility(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPlayerNametagHidden(final int entityId) {
|
||||
final UUID uuid = entityIdToUUID.get(entityId);
|
||||
if (uuid == null) {
|
||||
return false;
|
||||
}
|
||||
final GameProfileStorage profileStorage = user().get(GameProfileStorage.class);
|
||||
final GameProfileStorage.GameProfile profile = profileStorage.get(uuid);
|
||||
if (profile == null) {
|
||||
return false;
|
||||
}
|
||||
return user().get(ScoreboardTracker.class).isNametagHidden(profile.name);
|
||||
}
|
||||
|
||||
private int getNametagHiderEntityId(final int playerEntityId) {
|
||||
return Integer.MAX_VALUE - 32000 - playerEntityId;
|
||||
}
|
||||
|
||||
private void spawnNametagHiderEntity(final int playerEntityId) {
|
||||
final int entityId = getNametagHiderEntityId(playerEntityId);
|
||||
playerNametagHiderEntities.put(playerEntityId, entityId);
|
||||
|
||||
final List<EntityData> mobData = new ArrayList<>();
|
||||
mobData.add(new EntityData(0, EntityDataTypes1_7_6_10.BYTE, (byte) 0x20));
|
||||
mobData.add(new EntityData(16, EntityDataTypes1_7_6_10.BYTE, (byte) 0));
|
||||
|
||||
final PacketWrapper spawnMob = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_MOB, user());
|
||||
spawnMob.write(Types.VAR_INT, entityId);
|
||||
spawnMob.write(Types.UNSIGNED_BYTE, (short) EntityTypes1_8.EntityType.MAGMA_CUBE.getId());
|
||||
spawnMob.write(Types.INT, 0); // X
|
||||
spawnMob.write(Types.INT, 0); // Y
|
||||
spawnMob.write(Types.INT, 0); // Z
|
||||
spawnMob.write(Types.BYTE, (byte) 0); // Yaw
|
||||
spawnMob.write(Types.BYTE, (byte) 0); // Pitch
|
||||
spawnMob.write(Types.BYTE, (byte) 0); // Head yaw
|
||||
spawnMob.write(Types.SHORT, (short) 0); // Velocity x
|
||||
spawnMob.write(Types.SHORT, (short) 0); // Velocity y
|
||||
spawnMob.write(Types.SHORT, (short) 0); // Velocity z
|
||||
spawnMob.write(RewindTypes.ENTITY_DATA_LIST1_7, mobData);
|
||||
spawnMob.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
|
||||
final PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_LINK, user());
|
||||
attach.write(Types.INT, entityId);
|
||||
attach.write(Types.INT, playerEntityId);
|
||||
attach.write(Types.BOOLEAN, false);
|
||||
attach.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
private void despawnNametagHiderEntity(final int playerEntityId) {
|
||||
if (!playerNametagHiderEntities.containsKey(playerEntityId)) return;
|
||||
final int mobId = playerNametagHiderEntities.remove(playerEntityId);
|
||||
|
||||
final PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7_2_5.REMOVE_ENTITIES, user());
|
||||
despawn.write(Types.BYTE, (byte) 1);
|
||||
despawn.write(Types.INT, mobId);
|
||||
despawn.scheduleSend(Protocol1_8To1_7_6_10.class);
|
||||
}
|
||||
|
||||
public Int2ObjectMap<VirtualHologramEntity> getHolograms() {
|
||||
return holograms;
|
||||
}
|
||||
|
||||
public void setExtraHologramId(final int entityId, final int extraId) {
|
||||
extraHologramIds.put(extraId, entityId);
|
||||
}
|
||||
|
||||
public void removeExtraHologramId(int extraId) {
|
||||
extraHologramIds.remove(extraId);
|
||||
}
|
||||
|
||||
public int getHologramIdWithExtra(final int id) {
|
||||
if (holograms.containsKey(id)) {
|
||||
return id;
|
||||
}
|
||||
return extraHologramIds.getOrDefault(id, -1);
|
||||
}
|
||||
|
||||
public boolean isSpectator() {
|
||||
return clientEntityGameMode == 3;
|
||||
}
|
||||
|
||||
public void setClientEntityGameMode(int clientEntityGameMode) {
|
||||
this.clientEntityGameMode = clientEntityGameMode;
|
||||
}
|
||||
|
||||
public void updateEntityData(List<EntityData> entityData) {
|
||||
this.entityData.removeIf(first -> entityData.stream().anyMatch(second -> first.id() == second.id()));
|
||||
for (final EntityData data : entityData) {
|
||||
final Object value = data.value();
|
||||
if (value instanceof Item item) {
|
||||
this.entityData.add(new EntityData(data.id(), data.dataType(), item.copy()));
|
||||
} else {
|
||||
this.entityData.add(new EntityData(data.id(), data.dataType(), value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<EntityData> getEntityData() {
|
||||
return entityData;
|
||||
}
|
||||
|
||||
public void setClientEntityGameMode(int clientEntityGameMode) {
|
||||
this.clientEntityGameMode = clientEntityGameMode;
|
||||
}
|
||||
}
|
||||
+104
-98
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,129 +17,135 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viarewind.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.connection.StoredObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.DataItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.util.ChatColorUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GameProfileStorage extends StoredObject {
|
||||
private final Map<UUID, GameProfile> properties = new HashMap<>();
|
||||
private final Map<UUID, GameProfile> properties = new HashMap<>();
|
||||
private final ListMultimap<String, GameProfile> nameToProfile = ArrayListMultimap.create();
|
||||
|
||||
public GameProfileStorage(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
public GameProfileStorage(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
public GameProfile put(UUID uuid, String name) {
|
||||
GameProfile gameProfile = new GameProfile(uuid, name);
|
||||
properties.put(uuid, gameProfile);
|
||||
return gameProfile;
|
||||
}
|
||||
public GameProfile put(UUID uuid, String name, String displayName, int ping, int gamemode) {
|
||||
GameProfile gameProfile = new GameProfile(uuid, name, displayName, ping, gamemode);
|
||||
properties.put(uuid, gameProfile);
|
||||
nameToProfile.put(name, gameProfile);
|
||||
return gameProfile;
|
||||
}
|
||||
|
||||
public GameProfile get(UUID uuid) {
|
||||
return properties.get(uuid);
|
||||
}
|
||||
public GameProfile get(UUID uuid) {
|
||||
return properties.get(uuid);
|
||||
}
|
||||
|
||||
public GameProfile get(String name, boolean ignoreCase) {
|
||||
if (ignoreCase) name = name.toLowerCase();
|
||||
public List<GameProfile> get(String name, boolean ignoreCase) {
|
||||
if (ignoreCase) name = name.toLowerCase();
|
||||
return nameToProfile.get(name);
|
||||
}
|
||||
|
||||
for (GameProfile profile : properties.values()) {
|
||||
if (profile.name == null) continue;
|
||||
public List<GameProfile> getAllWithPrefix(String prefix, boolean ignoreCase) {
|
||||
if (ignoreCase) prefix = prefix.toLowerCase();
|
||||
|
||||
String n = ignoreCase ? profile.name.toLowerCase() : profile.name;
|
||||
ArrayList<GameProfile> profiles = new ArrayList<>();
|
||||
|
||||
if (n.equals(name)) {
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
for (GameProfile profile : properties.values()) {
|
||||
if (profile.name == null) continue;
|
||||
|
||||
public List<GameProfile> getAllWithPrefix(String prefix, boolean ignoreCase) {
|
||||
if (ignoreCase) prefix = prefix.toLowerCase();
|
||||
String n = ignoreCase ? profile.name.toLowerCase() : profile.name;
|
||||
|
||||
ArrayList<GameProfile> profiles = new ArrayList<>();
|
||||
if (n.startsWith(prefix)) profiles.add(profile);
|
||||
}
|
||||
|
||||
for (GameProfile profile : properties.values()) {
|
||||
if (profile.name == null) continue;
|
||||
return profiles;
|
||||
}
|
||||
|
||||
String n = ignoreCase ? profile.name.toLowerCase() : profile.name;
|
||||
|
||||
if (n.startsWith(prefix)) profiles.add(profile);
|
||||
}
|
||||
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public GameProfile remove(UUID uuid) {
|
||||
return properties.remove(uuid);
|
||||
}
|
||||
public GameProfile remove(UUID uuid) {
|
||||
GameProfile removedProfile = properties.remove(uuid);
|
||||
if (removedProfile != null) {
|
||||
nameToProfile.get(removedProfile.name).remove(removedProfile);
|
||||
}
|
||||
return removedProfile;
|
||||
}
|
||||
|
||||
|
||||
public static class GameProfile {
|
||||
public final String name;
|
||||
public final UUID uuid;
|
||||
public String displayName;
|
||||
public int ping;
|
||||
public List<Property> properties = new ArrayList<>();
|
||||
public int gamemode = 0;
|
||||
public static class GameProfile {
|
||||
public final UUID uuid;
|
||||
public final String name;
|
||||
public String displayName;
|
||||
public List<Property> properties = new ArrayList<>();
|
||||
public int ping;
|
||||
public int gamemode = 0;
|
||||
|
||||
public GameProfile(UUID uuid, String name) {
|
||||
this.name = name;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
public GameProfile(UUID uuid, String name, String displayName, int ping, int gamemode) {
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.ping = ping;
|
||||
this.gamemode = gamemode;
|
||||
}
|
||||
|
||||
public Item getSkull() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag ownerTag = new CompoundTag();
|
||||
tag.put("SkullOwner", ownerTag);
|
||||
ownerTag.put("Id", new StringTag(uuid.toString()));
|
||||
CompoundTag properties = new CompoundTag();
|
||||
ownerTag.put("Properties", properties);
|
||||
ListTag textures = new ListTag(CompoundTag.class);
|
||||
properties.put("textures", textures);
|
||||
for (Property property : this.properties) {
|
||||
if (property.name.equals("textures")) {
|
||||
CompoundTag textureTag = new CompoundTag();
|
||||
textureTag.put("Value", new StringTag(property.value));
|
||||
if (property.signature != null) {
|
||||
textureTag.put("Signature", new StringTag(property.signature));
|
||||
}
|
||||
textures.add(textureTag);
|
||||
}
|
||||
}
|
||||
public Item getSkull() {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
CompoundTag ownerTag = new CompoundTag();
|
||||
tag.put("SkullOwner", ownerTag);
|
||||
ownerTag.put("Id", new StringTag(uuid.toString()));
|
||||
CompoundTag properties = new CompoundTag();
|
||||
ownerTag.put("Properties", properties);
|
||||
ListTag textures = new ListTag(CompoundTag.class);
|
||||
properties.put("textures", textures);
|
||||
for (Property property : this.properties) {
|
||||
if (property.name.equals("textures")) {
|
||||
CompoundTag textureTag = new CompoundTag();
|
||||
textureTag.put("Value", new StringTag(property.value));
|
||||
if (property.signature != null) {
|
||||
textureTag.put("Signature", new StringTag(property.signature));
|
||||
}
|
||||
textures.add(textureTag);
|
||||
}
|
||||
}
|
||||
|
||||
return new DataItem(397, (byte) 1, (short) 3, tag);
|
||||
}
|
||||
return new DataItem(397, (byte) 1, (short) 3, tag);
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
String displayName = this.displayName == null ? name : this.displayName;
|
||||
if (displayName.length() > 16) displayName = ChatUtil.removeUnusedColor(displayName, 'f');
|
||||
if (displayName.length() > 16) displayName = ChatColorUtil.stripColor(displayName);
|
||||
if (displayName.length() > 16) displayName = displayName.substring(0, 16);
|
||||
return displayName;
|
||||
}
|
||||
public String getLegacyDisplayName() {
|
||||
String displayName = this.displayName == null ? name : this.displayName;
|
||||
if (displayName.length() > 16) displayName = ChatUtil.removeUnusedColor(displayName, 'f');
|
||||
if (displayName.length() > 16) displayName = ChatColorUtil.stripColor(displayName);
|
||||
if (displayName.length() > 16) displayName = displayName.substring(0, 16);
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
}
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Property {
|
||||
public final String name;
|
||||
public final String value;
|
||||
public final String signature;
|
||||
public static class Property {
|
||||
public final String name;
|
||||
public final String value;
|
||||
public final String signature;
|
||||
|
||||
public Property(String name, String value, String signature) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.signature = signature;
|
||||
}
|
||||
}
|
||||
public Property(String name, String value, String signature) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.signature = signature;
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
-47
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,66 +19,65 @@ package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.StoredObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class InventoryTracker extends StoredObject {
|
||||
public static final Map<String, Integer> WINDOW_TYPE_REGISTRY = new HashMap<>();
|
||||
public static final Map<String, Integer> WINDOW_TYPE_REGISTRY = new HashMap<>();
|
||||
|
||||
static {
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:container", 0);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:chest", 0);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:crafting_table", 1);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:furnace", 2);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:dispenser", 3);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:enchanting_table", 4);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:brewing_stand", 5);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:villager", 6);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:beacon", 7);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:anvil", 8);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:hopper", 9);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:dropper", 10);
|
||||
WINDOW_TYPE_REGISTRY.put("EntityHorse", 11);
|
||||
}
|
||||
static {
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:container", 0);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:chest", 0);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:crafting_table", 1);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:furnace", 2);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:dispenser", 3);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:enchanting_table", 4);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:brewing_stand", 5);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:villager", 6);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:beacon", 7);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:anvil", 8);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:hopper", 9);
|
||||
WINDOW_TYPE_REGISTRY.put("minecraft:dropper", 10);
|
||||
WINDOW_TYPE_REGISTRY.put("EntityHorse", 11);
|
||||
}
|
||||
|
||||
private final HashMap<Short, Short> windowTypeMap = new HashMap<>();
|
||||
private final HashMap<Short, FurnaceData> furnaceData = new HashMap<>();
|
||||
private final HashMap<Short, Short> windowTypeMap = new HashMap<>();
|
||||
private final HashMap<Short, FurnaceData> furnaceData = new HashMap<>();
|
||||
|
||||
public short levelCost = 0;
|
||||
public short anvilId = -1;
|
||||
public short levelCost = 0;
|
||||
public short anvilId = -1;
|
||||
|
||||
public InventoryTracker(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
public InventoryTracker(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
public short get(short windowId) {
|
||||
return windowTypeMap.getOrDefault(windowId, (short) -1);
|
||||
}
|
||||
public static short getInventoryType(String name) {
|
||||
return WINDOW_TYPE_REGISTRY.getOrDefault(name, -1).shortValue();
|
||||
}
|
||||
|
||||
public void remove(short windowId) {
|
||||
windowTypeMap.remove(windowId);
|
||||
furnaceData.remove(windowId);
|
||||
}
|
||||
public short get(short windowId) {
|
||||
return windowTypeMap.getOrDefault(windowId, (short) -1);
|
||||
}
|
||||
|
||||
public static short getInventoryType(String name) {
|
||||
return WINDOW_TYPE_REGISTRY.getOrDefault(name, -1).shortValue();
|
||||
}
|
||||
public void remove(short windowId) {
|
||||
windowTypeMap.remove(windowId);
|
||||
furnaceData.remove(windowId);
|
||||
}
|
||||
|
||||
public HashMap<Short, Short> getWindowTypeMap() {
|
||||
return windowTypeMap;
|
||||
}
|
||||
public HashMap<Short, Short> getWindowTypeMap() {
|
||||
return windowTypeMap;
|
||||
}
|
||||
|
||||
public HashMap<Short, FurnaceData> getFurnaceData() {
|
||||
return furnaceData;
|
||||
}
|
||||
public HashMap<Short, FurnaceData> getFurnaceData() {
|
||||
return furnaceData;
|
||||
}
|
||||
|
||||
public static class FurnaceData {
|
||||
public static class FurnaceData {
|
||||
|
||||
public short fuelLeft = 0;
|
||||
public short maxFuel = 0;
|
||||
public short progress = 0;
|
||||
public short maxProgress = 200;
|
||||
}
|
||||
public short fuelLeft = 0;
|
||||
public short maxFuel = 0;
|
||||
public short progress = 0;
|
||||
public short maxProgress = 200;
|
||||
}
|
||||
|
||||
}
|
||||
+53
-54
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,78 +20,77 @@ package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage;
|
||||
import com.viaversion.viaversion.api.connection.StoredObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerSessionStorage extends StoredObject {
|
||||
|
||||
// Player abilities
|
||||
public boolean sprinting, allowFly, flying, invincible, creative;
|
||||
public float flySpeed, walkSpeed;
|
||||
// Player inventory
|
||||
private final Map<UUID, Item[]> playerEquipment = new HashMap<>();
|
||||
|
||||
// Player position, rotation and data
|
||||
private double posX, posY, posZ;
|
||||
public double receivedPosY;
|
||||
public float yaw, pitch;
|
||||
public boolean onGround;
|
||||
// Player abilities
|
||||
public boolean sprinting, allowFly, flying, invincible, creative;
|
||||
public float flySpeed, walkSpeed;
|
||||
public double receivedPosY;
|
||||
public float yaw, pitch;
|
||||
public boolean onGround;
|
||||
|
||||
// Player inventory
|
||||
private final Map<UUID, Item[]> playerEquipment = new HashMap<>();
|
||||
// Player position, rotation and data
|
||||
private double posX, posY, posZ;
|
||||
|
||||
public PlayerSessionStorage(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
public PlayerSessionStorage(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
public byte combineAbilities() {
|
||||
byte flags = 0;
|
||||
public byte combineAbilities() {
|
||||
byte flags = 0;
|
||||
|
||||
if (invincible) flags |= 8;
|
||||
if (allowFly) flags |= 4;
|
||||
if (flying) flags |= 2;
|
||||
if (creative) flags |= 1;
|
||||
if (invincible) flags |= 8;
|
||||
if (allowFly) flags |= 4;
|
||||
if (flying) flags |= 2;
|
||||
if (creative) flags |= 1;
|
||||
|
||||
return flags;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public double getPosX() {
|
||||
return posX;
|
||||
}
|
||||
public double getPosX() {
|
||||
return posX;
|
||||
}
|
||||
|
||||
public double getPosY() {
|
||||
return posY;
|
||||
}
|
||||
public double getPosY() {
|
||||
return posY;
|
||||
}
|
||||
|
||||
public double getPosZ() {
|
||||
return posZ;
|
||||
}
|
||||
public double getPosZ() {
|
||||
return posZ;
|
||||
}
|
||||
|
||||
public void setPos(double x, double y, double z) {
|
||||
posX = x;
|
||||
posY = y;
|
||||
posZ = z;
|
||||
}
|
||||
public void setPos(double x, double y, double z) {
|
||||
posX = x;
|
||||
posY = y;
|
||||
posZ = z;
|
||||
}
|
||||
|
||||
public Item getPlayerEquipment(final UUID uuid, final int slot) {
|
||||
final Item[] items = playerEquipment.get(uuid);
|
||||
if (items == null || slot < 0 || slot >= items.length) {
|
||||
return null;
|
||||
}
|
||||
public Item getPlayerEquipment(final UUID uuid, final int slot) {
|
||||
final Item[] items = playerEquipment.get(uuid);
|
||||
if (items == null || slot < 0 || slot >= items.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return items[slot];
|
||||
}
|
||||
return items[slot];
|
||||
}
|
||||
|
||||
public void setPlayerEquipment(final UUID uuid, final Item equipment, final int slot) {
|
||||
final Item[] items = playerEquipment.computeIfAbsent(uuid, it -> new Item[5]);
|
||||
if (slot < 0 || slot >= items.length) {
|
||||
return;
|
||||
}
|
||||
public void setPlayerEquipment(final UUID uuid, final Item equipment, final int slot) {
|
||||
final Item[] items = playerEquipment.computeIfAbsent(uuid, it -> new Item[5]);
|
||||
if (slot < 0 || slot >= items.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
items[slot] = equipment;
|
||||
}
|
||||
items[slot] = equipment;
|
||||
}
|
||||
|
||||
public Map<UUID, Item[]> getPlayerEquipment() {
|
||||
return playerEquipment;
|
||||
}
|
||||
public Map<UUID, Item[]> getPlayerEquipment() {
|
||||
return playerEquipment;
|
||||
}
|
||||
}
|
||||
+164
-131
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,163 +23,196 @@ import com.viaversion.viaversion.api.connection.StoredObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ScoreboardTracker extends StoredObject {
|
||||
private final HashMap<String, List<String>> teams = new HashMap<>();
|
||||
private final HashSet<String> objectives = new HashSet<>();
|
||||
private final HashMap<String, ScoreTeam> scoreTeams = new HashMap<>();
|
||||
private final HashMap<String, Byte> teamColors = new HashMap<>();
|
||||
private final HashSet<String> scoreTeamNames = new HashSet<>();
|
||||
private String colorIndependentSidebar;
|
||||
private final HashMap<Byte, String> colorDependentSidebar = new HashMap<>();
|
||||
private final HashMap<String, List<String>> teams = new HashMap<>();
|
||||
private final HashSet<String> objectives = new HashSet<>();
|
||||
private final HashMap<String, ScoreTeam> scoreTeams = new HashMap<>();
|
||||
private final HashMap<String, Byte> teamColors = new HashMap<>();
|
||||
private final HashSet<String> scoreTeamNames = new HashSet<>();
|
||||
private final HashMap<Byte, String> colorDependentSidebar = new HashMap<>();
|
||||
private final HashMap<String, String> teamNameTagVisibilities = new HashMap<>();
|
||||
private String colorIndependentSidebar;
|
||||
|
||||
public ScoreboardTracker(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
public ScoreboardTracker(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
public void addPlayerToTeam(String player, String team) {
|
||||
teams.computeIfAbsent(team, key -> new ArrayList<>()).add(player);
|
||||
}
|
||||
public void addPlayerToTeam(String player, String team) {
|
||||
teams.computeIfAbsent(team, key -> new ArrayList<>()).add(player);
|
||||
}
|
||||
|
||||
public void setTeamColor(String team, Byte color) {
|
||||
teamColors.put(team, color);
|
||||
}
|
||||
public void setTeamColor(String team, Byte color) {
|
||||
teamColors.put(team, color);
|
||||
}
|
||||
|
||||
public Optional<Byte> getTeamColor(String team) {
|
||||
return Optional.ofNullable(teamColors.get(team));
|
||||
}
|
||||
public Optional<Byte> getTeamColor(String team) {
|
||||
return Optional.ofNullable(teamColors.get(team));
|
||||
}
|
||||
|
||||
public void addTeam(String team) {
|
||||
teams.computeIfAbsent(team, key -> new ArrayList<>());
|
||||
}
|
||||
public void addTeam(String team) {
|
||||
teams.computeIfAbsent(team, key -> new ArrayList<>());
|
||||
}
|
||||
|
||||
public void removeTeam(String team) {
|
||||
teams.remove(team);
|
||||
scoreTeams.remove(team);
|
||||
teamColors.remove(team);
|
||||
}
|
||||
public void removeTeam(String team) {
|
||||
teams.remove(team);
|
||||
scoreTeams.remove(team);
|
||||
teamColors.remove(team);
|
||||
teamNameTagVisibilities.remove(team);
|
||||
}
|
||||
|
||||
public boolean teamExists(String team) {
|
||||
return teams.containsKey(team);
|
||||
}
|
||||
public boolean teamExists(String team) {
|
||||
return teams.containsKey(team);
|
||||
}
|
||||
|
||||
public void removePlayerFromTeam(String player, String team) {
|
||||
List<String> teamPlayers = teams.get(team);
|
||||
if (teamPlayers != null) teamPlayers.remove(player);
|
||||
}
|
||||
public void removePlayerFromTeam(String player, String team) {
|
||||
List<String> teamPlayers = teams.get(team);
|
||||
if (teamPlayers != null) teamPlayers.remove(player);
|
||||
}
|
||||
|
||||
public boolean isPlayerInTeam(String player, String team) {
|
||||
List<String> teamPlayers = teams.get(team);
|
||||
return teamPlayers != null && teamPlayers.contains(player);
|
||||
}
|
||||
public boolean isPlayerInTeam(String player, String team) {
|
||||
List<String> teamPlayers = teams.get(team);
|
||||
return teamPlayers != null && teamPlayers.contains(player);
|
||||
}
|
||||
|
||||
public boolean isPlayerInTeam(String player) {
|
||||
for (List<String> teamPlayers : teams.values()) {
|
||||
if (teamPlayers.contains(player)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean isPlayerInTeam(String player) {
|
||||
for (List<String> teamPlayers : teams.values()) {
|
||||
if (teamPlayers.contains(player)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Optional<Byte> getPlayerTeamColor(String player) {
|
||||
Optional<String> team = getTeam(player);
|
||||
return team.isPresent() ? getTeamColor(team.get()) : Optional.empty();
|
||||
}
|
||||
public Optional<Byte> getPlayerTeamColor(String player) {
|
||||
Optional<String> team = getTeam(player);
|
||||
return team.isPresent() ? getTeamColor(team.get()) : Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<String> getTeam(String player) {
|
||||
for (Map.Entry<String, List<String>> entry : teams.entrySet())
|
||||
if (entry.getValue().contains(player))
|
||||
return Optional.of(entry.getKey());
|
||||
return Optional.empty();
|
||||
}
|
||||
public Optional<String> getTeam(String player) {
|
||||
for (Map.Entry<String, List<String>> entry : teams.entrySet())
|
||||
if (entry.getValue().contains(player))
|
||||
return Optional.of(entry.getKey());
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public void addObjective(String name) {
|
||||
objectives.add(name);
|
||||
}
|
||||
public void setTeamNameTagVisibility(String team, String visibility) {
|
||||
teamNameTagVisibilities.put(team, visibility);
|
||||
}
|
||||
|
||||
public void removeObjective(String name) {
|
||||
objectives.remove(name);
|
||||
colorDependentSidebar.values().remove(name);
|
||||
if (name.equals(colorIndependentSidebar)) {
|
||||
colorIndependentSidebar = null;
|
||||
}
|
||||
}
|
||||
public String getTeamNameTagVisibility(String team) {
|
||||
return teamNameTagVisibilities.getOrDefault(team, "always");
|
||||
}
|
||||
|
||||
public boolean objectiveExists(String name) {
|
||||
return objectives.contains(name);
|
||||
}
|
||||
public boolean isNametagHidden(String username) {
|
||||
for (Map.Entry<String, List<String>> entry : teams.entrySet()) {
|
||||
if (entry.getValue().contains(username)) {
|
||||
return "never".equalsIgnoreCase(teamNameTagVisibilities.getOrDefault(entry.getKey(), "always"));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String sendTeamForScore(String score) {
|
||||
if (score.length() <= 16) return score;
|
||||
if (scoreTeams.containsKey(score)) return scoreTeams.get(score).name;
|
||||
int l = 16;
|
||||
int i = Math.min(16, score.length() - 16);
|
||||
String name = score.substring(i, i + l);
|
||||
while (scoreTeamNames.contains(name) || teams.containsKey(name)) {
|
||||
i--;
|
||||
while (score.length() - l - i > 16) {
|
||||
l--;
|
||||
if (l < 1) return score;
|
||||
i = Math.min(16, score.length() - l);
|
||||
}
|
||||
name = score.substring(i, i + l);
|
||||
}
|
||||
String prefix = score.substring(0, i);
|
||||
String suffix = i + l >= score.length() ? "" : score.substring(i + l);
|
||||
public List<String> getTeamMembers(String team) {
|
||||
return teams.getOrDefault(team, new ArrayList<>());
|
||||
}
|
||||
|
||||
ScoreTeam scoreTeam = new ScoreTeam(name, prefix, suffix);
|
||||
scoreTeams.put(score, scoreTeam);
|
||||
scoreTeamNames.add(name);
|
||||
public void addObjective(String name) {
|
||||
objectives.add(name);
|
||||
}
|
||||
|
||||
PacketWrapper teamPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, getUser());
|
||||
teamPacket.write(Types.STRING, name);
|
||||
teamPacket.write(Types.BYTE, (byte) 0);
|
||||
teamPacket.write(Types.STRING, "ViaRewind");
|
||||
teamPacket.write(Types.STRING, prefix);
|
||||
teamPacket.write(Types.STRING, suffix);
|
||||
teamPacket.write(Types.BYTE, (byte) 0);
|
||||
teamPacket.write(Types.SHORT, (short) 1);
|
||||
teamPacket.write(Types.STRING, name);
|
||||
teamPacket.send(Protocol1_8To1_7_6_10.class);
|
||||
public void removeObjective(String name) {
|
||||
objectives.remove(name);
|
||||
colorDependentSidebar.values().remove(name);
|
||||
if (name.equals(colorIndependentSidebar)) {
|
||||
colorIndependentSidebar = null;
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
public boolean objectiveExists(String name) {
|
||||
return objectives.contains(name);
|
||||
}
|
||||
|
||||
public String removeTeamForScore(String score) {
|
||||
ScoreTeam scoreTeam = scoreTeams.remove(score);
|
||||
if (scoreTeam == null) return score;
|
||||
scoreTeamNames.remove(scoreTeam.name);
|
||||
public String sendTeamForScore(String score) {
|
||||
if (score.length() <= 16) return score;
|
||||
if (scoreTeams.containsKey(score)) return scoreTeams.get(score).name;
|
||||
|
||||
PacketWrapper teamPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, getUser());
|
||||
teamPacket.write(Types.STRING, scoreTeam.name);
|
||||
teamPacket.write(Types.BYTE, (byte) 1);
|
||||
teamPacket.send(Protocol1_8To1_7_6_10.class);
|
||||
// Find the longest window score[i, i+l) that:
|
||||
// - is not already claimed as a team name
|
||||
// - keeps prefix (score[0,i)) at most 16 chars i <= 16
|
||||
// - keeps suffix (score[i+l, end)) at most 16 chars score.length()-l-i <= 16
|
||||
for (int l = 16; l >= 1; l--) {
|
||||
final int iMax = Math.min(16, score.length() - l);
|
||||
final int iMin = Math.max(0, score.length() - l - 16);
|
||||
for (int i = iMax; i >= iMin; i--) {
|
||||
final String name = score.substring(i, i + l);
|
||||
if (scoreTeamNames.contains(name) || teams.containsKey(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return scoreTeam.name;
|
||||
}
|
||||
final String prefix = score.substring(0, i);
|
||||
final String suffix = i + l >= score.length() ? "" : score.substring(i + l);
|
||||
|
||||
public String getColorIndependentSidebar() {
|
||||
return this.colorIndependentSidebar;
|
||||
}
|
||||
final ScoreTeam scoreTeam = new ScoreTeam(name, prefix, suffix);
|
||||
scoreTeams.put(score, scoreTeam);
|
||||
scoreTeamNames.add(name);
|
||||
|
||||
public HashMap<Byte, String> getColorDependentSidebar() {
|
||||
return this.colorDependentSidebar;
|
||||
}
|
||||
final PacketWrapper teamPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, getUser());
|
||||
teamPacket.write(Types.STRING, name);
|
||||
teamPacket.write(Types.BYTE, (byte) 0);
|
||||
teamPacket.write(Types.STRING, "ViaRewind");
|
||||
teamPacket.write(Types.STRING, prefix);
|
||||
teamPacket.write(Types.STRING, suffix);
|
||||
teamPacket.write(Types.BYTE, (byte) 0);
|
||||
teamPacket.write(Types.SHORT, (short) 1);
|
||||
teamPacket.write(Types.STRING, name);
|
||||
teamPacket.send(Protocol1_8To1_7_6_10.class);
|
||||
|
||||
public void setColorIndependentSidebar(String colorIndependentSidebar) {
|
||||
this.colorIndependentSidebar = colorIndependentSidebar;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ScoreTeam {
|
||||
private final String prefix;
|
||||
private final String suffix;
|
||||
private final String name;
|
||||
return score;
|
||||
}
|
||||
|
||||
public ScoreTeam(String name, String prefix, String suffix) {
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
public String removeTeamForScore(String score) {
|
||||
ScoreTeam scoreTeam = scoreTeams.remove(score);
|
||||
if (scoreTeam == null) return score;
|
||||
scoreTeamNames.remove(scoreTeam.name);
|
||||
|
||||
PacketWrapper teamPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, getUser());
|
||||
teamPacket.write(Types.STRING, scoreTeam.name);
|
||||
teamPacket.write(Types.BYTE, (byte) 1);
|
||||
teamPacket.send(Protocol1_8To1_7_6_10.class);
|
||||
|
||||
return scoreTeam.name;
|
||||
}
|
||||
|
||||
public String getColorIndependentSidebar() {
|
||||
return this.colorIndependentSidebar;
|
||||
}
|
||||
|
||||
public void setColorIndependentSidebar(String colorIndependentSidebar) {
|
||||
this.colorIndependentSidebar = colorIndependentSidebar;
|
||||
}
|
||||
|
||||
public HashMap<Byte, String> getColorDependentSidebar() {
|
||||
return this.colorDependentSidebar;
|
||||
}
|
||||
|
||||
private static class ScoreTeam {
|
||||
private final String prefix;
|
||||
private final String suffix;
|
||||
private final String name;
|
||||
|
||||
public ScoreTeam(String name, String prefix, String suffix) {
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
-63
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,87 +21,87 @@ import com.viaversion.viaversion.api.connection.StoredObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
|
||||
public class WorldBorderEmulator extends StoredObject {
|
||||
private double x, z;
|
||||
private double oldDiameter, newDiameter;
|
||||
private double x, z;
|
||||
private double oldDiameter, newDiameter;
|
||||
|
||||
private long lerpTime;
|
||||
private long lerpStartTime;
|
||||
private long lerpTime;
|
||||
private long lerpStartTime;
|
||||
|
||||
private boolean init = false;
|
||||
private boolean init = false;
|
||||
|
||||
public WorldBorderEmulator(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
public WorldBorderEmulator(UserConnection user) {
|
||||
super(user);
|
||||
}
|
||||
|
||||
public void init(double x, double z, double oldDiameter, double newDiameter, long lerpTime) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
public void init(double x, double z, double oldDiameter, double newDiameter, long lerpTime) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
|
||||
this.oldDiameter = oldDiameter;
|
||||
this.newDiameter = newDiameter;
|
||||
this.oldDiameter = oldDiameter;
|
||||
this.newDiameter = newDiameter;
|
||||
|
||||
this.lerpTime = lerpTime;
|
||||
this.lerpTime = lerpTime;
|
||||
|
||||
init = true;
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
public void setCenter(double x, double z) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
public void setCenter(double x, double z) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public void lerpSize(double oldDiameter, double newDiameter, long lerpTime) {
|
||||
this.oldDiameter = oldDiameter;
|
||||
this.newDiameter = newDiameter;
|
||||
this.lerpTime = lerpTime;
|
||||
this.lerpStartTime = System.currentTimeMillis();
|
||||
}
|
||||
public void lerpSize(double oldDiameter, double newDiameter, long lerpTime) {
|
||||
this.oldDiameter = oldDiameter;
|
||||
this.newDiameter = newDiameter;
|
||||
this.lerpTime = lerpTime;
|
||||
this.lerpStartTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void setSize(double size) {
|
||||
this.oldDiameter = size;
|
||||
this.newDiameter = size;
|
||||
public double getSize() {
|
||||
if (lerpTime == 0) {
|
||||
return newDiameter;
|
||||
}
|
||||
|
||||
this.lerpTime = 0;
|
||||
}
|
||||
double percent = ((double) (System.currentTimeMillis() - lerpStartTime) / (double) (lerpTime));
|
||||
|
||||
public double getSize() {
|
||||
if (lerpTime == 0) {
|
||||
return newDiameter;
|
||||
}
|
||||
// Clamp value
|
||||
if (percent > 1.0D) percent = 1.0d;
|
||||
else if (percent < 0.0D) percent = 0.0d;
|
||||
|
||||
double percent = ((double) (System.currentTimeMillis() - lerpStartTime) / (double) (lerpTime));
|
||||
return oldDiameter + (newDiameter - oldDiameter) * percent;
|
||||
}
|
||||
|
||||
// Clamp value
|
||||
if (percent > 1.0D) percent = 1.0d;
|
||||
else if (percent < 0.0D) percent = 0.0d;
|
||||
public void setSize(double size) {
|
||||
this.oldDiameter = size;
|
||||
this.newDiameter = size;
|
||||
|
||||
return oldDiameter + (newDiameter - oldDiameter) * percent;
|
||||
}
|
||||
this.lerpTime = 0;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public boolean isInit() {
|
||||
return init;
|
||||
}
|
||||
public boolean isInit() {
|
||||
return init;
|
||||
}
|
||||
|
||||
public enum Side {
|
||||
NORTH(0, -1),
|
||||
EAST(1, 0),
|
||||
SOUTH(0, 1),
|
||||
WEST(-1, 0);
|
||||
public enum Side {
|
||||
NORTH(0, -1),
|
||||
EAST(1, 0),
|
||||
SOUTH(0, 1),
|
||||
WEST(-1, 0);
|
||||
|
||||
public final int modX;
|
||||
public final int modZ;
|
||||
public final int modX;
|
||||
public final int modZ;
|
||||
|
||||
Side(int modX, int modZ) {
|
||||
this.modX = modX;
|
||||
this.modZ = modZ;
|
||||
}
|
||||
}
|
||||
Side(int modX, int modZ) {
|
||||
this.modX = modX;
|
||||
this.modZ = modZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
-53
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -26,70 +26,69 @@ import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class WorldBorderUpdateTask implements Runnable {
|
||||
public static final int VIEW_DISTANCE = 16;
|
||||
public static final int VIEW_DISTANCE = 16;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
||||
final WorldBorderEmulator worldBorderEmulatorTracker = connection.get(WorldBorderEmulator.class);
|
||||
if (!worldBorderEmulatorTracker.isInit()) continue;
|
||||
@Override
|
||||
public void run() {
|
||||
for (UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
|
||||
final WorldBorderEmulator worldBorderEmulatorTracker = connection.get(WorldBorderEmulator.class);
|
||||
if (!worldBorderEmulatorTracker.isInit()) continue;
|
||||
|
||||
final PlayerSessionStorage playerSession = connection.get(PlayerSessionStorage.class);
|
||||
final PlayerSessionStorage playerSession = connection.get(PlayerSessionStorage.class);
|
||||
|
||||
double radius = worldBorderEmulatorTracker.getSize() / 2.0;
|
||||
double radius = worldBorderEmulatorTracker.getSize() / 2.0;
|
||||
|
||||
for (WorldBorderEmulator.Side side : WorldBorderEmulator.Side.values()) {
|
||||
double d;
|
||||
double pos;
|
||||
double center;
|
||||
if (side.modX != 0) {
|
||||
pos = playerSession.getPosZ();
|
||||
center = worldBorderEmulatorTracker.getZ();
|
||||
d = Math.abs(worldBorderEmulatorTracker.getX() + radius * side.modX - playerSession.getPosX());
|
||||
} else {
|
||||
center = worldBorderEmulatorTracker.getX();
|
||||
pos = playerSession.getPosX();
|
||||
d = Math.abs(worldBorderEmulatorTracker.getZ() + radius * side.modZ - playerSession.getPosZ());
|
||||
}
|
||||
if (d >= VIEW_DISTANCE) continue;
|
||||
for (WorldBorderEmulator.Side side : WorldBorderEmulator.Side.values()) {
|
||||
double d;
|
||||
double pos;
|
||||
double center;
|
||||
if (side.modX != 0) {
|
||||
pos = playerSession.getPosZ();
|
||||
center = worldBorderEmulatorTracker.getZ();
|
||||
d = Math.abs(worldBorderEmulatorTracker.getX() + radius * side.modX - playerSession.getPosX());
|
||||
} else {
|
||||
center = worldBorderEmulatorTracker.getX();
|
||||
pos = playerSession.getPosX();
|
||||
d = Math.abs(worldBorderEmulatorTracker.getZ() + radius * side.modZ - playerSession.getPosZ());
|
||||
}
|
||||
if (d >= VIEW_DISTANCE) continue;
|
||||
|
||||
double r = Math.sqrt(VIEW_DISTANCE * VIEW_DISTANCE - d * d);
|
||||
double r = Math.sqrt(VIEW_DISTANCE * VIEW_DISTANCE - d * d);
|
||||
|
||||
double minH = Math.ceil(pos - r);
|
||||
double maxH = Math.floor(pos + r);
|
||||
double minV = Math.ceil(playerSession.getPosY() - r);
|
||||
double maxV = Math.floor(playerSession.getPosY() + r);
|
||||
double minH = Math.ceil(pos - r);
|
||||
double maxH = Math.floor(pos + r);
|
||||
double minV = Math.ceil(playerSession.getPosY() - r);
|
||||
double maxV = Math.floor(playerSession.getPosY() + r);
|
||||
|
||||
if (minH < center - radius) minH = Math.ceil(center - radius);
|
||||
if (maxH > center + radius) maxH = Math.floor(center + radius);
|
||||
if (minV < 0.0) minV = 0.0;
|
||||
if (minH < center - radius) minH = Math.ceil(center - radius);
|
||||
if (maxH > center + radius) maxH = Math.floor(center + radius);
|
||||
if (minV < 0.0) minV = 0.0;
|
||||
|
||||
double centerH = (minH + maxH) / 2.0;
|
||||
double centerV = (minV + maxV) / 2.0;
|
||||
double centerH = (minH + maxH) / 2.0;
|
||||
double centerV = (minV + maxV) / 2.0;
|
||||
|
||||
double particleOffset = 2.5;
|
||||
double particleOffset = 2.5;
|
||||
|
||||
final PacketWrapper spawnParticle = PacketWrapper.create(ClientboundPackets1_8.LEVEL_PARTICLES, connection);
|
||||
spawnParticle.write(Types.STRING, ViaRewind.getConfig().getWorldBorderParticle()); // particle name
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX != 0 ? worldBorderEmulatorTracker.getX() + (radius * side.modX) : centerH)); // x
|
||||
spawnParticle.write(Types.FLOAT, (float) centerV); // y
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX == 0 ? worldBorderEmulatorTracker.getZ() + (radius * side.modZ) : centerH)); // z
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX != 0 ? 0f : (maxH - minH) / particleOffset)); // offset x
|
||||
spawnParticle.write(Types.FLOAT, (float) ((maxV - minV) / particleOffset)); // offset y
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX == 0 ? 0f : (maxH - minH) / particleOffset)); // offset z
|
||||
spawnParticle.write(Types.FLOAT, 0F); // particle data
|
||||
spawnParticle.write(Types.INT, (int) Math.floor((maxH - minH) * (maxV - minV) * 0.5));
|
||||
final PacketWrapper spawnParticle = PacketWrapper.create(ClientboundPackets1_8.LEVEL_PARTICLES, connection);
|
||||
spawnParticle.write(Types.STRING, ViaRewind.getConfig().getWorldBorderParticle()); // particle name
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX != 0 ? worldBorderEmulatorTracker.getX() + (radius * side.modX) : centerH)); // x
|
||||
spawnParticle.write(Types.FLOAT, (float) centerV); // y
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX == 0 ? worldBorderEmulatorTracker.getZ() + (radius * side.modZ) : centerH)); // z
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX != 0 ? 0f : (maxH - minH) / particleOffset)); // offset x
|
||||
spawnParticle.write(Types.FLOAT, (float) ((maxV - minV) / particleOffset)); // offset y
|
||||
spawnParticle.write(Types.FLOAT, (float) (side.modX == 0 ? 0f : (maxH - minH) / particleOffset)); // offset z
|
||||
spawnParticle.write(Types.FLOAT, 0F); // particle data
|
||||
spawnParticle.write(Types.INT, (int) Math.floor((maxH - minH) * (maxV - minV) * 0.5));
|
||||
|
||||
try {
|
||||
spawnParticle.send(Protocol1_8To1_7_6_10.class);
|
||||
} catch (Exception e) {
|
||||
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send world border particle", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
spawnParticle.send(Protocol1_8To1_7_6_10.class);
|
||||
} catch (Exception e) {
|
||||
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send world border particle", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+72
-66
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,98 +18,104 @@
|
||||
package com.viaversion.viarewind.protocol.v1_9to1_8;
|
||||
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.data.RewindMappingData1_8;
|
||||
import com.viaversion.viarewind.api.data.RewindMappingData;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.provider.InventoryProvider;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.rewriter.BlockItemPacketRewriter1_9;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.rewriter.EntityPacketRewriter1_9;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.rewriter.*;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.*;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.rewriter.PlayerPacketRewriter1_9;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.rewriter.WorldPacketRewriter1_9;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.BlockPlaceDestroyTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.BossBarStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.CooldownStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.EntityTracker1_9;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.LevitationStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.PlayerPositionTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.WindowTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.task.CooldownIndicatorTask;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.task.LevitationUpdateTask;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Protocol1_9To1_8 extends BackwardsProtocol<ClientboundPackets1_9, ClientboundPackets1_8, ServerboundPackets1_9, ServerboundPackets1_8> {
|
||||
|
||||
public static final ValueTransformer<Double, Integer> DOUBLE_TO_INT_TIMES_32 = new ValueTransformer<Double, Integer>(Types.INT) {
|
||||
@Override
|
||||
public Integer transform(PacketWrapper wrapper, Double inputValue) {
|
||||
return (int) (inputValue * 32.0D);
|
||||
}
|
||||
};
|
||||
public static final ValueTransformer<Float, Byte> DEGREES_TO_ANGLE = new ValueTransformer<Float, Byte>(Types.BYTE) {
|
||||
@Override
|
||||
public Byte transform(PacketWrapper packetWrapper, Float degrees) {
|
||||
return (byte) ((degrees / 360F) * 256);
|
||||
}
|
||||
};
|
||||
public static final ValueTransformer<Double, Integer> DOUBLE_TO_INT_TIMES_32 = new ValueTransformer<>(Types.INT) {
|
||||
@Override
|
||||
public Integer transform(PacketWrapper wrapper, Double inputValue) {
|
||||
return (int) (inputValue * 32.0D);
|
||||
}
|
||||
};
|
||||
public static final ValueTransformer<Float, Byte> DEGREES_TO_ANGLE = new ValueTransformer<>(Types.BYTE) {
|
||||
@Override
|
||||
public Byte transform(PacketWrapper packetWrapper, Float degrees) {
|
||||
return (byte) ((degrees / 360F) * 256);
|
||||
}
|
||||
};
|
||||
|
||||
public static final RewindMappingData1_8 MAPPINGS = new RewindMappingData1_8();
|
||||
public static final RewindMappingData MAPPINGS = new RewindMappingData("1.9.4", "1.8");
|
||||
|
||||
private final BlockItemPacketRewriter1_9 itemRewriter = new BlockItemPacketRewriter1_9(this);
|
||||
private final EntityPacketRewriter1_9 entityRewriter = new EntityPacketRewriter1_9(this);
|
||||
private final BlockItemPacketRewriter1_9 itemRewriter = new BlockItemPacketRewriter1_9(this);
|
||||
private final EntityPacketRewriter1_9 entityRewriter = new EntityPacketRewriter1_9(this);
|
||||
|
||||
public Protocol1_9To1_8() {
|
||||
super(ClientboundPackets1_9.class, ClientboundPackets1_8.class, ServerboundPackets1_9.class, ServerboundPackets1_8.class);
|
||||
}
|
||||
public Protocol1_9To1_8() {
|
||||
super(ClientboundPackets1_9.class, ClientboundPackets1_8.class, ServerboundPackets1_9.class, ServerboundPackets1_8.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
entityRewriter.register();
|
||||
itemRewriter.register();
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
entityRewriter.register();
|
||||
itemRewriter.register();
|
||||
new PlayerPacketRewriter1_9(this).register();
|
||||
new WorldPacketRewriter1_9(this).register();
|
||||
}
|
||||
|
||||
PlayerPacketRewriter1_9.register(this);
|
||||
WorldPacketRewriter1_9.register(this);
|
||||
}
|
||||
@Override
|
||||
public void init(UserConnection connection) {
|
||||
connection.addEntityTracker(this.getClass(), new EntityTracker1_9(connection));
|
||||
connection.addClientWorld(this.getClass(), new ClientWorld());
|
||||
|
||||
@Override
|
||||
public void init(UserConnection connection) {
|
||||
connection.addEntityTracker(this.getClass(), new EntityTracker1_9(connection));
|
||||
connection.put(new WindowTracker(connection));
|
||||
connection.put(new LevitationStorage());
|
||||
connection.put(new PlayerPositionTracker());
|
||||
connection.put(new CooldownStorage());
|
||||
connection.put(new BlockPlaceDestroyTracker());
|
||||
connection.put(new BossBarStorage(connection));
|
||||
}
|
||||
|
||||
connection.put(new WindowTracker(connection));
|
||||
connection.put(new LevitationStorage());
|
||||
connection.put(new PlayerPositionTracker());
|
||||
connection.put(new CooldownStorage());
|
||||
connection.put(new BlockPlaceDestroyTracker());
|
||||
connection.put(new BossBarStorage(connection));
|
||||
@Override
|
||||
public void register(ViaProviders providers) {
|
||||
providers.register(InventoryProvider.class, new InventoryProvider());
|
||||
|
||||
if (!connection.has(ClientWorld.class)) {
|
||||
connection.put(new ClientWorld());
|
||||
}
|
||||
}
|
||||
Via.getManager().getScheduler().scheduleRepeating(new LevitationUpdateTask(), 0L, 50L, TimeUnit.MILLISECONDS);
|
||||
Via.getManager().getScheduler().scheduleRepeating(new CooldownIndicatorTask(), 0L, 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(ViaProviders providers) {
|
||||
Via.getManager().getScheduler().scheduleRepeating(new LevitationUpdateTask(), 0L, 50L, TimeUnit.MILLISECONDS);
|
||||
Via.getManager().getScheduler().scheduleRepeating(new CooldownIndicatorTask(), 0L, 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
@Override
|
||||
public RewindMappingData getMappingData() {
|
||||
return MAPPINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RewindMappingData1_8 getMappingData() {
|
||||
return MAPPINGS;
|
||||
}
|
||||
@Override
|
||||
public BlockItemPacketRewriter1_9 getItemRewriter() {
|
||||
return itemRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockItemPacketRewriter1_9 getItemRewriter() {
|
||||
return itemRewriter;
|
||||
}
|
||||
@Override
|
||||
public EntityPacketRewriter1_9 getEntityRewriter() {
|
||||
return entityRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPacketRewriter1_9 getEntityRewriter() {
|
||||
return entityRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMappingDataToLoad() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean hasMappingDataToLoad() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+19
-19
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,26 +25,26 @@ import com.viaversion.viaversion.libs.gson.JsonPrimitive;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
|
||||
public class ActionBarVisualization implements CooldownVisualization {
|
||||
private final UserConnection user;
|
||||
private final UserConnection user;
|
||||
|
||||
public ActionBarVisualization(UserConnection user) {
|
||||
this.user = user;
|
||||
}
|
||||
public ActionBarVisualization(UserConnection user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(double progress) throws Exception {
|
||||
sendActionBar(CooldownVisualization.buildProgressText("■", progress));
|
||||
}
|
||||
@Override
|
||||
public void show(double progress) throws Exception {
|
||||
sendActionBar(CooldownVisualization.buildProgressText("■", progress));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() throws Exception {
|
||||
sendActionBar("§r");
|
||||
}
|
||||
@Override
|
||||
public void hide() throws Exception {
|
||||
sendActionBar("§r");
|
||||
}
|
||||
|
||||
private void sendActionBar(final String bar) {
|
||||
PacketWrapper actionBarPacket = PacketWrapper.create(ClientboundPackets1_8.CHAT, user);
|
||||
actionBarPacket.write(Types.COMPONENT, new JsonPrimitive(bar));
|
||||
actionBarPacket.write(Types.BYTE, (byte) 2); // Position - above hotbar
|
||||
actionBarPacket.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
private void sendActionBar(final String bar) {
|
||||
PacketWrapper actionBarPacket = PacketWrapper.create(ClientboundPackets1_8.CHAT, user);
|
||||
actionBarPacket.write(Types.COMPONENT, new JsonPrimitive(bar));
|
||||
actionBarPacket.write(Types.BYTE, (byte) 2); // Position - above hotbar
|
||||
actionBarPacket.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
}
|
||||
+36
-37
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,46 +23,45 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.libs.gson.JsonPrimitive;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BossBarVisualization implements CooldownVisualization {
|
||||
private final UserConnection user;
|
||||
private UUID bossUUID;
|
||||
private final UserConnection user;
|
||||
private UUID bossUUID;
|
||||
|
||||
public BossBarVisualization(UserConnection user) {
|
||||
this.user = user;
|
||||
}
|
||||
public BossBarVisualization(UserConnection user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(double progress) throws Exception {
|
||||
final PacketWrapper setBossbar = PacketWrapper.create(ClientboundPackets1_9.BOSS_EVENT, user);
|
||||
if (bossUUID == null) {
|
||||
bossUUID = UUID.randomUUID();
|
||||
setBossbar.write(Types.UUID, bossUUID);
|
||||
setBossbar.write(Types.VAR_INT, 0); // Action - add
|
||||
setBossbar.write(Types.COMPONENT, new JsonPrimitive(" ")); // Title
|
||||
setBossbar.write(Types.FLOAT, (float) progress); // Health
|
||||
setBossbar.write(Types.VAR_INT, 0); // Color
|
||||
setBossbar.write(Types.VAR_INT, 0); // Division
|
||||
setBossbar.write(Types.UNSIGNED_BYTE, (short) 0); // Flags
|
||||
} else {
|
||||
setBossbar.write(Types.UUID, bossUUID);
|
||||
setBossbar.write(Types.VAR_INT, 2); // Action - update health
|
||||
setBossbar.write(Types.FLOAT, (float) progress); // Health
|
||||
}
|
||||
setBossbar.send(Protocol1_9To1_8.class, false);
|
||||
}
|
||||
@Override
|
||||
public void show(double progress) throws Exception {
|
||||
final PacketWrapper setBossbar = PacketWrapper.create(ClientboundPackets1_9.BOSS_EVENT, user);
|
||||
if (bossUUID == null) {
|
||||
bossUUID = UUID.randomUUID();
|
||||
setBossbar.write(Types.UUID, bossUUID);
|
||||
setBossbar.write(Types.VAR_INT, 0); // Action - add
|
||||
setBossbar.write(Types.COMPONENT, new JsonPrimitive(" ")); // Title
|
||||
setBossbar.write(Types.FLOAT, (float) progress); // Health
|
||||
setBossbar.write(Types.VAR_INT, 0); // Color
|
||||
setBossbar.write(Types.VAR_INT, 0); // Division
|
||||
setBossbar.write(Types.UNSIGNED_BYTE, (short) 0); // Flags
|
||||
} else {
|
||||
setBossbar.write(Types.UUID, bossUUID);
|
||||
setBossbar.write(Types.VAR_INT, 2); // Action - update health
|
||||
setBossbar.write(Types.FLOAT, (float) progress); // Health
|
||||
}
|
||||
setBossbar.send(Protocol1_9To1_8.class, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() throws Exception {
|
||||
if (bossUUID == null) {
|
||||
return;
|
||||
}
|
||||
final PacketWrapper removeBossbar = PacketWrapper.create(ClientboundPackets1_9.BOSS_EVENT, user);
|
||||
removeBossbar.write(Types.UUID, bossUUID);
|
||||
removeBossbar.write(Types.VAR_INT, 1); // Action - remove
|
||||
removeBossbar.send(Protocol1_9To1_8.class, false);
|
||||
bossUUID = null;
|
||||
}
|
||||
@Override
|
||||
public void hide() throws Exception {
|
||||
if (bossUUID == null) {
|
||||
return;
|
||||
}
|
||||
final PacketWrapper removeBossbar = PacketWrapper.create(ClientboundPackets1_9.BOSS_EVENT, user);
|
||||
removeBossbar.write(Types.UUID, bossUUID);
|
||||
removeBossbar.write(Types.VAR_INT, 1); // Action - remove
|
||||
removeBossbar.send(Protocol1_9To1_8.class, false);
|
||||
bossUUID = null;
|
||||
}
|
||||
}
|
||||
+33
-35
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,45 +22,43 @@ import com.viaversion.viarewind.api.ViaRewindConfig.CooldownIndicator;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
|
||||
public interface CooldownVisualization {
|
||||
void show(double progress) throws Exception;
|
||||
int MAX_PROGRESS_TEXT_LENGTH = 10;
|
||||
|
||||
void hide() throws Exception;
|
||||
static String buildProgressText(String symbol, double cooldown) {
|
||||
int green = (int) Math.floor(((double) MAX_PROGRESS_TEXT_LENGTH) * cooldown);
|
||||
int grey = MAX_PROGRESS_TEXT_LENGTH - green;
|
||||
StringBuilder builder = new StringBuilder("§8");
|
||||
while (green-- > 0) builder.append(symbol);
|
||||
builder.append("§7");
|
||||
while (grey-- > 0) builder.append(symbol);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
void show(double progress) throws Exception;
|
||||
|
||||
int MAX_PROGRESS_TEXT_LENGTH = 10;
|
||||
void hide() throws Exception;
|
||||
|
||||
static String buildProgressText(String symbol, double cooldown) {
|
||||
int green = (int) Math.floor(((double) MAX_PROGRESS_TEXT_LENGTH) * cooldown);
|
||||
int grey = MAX_PROGRESS_TEXT_LENGTH - green;
|
||||
StringBuilder builder = new StringBuilder("§8");
|
||||
while (green-- > 0) builder.append(symbol);
|
||||
builder.append("§7");
|
||||
while (grey-- > 0) builder.append(symbol);
|
||||
return builder.toString();
|
||||
}
|
||||
interface Factory {
|
||||
Factory DISABLED = user -> new DisabledCooldownVisualization();
|
||||
|
||||
interface Factory {
|
||||
CooldownVisualization create(UserConnection user);
|
||||
static Factory fromConfiguration() {
|
||||
try {
|
||||
return fromIndicator(ViaRewind.getConfig().getCooldownIndicator());
|
||||
} catch (IllegalArgumentException e) {
|
||||
ViaRewind.getPlatform().getLogger().warning("Invalid cooldown-indicator setting");
|
||||
return DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
static Factory fromConfiguration() {
|
||||
try {
|
||||
return fromIndicator(ViaRewind.getConfig().getCooldownIndicator());
|
||||
} catch (IllegalArgumentException e) {
|
||||
ViaRewind.getPlatform().getLogger().warning("Invalid cooldown-indicator setting");
|
||||
return DISABLED;
|
||||
}
|
||||
}
|
||||
static Factory fromIndicator(CooldownIndicator indicator) {
|
||||
return switch (indicator) {
|
||||
case TITLE -> TitleCooldownVisualization::new;
|
||||
case BOSS_BAR -> BossBarVisualization::new;
|
||||
case ACTION_BAR -> ActionBarVisualization::new;
|
||||
case DISABLED -> DISABLED;
|
||||
};
|
||||
}
|
||||
|
||||
static Factory fromIndicator(CooldownIndicator indicator) {
|
||||
return switch (indicator) {
|
||||
case TITLE -> TitleCooldownVisualization::new;
|
||||
case BOSS_BAR -> BossBarVisualization::new;
|
||||
case ACTION_BAR -> ActionBarVisualization::new;
|
||||
case DISABLED -> DISABLED;
|
||||
default -> throw new IllegalArgumentException("Unexpected: " + indicator);
|
||||
};
|
||||
}
|
||||
|
||||
Factory DISABLED = user -> new DisabledCooldownVisualization();
|
||||
}
|
||||
CooldownVisualization create(UserConnection user);
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,12 +19,12 @@ package com.viaversion.viarewind.protocol.v1_9to1_8.cooldown;
|
||||
|
||||
public class DisabledCooldownVisualization implements CooldownVisualization {
|
||||
|
||||
@Override
|
||||
public void show(double progress) {
|
||||
}
|
||||
@Override
|
||||
public void show(double progress) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() {
|
||||
}
|
||||
@Override
|
||||
public void hide() {
|
||||
}
|
||||
|
||||
}
|
||||
+31
-31
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,45 +23,45 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.libs.gson.JsonPrimitive;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class TitleCooldownVisualization implements CooldownVisualization {
|
||||
|
||||
private static final int ACTION_SET_TITLE = 0;
|
||||
private static final int ACTION_SET_SUBTITLE = 1;
|
||||
private static final int ACTION_SET_TIMES_AND_DISPLAY = 2;
|
||||
private static final int ACTION_HIDE = 3;
|
||||
private static final int ACTION_SET_TITLE = 0;
|
||||
private static final int ACTION_SET_SUBTITLE = 1;
|
||||
private static final int ACTION_SET_TIMES_AND_DISPLAY = 2;
|
||||
private static final int ACTION_HIDE = 3;
|
||||
|
||||
private final UserConnection user;
|
||||
private final UserConnection user;
|
||||
|
||||
public TitleCooldownVisualization(UserConnection user) {
|
||||
this.user = user;
|
||||
}
|
||||
public TitleCooldownVisualization(UserConnection user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(double progress) throws Exception {
|
||||
final String text = CooldownVisualization.buildProgressText("˙", progress);
|
||||
@Override
|
||||
public void show(double progress) throws Exception {
|
||||
final String text = CooldownVisualization.buildProgressText("˙", progress);
|
||||
|
||||
sendTitlePacket(ACTION_SET_TITLE, wrapper -> wrapper.write(Types.COMPONENT, new JsonPrimitive("")));
|
||||
sendTitlePacket(ACTION_SET_SUBTITLE, wrapper -> wrapper.write(Types.COMPONENT, new JsonPrimitive(text)));
|
||||
sendTitlePacket(ACTION_SET_TIMES_AND_DISPLAY, wrapper -> {
|
||||
wrapper.write(Types.INT, 0);
|
||||
wrapper.write(Types.INT, 2);
|
||||
wrapper.write(Types.INT, 5);
|
||||
});
|
||||
}
|
||||
sendTitlePacket(ACTION_SET_TITLE, wrapper -> wrapper.write(Types.COMPONENT, new JsonPrimitive("")));
|
||||
sendTitlePacket(ACTION_SET_SUBTITLE, wrapper -> wrapper.write(Types.COMPONENT, new JsonPrimitive(text)));
|
||||
sendTitlePacket(ACTION_SET_TIMES_AND_DISPLAY, wrapper -> {
|
||||
wrapper.write(Types.INT, 0);
|
||||
wrapper.write(Types.INT, 2);
|
||||
wrapper.write(Types.INT, 5);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide() throws Exception {
|
||||
sendTitlePacket(ACTION_HIDE, wrapper -> {});
|
||||
}
|
||||
@Override
|
||||
public void hide() throws Exception {
|
||||
sendTitlePacket(ACTION_HIDE, wrapper -> {
|
||||
});
|
||||
}
|
||||
|
||||
private void sendTitlePacket(int action, Consumer<PacketWrapper> writer) {
|
||||
final PacketWrapper title = PacketWrapper.create(ClientboundPackets1_8.SET_TITLES, user);
|
||||
title.write(Types.VAR_INT, action);
|
||||
writer.accept(title);
|
||||
title.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
private void sendTitlePacket(int action, Consumer<PacketWrapper> writer) {
|
||||
final PacketWrapper title = PacketWrapper.create(ClientboundPackets1_8.SET_TITLES, user);
|
||||
title.write(Types.VAR_INT, action);
|
||||
writer.accept(title);
|
||||
title.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
}
|
||||
+43
-43
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,49 +21,49 @@ import java.util.HashMap;
|
||||
|
||||
public class EffectIdMappings1_8 {
|
||||
|
||||
private static final HashMap<Integer, Integer> effects = new HashMap<>();
|
||||
private static final HashMap<Integer, Integer> effects = new HashMap<>();
|
||||
|
||||
static {
|
||||
effects.put(1003, 1002);
|
||||
effects.put(1005, 1003);
|
||||
effects.put(1006, 1003);
|
||||
effects.put(1007, 1003);
|
||||
effects.put(1008, 1003);
|
||||
effects.put(1009, 1004);
|
||||
effects.put(1010, 1005);
|
||||
effects.put(1011, 1006);
|
||||
effects.put(1012, 1006);
|
||||
effects.put(1013, 1006);
|
||||
effects.put(1014, 1006);
|
||||
effects.put(1015, 1007);
|
||||
effects.put(1016, 1008);
|
||||
effects.put(1017, 1008);
|
||||
effects.put(1018, 1009);
|
||||
effects.put(1019, 1010);
|
||||
effects.put(1020, 1011);
|
||||
effects.put(1021, 1012);
|
||||
effects.put(1022, 1012);
|
||||
effects.put(1023, 1013);
|
||||
effects.put(1024, 1014);
|
||||
effects.put(1025, 1015);
|
||||
effects.put(1026, 1016);
|
||||
effects.put(1027, 1017);
|
||||
effects.put(1028, 1018);
|
||||
effects.put(1029, 1020);
|
||||
effects.put(1030, 1021);
|
||||
effects.put(1031, 1022);
|
||||
effects.put(1032, -1);
|
||||
effects.put(1033, -1);
|
||||
effects.put(1034, -1);
|
||||
effects.put(1035, -1);
|
||||
effects.put(1036, 1003);
|
||||
effects.put(1037, 1006);
|
||||
static {
|
||||
effects.put(1003, 1002);
|
||||
effects.put(1005, 1003);
|
||||
effects.put(1006, 1003);
|
||||
effects.put(1007, 1003);
|
||||
effects.put(1008, 1003);
|
||||
effects.put(1009, 1004);
|
||||
effects.put(1010, 1005);
|
||||
effects.put(1011, 1006);
|
||||
effects.put(1012, 1006);
|
||||
effects.put(1013, 1006);
|
||||
effects.put(1014, 1006);
|
||||
effects.put(1015, 1007);
|
||||
effects.put(1016, 1008);
|
||||
effects.put(1017, 1008);
|
||||
effects.put(1018, 1009);
|
||||
effects.put(1019, 1010);
|
||||
effects.put(1020, 1011);
|
||||
effects.put(1021, 1012);
|
||||
effects.put(1022, 1012);
|
||||
effects.put(1023, 1013);
|
||||
effects.put(1024, 1014);
|
||||
effects.put(1025, 1015);
|
||||
effects.put(1026, 1016);
|
||||
effects.put(1027, 1017);
|
||||
effects.put(1028, 1018);
|
||||
effects.put(1029, 1020);
|
||||
effects.put(1030, 1021);
|
||||
effects.put(1031, 1022);
|
||||
effects.put(1032, -1);
|
||||
effects.put(1033, -1);
|
||||
effects.put(1034, -1);
|
||||
effects.put(1035, -1);
|
||||
effects.put(1036, 1003);
|
||||
effects.put(1037, 1006);
|
||||
|
||||
effects.put(3000, -1);
|
||||
effects.put(3001, -1);
|
||||
}
|
||||
effects.put(3000, -1);
|
||||
effects.put(3001, -1);
|
||||
}
|
||||
|
||||
public static int getOldId(int id) {
|
||||
return effects.getOrDefault(id, id);
|
||||
}
|
||||
public static int getOldId(int id) {
|
||||
return effects.getOrDefault(id, id);
|
||||
}
|
||||
}
|
||||
+22
-27
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,39 +21,34 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_9;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.data.EntityDataIndex1_9;
|
||||
import com.viaversion.viaversion.util.Pair;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
public class EntityDataIndex1_8 {
|
||||
|
||||
private static final HashMap<Pair<EntityTypes1_9.EntityType, Integer>, EntityDataIndex1_9> ENTITY_DATA_REWRITES = new HashMap<>();
|
||||
private static final HashMap<Pair<EntityTypes1_9.EntityType, Integer>, EntityDataIndex1_9> ENTITY_DATA_REWRITES = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (EntityDataIndex1_9 index : EntityDataIndex1_9.values()) {
|
||||
ENTITY_DATA_REWRITES.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
|
||||
}
|
||||
}
|
||||
static {
|
||||
for (EntityDataIndex1_9 index : EntityDataIndex1_9.values()) {
|
||||
ENTITY_DATA_REWRITES.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<EntityDataIndex1_9> getIndex(final EntityType type, final int index) {
|
||||
final Pair<EntityType, Integer> pair = new Pair<>(type, index);
|
||||
if (ENTITY_DATA_REWRITES.containsKey(pair)) {
|
||||
return Optional.of(ENTITY_DATA_REWRITES.get(pair));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
private static Optional<EntityDataIndex1_9> getIndex(final EntityType type, final int index) {
|
||||
final Pair<EntityType, Integer> pair = new Pair<>(type, index);
|
||||
return Optional.ofNullable(ENTITY_DATA_REWRITES.get(pair));
|
||||
}
|
||||
|
||||
public static EntityDataIndex1_9 searchIndex(final EntityType type, final int index) {
|
||||
EntityType currentType = type;
|
||||
do {
|
||||
final Optional<EntityDataIndex1_9> optMeta = getIndex(currentType, index);
|
||||
if (optMeta.isPresent()) {
|
||||
return optMeta.get();
|
||||
}
|
||||
currentType = currentType.getParent();
|
||||
} while (currentType != null);
|
||||
return null;
|
||||
}
|
||||
public static EntityDataIndex1_9 searchIndex(final EntityType type, final int index) {
|
||||
EntityType currentType = type;
|
||||
do {
|
||||
final Optional<EntityDataIndex1_9> optMeta = getIndex(currentType, index);
|
||||
if (optMeta.isPresent()) {
|
||||
return optMeta.get();
|
||||
}
|
||||
currentType = currentType.getParent();
|
||||
} while (currentType != null);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+53
-55
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,64 +18,62 @@
|
||||
package com.viaversion.viarewind.protocol.v1_9to1_8.data;
|
||||
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.data.PotionIdMappings1_9;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// TODO | Check if this is correct???
|
||||
public class PotionIdMappings1_8 {
|
||||
public static final Map<String, String> POTION_NAME_INDEX = new HashMap<>();
|
||||
public static final Map<String, Integer> POTION_NAME_TO_ID = new HashMap<>();
|
||||
public static final Map<String, String> POTION_NAME_INDEX = new HashMap<>();
|
||||
public static final Map<String, Integer> POTION_NAME_TO_ID = new HashMap<>();
|
||||
|
||||
static {
|
||||
POTION_NAME_TO_ID.putAll(PotionIdMappings1_9.POTION_NAME_TO_ID);
|
||||
POTION_NAME_TO_ID.put("luck", 8203);
|
||||
static {
|
||||
POTION_NAME_TO_ID.putAll(PotionIdMappings1_9.POTION_NAME_TO_ID);
|
||||
POTION_NAME_TO_ID.put("luck", 8203); // Map new potion to similar one (luck->leaping)
|
||||
|
||||
POTION_NAME_INDEX.put("water", "§rWater Bottle");
|
||||
POTION_NAME_INDEX.put("mundane", "§rMundane Potion");
|
||||
POTION_NAME_INDEX.put("thick", "§rThick Potion");
|
||||
POTION_NAME_INDEX.put("awkward", "§rAwkward Potion");
|
||||
POTION_NAME_INDEX.put("water_splash", "§rSplash Water Bottle");
|
||||
POTION_NAME_INDEX.put("mundane_splash", "§rMundane Splash Potion");
|
||||
POTION_NAME_INDEX.put("thick_splash", "§rThick Splash Potion");
|
||||
POTION_NAME_INDEX.put("awkward_splash", "§rAwkward Splash Potion");
|
||||
POTION_NAME_INDEX.put("water_lingering", "§rLingering Water Bottle");
|
||||
POTION_NAME_INDEX.put("mundane_lingering", "§rMundane Lingering Potion");
|
||||
POTION_NAME_INDEX.put("thick_lingering", "§rThick Lingering Potion");
|
||||
POTION_NAME_INDEX.put("awkward_lingering", "§rAwkward Lingering Potion");
|
||||
POTION_NAME_INDEX.put("night_vision_lingering", "§rLingering Potion of Night Vision");
|
||||
POTION_NAME_INDEX.put("long_night_vision_lingering", "§rLingering Potion of Night Vision");
|
||||
POTION_NAME_INDEX.put("invisibility_lingering", "§rLingering Potion of Invisibility");
|
||||
POTION_NAME_INDEX.put("long_invisibility_lingering", "§rLingering Potion of Invisibility");
|
||||
POTION_NAME_INDEX.put("leaping_lingering", "§rLingering Potion of Leaping");
|
||||
POTION_NAME_INDEX.put("long_leaping_lingering", "§rLingering Potion of Leaping");
|
||||
POTION_NAME_INDEX.put("strong_leaping_lingering", "§rLingering Potion of Leaping");
|
||||
POTION_NAME_INDEX.put("fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
|
||||
POTION_NAME_INDEX.put("long_fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
|
||||
POTION_NAME_INDEX.put("swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||
POTION_NAME_INDEX.put("long_swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||
POTION_NAME_INDEX.put("strong_swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||
POTION_NAME_INDEX.put("slowness_lingering", "§rLingering Potion of Slowness");
|
||||
POTION_NAME_INDEX.put("long_slowness_lingering", "§rLingering Potion of Slowness");
|
||||
POTION_NAME_INDEX.put("water_breathing_lingering", "§rLingering Potion of Water Breathing");
|
||||
POTION_NAME_INDEX.put("long_water_breathing_lingering", "§rLingering Potion of Water Breathing");
|
||||
POTION_NAME_INDEX.put("healing_lingering", "§rLingering Potion of Healing");
|
||||
POTION_NAME_INDEX.put("strong_healing_lingering", "§rLingering Potion of Healing");
|
||||
POTION_NAME_INDEX.put("harming_lingering", "§rLingering Potion of Harming");
|
||||
POTION_NAME_INDEX.put("strong_harming_lingering", "§rLingering Potion of Harming");
|
||||
POTION_NAME_INDEX.put("poison_lingering", "§rLingering Potion of Poisen");
|
||||
POTION_NAME_INDEX.put("long_poison_lingering", "§rLingering Potion of Poisen");
|
||||
POTION_NAME_INDEX.put("strong_poison_lingering", "§rLingering Potion of Poisen");
|
||||
POTION_NAME_INDEX.put("regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||
POTION_NAME_INDEX.put("long_regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||
POTION_NAME_INDEX.put("strong_regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||
POTION_NAME_INDEX.put("strength_lingering", "§rLingering Potion of Strength");
|
||||
POTION_NAME_INDEX.put("long_strength_lingering", "§rLingering Potion of Strength");
|
||||
POTION_NAME_INDEX.put("strong_strength_lingering", "§rLingering Potion of Strength");
|
||||
POTION_NAME_INDEX.put("weakness_lingering", "§rLingering Potion of Weakness");
|
||||
POTION_NAME_INDEX.put("long_weakness_lingering", "§rLingering Potion of Weakness");
|
||||
POTION_NAME_INDEX.put("luck_lingering", "§rLingering Potion of Luck");
|
||||
POTION_NAME_INDEX.put("luck", "§rPotion of Luck");
|
||||
POTION_NAME_INDEX.put("luck_splash", "§rSplash Potion of Luck");
|
||||
}
|
||||
POTION_NAME_INDEX.put("water", "§rWater Bottle");
|
||||
POTION_NAME_INDEX.put("mundane", "§rMundane Potion");
|
||||
POTION_NAME_INDEX.put("thick", "§rThick Potion");
|
||||
POTION_NAME_INDEX.put("awkward", "§rAwkward Potion");
|
||||
POTION_NAME_INDEX.put("water_splash", "§rSplash Water Bottle");
|
||||
POTION_NAME_INDEX.put("mundane_splash", "§rMundane Splash Potion");
|
||||
POTION_NAME_INDEX.put("thick_splash", "§rThick Splash Potion");
|
||||
POTION_NAME_INDEX.put("awkward_splash", "§rAwkward Splash Potion");
|
||||
POTION_NAME_INDEX.put("water_lingering", "§rLingering Water Bottle");
|
||||
POTION_NAME_INDEX.put("mundane_lingering", "§rMundane Lingering Potion");
|
||||
POTION_NAME_INDEX.put("thick_lingering", "§rThick Lingering Potion");
|
||||
POTION_NAME_INDEX.put("awkward_lingering", "§rAwkward Lingering Potion");
|
||||
POTION_NAME_INDEX.put("night_vision_lingering", "§rLingering Potion of Night Vision");
|
||||
POTION_NAME_INDEX.put("long_night_vision_lingering", "§rLingering Potion of Night Vision");
|
||||
POTION_NAME_INDEX.put("invisibility_lingering", "§rLingering Potion of Invisibility");
|
||||
POTION_NAME_INDEX.put("long_invisibility_lingering", "§rLingering Potion of Invisibility");
|
||||
POTION_NAME_INDEX.put("leaping_lingering", "§rLingering Potion of Leaping");
|
||||
POTION_NAME_INDEX.put("long_leaping_lingering", "§rLingering Potion of Leaping");
|
||||
POTION_NAME_INDEX.put("strong_leaping_lingering", "§rLingering Potion of Leaping");
|
||||
POTION_NAME_INDEX.put("fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
|
||||
POTION_NAME_INDEX.put("long_fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
|
||||
POTION_NAME_INDEX.put("swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||
POTION_NAME_INDEX.put("long_swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||
POTION_NAME_INDEX.put("strong_swiftness_lingering", "§rLingering Potion of Swiftness");
|
||||
POTION_NAME_INDEX.put("slowness_lingering", "§rLingering Potion of Slowness");
|
||||
POTION_NAME_INDEX.put("long_slowness_lingering", "§rLingering Potion of Slowness");
|
||||
POTION_NAME_INDEX.put("water_breathing_lingering", "§rLingering Potion of Water Breathing");
|
||||
POTION_NAME_INDEX.put("long_water_breathing_lingering", "§rLingering Potion of Water Breathing");
|
||||
POTION_NAME_INDEX.put("healing_lingering", "§rLingering Potion of Healing");
|
||||
POTION_NAME_INDEX.put("strong_healing_lingering", "§rLingering Potion of Healing");
|
||||
POTION_NAME_INDEX.put("harming_lingering", "§rLingering Potion of Harming");
|
||||
POTION_NAME_INDEX.put("strong_harming_lingering", "§rLingering Potion of Harming");
|
||||
POTION_NAME_INDEX.put("poison_lingering", "§rLingering Potion of Poisen");
|
||||
POTION_NAME_INDEX.put("long_poison_lingering", "§rLingering Potion of Poisen");
|
||||
POTION_NAME_INDEX.put("strong_poison_lingering", "§rLingering Potion of Poisen");
|
||||
POTION_NAME_INDEX.put("regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||
POTION_NAME_INDEX.put("long_regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||
POTION_NAME_INDEX.put("strong_regeneration_lingering", "§rLingering Potion of Regeneration");
|
||||
POTION_NAME_INDEX.put("strength_lingering", "§rLingering Potion of Strength");
|
||||
POTION_NAME_INDEX.put("long_strength_lingering", "§rLingering Potion of Strength");
|
||||
POTION_NAME_INDEX.put("strong_strength_lingering", "§rLingering Potion of Strength");
|
||||
POTION_NAME_INDEX.put("weakness_lingering", "§rLingering Potion of Weakness");
|
||||
POTION_NAME_INDEX.put("long_weakness_lingering", "§rLingering Potion of Weakness");
|
||||
POTION_NAME_INDEX.put("luck_lingering", "§rLingering Potion of Luck");
|
||||
POTION_NAME_INDEX.put("luck", "§rPotion of Luck");
|
||||
POTION_NAME_INDEX.put("luck_splash", "§rSplash Potion of Luck");
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_9to1_8.data;
|
||||
|
||||
import com.viaversion.viarewind.api.data.RewindMappingDataLoader;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.ObjectArrayList;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.ObjectList;
|
||||
import com.viaversion.viaversion.libs.gson.JsonArray;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
|
||||
public final class RewindMappingData1_8 extends com.viaversion.viarewind.api.data.RewindMappingData {
|
||||
|
||||
private final ObjectList<String> sounds = new ObjectArrayList<>();
|
||||
|
||||
public RewindMappingData1_8() {
|
||||
super("1.9.4", "1.8");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadExtras(CompoundTag data) {
|
||||
super.loadExtras(data);
|
||||
|
||||
final JsonArray sounds = RewindMappingDataLoader.INSTANCE.loadData("sounds-1.9.json").getAsJsonArray("sounds");
|
||||
for (final JsonElement sound : sounds) {
|
||||
this.sounds.add(sound.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
public String soundName(final int soundId) {
|
||||
return sounds.get(soundId);
|
||||
}
|
||||
}
|
||||
+184
-183
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -28,225 +28,226 @@ import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_8;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WitherBossBar implements BossBar {
|
||||
|
||||
private static int highestId = Integer.MAX_VALUE - 10000;
|
||||
private static int highestId = Integer.MAX_VALUE - 10000;
|
||||
|
||||
private final UUID uuid;
|
||||
private String title;
|
||||
private float health;
|
||||
private boolean visible = false;
|
||||
private final UUID uuid;
|
||||
private final UserConnection connection;
|
||||
private final int entityId = highestId++;
|
||||
private String title;
|
||||
private float health;
|
||||
private boolean visible = false;
|
||||
private double locX, locY, locZ;
|
||||
|
||||
private final UserConnection connection;
|
||||
public WitherBossBar(UserConnection connection, UUID uuid, String title, float health) {
|
||||
this.connection = connection;
|
||||
this.uuid = uuid;
|
||||
this.title = title;
|
||||
this.health = health;
|
||||
}
|
||||
|
||||
private final int entityId = highestId++;
|
||||
private double locX, locY, locZ;
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public WitherBossBar(UserConnection connection, UUID uuid, String title, float health) {
|
||||
this.connection = connection;
|
||||
this.uuid = uuid;
|
||||
this.title = title;
|
||||
this.health = health;
|
||||
}
|
||||
@Override
|
||||
public BossBar setTitle(String title) {
|
||||
this.title = title;
|
||||
if (this.visible) {
|
||||
updateEntityData();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
@Override
|
||||
public float getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar setTitle(String title) {
|
||||
this.title = title;
|
||||
if (this.visible) {
|
||||
updateEntityData();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public BossBar setHealth(float health) {
|
||||
this.health = health;
|
||||
if (this.health <= 0) {
|
||||
this.health = 0.0001f;
|
||||
}
|
||||
if (this.visible) {
|
||||
updateEntityData();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getHealth() {
|
||||
return health;
|
||||
}
|
||||
@Override
|
||||
public BossColor getColor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar setHealth(float health) {
|
||||
this.health = health;
|
||||
if (this.health <= 0) {
|
||||
this.health = 0.0001f;
|
||||
}
|
||||
if (this.visible) {
|
||||
updateEntityData();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public BossBar setColor(BossColor bossColor) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support color");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossColor getColor() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public BossStyle getStyle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar setColor(BossColor bossColor) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support color");
|
||||
}
|
||||
@Override
|
||||
public BossBar setStyle(BossStyle bossStyle) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support styles");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossStyle getStyle() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public BossBar addPlayer(UUID uuid) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar setStyle(BossStyle bossStyle) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support styles");
|
||||
}
|
||||
@Override
|
||||
public BossBar addConnection(UserConnection userConnection) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar addPlayer(UUID uuid) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
@Override
|
||||
public BossBar removePlayer(UUID uuid) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar addConnection(UserConnection userConnection) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
@Override
|
||||
public BossBar removeConnection(UserConnection userConnection) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar removePlayer(UUID uuid) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
@Override
|
||||
public BossBar addFlag(BossFlag bossFlag) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support flags");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar removeConnection(UserConnection userConnection) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
@Override
|
||||
public BossBar removeFlag(BossFlag bossFlag) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support flags");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar addFlag(BossFlag bossFlag) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support flags");
|
||||
}
|
||||
@Override
|
||||
public boolean hasFlag(BossFlag bossFlag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar removeFlag(BossFlag bossFlag) {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " does not support flags");
|
||||
}
|
||||
@Override
|
||||
public Set<UUID> getPlayers() {
|
||||
return Collections.singleton(connection.getProtocolInfo().getUuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFlag(BossFlag bossFlag) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public Set<UserConnection> getConnections() {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getPlayers() {
|
||||
return Collections.singleton(connection.getProtocolInfo().getUuid());
|
||||
}
|
||||
@Override
|
||||
public BossBar show() {
|
||||
if (!this.visible) {
|
||||
addWither();
|
||||
this.visible = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UserConnection> getConnections() {
|
||||
throw new UnsupportedOperationException(this.getClass().getName() + " is only for one UserConnection!");
|
||||
}
|
||||
@Override
|
||||
public BossBar hide() {
|
||||
if (this.visible) {
|
||||
removeWither();
|
||||
this.visible = false;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar show() {
|
||||
if (!this.visible) {
|
||||
addWither();
|
||||
this.visible = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar hide() {
|
||||
if (this.visible) {
|
||||
removeWither();
|
||||
this.visible = false;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public UUID getId() {
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
public void setLocation(double x, double y, double z) {
|
||||
locX = x;
|
||||
locY = y;
|
||||
locZ = z;
|
||||
updateLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getId() {
|
||||
return this.uuid;
|
||||
}
|
||||
private void addWither() {
|
||||
final PacketWrapper addMob = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_MOB, this.connection);
|
||||
addMob.write(Types.VAR_INT, entityId);
|
||||
addMob.write(Types.UNSIGNED_BYTE, (short) 64);
|
||||
addMob.write(Types.INT, (int) (locX * 32D));
|
||||
addMob.write(Types.INT, (int) (locY * 32D));
|
||||
addMob.write(Types.INT, (int) (locZ * 32D));
|
||||
addMob.write(Types.BYTE, (byte) 0);
|
||||
addMob.write(Types.BYTE, (byte) 0);
|
||||
addMob.write(Types.BYTE, (byte) 0);
|
||||
addMob.write(Types.SHORT, (short) 0);
|
||||
addMob.write(Types.SHORT, (short) 0);
|
||||
addMob.write(Types.SHORT, (short) 0);
|
||||
|
||||
public void setLocation(double x, double y, double z) {
|
||||
locX = x;
|
||||
locY = y;
|
||||
locZ = z;
|
||||
updateLocation();
|
||||
}
|
||||
final List<EntityData> entityData = new ArrayList<>();
|
||||
entityData.add(new EntityData(0, EntityDataTypes1_8.BYTE, (byte) 0x20));
|
||||
entityData.add(new EntityData(2, EntityDataTypes1_8.STRING, title));
|
||||
entityData.add(new EntityData(3, EntityDataTypes1_8.BYTE, (byte) 1));
|
||||
entityData.add(new EntityData(6, EntityDataTypes1_8.FLOAT, health * 300f));
|
||||
entityData.add(new EntityData(20, EntityDataTypes1_8.INT, 880));
|
||||
|
||||
private void addWither() {
|
||||
final PacketWrapper addMob = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_MOB, this.connection);
|
||||
addMob.write(Types.VAR_INT, entityId);
|
||||
addMob.write(Types.UNSIGNED_BYTE, (short) 64);
|
||||
addMob.write(Types.INT, (int) (locX * 32D));
|
||||
addMob.write(Types.INT, (int) (locY * 32D));
|
||||
addMob.write(Types.INT, (int) (locZ * 32D));
|
||||
addMob.write(Types.BYTE, (byte) 0);
|
||||
addMob.write(Types.BYTE, (byte) 0);
|
||||
addMob.write(Types.BYTE, (byte) 0);
|
||||
addMob.write(Types.SHORT, (short) 0);
|
||||
addMob.write(Types.SHORT, (short) 0);
|
||||
addMob.write(Types.SHORT, (short) 0);
|
||||
addMob.write(Types.ENTITY_DATA_LIST1_8, entityData);
|
||||
addMob.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
final List<EntityData> entityData = new ArrayList<>();
|
||||
entityData.add(new EntityData(0, EntityDataTypes1_8.BYTE, (byte) 0x20));
|
||||
entityData.add(new EntityData(2, EntityDataTypes1_8.STRING, title));
|
||||
entityData.add(new EntityData(3, EntityDataTypes1_8.BYTE, (byte) 1));
|
||||
entityData.add(new EntityData(6, EntityDataTypes1_8.FLOAT, health * 300f));
|
||||
private void updateLocation() {
|
||||
final PacketWrapper teleportEntity = PacketWrapper.create(ClientboundPackets1_7_2_5.TELEPORT_ENTITY, this.connection);
|
||||
teleportEntity.write(Types.VAR_INT, entityId);
|
||||
teleportEntity.write(Types.INT, (int) (locX * 32D));
|
||||
teleportEntity.write(Types.INT, (int) (locY * 32D));
|
||||
teleportEntity.write(Types.INT, (int) (locZ * 32D));
|
||||
teleportEntity.write(Types.BYTE, (byte) 0);
|
||||
teleportEntity.write(Types.BYTE, (byte) 0);
|
||||
teleportEntity.write(Types.BOOLEAN, false);
|
||||
teleportEntity.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
addMob.write(Types1_8.ENTITY_DATA_LIST, entityData);
|
||||
addMob.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
private void updateEntityData() {
|
||||
final PacketWrapper setEntityData = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_DATA, this.connection);
|
||||
setEntityData.write(Types.VAR_INT, entityId);
|
||||
|
||||
private void updateLocation() {
|
||||
final PacketWrapper teleportEntity = PacketWrapper.create(ClientboundPackets1_7_2_5.TELEPORT_ENTITY, this.connection);
|
||||
teleportEntity.write(Types.VAR_INT, entityId);
|
||||
teleportEntity.write(Types.INT, (int) (locX * 32D));
|
||||
teleportEntity.write(Types.INT, (int) (locY * 32D));
|
||||
teleportEntity.write(Types.INT, (int) (locZ * 32D));
|
||||
teleportEntity.write(Types.BYTE, (byte) 0);
|
||||
teleportEntity.write(Types.BYTE, (byte) 0);
|
||||
teleportEntity.write(Types.BOOLEAN, false);
|
||||
teleportEntity.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
final List<EntityData> entityData = new ArrayList<>();
|
||||
entityData.add(new EntityData(2, EntityDataTypes1_8.STRING, title));
|
||||
entityData.add(new EntityData(6, EntityDataTypes1_8.FLOAT, health * 300f));
|
||||
|
||||
private void updateEntityData() {
|
||||
final PacketWrapper setEntityData = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_DATA, this.connection);
|
||||
setEntityData.write(Types.VAR_INT, entityId);
|
||||
setEntityData.write(Types.ENTITY_DATA_LIST1_8, entityData);
|
||||
setEntityData.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
final List<EntityData> entityData = new ArrayList<>();
|
||||
entityData.add(new EntityData(2, EntityDataTypes1_8.STRING, title));
|
||||
entityData.add(new EntityData(6, EntityDataTypes1_8.FLOAT, health * 300f));
|
||||
private void removeWither() {
|
||||
final PacketWrapper removeEntity = PacketWrapper.create(ClientboundPackets1_7_2_5.REMOVE_ENTITIES, this.connection);
|
||||
removeEntity.write(Types.VAR_INT_ARRAY_PRIMITIVE, new int[]{entityId});
|
||||
removeEntity.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
setEntityData.write(Types1_8.ENTITY_DATA_LIST, entityData);
|
||||
setEntityData.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
public void setPlayerLocation(double posX, double posY, double posZ, float yaw, float pitch) {
|
||||
double yawR = Math.toRadians(yaw);
|
||||
double pitchR = Math.toRadians(pitch);
|
||||
|
||||
private void removeWither() {
|
||||
final PacketWrapper removeEntity = PacketWrapper.create(ClientboundPackets1_7_2_5.REMOVE_ENTITIES, this.connection);
|
||||
removeEntity.write(Types.VAR_INT_ARRAY_PRIMITIVE, new int[]{entityId});
|
||||
removeEntity.scheduleSend(Protocol1_9To1_8.class);
|
||||
}
|
||||
posX -= Math.cos(pitchR) * Math.sin(yawR) * 48;
|
||||
posY -= Math.sin(pitchR) * 48;
|
||||
posZ += Math.cos(pitchR) * Math.cos(yawR) * 48;
|
||||
|
||||
public void setPlayerLocation(double posX, double posY, double posZ, float yaw, float pitch) {
|
||||
double yawR = Math.toRadians(yaw);
|
||||
double pitchR = Math.toRadians(pitch);
|
||||
|
||||
posX -= Math.cos(pitchR) * Math.sin(yawR) * 48;
|
||||
posY -= Math.sin(pitchR) * 48;
|
||||
posZ += Math.cos(pitchR) * Math.cos(yawR) * 48;
|
||||
|
||||
setLocation(posX, posY, posZ);
|
||||
}
|
||||
setLocation(posX, posY, posZ);
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_9to1_8.provider;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.platform.providers.Provider;
|
||||
|
||||
public class InventoryProvider implements Provider {
|
||||
|
||||
public boolean hasElytra(final UserConnection connection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
+264
-255
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,6 +17,11 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_9to1_8.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.api.rewriters.LegacyEnchantmentRewriter;
|
||||
import com.viaversion.viarewind.api.rewriter.VRBlockItemRewriter;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
|
||||
@@ -26,309 +31,313 @@ import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.nbt.tag.*;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.data.EntityIds1_8;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.data.PotionIdMappings1_9;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_8;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockItemPacketRewriter1_9 extends VRBlockItemRewriter<ClientboundPackets1_9, ServerboundPackets1_8, Protocol1_9To1_8> {
|
||||
|
||||
public final Set<String> VALID_ATTRIBUTES = new HashSet<>();
|
||||
public final Set<String> VALID_ATTRIBUTES = new HashSet<>();
|
||||
|
||||
private LegacyEnchantmentRewriter enchantmentRewriter;
|
||||
private LegacyEnchantmentRewriter enchantmentRewriter;
|
||||
|
||||
public BlockItemPacketRewriter1_9(Protocol1_9To1_8 protocol) {
|
||||
super(protocol, "1.9");
|
||||
public BlockItemPacketRewriter1_9(Protocol1_9To1_8 protocol) {
|
||||
super(protocol, "1.9");
|
||||
|
||||
VALID_ATTRIBUTES.add("generic.maxHealth");
|
||||
VALID_ATTRIBUTES.add("generic.followRange");
|
||||
VALID_ATTRIBUTES.add("generic.knockbackResistance");
|
||||
VALID_ATTRIBUTES.add("generic.movementSpeed");
|
||||
VALID_ATTRIBUTES.add("generic.attackDamage");
|
||||
VALID_ATTRIBUTES.add("horse.jumpStrength");
|
||||
VALID_ATTRIBUTES.add("zombie.spawnReinforcements");
|
||||
}
|
||||
VALID_ATTRIBUTES.add("generic.maxHealth");
|
||||
VALID_ATTRIBUTES.add("generic.followRange");
|
||||
VALID_ATTRIBUTES.add("generic.knockbackResistance");
|
||||
VALID_ATTRIBUTES.add("generic.movementSpeed");
|
||||
VALID_ATTRIBUTES.add("generic.attackDamage");
|
||||
VALID_ATTRIBUTES.add("horse.jumpStrength");
|
||||
VALID_ATTRIBUTES.add("zombie.spawnReinforcements");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
registerBlockChange(ClientboundPackets1_9.BLOCK_UPDATE);
|
||||
registerMultiBlockChange(ClientboundPackets1_9.CHUNK_BLOCKS_UPDATE);
|
||||
registerSetCreativeModeSlot(ServerboundPackets1_8.SET_CREATIVE_MODE_SLOT);
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
registerBlockChange(ClientboundPackets1_9.BLOCK_UPDATE);
|
||||
registerMultiBlockChange(ClientboundPackets1_9.CHUNK_BLOCKS_UPDATE);
|
||||
registerSetCreativeModeSlot(ServerboundPackets1_8.SET_CREATIVE_MODE_SLOT);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_CLOSE, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_CLOSE, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
|
||||
final WindowTracker tracker = wrapper.user().get(WindowTracker.class);
|
||||
final WindowTracker tracker = wrapper.user().get(WindowTracker.class);
|
||||
|
||||
final String windowType = tracker.get(windowId);
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:enchanting_table")) {
|
||||
tracker.clearEnchantmentProperties();
|
||||
}
|
||||
tracker.remove(windowId);
|
||||
});
|
||||
final String windowType = tracker.get(windowId);
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:enchanting_table")) {
|
||||
tracker.clearEnchantmentProperties();
|
||||
}
|
||||
tracker.remove(windowId);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.OPEN_SCREEN, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
final String windowType = wrapper.passthrough(Types.STRING);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.OPEN_SCREEN, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
final String windowType = wrapper.passthrough(Types.STRING);
|
||||
|
||||
wrapper.user().get(WindowTracker.class).put(windowId, windowType);
|
||||
});
|
||||
wrapper.user().get(WindowTracker.class).put(windowId, windowType);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_CONTENT, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_CONTENT, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
|
||||
Item[] items = wrapper.read(Types.ITEM1_8_SHORT_ARRAY);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
Item[] items = wrapper.read(Types.ITEM1_8_SHORT_ARRAY);
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
items[i] = handleItemToClient(wrapper.user(), items[i]);
|
||||
}
|
||||
|
||||
if (windowId == 0 && items.length == 46) {
|
||||
Item[] old = items;
|
||||
items = new Item[45];
|
||||
System.arraycopy(old, 0, items, 0, 45);
|
||||
} else {
|
||||
final String type = wrapper.user().get(WindowTracker.class).get(windowId);
|
||||
if (type != null && type.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||
System.arraycopy(items, 0, wrapper.user().get(WindowTracker.class).getBrewingItems(windowId), 0, 4);
|
||||
WindowTracker.updateBrewingStand(wrapper.user(), items[4], windowId);
|
||||
Item[] old = items;
|
||||
items = new Item[old.length - 1];
|
||||
System.arraycopy(old, 0, items, 0, 4);
|
||||
System.arraycopy(old, 5, items, 4, old.length - 5);
|
||||
}
|
||||
}
|
||||
if (windowId == 0 && items.length == 46) {
|
||||
Item[] old = items;
|
||||
items = new Item[45];
|
||||
System.arraycopy(old, 0, items, 0, 45);
|
||||
} else {
|
||||
final String type = wrapper.user().get(WindowTracker.class).get(windowId);
|
||||
if (type != null && type.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||
System.arraycopy(items, 0, wrapper.user().get(WindowTracker.class).getBrewingItems(windowId), 0, 4);
|
||||
WindowTracker.updateBrewingStand(wrapper.user(), items[4], windowId);
|
||||
Item[] old = items;
|
||||
items = new Item[old.length - 1];
|
||||
System.arraycopy(old, 0, items, 0, 4);
|
||||
System.arraycopy(old, 5, items, 4, old.length - 5);
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.write(Types.ITEM1_8_SHORT_ARRAY, items);
|
||||
});
|
||||
wrapper.write(Types.ITEM1_8_SHORT_ARRAY, items);
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_SLOT, wrapper -> {
|
||||
final byte windowId = wrapper.passthrough(Types.UNSIGNED_BYTE).byteValue();
|
||||
final short slot = wrapper.passthrough(Types.SHORT);
|
||||
final Item item = wrapper.passthrough(Types.ITEM1_8);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_SLOT, wrapper -> {
|
||||
final byte windowId = wrapper.passthrough(Types.BYTE);
|
||||
final short slot = wrapper.passthrough(Types.SHORT);
|
||||
final Item item = wrapper.passthrough(Types.ITEM1_8);
|
||||
|
||||
handleItemToClient(wrapper.user(), item);
|
||||
if (windowId == 0 && slot == 45) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
final WindowTracker windowTracker = wrapper.user().get(WindowTracker.class);
|
||||
final String windowType = windowTracker.get(windowId);
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||
if (slot > 4) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot - 1));
|
||||
} else if (slot == 4) {
|
||||
wrapper.cancel();
|
||||
WindowTracker.updateBrewingStand(wrapper.user(), wrapper.get(Types.ITEM1_8, 0), windowId);
|
||||
} else {
|
||||
windowTracker.getBrewingItems(windowId)[slot] = wrapper.get(Types.ITEM1_8, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
handleItemToClient(wrapper.user(), item);
|
||||
if (windowId == 0 && slot == 45) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
final WindowTracker windowTracker = wrapper.user().get(WindowTracker.class);
|
||||
final String windowType = windowTracker.get(windowId);
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||
if (slot > 4) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot - 1));
|
||||
} else if (slot == 4) {
|
||||
wrapper.cancel();
|
||||
WindowTracker.updateBrewingStand(wrapper.user(), wrapper.get(Types.ITEM1_8, 0), windowId);
|
||||
} else {
|
||||
windowTracker.getBrewingItems(windowId)[slot] = wrapper.get(Types.ITEM1_8, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CONTAINER_CLOSE, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
wrapper.user().get(WindowTracker.class).remove(windowId);
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CONTAINER_CLOSE, wrapper -> {
|
||||
final byte windowId = wrapper.passthrough(Types.BYTE);
|
||||
wrapper.user().get(WindowTracker.class).remove(windowId);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CONTAINER_CLICK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.UNSIGNED_BYTE); // Window id
|
||||
map(Types.SHORT); // Slot
|
||||
map(Types.BYTE); // Button
|
||||
map(Types.SHORT); // Action number
|
||||
map(Types.BYTE, Types.VAR_INT); // Mode
|
||||
map(Types.ITEM1_8); // Clicked item
|
||||
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
|
||||
handler(wrapper -> {
|
||||
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
final String windowType = wrapper.user().get(WindowTracker.class).get(windowId);
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CONTAINER_CLICK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BYTE); // Window id
|
||||
map(Types.SHORT); // Slot
|
||||
map(Types.BYTE); // Button
|
||||
map(Types.SHORT); // Action number
|
||||
map(Types.BYTE, Types.VAR_INT); // Mode
|
||||
map(Types.ITEM1_8); // Clicked item
|
||||
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
|
||||
handler(wrapper -> {
|
||||
final byte windowId = wrapper.get(Types.BYTE, 0);
|
||||
final String windowType = wrapper.user().get(WindowTracker.class).get(windowId);
|
||||
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
if (slot > 3) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot + 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:brewing_stand")) {
|
||||
final short slot = wrapper.get(Types.SHORT, 0);
|
||||
if (slot > 3) {
|
||||
wrapper.set(Types.SHORT, 0, (short) (slot + 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_DATA, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
short key = wrapper.read(Types.SHORT);
|
||||
short value = wrapper.read(Types.SHORT);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_DATA, wrapper -> {
|
||||
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
|
||||
short key = wrapper.read(Types.SHORT);
|
||||
short value = wrapper.read(Types.SHORT);
|
||||
|
||||
final WindowTracker tracker = wrapper.user().get(WindowTracker.class);
|
||||
final String windowType = tracker.get(windowId);
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:enchanting_table")) {
|
||||
if (key >= 4 && key <= 6) { // Store enchantment ids
|
||||
tracker.putEnchantmentProperty(key, value);
|
||||
wrapper.cancel();
|
||||
} else if (key >= 7 && key <= 9) { // Mix levels with tracked ids
|
||||
key -= 3;
|
||||
final short property = tracker.getEnchantmentValue(key);
|
||||
value = (short) (property | (value << 8));
|
||||
}
|
||||
}
|
||||
wrapper.write(Types.SHORT, key);
|
||||
wrapper.write(Types.SHORT, value);
|
||||
});
|
||||
}
|
||||
final WindowTracker tracker = wrapper.user().get(WindowTracker.class);
|
||||
final String windowType = tracker.get(windowId);
|
||||
if (windowType != null && windowType.equalsIgnoreCase("minecraft:enchanting_table")) {
|
||||
if (key >= 4 && key <= 6) { // Store enchantment ids
|
||||
tracker.putEnchantmentProperty(key, value);
|
||||
wrapper.cancel();
|
||||
} else if (key >= 7 && key <= 9) { // Mix levels with tracked ids
|
||||
key -= 3;
|
||||
final short property = tracker.getEnchantmentValue(key);
|
||||
value = (short) (property | (value << 8));
|
||||
}
|
||||
}
|
||||
wrapper.write(Types.SHORT, key);
|
||||
wrapper.write(Types.SHORT, value);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName());
|
||||
enchantmentRewriter.registerEnchantment(9, "§7Frost Walker");
|
||||
enchantmentRewriter.registerEnchantment(70, "§7Mending");
|
||||
}
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName());
|
||||
enchantmentRewriter.registerEnchantment(9, "§7Frost Walker");
|
||||
enchantmentRewriter.registerEnchantment(70, "§7Mending");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item handleItemToClient(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToClient(connection, item);
|
||||
@Override
|
||||
public Item handleItemToClient(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToClient(connection, item);
|
||||
|
||||
CompoundTag tag = item.tag();
|
||||
if (tag == null) {
|
||||
item.setTag(tag = new CompoundTag());
|
||||
}
|
||||
CompoundTag tag = item.tag();
|
||||
enchantmentRewriter.handleToClient(item);
|
||||
|
||||
enchantmentRewriter.handleToClient(item);
|
||||
CompoundTag displayTag = tag == null ? null : tag.getCompoundTag("display");
|
||||
if (item.data() != 0) {
|
||||
final ByteTag unbreakableTag = tag == null ? null : tag.getByteTag("Unbreakable");
|
||||
if (unbreakableTag != null && unbreakableTag.asByte() != 0) {
|
||||
tag.put(nbtTagName() + "|Unbreakable", new ByteTag(unbreakableTag.asByte()));
|
||||
tag.remove("Unbreakable");
|
||||
|
||||
CompoundTag displayTag = tag.getCompoundTag("display");
|
||||
if (item.data() != 0 && tag.contains("Unbreakable")) {
|
||||
final ByteTag unbreakableTag = tag.getByteTag("Unbreakable");
|
||||
if (unbreakableTag != null && unbreakableTag.asByte() != 0) {
|
||||
tag.put(nbtTagName() + "|Unbreakable", new ByteTag(unbreakableTag.asByte()));
|
||||
tag.remove("Unbreakable");
|
||||
if (displayTag == null) { // Remove the display tag again if it was only added to emulate unbreakable
|
||||
tag.put("display", displayTag = new CompoundTag());
|
||||
tag.put(nbtTagName() + "|noDisplay", new ByteTag(true));
|
||||
}
|
||||
|
||||
if (displayTag == null) { // Remove the display tag again if it was only added to emulate unbreakable
|
||||
tag.put("display", displayTag = new CompoundTag());
|
||||
tag.put(nbtTagName() + "|noDisplay", new ByteTag(true));
|
||||
}
|
||||
ListTag<StringTag> loreTag = displayTag.getListTag("Lore", StringTag.class);
|
||||
if (loreTag == null) {
|
||||
displayTag.put("Lore", loreTag = new ListTag<>(StringTag.class));
|
||||
}
|
||||
loreTag.add(new StringTag("§9Unbreakable"));
|
||||
}
|
||||
}
|
||||
|
||||
ListTag<StringTag> loreTag = displayTag.getListTag("Lore", StringTag.class);
|
||||
if (loreTag == null) {
|
||||
displayTag.put("Lore", loreTag = new ListTag<>(StringTag.class));
|
||||
}
|
||||
loreTag.add(new StringTag("§9Unbreakable"));
|
||||
}
|
||||
}
|
||||
if (item.identifier() == 383 && item.data() == 0) { // Spawn eggs
|
||||
int data = 0;
|
||||
final CompoundTag entityTag = tag == null ? null : tag.getCompoundTag("EntityTag");
|
||||
if (entityTag != null) {
|
||||
final StringTag idTag = entityTag.getStringTag("id");
|
||||
if (idTag != null) {
|
||||
final String id = idTag.getValue();
|
||||
if (EntityIds1_8.ENTITY_NAME_TO_ID.containsKey(id)) {
|
||||
data = EntityIds1_8.ENTITY_NAME_TO_ID.get(id);
|
||||
} else if (displayTag == null) {
|
||||
tag.put("display", displayTag = new CompoundTag());
|
||||
tag.put(nbtTagName() + "|noDisplay", new ByteTag(true));
|
||||
displayTag.put("Name", new StringTag("§rSpawn " + id));
|
||||
}
|
||||
}
|
||||
}
|
||||
item.setData((short) data);
|
||||
}
|
||||
|
||||
if (item.identifier() == 383 && item.data() == 0) { // Spawn eggs
|
||||
int data = 0;
|
||||
final CompoundTag entityTag = tag.getCompoundTag("EntityTag");
|
||||
if (entityTag != null) {
|
||||
final StringTag idTag = entityTag.getStringTag("id");
|
||||
if (idTag != null) {
|
||||
final String id = idTag.getValue();
|
||||
if (EntityIds1_8.ENTITY_NAME_TO_ID.containsKey(id)) {
|
||||
data = EntityIds1_8.ENTITY_NAME_TO_ID.get(id);
|
||||
} else if (displayTag == null) {
|
||||
tag.put("display", displayTag = new CompoundTag());
|
||||
tag.put(nbtTagName() + "|noDisplay", new ByteTag(true));
|
||||
displayTag.put("Name", new StringTag("§rSpawn " + id));
|
||||
}
|
||||
}
|
||||
}
|
||||
item.setData((short) data);
|
||||
}
|
||||
// Potion, splash potion, lingering potion
|
||||
final boolean potion = item.identifier() == 373;
|
||||
final boolean splashPotion = item.identifier() == 438;
|
||||
final boolean lingeringPotion = item.identifier() == 441;
|
||||
|
||||
// Potion, splash potion, lingering potion
|
||||
final boolean potion = item.identifier() == 373;
|
||||
final boolean splashPotion = item.identifier() == 438;
|
||||
final boolean lingeringPotion = item.identifier() == 441;
|
||||
if (potion || splashPotion || lingeringPotion) {
|
||||
int data = 0;
|
||||
final StringTag potionTag = tag == null ? null : tag.getStringTag("Potion");
|
||||
if (potionTag != null) {
|
||||
String potionName = Key.stripMinecraftNamespace(potionTag.getValue());
|
||||
if (PotionIdMappings1_8.POTION_NAME_TO_ID.containsKey(potionName)) {
|
||||
data = PotionIdMappings1_8.POTION_NAME_TO_ID.get(potionName);
|
||||
}
|
||||
if (splashPotion) {
|
||||
potionName += "_splash";
|
||||
} else if (lingeringPotion) {
|
||||
potionName += "_lingering";
|
||||
}
|
||||
// Don't override custom name
|
||||
if ((displayTag == null || !displayTag.contains("Name")) && PotionIdMappings1_8.POTION_NAME_INDEX.containsKey(potionName)) {
|
||||
tag.put("display", displayTag = new CompoundTag());
|
||||
tag.put(nbtTagName() + "|noDisplay", new ByteTag(true));
|
||||
displayTag.put("Name", new StringTag(PotionIdMappings1_8.POTION_NAME_INDEX.get(potionName)));
|
||||
}
|
||||
}
|
||||
if (splashPotion || lingeringPotion) { // Convert splash and lingering potions to normal potions
|
||||
item.setIdentifier(373);
|
||||
data += 8192;
|
||||
}
|
||||
|
||||
if (potion || splashPotion || lingeringPotion) {
|
||||
int data = 0;
|
||||
final StringTag potionTag = tag.getStringTag("Potion");
|
||||
if (potionTag != null) {
|
||||
String potionName = Key.stripMinecraftNamespace(potionTag.getValue());
|
||||
if (PotionIdMappings1_8.POTION_NAME_TO_ID.containsKey(potionName)) {
|
||||
data = PotionIdMappings1_8.POTION_NAME_TO_ID.get(potionName);
|
||||
}
|
||||
if (splashPotion) {
|
||||
potionName += "_splash";
|
||||
} else if (lingeringPotion) {
|
||||
potionName += "_lingering";
|
||||
}
|
||||
// Don't override custom name
|
||||
if ((displayTag == null || !displayTag.contains("Name")) && PotionIdMappings1_8.POTION_NAME_INDEX.containsKey(potionName)) {
|
||||
tag.put("display", displayTag = new CompoundTag());
|
||||
tag.put(nbtTagName() + "|noDisplay", new ByteTag(true));
|
||||
displayTag.put("Name", new StringTag(PotionIdMappings1_8.POTION_NAME_INDEX.get(potionName)));
|
||||
}
|
||||
}
|
||||
if (splashPotion || lingeringPotion) { // Convert splash and lingering potions to normal potions
|
||||
item.setIdentifier(373);
|
||||
data += 8192;
|
||||
}
|
||||
item.setData((short) data);
|
||||
}
|
||||
|
||||
item.setData((short) data);
|
||||
}
|
||||
final ListTag<CompoundTag> attributeModifiers = tag == null ? null : tag.getListTag("AttributeModifiers", CompoundTag.class);
|
||||
if (attributeModifiers != null) {
|
||||
tag.put(nbtTagName() + "|AttributeModifiers", attributeModifiers.copy());
|
||||
attributeModifiers.getValue().removeIf(entries -> {
|
||||
final StringTag nameTag = entries.getStringTag("AttributeName");
|
||||
return nameTag != null && !VALID_ATTRIBUTES.contains(nameTag.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> attributeModifiers = tag.getListTag("AttributeModifiers", CompoundTag.class);
|
||||
if (attributeModifiers != null) {
|
||||
tag.put(nbtTagName() + "|AttributeModifiers", attributeModifiers.copy());
|
||||
attributeModifiers.getValue().removeIf(entries -> {
|
||||
final StringTag nameTag = entries.getStringTag("AttributeName");
|
||||
return nameTag != null && !VALID_ATTRIBUTES.contains(nameTag.getValue());
|
||||
});
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
@Override
|
||||
public Item handleItemToServer(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToServer(connection, item);
|
||||
|
||||
@Override
|
||||
public Item handleItemToServer(UserConnection connection, Item item) {
|
||||
if (item == null) return null;
|
||||
super.handleItemToServer(connection, item);
|
||||
CompoundTag tag = item.tag();
|
||||
|
||||
CompoundTag tag = item.tag();
|
||||
if (tag == null) {
|
||||
item.setTag(tag = new CompoundTag());
|
||||
}
|
||||
enchantmentRewriter.handleToServer(item);
|
||||
|
||||
enchantmentRewriter.handleToServer(item);
|
||||
if (item.identifier() == 383 && item.data() != 0) { // Spawn eggs
|
||||
if ((tag == null || !tag.contains("EntityTag")) && EntityIds1_8.ENTITY_ID_TO_NAME.containsKey((int) item.data())) {
|
||||
if (tag == null) {
|
||||
item.setTag(tag = new CompoundTag());
|
||||
}
|
||||
final CompoundTag entityTag = new CompoundTag();
|
||||
entityTag.put("id", new StringTag(EntityIds1_8.ENTITY_ID_TO_NAME.get((int) item.data())));
|
||||
tag.put("EntityTag", entityTag);
|
||||
}
|
||||
item.setData((short) 0);
|
||||
}
|
||||
|
||||
if (item.identifier() == 383 && item.data() != 0) { // Spawn eggs
|
||||
if (!tag.contains("EntityTag") && EntityIds1_8.ENTITY_ID_TO_NAME.containsKey((int) item.data())) {
|
||||
final CompoundTag entityTag = new CompoundTag();
|
||||
entityTag.put("id", new StringTag(EntityIds1_8.ENTITY_ID_TO_NAME.get((int) item.data())));
|
||||
tag.put("EntityTag", entityTag);
|
||||
}
|
||||
item.setData((short) 0);
|
||||
}
|
||||
|
||||
if (item.identifier() == 373 && !tag.contains("Potion")) { // Potions
|
||||
if (item.identifier() == 373 && (tag == null || !tag.contains("Potion"))) { // Potions
|
||||
if (item.data() >= 16384) {
|
||||
item.setIdentifier(438);
|
||||
item.setData((short) (item.data() - 8192));
|
||||
}
|
||||
item.setIdentifier(438);
|
||||
item.setData((short) (item.data() - 8192));
|
||||
}
|
||||
|
||||
final String name = item.data() == 8192 ? "water" : PotionIdMappings1_9.potionNameFromDamage(item.data());
|
||||
tag.put("Potion", new StringTag("minecraft:" + name));
|
||||
item.setData((short) 0);
|
||||
}
|
||||
if (tag == null) {
|
||||
item.setTag(tag = new CompoundTag());
|
||||
|
||||
final Tag noDisplayTag = tag.remove(nbtTagName() + "|noDisplay");
|
||||
if (noDisplayTag != null) {
|
||||
tag.remove("display");
|
||||
}
|
||||
final Tag unbreakableTag = tag.remove(nbtTagName() + "|Unbreakable");
|
||||
if (unbreakableTag != null) {
|
||||
tag.put("Unbreakable", unbreakableTag);
|
||||
}
|
||||
final Tag attributeModifiersTag = tag.remove(nbtTagName() + "|AttributeModifiers");
|
||||
if (attributeModifiersTag != null) {
|
||||
tag.put("AttributeModifiers", attributeModifiersTag);
|
||||
}
|
||||
final String name = item.data() == 8192 ? "water" : PotionIdMappings1_9.potionNameFromDamage(item.data());
|
||||
tag.put("Potion", new StringTag("minecraft:" + name));
|
||||
}
|
||||
item.setData((short) 0);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
if (tag == null) {
|
||||
return item;
|
||||
}
|
||||
final Tag noDisplayTag = tag.remove(nbtTagName() + "|noDisplay");
|
||||
if (noDisplayTag != null) {
|
||||
tag.remove("display");
|
||||
if (tag.isEmpty()) {
|
||||
item.setTag(null);
|
||||
}
|
||||
}
|
||||
final Tag unbreakableTag = tag.remove(nbtTagName() + "|Unbreakable");
|
||||
if (unbreakableTag != null) {
|
||||
tag.put("Unbreakable", unbreakableTag);
|
||||
}
|
||||
final Tag attributeModifiersTag = tag.remove(nbtTagName() + "|AttributeModifiers");
|
||||
if (attributeModifiersTag != null) {
|
||||
tag.put("AttributeModifiers", attributeModifiersTag);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
+551
-519
File diff suppressed because it is too large.
Load diff
+458
-394
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,454 +17,518 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_9to1_8.rewriter;
|
||||
|
||||
import com.viaversion.viarewind.ViaRewind;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.*;
|
||||
import com.viaversion.viarewind.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_9;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_8;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viarewind.ViaRewind;
|
||||
import com.viaversion.viarewind.api.type.RewindTypes;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.provider.InventoryProvider;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.BlockPlaceDestroyTracker;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.BossBarStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.CooldownStorage;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.EntityTracker1_9;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.PlayerPositionTracker;
|
||||
import com.viaversion.viarewind.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.data.entity.EntityTracker;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_9;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.rewriter.RewriterBase;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.libs.gson.JsonParser;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_9;
|
||||
|
||||
import com.viaversion.viaversion.util.StringUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerPacketRewriter1_9 {
|
||||
public class PlayerPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
|
||||
|
||||
public static void register(final Protocol1_9To1_8 protocol) {
|
||||
protocol.registerClientbound(ClientboundPackets1_9.BOSS_EVENT, null, wrapper -> {
|
||||
wrapper.cancel();
|
||||
final BossBarStorage bossbar = wrapper.user().get(BossBarStorage.class);
|
||||
public PlayerPacketRewriter1_9(Protocol1_9To1_8 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
final UUID uuid = wrapper.read(Types.UUID);
|
||||
final int action = wrapper.read(Types.VAR_INT);
|
||||
if (action == 0 /* add */) {
|
||||
final JsonElement title = wrapper.read(Types.COMPONENT);
|
||||
final float health = wrapper.read(Types.FLOAT);
|
||||
wrapper.read(Types.VAR_INT); // Color
|
||||
wrapper.read(Types.VAR_INT); // Division
|
||||
wrapper.read(Types.UNSIGNED_BYTE); // Flags
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
protocol.registerClientbound(ClientboundPackets1_9.BOSS_EVENT, null, wrapper -> {
|
||||
wrapper.cancel();
|
||||
final BossBarStorage bossbar = wrapper.user().get(BossBarStorage.class);
|
||||
|
||||
bossbar.add(uuid, ChatUtil.jsonToLegacy(wrapper.user(), title), health);
|
||||
} else if (action == 1 /* remove */) {
|
||||
bossbar.remove(uuid);
|
||||
} else if (action == 2 /* update health */) {
|
||||
final float health = wrapper.read(Types.FLOAT);
|
||||
bossbar.updateHealth(uuid, health);
|
||||
} else if (action == 3 /* update title */) {
|
||||
final JsonElement title = wrapper.read(Types.COMPONENT);
|
||||
bossbar.updateTitle(uuid, ChatUtil.jsonToLegacy(wrapper.user(), title));
|
||||
}
|
||||
});
|
||||
final UUID uuid = wrapper.read(Types.UUID);
|
||||
final int action = wrapper.read(Types.VAR_INT);
|
||||
if (action == 0 /* add */) {
|
||||
final JsonElement title = wrapper.read(Types.COMPONENT);
|
||||
final float health = wrapper.read(Types.FLOAT);
|
||||
wrapper.read(Types.VAR_INT); // Color
|
||||
wrapper.read(Types.VAR_INT); // Division
|
||||
wrapper.read(Types.UNSIGNED_BYTE); // Flags
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.SET_PLAYER_TEAM, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Team name
|
||||
map(Types.BYTE); // Mode
|
||||
handler(wrapper -> {
|
||||
final byte mode = wrapper.get(Types.BYTE, 0);
|
||||
if (mode == 0 /* create team */ || mode == 2 /* update team info */) {
|
||||
wrapper.passthrough(Types.STRING); // Display name
|
||||
wrapper.passthrough(Types.STRING); // Prefix
|
||||
wrapper.passthrough(Types.STRING); // Suffix
|
||||
wrapper.passthrough(Types.BYTE); // Friendly fire
|
||||
wrapper.passthrough(Types.STRING); // Name tag visibility
|
||||
wrapper.read(Types.STRING); // Collision rule
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
bossbar.add(uuid, ChatUtil.jsonToLegacy(title), health);
|
||||
} else if (action == 1 /* remove */) {
|
||||
bossbar.remove(uuid);
|
||||
} else if (action == 2 /* update health */) {
|
||||
final float health = wrapper.read(Types.FLOAT);
|
||||
bossbar.updateHealth(uuid, health);
|
||||
} else if (action == 3 /* update title */) {
|
||||
final JsonElement title = wrapper.read(Types.COMPONENT);
|
||||
bossbar.updateTitle(uuid, ChatUtil.jsonToLegacy(title));
|
||||
}
|
||||
});
|
||||
|
||||
protocol.cancelClientbound(ClientboundPackets1_9.COOLDOWN);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.SET_PLAYER_TEAM, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Team name
|
||||
map(Types.BYTE); // Mode
|
||||
handler(wrapper -> {
|
||||
final byte mode = wrapper.get(Types.BYTE, 0);
|
||||
if (mode == 0 /* create team */ || mode == 2 /* update team info */) {
|
||||
wrapper.passthrough(Types.STRING); // Display name
|
||||
wrapper.passthrough(Types.STRING); // Prefix
|
||||
wrapper.passthrough(Types.STRING); // Suffix
|
||||
wrapper.passthrough(Types.BYTE); // Friendly fire
|
||||
wrapper.passthrough(Types.STRING); // Name tag visibility
|
||||
wrapper.read(Types.STRING); // Collision rule
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CUSTOM_PAYLOAD, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Channel
|
||||
handlerSoftFail(wrapper -> {
|
||||
final String channel = wrapper.get(Types.STRING, 0);
|
||||
if (channel.equals("MC|BOpen")) {
|
||||
wrapper.read(Types.VAR_INT);
|
||||
} else if (channel.equals("MC|TrList")) {
|
||||
protocol.getItemRewriter().handleTradeList(wrapper);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.cancelClientbound(ClientboundPackets1_9.COOLDOWN);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.PLAYER_POSITION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.DOUBLE); // X
|
||||
map(Types.DOUBLE); // Feet y
|
||||
map(Types.DOUBLE); // Z
|
||||
map(Types.FLOAT); // Yaw
|
||||
map(Types.FLOAT); // Pitch
|
||||
map(Types.BYTE); // Relative arguments
|
||||
handler(wrapper -> {
|
||||
final PlayerPositionTracker pos = wrapper.user().get(PlayerPositionTracker.class);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CUSTOM_PAYLOAD, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Channel
|
||||
handlerSoftFail(wrapper -> {
|
||||
final String channel = wrapper.get(Types.STRING, 0);
|
||||
if (channel.equals("MC|BOpen")) {
|
||||
wrapper.read(Types.VAR_INT);
|
||||
} else if (channel.equals("MC|TrList")) {
|
||||
protocol.getItemRewriter().handleTradeList(wrapper);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
pos.setConfirmId(wrapper.read(Types.VAR_INT));
|
||||
protocol.registerClientbound(ClientboundPackets1_9.PLAYER_POSITION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.DOUBLE); // X
|
||||
map(Types.DOUBLE); // Feet y
|
||||
map(Types.DOUBLE); // Z
|
||||
map(Types.FLOAT); // Yaw
|
||||
map(Types.FLOAT); // Pitch
|
||||
map(Types.BYTE); // Relative arguments
|
||||
handler(wrapper -> {
|
||||
final PlayerPositionTracker pos = wrapper.user().get(PlayerPositionTracker.class);
|
||||
|
||||
byte flags = wrapper.get(Types.BYTE, 0);
|
||||
double x = wrapper.get(Types.DOUBLE, 0);
|
||||
double y = wrapper.get(Types.DOUBLE, 1);
|
||||
double z = wrapper.get(Types.DOUBLE, 2);
|
||||
float yaw = wrapper.get(Types.FLOAT, 0);
|
||||
float pitch = wrapper.get(Types.FLOAT, 1);
|
||||
pos.setConfirmId(wrapper.read(Types.VAR_INT));
|
||||
|
||||
wrapper.set(Types.BYTE, 0, (byte) 0);
|
||||
byte flags = wrapper.get(Types.BYTE, 0);
|
||||
double x = wrapper.get(Types.DOUBLE, 0);
|
||||
double y = wrapper.get(Types.DOUBLE, 1);
|
||||
double z = wrapper.get(Types.DOUBLE, 2);
|
||||
float yaw = wrapper.get(Types.FLOAT, 0);
|
||||
float pitch = wrapper.get(Types.FLOAT, 1);
|
||||
|
||||
if (flags != 0) {
|
||||
if ((flags & 0x01) != 0) {
|
||||
x += pos.getPosX();
|
||||
wrapper.set(Types.DOUBLE, 0, x);
|
||||
}
|
||||
if ((flags & 0x02) != 0) {
|
||||
y += pos.getPosY();
|
||||
wrapper.set(Types.DOUBLE, 1, y);
|
||||
}
|
||||
if ((flags & 0x04) != 0) {
|
||||
z += pos.getPosZ();
|
||||
wrapper.set(Types.DOUBLE, 2, z);
|
||||
}
|
||||
if ((flags & 0x08) != 0) {
|
||||
yaw += pos.getYaw();
|
||||
wrapper.set(Types.FLOAT, 0, yaw);
|
||||
}
|
||||
if ((flags & 0x10) != 0) {
|
||||
pitch += pos.getPitch();
|
||||
wrapper.set(Types.FLOAT, 1, pitch);
|
||||
}
|
||||
}
|
||||
wrapper.set(Types.BYTE, 0, (byte) 0);
|
||||
|
||||
pos.setPos(x, y, z);
|
||||
pos.setYaw(yaw);
|
||||
pos.setPitch(pitch);
|
||||
});
|
||||
}
|
||||
});
|
||||
if (flags != 0) {
|
||||
if ((flags & 0x01) != 0) {
|
||||
x += pos.getPosX();
|
||||
wrapper.set(Types.DOUBLE, 0, x);
|
||||
}
|
||||
if ((flags & 0x02) != 0) {
|
||||
y += pos.getPosY();
|
||||
wrapper.set(Types.DOUBLE, 1, y);
|
||||
}
|
||||
if ((flags & 0x04) != 0) {
|
||||
z += pos.getPosZ();
|
||||
wrapper.set(Types.DOUBLE, 2, z);
|
||||
}
|
||||
if ((flags & 0x08) != 0) {
|
||||
yaw += pos.getYaw();
|
||||
wrapper.set(Types.FLOAT, 0, yaw);
|
||||
}
|
||||
if ((flags & 0x10) != 0) {
|
||||
pitch += pos.getPitch();
|
||||
wrapper.set(Types.FLOAT, 1, pitch);
|
||||
}
|
||||
}
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.RESPAWN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Dimension
|
||||
handler(wrapper -> wrapper.user().get(BossBarStorage.class).reset());
|
||||
handler(wrapper -> {
|
||||
final ClientWorld world = wrapper.user().get(ClientWorld.class);
|
||||
world.setEnvironment(wrapper.get(Types.INT, 0));
|
||||
});
|
||||
}
|
||||
});
|
||||
pos.setPos(x, y, z);
|
||||
pos.setYaw(yaw);
|
||||
pos.setPitch(pitch);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CHAT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Message
|
||||
handler(wrapper -> {
|
||||
if (!ViaRewind.getConfig().isEnableOffhand()) {
|
||||
return;
|
||||
}
|
||||
final String message = wrapper.get(Types.STRING, 0);
|
||||
if (message.toLowerCase().trim().startsWith(ViaRewind.getConfig().getOffhandCommand())) {
|
||||
wrapper.cancel();
|
||||
final PacketWrapper swapItems = PacketWrapper.create(ServerboundPackets1_9.PLAYER_ACTION, wrapper.user());
|
||||
swapItems.write(Types.VAR_INT, 6);
|
||||
swapItems.write(Types.BLOCK_POSITION1_8, new BlockPosition(0, 0, 0));
|
||||
swapItems.write(Types.UNSIGNED_BYTE, (short) 255);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.RESPAWN, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Dimension
|
||||
handler(wrapper -> {
|
||||
final ClientWorld world = wrapper.user().getClientWorld(Protocol1_9To1_8.class);
|
||||
final int dimension = wrapper.get(Types.INT, 0);
|
||||
|
||||
swapItems.sendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (world.setEnvironment(dimension)) {
|
||||
final EntityTracker tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
|
||||
tracker.clearEntities();
|
||||
wrapper.user().get(BossBarStorage.class).reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.INTERACT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Target
|
||||
map(Types.VAR_INT); // Type
|
||||
handler(wrapper -> {
|
||||
final int type = wrapper.get(Types.VAR_INT, 1);
|
||||
if (type == 2 /* attack */) {
|
||||
wrapper.passthrough(Types.FLOAT); // Target x
|
||||
wrapper.passthrough(Types.FLOAT); // Target y
|
||||
wrapper.passthrough(Types.FLOAT); // Target z
|
||||
}
|
||||
if (type == 2 /* attack */ || type == 0 /* interact */) {
|
||||
wrapper.write(Types.VAR_INT, 0); // Hand
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// Packet implementation doesn't do anything until 1.9
|
||||
protocol.registerClientbound(ClientboundPackets1_9.PLAYER_COMBAT, wrapper -> {
|
||||
if (!ViaRewind.getConfig().handlePlayerCombatPacket()) {
|
||||
return;
|
||||
}
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_STATUS_ONLY, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BOOLEAN); // On ground
|
||||
handler(wrapper -> {
|
||||
wrapper.user().get(PlayerPositionTracker.class).sendAnimations();
|
||||
final int action = wrapper.passthrough(Types.VAR_INT);
|
||||
if (action != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
|
||||
if (tracker.isInsideVehicle(tracker.clientEntityId())) {
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
final EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
|
||||
final int entityId = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.passthrough(Types.INT); // Killer id
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_POS, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.DOUBLE); // X
|
||||
map(Types.DOUBLE); // Feet y
|
||||
map(Types.DOUBLE); // Z
|
||||
map(Types.BOOLEAN); // On ground
|
||||
handler(wrapper -> {
|
||||
wrapper.user().get(PlayerPositionTracker.class).sendAnimations();
|
||||
if (entityId != tracker.clientEntityId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PlayerPositionTracker pos = wrapper.user().get(PlayerPositionTracker.class);
|
||||
if (pos.getConfirmId() != -1) {
|
||||
return;
|
||||
}
|
||||
pos.setPos(wrapper.get(Types.DOUBLE, 0), wrapper.get(Types.DOUBLE, 1), wrapper.get(Types.DOUBLE, 2));
|
||||
pos.setOnGround(wrapper.get(Types.BOOLEAN, 0));
|
||||
});
|
||||
handler(wrapper -> wrapper.user().get(BossBarStorage.class).updateLocation());
|
||||
}
|
||||
});
|
||||
final JsonElement message = wrapper.passthrough(Types.COMPONENT);
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_ROT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.FLOAT); // Yaw
|
||||
map(Types.FLOAT); // Pitch
|
||||
map(Types.BOOLEAN); // On ground
|
||||
handler(wrapper -> {
|
||||
wrapper.user().get(PlayerPositionTracker.class).sendAnimations();
|
||||
final PacketWrapper killPlayer = wrapper.create(ClientboundPackets1_8.SET_HEALTH);
|
||||
killPlayer.write(Types.FLOAT, 0F); // Health
|
||||
killPlayer.write(Types.VAR_INT, 0); // Food
|
||||
killPlayer.write(Types.FLOAT, 0F); // Food Saturation
|
||||
killPlayer.scheduleSend(Protocol1_9To1_8.class);
|
||||
|
||||
PlayerPositionTracker pos = wrapper.user().get(PlayerPositionTracker.class);
|
||||
if (pos.getConfirmId() != -1) return;
|
||||
pos.setYaw(wrapper.get(Types.FLOAT, 0));
|
||||
pos.setPitch(wrapper.get(Types.FLOAT, 1));
|
||||
pos.setOnGround(wrapper.get(Types.BOOLEAN, 0));
|
||||
});
|
||||
handler(wrapper -> wrapper.user().get(BossBarStorage.class).updateLocation());
|
||||
}
|
||||
});
|
||||
final PacketWrapper chatMessage = wrapper.create(ClientboundPackets1_8.CHAT);
|
||||
chatMessage.write(Types.COMPONENT, message);
|
||||
chatMessage.write(Types.BYTE, (byte) 2); // Position - above hotbar
|
||||
chatMessage.scheduleSend(Protocol1_9To1_8.class);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_POS_ROT, wrapper -> {
|
||||
final double x = wrapper.passthrough(Types.DOUBLE);
|
||||
final double y = wrapper.passthrough(Types.DOUBLE);
|
||||
final double z = wrapper.passthrough(Types.DOUBLE);
|
||||
final float yaw = wrapper.passthrough(Types.FLOAT);
|
||||
final float pitch = wrapper.passthrough(Types.FLOAT);
|
||||
final boolean onGround = wrapper.passthrough(Types.BOOLEAN);
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CHAT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Message
|
||||
handler(wrapper -> {
|
||||
if (!ViaRewind.getConfig().isEnableOffhand()) {
|
||||
return;
|
||||
}
|
||||
final String message = wrapper.get(Types.STRING, 0);
|
||||
if (message.toLowerCase().trim().startsWith(ViaRewind.getConfig().getOffhandCommand())) {
|
||||
wrapper.cancel();
|
||||
final PacketWrapper swapItems = PacketWrapper.create(ServerboundPackets1_9.PLAYER_ACTION, wrapper.user());
|
||||
swapItems.write(Types.VAR_INT, 6);
|
||||
swapItems.write(Types.BLOCK_POSITION1_8, new BlockPosition(0, 0, 0));
|
||||
swapItems.write(Types.UNSIGNED_BYTE, (short) 255);
|
||||
|
||||
PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
|
||||
storage.sendAnimations();
|
||||
if (storage.getConfirmId() != -1) {
|
||||
if (storage.getPosX() == x && storage.getPosY() == y && storage.getPosZ() == z && storage.getYaw() == yaw && storage.getPitch() == pitch) {
|
||||
final PacketWrapper confirmTeleport = PacketWrapper.create(ServerboundPackets1_9.ACCEPT_TELEPORTATION, wrapper.user());
|
||||
confirmTeleport.write(Types.VAR_INT, storage.getConfirmId());
|
||||
confirmTeleport.sendToServer(Protocol1_9To1_8.class);
|
||||
swapItems.sendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
storage.setConfirmId(-1);
|
||||
}
|
||||
} else {
|
||||
storage.setPos(x, y, z);
|
||||
storage.setYaw(yaw);
|
||||
storage.setPitch(pitch);
|
||||
storage.setOnGround(onGround);
|
||||
wrapper.user().get(BossBarStorage.class).updateLocation();
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_8.INTERACT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Target
|
||||
map(Types.VAR_INT); // Type
|
||||
handler(wrapper -> {
|
||||
final int type = wrapper.get(Types.VAR_INT, 1);
|
||||
if (type == 2 /* attack */) {
|
||||
wrapper.passthrough(Types.FLOAT); // Target x
|
||||
wrapper.passthrough(Types.FLOAT); // Target y
|
||||
wrapper.passthrough(Types.FLOAT); // Target z
|
||||
}
|
||||
if (type == 2 /* attack */ || type == 0 /* interact */) {
|
||||
wrapper.write(Types.VAR_INT, 0); // Hand
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_ACTION, wrapper -> {
|
||||
final int status = wrapper.passthrough(Types.VAR_INT);
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_STATUS_ONLY, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BOOLEAN); // On ground
|
||||
handler(wrapper -> {
|
||||
wrapper.user().get(PlayerPositionTracker.class).sendAnimations();
|
||||
|
||||
final BlockPlaceDestroyTracker tracker = wrapper.user().get(BlockPlaceDestroyTracker.class);
|
||||
if (status == 0 || status == 1 || status == 2) { // Start, cancel or finish
|
||||
tracker.setMining();
|
||||
}
|
||||
final EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
|
||||
if (tracker.isInsideVehicle(tracker.clientEntityId())) {
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
final CooldownStorage cooldown = wrapper.user().get(CooldownStorage.class);
|
||||
if (status == 1) { // Cancel
|
||||
tracker.setLastMining(0);
|
||||
cooldown.hit();
|
||||
} else if (status == 2) { // Finish
|
||||
tracker.setLastMining(System.currentTimeMillis() + 100);
|
||||
cooldown.setLastHit(0);
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_POS, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.DOUBLE); // X
|
||||
map(Types.DOUBLE); // Feet y
|
||||
map(Types.DOUBLE); // Z
|
||||
map(Types.BOOLEAN); // On ground
|
||||
handler(wrapper -> {
|
||||
final PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
|
||||
storage.sendAnimations();
|
||||
if (storage.getConfirmId() != -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.USE_ITEM_ON, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.BYTE, Types.VAR_INT); // Face
|
||||
read(Types.ITEM1_8); // Current item
|
||||
create(Types.VAR_INT, 0); // Hand - main
|
||||
map(Types.BYTE, Types.UNSIGNED_BYTE); // Cursor position x
|
||||
map(Types.BYTE, Types.UNSIGNED_BYTE); // Cursor position y
|
||||
map(Types.BYTE, Types.UNSIGNED_BYTE); // Cursor position z
|
||||
handler(wrapper -> {
|
||||
if (wrapper.get(Types.VAR_INT, 0) == -1) {
|
||||
wrapper.cancel();
|
||||
final PacketWrapper useItem = PacketWrapper.create(ServerboundPackets1_9.USE_ITEM, wrapper.user());
|
||||
useItem.write(Types.VAR_INT, 0);
|
||||
useItem.sendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
storage.setPos(wrapper.get(Types.DOUBLE, 0), wrapper.get(Types.DOUBLE, 1), wrapper.get(Types.DOUBLE, 2));
|
||||
storage.setOnGround(wrapper.get(Types.BOOLEAN, 0));
|
||||
});
|
||||
handler(wrapper -> wrapper.user().get(BossBarStorage.class).updateLocation());
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.SET_CARRIED_ITEM, wrapper -> wrapper.user().get(CooldownStorage.class).hit());
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_ROT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.FLOAT); // Yaw
|
||||
map(Types.FLOAT); // Pitch
|
||||
map(Types.BOOLEAN); // On ground
|
||||
handler(wrapper -> {
|
||||
final PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
|
||||
storage.sendAnimations();
|
||||
if (storage.getConfirmId() != -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Queue swing packet to be sent after on ground idle packets
|
||||
protocol.registerServerbound(ServerboundPackets1_8.SWING, wrapper -> {
|
||||
wrapper.cancel();
|
||||
storage.setYaw(wrapper.get(Types.FLOAT, 0));
|
||||
storage.setPitch(wrapper.get(Types.FLOAT, 1));
|
||||
storage.setOnGround(wrapper.get(Types.BOOLEAN, 0));
|
||||
});
|
||||
handler(wrapper -> wrapper.user().get(BossBarStorage.class).updateLocation());
|
||||
}
|
||||
});
|
||||
|
||||
final PacketWrapper swing = PacketWrapper.create(ServerboundPackets1_9.SWING, wrapper.user());
|
||||
swing.write(Types.VAR_INT, 0); // Main Hand
|
||||
wrapper.user().get(PlayerPositionTracker.class).queueAnimation(swing);
|
||||
protocol.registerServerbound(ServerboundPackets1_8.MOVE_PLAYER_POS_ROT, wrapper -> {
|
||||
final double x = wrapper.passthrough(Types.DOUBLE);
|
||||
final double y = wrapper.passthrough(Types.DOUBLE);
|
||||
final double z = wrapper.passthrough(Types.DOUBLE);
|
||||
final float yaw = wrapper.passthrough(Types.FLOAT);
|
||||
final float pitch = wrapper.passthrough(Types.FLOAT);
|
||||
final boolean onGround = wrapper.passthrough(Types.BOOLEAN);
|
||||
|
||||
wrapper.user().get(BlockPlaceDestroyTracker.class).updateMining();
|
||||
wrapper.user().get(CooldownStorage.class).hit();
|
||||
});
|
||||
final PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
|
||||
storage.sendAnimations();
|
||||
if (storage.getConfirmId() != -1) {
|
||||
if (storage.getPosX() == x && storage.getPosY() == y && storage.getPosZ() == z && storage.getYaw() == yaw && storage.getPitch() == pitch) {
|
||||
final PacketWrapper confirmTeleport = PacketWrapper.create(ServerboundPackets1_9.ACCEPT_TELEPORTATION, wrapper.user());
|
||||
confirmTeleport.write(Types.VAR_INT, storage.getConfirmId());
|
||||
confirmTeleport.sendToServer(Protocol1_9To1_8.class);
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_COMMAND, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Entity id
|
||||
map(Types.VAR_INT); // Action id
|
||||
map(Types.VAR_INT); // Action parameter
|
||||
handler(wrapper -> {
|
||||
final PlayerPositionTracker tracker = wrapper.user().get(PlayerPositionTracker.class);
|
||||
final int action = wrapper.get(Types.VAR_INT, 1);
|
||||
if (action == 6) { // Jump with horse
|
||||
wrapper.set(Types.VAR_INT, 1, 7);
|
||||
} else if (action == 0 && !tracker.isOnGround()) { // Start sneaking
|
||||
final PacketWrapper elytra = PacketWrapper.create(ServerboundPackets1_9.PLAYER_COMMAND, wrapper.user());
|
||||
elytra.write(Types.VAR_INT, wrapper.get(Types.VAR_INT, 0));
|
||||
elytra.write(Types.VAR_INT, 8);
|
||||
elytra.write(Types.VAR_INT, 0);
|
||||
elytra.scheduleSendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
storage.setConfirmId(-1);
|
||||
}
|
||||
} else {
|
||||
storage.setPos(x, y, z);
|
||||
storage.setYaw(yaw);
|
||||
storage.setPitch(pitch);
|
||||
storage.setOnGround(onGround);
|
||||
wrapper.user().get(BossBarStorage.class).updateLocation();
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_INPUT, wrapper -> {
|
||||
final float sideways = wrapper.passthrough(Types.FLOAT);
|
||||
final float forward = wrapper.passthrough(Types.FLOAT);
|
||||
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_ACTION, wrapper -> {
|
||||
final int status = wrapper.passthrough(Types.VAR_INT);
|
||||
|
||||
final EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
|
||||
final int vehicle = tracker.getVehicle(tracker.clientEntityId());
|
||||
final BlockPlaceDestroyTracker tracker = wrapper.user().get(BlockPlaceDestroyTracker.class);
|
||||
if (status == 0 || status == 1 || status == 2) { // Start, cancel or finish
|
||||
tracker.setMining();
|
||||
}
|
||||
|
||||
if (vehicle != -1 && tracker.entityType(vehicle) == EntityTypes1_9.EntityType.BOAT) {
|
||||
final PacketWrapper paddleBoat = PacketWrapper.create(ServerboundPackets1_9.PADDLE_BOAT, wrapper.user());
|
||||
paddleBoat.write(Types.BOOLEAN, forward != 0.0f || sideways < 0.0f);
|
||||
paddleBoat.write(Types.BOOLEAN, forward != 0.0f || sideways > 0.0f);
|
||||
paddleBoat.scheduleSendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
final CooldownStorage cooldown = wrapper.user().get(CooldownStorage.class);
|
||||
if (status == 1) { // Cancel
|
||||
tracker.setLastMining(0);
|
||||
cooldown.hit();
|
||||
} else if (status == 2) { // Finish
|
||||
tracker.setLastMining(System.currentTimeMillis() + 100);
|
||||
cooldown.setLastHit(0);
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.SIGN_UPDATE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
handler(wrapper -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
wrapper.write(Types.STRING, ChatUtil.jsonToLegacy(wrapper.user(), wrapper.read(Types.COMPONENT)));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_8.USE_ITEM_ON, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.BYTE, Types.VAR_INT); // Face
|
||||
read(Types.ITEM1_8); // Current item
|
||||
create(Types.VAR_INT, 0); // Hand - main
|
||||
map(Types.BYTE, Types.UNSIGNED_BYTE); // Cursor position x
|
||||
map(Types.BYTE, Types.UNSIGNED_BYTE); // Cursor position y
|
||||
map(Types.BYTE, Types.UNSIGNED_BYTE); // Cursor position z
|
||||
handler(wrapper -> {
|
||||
if (wrapper.get(Types.VAR_INT, 0) == -1) {
|
||||
wrapper.cancel();
|
||||
final PacketWrapper useItem = PacketWrapper.create(ServerboundPackets1_9.USE_ITEM, wrapper.user());
|
||||
useItem.write(Types.VAR_INT, 0);
|
||||
useItem.sendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.COMMAND_SUGGESTION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Message
|
||||
create(Types.BOOLEAN, false); // Has position
|
||||
map(Types.OPTIONAL_POSITION1_8); // Looked at block (position)
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_8.SET_CARRIED_ITEM, wrapper -> wrapper.user().get(CooldownStorage.class).hit());
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CLIENT_INFORMATION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Locale
|
||||
map(Types.BYTE); // View distance
|
||||
map(Types.BYTE, Types.VAR_INT); // Chat mode
|
||||
map(Types.BOOLEAN); // Chat colors
|
||||
map(Types.UNSIGNED_BYTE); // Displayed skin parts
|
||||
create(Types.VAR_INT, 1); // Main hand
|
||||
handler(wrapper -> {
|
||||
final short flags = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
// Queue swing packet to be sent after on ground idle packets
|
||||
protocol.registerServerbound(ServerboundPackets1_8.SWING, wrapper -> {
|
||||
wrapper.cancel();
|
||||
|
||||
final PacketWrapper updateSkin = PacketWrapper.create(ClientboundPackets1_8.SET_ENTITY_DATA, wrapper.user());
|
||||
updateSkin.write(Types.VAR_INT, wrapper.user().getEntityTracker(Protocol1_9To1_8.class).clientEntityId());
|
||||
final PacketWrapper swing = PacketWrapper.create(ServerboundPackets1_9.SWING, wrapper.user());
|
||||
swing.write(Types.VAR_INT, 0); // Main Hand
|
||||
wrapper.user().get(PlayerPositionTracker.class).queueAnimation(swing);
|
||||
|
||||
final List<EntityData> entityData = new ArrayList<>();
|
||||
entityData.add(new EntityData(10, EntityDataTypes1_8.BYTE, (byte) flags));
|
||||
wrapper.user().get(BlockPlaceDestroyTracker.class).updateMining();
|
||||
wrapper.user().get(CooldownStorage.class).hit();
|
||||
});
|
||||
|
||||
updateSkin.write(Types1_8.ENTITY_DATA_LIST, entityData);
|
||||
updateSkin.scheduleSend(Protocol1_9To1_8.class);
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_COMMAND, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Entity id
|
||||
map(Types.VAR_INT); // Action id
|
||||
map(Types.VAR_INT); // Action parameter
|
||||
handler(wrapper -> {
|
||||
final PlayerPositionTracker tracker = wrapper.user().get(PlayerPositionTracker.class);
|
||||
final InventoryProvider provider = Via.getManager().getProviders().get(InventoryProvider.class);
|
||||
final int action = wrapper.get(Types.VAR_INT, 1);
|
||||
if (action == 6) { // Jump with horse
|
||||
wrapper.set(Types.VAR_INT, 1, 7);
|
||||
} else if (action == 0 && provider.hasElytra(wrapper.user()) && !tracker.isOnGround()) { // Start sneaking
|
||||
final PacketWrapper elytra = PacketWrapper.create(ServerboundPackets1_9.PLAYER_COMMAND, wrapper.user());
|
||||
elytra.write(Types.VAR_INT, wrapper.get(Types.VAR_INT, 0));
|
||||
elytra.write(Types.VAR_INT, 8);
|
||||
elytra.write(Types.VAR_INT, 0);
|
||||
elytra.scheduleSendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CUSTOM_PAYLOAD, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Channel
|
||||
handlerSoftFail(wrapper -> {
|
||||
final String channel = wrapper.get(Types.STRING, 0);
|
||||
if (channel.equals("MC|BEdit") || channel.equals("MC|BSign")) {
|
||||
Item book = wrapper.passthrough(Types.ITEM1_8);
|
||||
book.setIdentifier(386);
|
||||
CompoundTag tag = book.tag();
|
||||
if (tag.contains("pages")) {
|
||||
ListTag<StringTag> pages = tag.getListTag("pages", StringTag.class);
|
||||
if (pages.size() > ViaRewind.getConfig().getMaxBookPages()) {
|
||||
wrapper.user().disconnect("Too many book pages");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < pages.size(); i++) {
|
||||
StringTag page = pages.get(i);
|
||||
String value = page.getValue();
|
||||
if (value.length() > ViaRewind.getConfig().getMaxBookPageSize()) {
|
||||
wrapper.user().disconnect("Book page too large");
|
||||
return;
|
||||
}
|
||||
value = ChatUtil.jsonToLegacy(wrapper.user(), value);
|
||||
page.setValue(value);
|
||||
}
|
||||
}
|
||||
} else if (channel.equals("MC|AdvCdm")) {
|
||||
wrapper.set(Types.STRING, 0, "MC|AdvCmd");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_INPUT, wrapper -> {
|
||||
final float sideways = wrapper.passthrough(Types.FLOAT);
|
||||
final float forward = wrapper.passthrough(Types.FLOAT);
|
||||
|
||||
final EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
|
||||
final Integer vehicle = tracker.getVehicle(tracker.clientEntityId());
|
||||
|
||||
if (vehicle != null && tracker.entityType(vehicle) == EntityTypes1_9.EntityType.BOAT) {
|
||||
final PacketWrapper paddleBoat = PacketWrapper.create(ServerboundPackets1_9.PADDLE_BOAT, wrapper.user());
|
||||
paddleBoat.write(Types.BOOLEAN, forward != 0.0f || sideways < 0.0f);
|
||||
paddleBoat.write(Types.BOOLEAN, forward != 0.0f || sideways > 0.0f);
|
||||
paddleBoat.scheduleSendToServer(Protocol1_9To1_8.class);
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.SIGN_UPDATE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
handler(wrapper -> {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
final JsonElement json = wrapper.read(Types.COMPONENT);
|
||||
if (!json.isJsonPrimitive()) {
|
||||
throw new IllegalStateException("Invalid sign text: " + StringUtil.forLogging(json));
|
||||
}
|
||||
|
||||
wrapper.write(Types.STRING, ChatUtil.jsonToLegacy(json));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.COMMAND_SUGGESTION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Message
|
||||
create(Types.BOOLEAN, false); // Has position
|
||||
map(Types.OPTIONAL_POSITION1_8); // Looked at block (position)
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CLIENT_INFORMATION, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Locale
|
||||
map(Types.BYTE); // View distance
|
||||
map(Types.BYTE, Types.VAR_INT); // Chat mode
|
||||
map(Types.BOOLEAN); // Chat colors
|
||||
map(Types.UNSIGNED_BYTE); // Displayed skin parts
|
||||
create(Types.VAR_INT, 1); // Main hand
|
||||
handler(wrapper -> {
|
||||
final short flags = wrapper.get(Types.UNSIGNED_BYTE, 0);
|
||||
|
||||
final PacketWrapper updateSkin = PacketWrapper.create(ClientboundPackets1_8.SET_ENTITY_DATA, wrapper.user());
|
||||
updateSkin.write(Types.VAR_INT, wrapper.user().getEntityTracker(Protocol1_9To1_8.class).clientEntityId());
|
||||
|
||||
final List<EntityData> entityData = new ArrayList<>();
|
||||
entityData.add(new EntityData(10, EntityDataTypes1_8.BYTE, (byte) flags));
|
||||
|
||||
updateSkin.write(Types.ENTITY_DATA_LIST1_8, entityData);
|
||||
updateSkin.scheduleSend(Protocol1_9To1_8.class);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_8.CUSTOM_PAYLOAD, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Channel
|
||||
handlerSoftFail(wrapper -> {
|
||||
final String channel = wrapper.get(Types.STRING, 0);
|
||||
if (channel.equals("MC|BEdit") || channel.equals("MC|BSign")) {
|
||||
final Item book = wrapper.passthrough(Types.ITEM1_8);
|
||||
book.setIdentifier(386);
|
||||
final CompoundTag tag = book.tag();
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
final ListTag<StringTag> pages = tag.getListTag("pages", StringTag.class);
|
||||
if (pages == null) {
|
||||
return;
|
||||
}
|
||||
if (pages.size() > ViaRewind.getConfig().getMaxBookPages()) {
|
||||
wrapper.user().disconnect("Too many book pages");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < pages.size(); i++) {
|
||||
final StringTag pageTag = pages.get(i);
|
||||
final String value = pageTag.getValue();
|
||||
|
||||
if (value.length() > ViaRewind.getConfig().getMaxBookPageSize()) {
|
||||
wrapper.user().disconnect("Book page too large");
|
||||
return;
|
||||
}
|
||||
|
||||
pageTag.setValue(ChatUtil.jsonToLegacy(value));
|
||||
}
|
||||
} else if (channel.equals("MC|AdvCdm")) {
|
||||
wrapper.set(Types.STRING, 0, "MC|AdvCmd");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+211
-208
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,11 +17,12 @@
|
||||
*/
|
||||
package com.viaversion.viarewind.protocol.v1_9to1_8.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viarewind.ViaRewind;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
|
||||
import com.viaversion.viarewind.protocol.v1_9to1_8.data.EffectIdMappings1_8;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.Environment;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.BaseChunk;
|
||||
@@ -32,236 +33,238 @@ import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.rewriter.RewriterBase;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_8;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_1;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
|
||||
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class WorldPacketRewriter1_9 {
|
||||
public class WorldPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
|
||||
|
||||
public static void register(Protocol1_9To1_8 protocol) {
|
||||
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_ENTITY_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.UNSIGNED_BYTE); // Action
|
||||
map(Types.NAMED_COMPOUND_TAG); // Tag
|
||||
handler(wrapper -> {
|
||||
final CompoundTag tag = wrapper.get(Types.NAMED_COMPOUND_TAG, 0);
|
||||
public WorldPacketRewriter1_9(Protocol1_9To1_8 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
if (tag.remove("SpawnData") instanceof CompoundTag spawnData) {
|
||||
final Tag id = spawnData.remove("id");
|
||||
if (id instanceof StringTag) {
|
||||
tag.put("EntityId", id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_ENTITY_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.UNSIGNED_BYTE); // Action
|
||||
map(Types.NAMED_COMPOUND_TAG); // Tag
|
||||
handler(wrapper -> {
|
||||
final CompoundTag tag = wrapper.get(Types.NAMED_COMPOUND_TAG, 0);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.UNSIGNED_BYTE); // Byte 1 (depending on block type)
|
||||
map(Types.UNSIGNED_BYTE); // Byte 2 (depending on block type)
|
||||
map(Types.VAR_INT); // Block
|
||||
handler(wrapper -> {
|
||||
final int block = wrapper.get(Types.VAR_INT, 0);
|
||||
if (block >= 219 && block <= 234) {
|
||||
wrapper.set(Types.VAR_INT, 0, 130);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (tag.remove("SpawnData") instanceof CompoundTag spawnData) {
|
||||
final Tag id = spawnData.remove("id");
|
||||
if (id instanceof StringTag) {
|
||||
tag.put("EntityId", id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CUSTOM_SOUND, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Sound name
|
||||
handler(wrapper -> {
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
name = protocol.getMappingData().getMappedNamedSound(name);
|
||||
if (name == null) {
|
||||
wrapper.cancel();
|
||||
} else {
|
||||
wrapper.set(Types.STRING, 0, name);
|
||||
}
|
||||
});
|
||||
read(Types.VAR_INT); // Sound category
|
||||
map(Types.INT); // Effect position x
|
||||
map(Types.INT); // Effect position y
|
||||
map(Types.INT); // Effect position z
|
||||
map(Types.FLOAT); // Volume
|
||||
map(Types.UNSIGNED_BYTE); // Pitch
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.UNSIGNED_BYTE); // Byte 1 (depending on block type)
|
||||
map(Types.UNSIGNED_BYTE); // Byte 2 (depending on block type)
|
||||
map(Types.VAR_INT); // Block
|
||||
handler(wrapper -> {
|
||||
final int block = wrapper.get(Types.VAR_INT, 0);
|
||||
if (block >= 219 && block <= 234) {
|
||||
wrapper.set(Types.VAR_INT, 0, 130);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.FORGET_LEVEL_CHUNK, ClientboundPackets1_8.LEVEL_CHUNK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final Environment environment = wrapper.user().get(ClientWorld.class).getEnvironment();
|
||||
protocol.registerClientbound(ClientboundPackets1_9.CUSTOM_SOUND, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.STRING); // Sound name
|
||||
handler(wrapper -> {
|
||||
String name = wrapper.get(Types.STRING, 0);
|
||||
name = protocol.getMappingData().getMappedNamedSound(name);
|
||||
if (name == null) {
|
||||
wrapper.cancel();
|
||||
} else {
|
||||
wrapper.set(Types.STRING, 0, name);
|
||||
}
|
||||
});
|
||||
read(Types.VAR_INT); // Sound category
|
||||
map(Types.INT); // Effect position x
|
||||
map(Types.INT); // Effect position y
|
||||
map(Types.INT); // Effect position z
|
||||
map(Types.FLOAT); // Volume
|
||||
map(Types.UNSIGNED_BYTE); // Pitch
|
||||
}
|
||||
});
|
||||
|
||||
final int chunkX = wrapper.read(Types.INT);
|
||||
final int chunkZ = wrapper.read(Types.INT);
|
||||
protocol.registerClientbound(ClientboundPackets1_9.FORGET_LEVEL_CHUNK, ClientboundPackets1_8.LEVEL_CHUNK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final Environment environment = wrapper.user().getClientWorld(Protocol1_9To1_8.class).getEnvironment();
|
||||
|
||||
wrapper.write(ChunkType1_8.forEnvironment(environment), new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], null, new ArrayList<>()));
|
||||
});
|
||||
}
|
||||
});
|
||||
final int chunkX = wrapper.read(Types.INT);
|
||||
final int chunkZ = wrapper.read(Types.INT);
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.LEVEL_CHUNK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final Environment environment = wrapper.user().get(ClientWorld.class).getEnvironment();
|
||||
wrapper.write(ChunkType1_8.forEnvironment(environment), new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], null, new ArrayList<>()));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Chunk chunk = wrapper.read(ChunkType1_9_1.forEnvironment(environment));
|
||||
protocol.registerClientbound(ClientboundPackets1_9.LEVEL_CHUNK, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final Environment environment = wrapper.user().getClientWorld(Protocol1_9To1_8.class).getEnvironment();
|
||||
|
||||
for (ChunkSection section : chunk.getSections()) {
|
||||
if (section == null) continue;
|
||||
DataPalette palette = section.palette(PaletteType.BLOCKS);
|
||||
for (int i = 0; i < palette.size(); i++) {
|
||||
int block = palette.idByIndex(i);
|
||||
int replacedBlock = protocol.getItemRewriter().handleBlockId(block);
|
||||
palette.setIdByIndex(i, replacedBlock);
|
||||
}
|
||||
}
|
||||
Chunk chunk = wrapper.read(ChunkType1_9_1.forEnvironment(environment));
|
||||
|
||||
if (chunk.isFullChunk() && chunk.getBitmask() == 0) { // This would be an unload packet for 1.8 clients. Just set one air section
|
||||
boolean skylight = environment == Environment.NORMAL;
|
||||
ChunkSection[] sections = new ChunkSection[16];
|
||||
ChunkSection section = new ChunkSectionImpl(true);
|
||||
sections[0] = section;
|
||||
section.palette(PaletteType.BLOCKS).addId(0);
|
||||
if (skylight) section.getLight().setSkyLight(new byte[2048]);
|
||||
chunk = new BaseChunk(chunk.getX(), chunk.getZ(), true, false, 1, sections, chunk.getBiomeData(), chunk.getBlockEntities());
|
||||
}
|
||||
for (ChunkSection section : chunk.getSections()) {
|
||||
if (section == null) continue;
|
||||
DataPalette palette = section.palette(PaletteType.BLOCKS);
|
||||
for (int i = 0; i < palette.size(); i++) {
|
||||
int block = palette.idByIndex(i);
|
||||
int replacedBlock = protocol.getItemRewriter().handleBlockId(block);
|
||||
palette.setIdByIndex(i, replacedBlock);
|
||||
}
|
||||
}
|
||||
|
||||
wrapper.write(ChunkType1_8.forEnvironment(environment), chunk);
|
||||
if (chunk.isFullChunk() && chunk.getBitmask() == 0) { // This would be an unload packet for 1.8 clients. Just set one air section
|
||||
boolean skylight = environment == Environment.NORMAL;
|
||||
ChunkSection[] sections = new ChunkSection[16];
|
||||
ChunkSection section = new ChunkSectionImpl(true);
|
||||
sections[0] = section;
|
||||
section.palette(PaletteType.BLOCKS).addId(0);
|
||||
if (skylight) section.getLight().setSkyLight(new byte[2048]);
|
||||
chunk = new BaseChunk(chunk.getX(), chunk.getZ(), true, false, 1, sections, chunk.getBiomeData(), chunk.getBlockEntities());
|
||||
}
|
||||
|
||||
chunk.getBlockEntities().forEach(nbt -> {
|
||||
if (!nbt.contains("x") || !nbt.contains("y") || !nbt.contains("z") || !nbt.contains("id")) {
|
||||
return;
|
||||
}
|
||||
BlockPosition position = new BlockPosition((int) nbt.get("x").getValue(), (int) nbt.get("y").getValue(), (int) nbt.get("z").getValue());
|
||||
String id = (String) nbt.get("id").getValue();
|
||||
wrapper.write(ChunkType1_8.forEnvironment(environment), chunk);
|
||||
|
||||
short action;
|
||||
switch (id) {
|
||||
case "minecraft:mob_spawner":
|
||||
action = 1;
|
||||
break;
|
||||
case "minecraft:command_block":
|
||||
action = 2;
|
||||
break;
|
||||
case "minecraft:beacon":
|
||||
action = 3;
|
||||
break;
|
||||
case "minecraft:skull":
|
||||
action = 4;
|
||||
break;
|
||||
case "minecraft:flower_pot":
|
||||
action = 5;
|
||||
break;
|
||||
case "minecraft:banner":
|
||||
action = 6;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
chunk.getBlockEntities().forEach(nbt -> {
|
||||
if (!nbt.contains("x") || !nbt.contains("y") || !nbt.contains("z") || !nbt.contains("id")) {
|
||||
return;
|
||||
}
|
||||
BlockPosition position = new BlockPosition((int) nbt.get("x").getValue(), (int) nbt.get("y").getValue(), (int) nbt.get("z").getValue());
|
||||
String id = (String) nbt.get("id").getValue();
|
||||
|
||||
final PacketWrapper blockEntityData = PacketWrapper.create(ClientboundPackets1_9.BLOCK_ENTITY_DATA, wrapper.user());
|
||||
blockEntityData.write(Types.BLOCK_POSITION1_8, position);
|
||||
blockEntityData.write(Types.UNSIGNED_BYTE, action);
|
||||
blockEntityData.write(Types.NAMED_COMPOUND_TAG, nbt);
|
||||
blockEntityData.scheduleSend(Protocol1_9To1_8.class, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
short action;
|
||||
switch (id) {
|
||||
case "minecraft:mob_spawner":
|
||||
action = 1;
|
||||
break;
|
||||
case "minecraft:command_block":
|
||||
action = 2;
|
||||
break;
|
||||
case "minecraft:beacon":
|
||||
action = 3;
|
||||
break;
|
||||
case "minecraft:skull":
|
||||
action = 4;
|
||||
break;
|
||||
case "minecraft:flower_pot":
|
||||
action = 5;
|
||||
break;
|
||||
case "minecraft:banner":
|
||||
action = 6;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.LEVEL_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Effect id
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.INT); // data
|
||||
map(Types.BOOLEAN); // disable relative volume
|
||||
handler(wrapper -> {
|
||||
int id = wrapper.get(Types.INT, 0);
|
||||
id = EffectIdMappings1_8.getOldId(id);
|
||||
if (id == -1) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
wrapper.set(Types.INT, 0, id);
|
||||
if (id == 2001) {
|
||||
int replacedBlock = protocol.getItemRewriter().handleBlockId(wrapper.get(Types.INT, 1));
|
||||
wrapper.set(Types.INT, 1, replacedBlock);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
final PacketWrapper blockEntityData = PacketWrapper.create(ClientboundPackets1_9.BLOCK_ENTITY_DATA, wrapper.user());
|
||||
blockEntityData.write(Types.BLOCK_POSITION1_8, position);
|
||||
blockEntityData.write(Types.UNSIGNED_BYTE, action);
|
||||
blockEntityData.write(Types.NAMED_COMPOUND_TAG, nbt);
|
||||
blockEntityData.scheduleSend(Protocol1_9To1_8.class, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.LEVEL_PARTICLES, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Particle id
|
||||
handler(wrapper -> {
|
||||
int id = wrapper.get(Types.INT, 0);
|
||||
if (id > 41 && !ViaRewind.getConfig().isReplaceParticles()) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
if (id == 42) { // Dragon Breath
|
||||
wrapper.set(Types.INT, 0, 24); // Portal
|
||||
} else if (id == 43) { // End Rod
|
||||
wrapper.set(Types.INT, 0, 3); // Firework Spark
|
||||
} else if (id == 44) { // Damage Indicator
|
||||
wrapper.set(Types.INT, 0, 34); // Heart
|
||||
} else if (id == 45) { // Sweep Attack
|
||||
wrapper.set(Types.INT, 0, 1); // Large Explosion
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_9.LEVEL_EVENT, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Effect id
|
||||
map(Types.BLOCK_POSITION1_8); // Position
|
||||
map(Types.INT); // data
|
||||
map(Types.BOOLEAN); // disable relative volume
|
||||
handler(wrapper -> {
|
||||
int id = wrapper.get(Types.INT, 0);
|
||||
id = EffectIdMappings1_8.getOldId(id);
|
||||
if (id == -1) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
wrapper.set(Types.INT, 0, id);
|
||||
if (id == 2001) {
|
||||
int replacedBlock = protocol.getItemRewriter().handleBlockId(wrapper.get(Types.INT, 1));
|
||||
wrapper.set(Types.INT, 1, replacedBlock);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.MAP_ITEM_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Item damage
|
||||
map(Types.BYTE); // Scale
|
||||
read(Types.BOOLEAN); // Tracking position
|
||||
}
|
||||
});
|
||||
protocol.registerClientbound(ClientboundPackets1_9.LEVEL_PARTICLES, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.INT); // Particle id
|
||||
handler(wrapper -> {
|
||||
int id = wrapper.get(Types.INT, 0);
|
||||
if (id > 41 && !ViaRewind.getConfig().isReplaceParticles()) {
|
||||
wrapper.cancel();
|
||||
return;
|
||||
}
|
||||
if (id == 42) { // Dragon Breath
|
||||
wrapper.set(Types.INT, 0, 24); // Portal
|
||||
} else if (id == 43) { // End Rod
|
||||
wrapper.set(Types.INT, 0, 3); // Firework Spark
|
||||
} else if (id == 44) { // Damage Indicator
|
||||
wrapper.set(Types.INT, 0, 34); // Heart
|
||||
} else if (id == 45) { // Sweep Attack
|
||||
wrapper.set(Types.INT, 0, 1); // Large Explosion
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.SOUND, ClientboundPackets1_8.CUSTOM_SOUND, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final int soundId = wrapper.read(Types.VAR_INT);
|
||||
final String soundName = protocol.getMappingData().soundName(soundId);
|
||||
if (soundName == null) {
|
||||
wrapper.cancel();
|
||||
} else {
|
||||
wrapper.write(Types.STRING, protocol.getMappingData().getMappedNamedSound(soundName));
|
||||
}
|
||||
});
|
||||
read(Types.VAR_INT); // Sound category
|
||||
map(Types.INT); // Effect position x
|
||||
map(Types.INT); // Effect position y
|
||||
map(Types.INT); // Effect position z
|
||||
map(Types.FLOAT); // Volume
|
||||
map(Types.UNSIGNED_BYTE); // Pitch
|
||||
}
|
||||
});
|
||||
}
|
||||
protocol.registerClientbound(ClientboundPackets1_9.MAP_ITEM_DATA, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types.VAR_INT); // Item damage
|
||||
map(Types.BYTE); // Scale
|
||||
read(Types.BOOLEAN); // Tracking position
|
||||
}
|
||||
});
|
||||
|
||||
protocol.registerClientbound(ClientboundPackets1_9.SOUND, ClientboundPackets1_8.CUSTOM_SOUND, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
handler(wrapper -> {
|
||||
final int soundId = wrapper.read(Types.VAR_INT);
|
||||
final int mappedSoundId = protocol.getMappingData().getFullSoundMappings().getNewId(soundId);
|
||||
if (mappedSoundId == -1) {
|
||||
wrapper.cancel();
|
||||
} else {
|
||||
wrapper.write(Types.STRING, protocol.getMappingData().getFullSoundMappings().mappedIdentifier(mappedSoundId));
|
||||
}
|
||||
});
|
||||
read(Types.VAR_INT); // Sound category
|
||||
map(Types.INT); // Effect position x
|
||||
map(Types.INT); // Effect position y
|
||||
map(Types.INT); // Effect position z
|
||||
map(Types.FLOAT); // Volume
|
||||
map(Types.UNSIGNED_BYTE); // Pitch
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+17
-17
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
|
||||
* Copyright (C) 2018-2024 ViaVersion and contributors
|
||||
* Copyright (C) 2018-2026 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,24 +20,24 @@ package com.viaversion.viarewind.protocol.v1_9to1_8.storage;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
|
||||
public class BlockPlaceDestroyTracker implements StorableObject {
|
||||
private long lastMining;
|
||||
private long lastMining;
|
||||
|
||||
public boolean isMining() {
|
||||
long time = System.currentTimeMillis() - lastMining;
|
||||
return time < 75;
|
||||
}
|
||||
public boolean isMining() {
|
||||
long time = System.currentTimeMillis() - lastMining;
|
||||
return time < 75;
|
||||
}
|
||||
|
||||
public void setMining() {
|
||||
lastMining = System.currentTimeMillis();
|
||||
}
|
||||
public void setMining() {
|
||||
lastMining = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void updateMining() {
|
||||
if (this.isMining()) {
|
||||
lastMining = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
public void updateMining() {
|
||||
if (this.isMining()) {
|
||||
lastMining = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public void setLastMining(long lastMining) {
|
||||
this.lastMining = lastMining;
|
||||
}
|
||||
public void setLastMining(long lastMining) {
|
||||
this.lastMining = lastMining;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 135 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user