Compare commits

..
42 Commits
Author SHA1 Message Date
FlorianMichael 901463e095 4.0.8 Release 2025-06-20 20:11:01 +02:00
FlorianMichael 227d37b2b9 Update VV api usage 2025-06-16 18:27:46 +02:00
FlorianMichael be5bb6e07c Write flags as byte in PLAYER_INPUT 1.8->1.7 2025-06-10 20:16:14 +02:00
Nassim Jahnke 064dbee920 Update profile properties type 2025-05-26 17:32:13 +02:00
FlorianMichael 783006baa5 Auto: Gradle 8.14.1 2025-05-22 17:51:04 +02:00
Adrian ba93a40d22 Change end rod block state mapping to white stained glass in 1.9->1.8 (#584) 2025-05-22 00:18:48 +02:00
dependabot[bot] 422f81dd2e Bump org.gradle.toolchains.foojay-resolver-convention (#583)
Bumps org.gradle.toolchains.foojay-resolver-convention from 0.10.0 to 1.0.0.

---
updated-dependencies:
- dependency-name: org.gradle.toolchains.foojay-resolver-convention
  dependency-version: 1.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-22 00:12:32 +02:00
FlorianMichael aa47e3c0a5 Update BaseProject 2025-05-19 00:12:39 +02:00
FlorianMichael 094298771e Update ClassTokenReplacer 2025-05-17 17:57:07 +02:00
FlorianMichael 66133d1ccc Update VV api usage 2025-05-17 15:37:37 +02:00
FlorianMichael 11011d59aa Rewrite build files 2025-05-15 15:28:44 +02:00
FlorianMichael 691cbf1b2a Small cleanup 2025-05-15 11:18:26 +02:00
EthanKeating 8d8675a891 Fix hologram movement by wrapping them to an interpolated entity in 1.8->1.7 (#580)
* Hologram movement fix for 1.7 clients

* fix: addressed feedback from PR review
2025-05-15 08:26:12 +02:00
Beanes 4fa2f10f3a Use correct entity id data type in 1.8->1.7 entity data sending (#579) 2025-05-08 20:24:50 +02:00
FlorianMichael c2e516dcd2 Auto: Gradle 8.14 2025-04-26 16:25:07 +02:00
BeanesandFlorianMichael 153eedd5eb Optimize memory usage for 1.7 chunk rewriting (#577)
* Optimize memory usage

* Bump version; cleanup code

---------

Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-04-22 23:52:39 +02:00
FlorianMichael 2d404608ee [ci skip] Reformat GH issue templates 2025-04-20 14:41:56 +02:00
FlorianMichael bbc1d77939 4.0.7 Release 2025-03-31 01:08:03 +02:00
dependabot[bot] fa36428391 Bump io.papermc.hangar-publish-plugin from 0.1.2 to 0.1.3 (#568)
Bumps io.papermc.hangar-publish-plugin from 0.1.2 to 0.1.3.

---
updated-dependencies:
- dependency-name: io.papermc.hangar-publish-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-29 14:47:08 +01:00
FlorianMichael b6dee43620 Update VV api usage 2025-03-29 14:46:44 +01:00
FlorianMichael 371c25f9d0 Update MCStructs to 3.0.0 2025-03-29 14:46:14 +01:00
FlorianMichael a41bbc2d67 4.0.6 Release 2025-03-28 19:07:24 +01:00
Nassim Jahnke de84a8fffc Replace deprecated class use 2025-03-26 13:47:29 +01:00
Nassim Jahnke 22ff1416c2 Fix serverbound container_close container types
Fixes #566
2025-03-13 13:58:14 +01:00
FlorianMichael 00b74ef2dd Update container id types 2025-03-12 18:31:20 +01:00
FlorianMichael 8d5b348318 Fix data field getting in ADD_ENTITY handler in 1.9->1.8 2025-03-09 01:06:11 +01:00
FlorianMichael 51f001ac3e Don't use -1 as indicator in EntityTracker1_9#getVehicle 2025-02-26 20:21:50 +01:00
FlorianMichael e27caba231 Cleanup code here and there 2025-02-25 21:40:03 +01:00
FlorianMichael 07aab015ea Auto: Gradle 8.13, .editorconfig 2025-02-25 18:44:28 +01:00
FlorianMichael 6bcf8d8895 Update ViaProxy, exclude run folder in .gitignore 2025-02-12 16:28:41 +01:00
FlorianMichael 43c42f44f6 Move handler names to the platform
As needs platform handling it should be directly exposed to the wrapper rather than being in the storage
2025-02-12 16:25:37 +01:00
FlorianMichael 295d87d49f Add functions to allow changing the handler names in TrackingCompressionHandlerProvider 2025-01-28 19:01:45 +01:00
FlorianMichael ab97e248da Auto: Gradle 8.12.1 2025-01-24 15:44:23 +01:00
FlorianMichael 276b9ba386 Update VV API usage 2025-01-10 22:44:59 +01:00
FlorianMichael 351ff79187 4.0.5 Release 2025-01-01 21:29:53 +01:00
FlorianMichael 87ed2160c9 Auto: 2025 2025-01-01 01:07:59 +01:00
FlorianMichael 668ed3c455 Auto: Gradle 8.12 2024-12-22 02:12:08 +01:00
FlorianMichael 3a0c742878 Auto: Migrate to setup-gradle action 2024-12-17 00:29:36 +01:00
FlorianMichael bc7b33f28a Handle unknown entity types correctly 2024-12-16 01:27:26 +01:00
FlorianMichael 657dcaa682 Do not persist credentials 2024-12-15 18:05:25 +01:00
FlorianMichael 3676906fbf Remove wiki.vg references 2024-12-13 22:50:24 +01:00
FlorianMichael dc9dbe9900 Bump version to 4.0.5-SNAPSHOT 2024-12-13 22:50:06 +01:00
116 changed files with 1019 additions and 1168 deletions

No files matched your search

+14 -2
View File
@@ -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
+2 -2
View File
@@ -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
+18 -18
View File
@@ -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
+4 -11
View File
@@ -7,22 +7,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
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
+4 -2
View File
@@ -12,8 +12,10 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
@@ -1,14 +0,0 @@
name: Update Gradle Wrapper
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 0"
jobs:
update-gradle-wrapper:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Update Gradle Wrapper
uses: gradle-update/update-gradle-wrapper-action@v2
+18 -97
View File
@@ -1,113 +1,34 @@
### 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/
*.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
View File
@@ -3,7 +3,7 @@
[![Build Status](https://github.com/ViaVersion/ViaRewind/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/ViaVersion/ViaRewind/actions)
[![Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](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):**
-7
View File
@@ -1,7 +0,0 @@
plugins {
id "groovy-gradle-plugin"
}
repositories {
gradlePluginPortal()
}
@@ -1,74 +0,0 @@
plugins {
id "java-library"
id "maven-publish"
id "idea"
}
repositories {
mavenCentral()
maven {
name = "ViaVersion"
url "https://repo.viaversion.com"
}
}
base {
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
compileJava.options.encoding = compileTestJava.options.encoding = javadoc.options.encoding = "UTF-8"
group = rootProject.maven_group
version = rootProject.maven_version
description = rootProject.maven_description
}
dependencies {
compileOnly "com.viaversion:viaversion:5.0.4-SNAPSHOT"
compileOnly "com.viaversion:viabackwards:5.0.4-SNAPSHOT"
}
publishing {
repositories {
maven {
name = "Via"
url = "https://repo.viaversion.com/"
credentials(PasswordCredentials)
authentication {
basic(BasicAuthentication)
}
}
}
publications {
main(MavenPublication) {
artifactId = project.name
groupId = project.maven_group
version = project.maven_version
from components.java
pom {
name = "ViaRewind"
description = project.description
url = "https://github.com/ViaVersion/ViaRewind"
licenses {
license {
name = "GPL-3.0 License"
url = "https://github.com/ViaVersion/ViaRewind/blob/main/LICENSE"
}
}
developers {
developer {
id = "FlorianMichael"
name = "EnZaXD"
email = "florian.michael07@gmail.com"
}
}
scm {
connection = "scm:git:git://github.com/ViaVersion/ViaRewind.git"
developerConnection = "scm:git:ssh://github.com/ViaVersion/ViaRewind.git"
url = "github.com/ViaVersion/ViaRewind"
}
}
}
}
}
@@ -1,7 +0,0 @@
plugins {
id "vr.base-conventions"
}
dependencies {
compileOnly project(":viarewind-common")
}
-142
View File
@@ -1,142 +0,0 @@
plugins {
id "vr.base-conventions"
id "io.papermc.hangar-publish-plugin" version "0.1.2"
id "com.modrinth.minotaur" version "2.+"
}
base {
archivesName = "ViaRewind"
}
configurations {
publishInclude
}
dependencies {
publishInclude project(":viarewind-common")
publishInclude project(":viarewind-bukkit")
publishInclude project(":viarewind-fabric")
publishInclude project(":viarewind-sponge")
publishInclude project(":viarewind-velocity")
}
jar {
dependsOn configurations.publishInclude
from {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
configurations.publishInclude.collect {
zipTree(it)
}
} {
exclude "META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA"
}
manifest {
attributes(
"paperweight-mappings-namespace": "mojang"
)
}
from("LICENSE") {
rename { "${it}_${project.name ?: rootProject.name}" }
}
}
idea {
module {
["run"].each {
excludeDirs << file("$it")
}
}
}
// -----------------------------------------------------
// Publishing
Provider<String> latestCommitHash() {
return providers.exec {
commandLine = ["git", "rev-parse", "--short", "HEAD"]
}.standardOutput.getAsText().map(String::trim)
}
Provider<String> latestCommitMessage() {
return providers.exec {
commandLine = ["git", "log", "-1", "--pretty=%B"]
}.standardOutput.getAsText().map(String::trim)
}
Provider<String> branchName() {
return providers.exec {
commandLine = ["git", "rev-parse", "--abbrev-ref", "HEAD"]
}.standardOutput.getAsText().map(String::trim)
}
def branch = branchName().get()
def baseVersion = project.maven_version
def isRelease = !baseVersion.contains('-')
def isMainBranch = branch == "master"
if (!isRelease || isMainBranch) { // Only publish releases from the main branch
def suffixedVersion = isRelease ? baseVersion : baseVersion + "+" + System.getenv("GITHUB_RUN_NUMBER")
def commitHash = latestCommitHash().get()
def changelogContent = "[${commitHash}](https://github.com/ViaVersion/ViaRewind/commit/${commitHash}) ${latestCommitMessage().get()}"
modrinth {
def mcVersions = project.mcVersions
.split(',')
.collect { it.trim() }
token.set(System.getenv("MODRINTH_TOKEN"))
projectId.set("viarewind")
versionType.set(isRelease ? "release" : isMainBranch ? "beta" : "alpha")
versionNumber.set(suffixedVersion)
versionName.set(suffixedVersion)
changelog.set(changelogContent)
uploadFile.set(jar.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")
}
}
hangarPublish {
publications.register("plugin") {
version = suffixedVersion
id = "ViaRewind"
channel = isRelease ? "Release" : isMainBranch ? "Snapshot" : "Alpha"
changelog = changelogContent
apiKey = System.getenv("HANGAR_TOKEN")
platforms {
PAPER {
jar = project.jar.archiveFile
platformVersions = [property('mcVersionRange') as String]
dependencies {
hangar("ViaVersion") {
required = true
}
hangar("ViaBackwards") {
required = true
}
}
}
VELOCITY {
jar = project.jar.archiveFile
platformVersions = [property("velocityVersion") as String]
dependencies {
hangar("ViaVersion") {
required = true
}
hangar("ViaBackwards") {
required = true
}
}
}
}
}
}
}
+142
View File
@@ -0,0 +1,142 @@
import de.florianmichael.baseproject.*
plugins {
`java-library`
id("io.papermc.hangar-publish-plugin")
id("com.modrinth.minotaur")
id("de.florianmichael.baseproject.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.4.0")
compileOnly("com.viaversion:viabackwards:5.4.0")
}
tasks {
processResources {
val projectVersion = project.version
val projectDescription = project.description
filesMatching(listOf("plugin.yml", "fabric.mod.json", "META-INF/sponge_plugins.json")) {
expand("version" to projectVersion, "description" to projectDescription)
}
}
}
}
base {
archivesName.set("ViaRewind")
}
val shade = configureShadedDependencies()
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("")
}
}
-24
View File
@@ -1,24 +0,0 @@
plugins {
id "vr.platform-conventions"
}
repositories {
maven {
name = "SpigotMC"
url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
}
maven {
name = "SpongePowered"
url "https://repo.spongepowered.org/repository/maven-public/"
}
}
dependencies {
compileOnly(annotationProcessor("org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT"))
}
processResources {
filesMatching("plugin.yml") {
expand("version": project.version, "description": project.description)
}
}
+4
View File
@@ -0,0 +1,4 @@
dependencies {
compileOnly(project(":viarewind-common"))
compileOnly("org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT")
}
@@ -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-2025 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
-49
View File
@@ -1,49 +0,0 @@
plugins {
id "vr.base-conventions"
id "net.raphimc.class-token-replacer" version "1.0.0"
}
dependencies {
compileOnly "io.netty:netty-all:4.0.20.Final"
compileOnly "com.google.guava:guava:17.0"
}
sourceSets {
main {
classTokenReplacer {
property("\${version}", rootProject.maven_version)
property("\${impl_version}", "git-ViaRewind-${rootProject.maven_version}:${rootProject.latestCommitHash().get()}")
}
}
}
// Task to quickly test/debug code changes using https://github.com/ViaVersion/ViaProxy
// For further instructions see the ViaProxy repository README
tasks.register("runViaProxy", JavaExec) {
dependsOn tasks.jar
def viaProxyConfiguration = configurations.create("viaProxy")
viaProxyConfiguration.dependencies.add(dependencies.create("net.raphimc:ViaProxy:3.3.5-SNAPSHOT") {
transitive = false
})
mainClass = "net.raphimc.viaproxy.ViaProxy"
classpath = viaProxyConfiguration
workingDir = file("run")
jvmArgs = ["-DskipUpdateCheck"]
if (System.getProperty("viaproxy.gui.autoStart") != null) {
jvmArgs("-Dviaproxy.gui.autoStart")
}
doFirst {
def jarsDir = file("$workingDir/jars")
jarsDir.mkdirs()
file("$jarsDir/${project.name}.jar").bytes = tasks.jar.archiveFile.get().asFile.bytes
}
doLast {
file("$workingDir/jars/${project.name}.jar").delete()
file("$workingDir/logs").deleteDir()
}
}
+58
View File
@@ -0,0 +1,58 @@
import de.florianmichael.baseproject.*
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")
viaProxy("net.raphimc:ViaProxy:3.4.2-SNAPSHOT") {
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,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 ViaVersion and contributors
* Copyright (C) 2018-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -86,7 +86,7 @@ public interface ViaRewindConfig extends Config {
/**
* 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>)
* @return the particle name
*/
String getWorldBorderParticle();
@@ -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-2025 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
@@ -70,4 +70,23 @@ public interface ViaRewindPlatform {
* @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";
}
}
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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,7 +21,7 @@ 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 byte[] blockLSBArray = new byte[ChunkSection.SIZE];
private final NibbleArray blockMetadataArray = new NibbleArray(this.blockLSBArray.length);
private final NibbleArray blockLightArray = new NibbleArray(this.blockLSBArray.length);
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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,7 +26,6 @@ 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.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
@@ -40,19 +39,6 @@ public abstract class VREntityRewriter<C extends ClientboundPacketType, T extend
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(getDimensionHandler());
}
});
}
protected void removeEntities(final UserConnection connection, final int[] entities) {
final EntityTrackerBase tracker = tracker(connection);
for (int entityId : entities) {
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -47,4 +47,7 @@ public class RewindTypes {
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);
}
@@ -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-2025 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,7 +23,6 @@ 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[]> {
@@ -42,18 +41,22 @@ public class BulkChunkType1_7_6 extends Type<Chunk[]> {
@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];
final byte[][] dataArrays = new byte[chunkCount][];
int dataSize = 0;
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());
final byte[] data = chunkData.key();
dataArrays[i] = data;
dataSize += data.length;
} catch (Exception e) {
throw new RuntimeException("Unable to serialize chunk", e);
}
@@ -62,7 +65,13 @@ public class BulkChunkType1_7_6 extends Type<Chunk[]> {
primaryBitMask[i] = (short) chunk.getBitmask();
additionalBitMask[i] = chunkData.value();
}
final byte[] data = output.toByteArray();
final byte[] data = new byte[dataSize];
int destPos = 0;
for (final byte[] array : dataArrays) {
System.arraycopy(array, 0, data, destPos, array.length);
destPos += array.length;
}
final Deflater deflater = new Deflater();
byte[] compressedData;
@@ -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-2025 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,10 +23,12 @@ 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();
@@ -94,29 +96,41 @@ public class ChunkType1_7_6 extends Type<Chunk> {
}
}
final ByteArrayOutputStream output = new ByteArrayOutputStream();
final boolean biomes = chunk.isFullChunk() && chunk.getBiomeData() != null;
final int totalSize = calculateSize(storageArrays, chunk.getBitmask(), biomes);
final byte[] output = new byte[totalSize];
int index = 0;
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockLSBArray());
final byte[] blockLSBArray = storageArrays[i].getBlockLSBArray();
System.arraycopy(blockLSBArray, 0, output, index, blockLSBArray.length);
index += blockLSBArray.length;
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockMetadataArray().getHandle());
final byte[] blockMetadataArray = storageArrays[i].getBlockMetadataArray().getHandle();
System.arraycopy(blockMetadataArray, 0, output, index, blockMetadataArray.length);
index += blockMetadataArray.length;
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockLightArray().getHandle());
final byte[] blockLightArray = storageArrays[i].getBlockLightArray().getHandle();
System.arraycopy(blockLightArray, 0, output, index, blockLightArray.length);
index += blockLightArray.length;
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].getSkyLightArray() != null) {
output.write(storageArrays[i].getSkyLightArray().getHandle());
final byte[] skyLightArray = storageArrays[i].getSkyLightArray().getHandle();
System.arraycopy(skyLightArray, 0, output, index, skyLightArray.length);
index += skyLightArray.length;
}
}
@@ -124,16 +138,42 @@ public class ChunkType1_7_6 extends Type<Chunk> {
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());
final byte[] blockMSBArray = storageArrays[i].getOrCreateBlockMSBArray().getHandle();
System.arraycopy(blockMSBArray, 0, output, index, blockMSBArray.length);
index += blockMSBArray.length;
}
}
if (chunk.isFullChunk() && chunk.getBiomeData() != null) {
if (biomes) {
for (int biome : chunk.getBiomeData()) {
output.write(biome);
output[index++] = (byte) biome;
}
}
return new Pair<>(output.toByteArray(), additionalBitMask);
return new Pair<>(output, additionalBitMask);
}
private static int calculateSize(final ExtendedBlockStorage[] storageArrays, final int bitmask, final boolean biomes) {
int totalSize = 0;
for (int i = 0; i < storageArrays.length; i++) {
if ((bitmask & 1 << i) != 0) {
totalSize += SIZE; // Block lsb array
totalSize += SIZE / 2; // Block metadata array
totalSize += LIGHT_LENGTH; // Block light array
if (storageArrays[i].getSkyLightArray() != null) {
totalSize += LIGHT_LENGTH;
}
if (storageArrays[i].hasBlockMSBArray()) {
totalSize += SIZE / 2; // Block msb array
}
}
}
if (biomes) {
totalSize += 256;
}
return totalSize;
}
}
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -1,32 +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.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);
}
@@ -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-2025 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;
@@ -47,7 +47,7 @@ public class Protocol1_7_6_10To1_7_2_5 extends AbstractProtocol<ClientboundPacke
@Override
protected void registerPackets() {
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, new PacketHandlers() {
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_FINISHED, new PacketHandlers() {
@Override
public void register() {
map(Types.STRING, REMOVE_DASHES); // Uuid
@@ -75,7 +75,7 @@ public class Protocol1_7_6_10To1_7_2_5 extends AbstractProtocol<ClientboundPacke
map(Types.BYTE); // Yaw
map(Types.BYTE); // Pitch
map(Types.SHORT); // Item in hand
map(Types1_7_6_10.ENTITY_DATA_LIST); // Entity data
map(RewindTypes.ENTITY_DATA_LIST1_7); // Entity data
}
});
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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,13 @@
*/
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.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
@@ -33,293 +33,294 @@ 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 boolean small = false;
private boolean marker = false;
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(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 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(false);
}
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(false);
}
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(false);
}
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
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;
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) {
currentState = State.HOLOGRAM;
} else {
currentState = State.ZOMBIE;
}
// 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(false);
}
}
State prevState = currentState;
if (invisible && name != null) {
currentState = State.HOLOGRAM;
} else {
currentState = State.ZOMBIE;
}
private void updateLocation(final boolean remount) {
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) {
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);
}
entityHeadLook.write(Types.INT, entityId);
entityHeadLook.write(Types.BYTE, (byte) ((headYaw / 360f) * 256));
// Don't ask me where this offset is coming from
teleportEntity(entityIds[0], locX, (locY + (marker ? 54.3625 : small ? 56 : 57) - 0.16), locZ, 0, 0); // Skull
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 (remount) {
teleportEntity(entityIds[1], locX, locY + 56.75, locZ, 0, 0); // Horse
// 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
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);
}
}
}
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) {
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[1]);
// 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.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));
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.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 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);
entityIds = new int[]{entityId};
} else if (currentState == State.HOLOGRAM) {
final int[] entityIds = { entityId, additionalEntityId() };
final List<EntityData> squidEntityData = new ArrayList<>();
squidEntityData.add(new EntityData(0, EntityDataTypes1_8.BYTE, (byte) 32));
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[0], EntityTypes1_8.EntityType.SQUID.getId(), locX, locY, locZ, squidEntityData);
spawnEntity(entityIds[1], EntityTypes1_8.EntityType.HORSE.getId(), locX, locY, locZ, new ArrayList<>());
spawnEntity(entityIds[1], EntityTypes1_8.EntityType.HORSE.getId(), locX, locY, locZ); // Horse
this.entityIds = entityIds;
}
this.entityIds = entityIds;
}
sendEntityDataUpdate(entityRewriter);
updateLocation(true);
}
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;
public AABB getBoundingBox() {
final double width = this.small ? 0.25 : 0.5;
final double height = this.small ? 0.9875 : 1.975;
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);
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);
return new AABB(min, max);
}
return new AABB(min, max);
}
private int additionalEntityId() {
return Integer.MAX_VALUE - 16000 - entityId;
}
private int additionalEntityId() {
return Integer.MAX_VALUE - 16000 - entityId;
}
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);
}
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);
}
private enum State {
HOLOGRAM, ZOMBIE
}
private enum State {
HOLOGRAM, ZOMBIE
}
}
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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,7 @@
*/
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;
@@ -26,15 +27,13 @@ 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));
pipeline.addBefore(Via.getManager().getInjector().getEncoderName(), ViaRewind.getPlatform().compressHandlerName(), getEncoder(threshold));
pipeline.addBefore(Via.getManager().getInjector().getDecoderName(), ViaRewind.getPlatform().decompressHandlerName(), getDecoder(threshold));
} else {
setCompressionEnabled(user, true); // We need to remove compression for 1.7 clients
}
@@ -47,12 +46,9 @@ public class TrackingCompressionHandlerProvider extends CompressionHandlerProvid
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";
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
@@ -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-2025 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
@@ -81,11 +81,11 @@ public class BlockItemPacketRewriter1_8 extends VRBlockItemRewriter<ClientboundP
protocol.registerClientbound(ClientboundPackets1_8.CONTAINER_SET_SLOT, new PacketHandlers() {
@Override
public void register() {
map(Types.UNSIGNED_BYTE); // Window id
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 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) {
@@ -100,7 +100,7 @@ public class BlockItemPacketRewriter1_8 extends VRBlockItemRewriter<ClientboundP
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(RewindTypes.COMPRESSED_NBT_ITEM, 0)));
handler(wrapper -> {
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0);
final byte windowId = wrapper.get(Types.BYTE, 0);
if (windowId != 0) {
return;
}
@@ -224,7 +224,7 @@ public class BlockItemPacketRewriter1_8 extends VRBlockItemRewriter<ClientboundP
});
protocol.registerServerbound(ServerboundPackets1_7_2_5.CONTAINER_CLOSE, wrapper -> {
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
final byte windowId = wrapper.passthrough(Types.BYTE);
wrapper.user().get(InventoryTracker.class).remove(windowId);
});
@@ -232,10 +232,10 @@ public class BlockItemPacketRewriter1_8 extends VRBlockItemRewriter<ClientboundP
protocol.registerServerbound(ServerboundPackets1_7_2_5.CONTAINER_CLICK, new PacketHandlers() {
@Override
public void register() {
map(Types.BYTE, Types.UNSIGNED_BYTE); // Window id
map(Types.BYTE); // Window id
map(Types.SHORT); // Slot
handler(wrapper -> {
final short windowId = wrapper.get(Types.UNSIGNED_BYTE, 0); // Window id
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);
@@ -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-2025 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,7 +23,6 @@ import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.api.rewriter.VREntityRewriter;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
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.protocol.v1_8to1_7_6_10.data.EntityDataIndex1_7_6_10;
@@ -41,7 +40,6 @@ import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEvent;
import com.viaversion.viaversion.util.IdAndData;
@@ -108,11 +106,11 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
@Override
public void register() {
map(Types.VAR_INT, Types.INT); // Entity id
map(Types1_8.ENTITY_DATA_LIST, Types1_7_6_10.ENTITY_DATA_LIST); // Entity data
map(Types.ENTITY_DATA_LIST1_8, RewindTypes.ENTITY_DATA_LIST1_7); // Entity data
handler(wrapper -> {
final EntityTracker1_8 tracker = tracker(wrapper.user());
final int entityId = wrapper.get(Types.INT, 0);
final List<EntityData> entityData = wrapper.get(Types1_7_6_10.ENTITY_DATA_LIST, 0);
final List<EntityData> entityData = wrapper.get(RewindTypes.ENTITY_DATA_LIST1_7, 0);
if (tracker.getHolograms().containsKey(entityId)) {
wrapper.cancel();
tracker.getHolograms().get(entityId).syncState(EntityPacketRewriter1_8.this, entityData);
@@ -145,7 +143,11 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
handler(wrapper -> {
final int entityId = wrapper.get(Types.VAR_INT, 0);
final EntityTypes1_8.EntityType type = EntityTypes1_8.getTypeFromId(wrapper.get(Types.BYTE, 0), true);
int data = wrapper.get(Types.INT, 3);
final EntityTypes1_8.EntityType type = EntityTypes1_8.ObjectType.getEntityType(wrapper.get(Types.BYTE, 0), data);
if (type == null) {
return;
}
int x = wrapper.get(Types.INT, 0);
int y = wrapper.get(Types.INT, 1);
@@ -154,8 +156,6 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
byte pitch = wrapper.get(Types.BYTE, 1);
byte yaw = wrapper.get(Types.BYTE, 2);
int data = wrapper.get(Types.INT, 3);
if (type == EntityTypes1_8.ObjectType.ITEM_FRAME.getType()) {
yaw = switch (yaw) {
case -128 -> {
@@ -184,7 +184,7 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
hologram.setPosition(x / 32.0, y / 32.0, z / 32.0);
hologram.setRotation(yaw * 360f / 256, pitch * 360f / 256);
hologram.setHeadYaw(yaw * 360f / 256);
} else if (type != null && type.isOrHasParent(EntityTypes1_8.EntityType.FALLING_BLOCK)) {
} else if (type.isOrHasParent(EntityTypes1_8.EntityType.FALLING_BLOCK)) {
int blockId = data & 0xFFF;
int blockData = data >> 12 & 0xF;
final IdAndData replace = protocol.getItemRewriter().handleBlock(blockId, blockData);
@@ -256,7 +256,7 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
map(Types.SHORT); // Velocity x
map(Types.SHORT); // Velocity y
map(Types.SHORT); // Velocity z
map(Types1_8.ENTITY_DATA_LIST, Types1_7_6_10.ENTITY_DATA_LIST); // Entity data
map(Types.ENTITY_DATA_LIST1_8, RewindTypes.ENTITY_DATA_LIST1_7); // Entity data
handler(getTrackerHandler(Types.UNSIGNED_BYTE, 0));
@@ -264,7 +264,7 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
handler(wrapper -> {
final short typeId = wrapper.get(Types.UNSIGNED_BYTE, 0);
final EntityTypes1_8.EntityType type = EntityTypes1_8.getTypeFromId(typeId, false);
final EntityTypes1_8.EntityType type = EntityTypes1_8.EntityType.findById(typeId);
if (type == EntityTypes1_8.EntityType.ARMOR_STAND) {
wrapper.cancel();
final int entityId = wrapper.get(Types.VAR_INT, 0);
@@ -282,10 +282,10 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
hologram.setPosition(x / 32.0, y / 32.0, z / 32.0);
hologram.setRotation(yaw * 360f / 256, pitch * 360f / 256);
hologram.setHeadYaw(headYaw * 360f / 256);
hologram.syncState(protocol().getEntityRewriter(), wrapper.get(Types1_7_6_10.ENTITY_DATA_LIST, 0));
hologram.syncState(protocol().getEntityRewriter(), wrapper.get(RewindTypes.ENTITY_DATA_LIST1_7, 0));
}
});
handler(getMobSpawnRewriter(Types1_7_6_10.ENTITY_DATA_LIST));
handler(getMobSpawnRewriter(RewindTypes.ENTITY_DATA_LIST1_7));
}
});
protocol.registerClientbound(ClientboundPackets1_8.ADD_PLAYER, new PacketHandlers() {
@@ -335,9 +335,9 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
map(Types.BYTE); // Yaw
map(Types.BYTE); // Pitch
map(Types.SHORT); // Current item
map(Types1_8.ENTITY_DATA_LIST, Types1_7_6_10.ENTITY_DATA_LIST); // Entity data
map(Types.ENTITY_DATA_LIST1_8, RewindTypes.ENTITY_DATA_LIST1_7); // Entity data
handler(getTrackerAndDataHandler(Types1_7_6_10.ENTITY_DATA_LIST, EntityTypes1_8.EntityType.PLAYER));
handler(getTrackerAndDataHandler(RewindTypes.ENTITY_DATA_LIST1_7, EntityTypes1_8.EntityType.PLAYER));
}
});
protocol.registerClientbound(ClientboundPackets1_8.SET_EQUIPPED_ITEM, new PacketHandlers() {
@@ -695,11 +695,11 @@ public class EntityPacketRewriter1_8 extends VREntityRewriter<ClientboundPackets
@Override
public EntityTypes1_8.EntityType typeFromId(int type) {
return EntityTypes1_8.getTypeFromId(type, false);
return EntityTypes1_8.EntityType.findById(type);
}
@Override
public EntityTypes1_8.EntityType objectTypeFromId(int type) {
return EntityTypes1_8.getTypeFromId(type, true);
public EntityTypes1_8.EntityType objectTypeFromId(int type, int data) {
return EntityTypes1_8.ObjectType.getEntityType(type, data);
}
}
@@ -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-2025 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.rewriter;
import com.viaversion.viarewind.ViaRewind;
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.protocol.v1_7_6_10to1_7_2_5.packet.ServerboundPackets1_7_2_5;
@@ -31,6 +30,7 @@ import com.viaversion.viarewind.api.minecraft.math.Ray3d;
import com.viaversion.viarewind.api.minecraft.math.RayTracing;
import com.viaversion.viarewind.api.minecraft.math.Vector3d;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.GameProfile;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@@ -123,8 +123,8 @@ public class PlayerPacketRewriter1_8 extends RewriterBase<Protocol1_8To1_7_6_10>
}
// 1.8 clients do keep entity data after respawn, 1.7 clients don't
final PacketWrapper setEntityData = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_DATA, wrapper.user());
setEntityData.write(Types.VAR_INT, tracker.clientEntityId());
setEntityData.write(Types1_7_6_10.ENTITY_DATA_LIST, tracker.getEntityData());
setEntityData.write(Types.INT, tracker.clientEntityId());
setEntityData.write(RewindTypes.ENTITY_DATA_LIST1_7, tracker.getEntityData());
setEntityData.send(Protocol1_8To1_7_6_10.class);
});
}
@@ -241,13 +241,10 @@ public class PlayerPacketRewriter1_8 extends RewriterBase<Protocol1_8To1_7_6_10>
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null) gameProfile = gameProfileStorage.put(uuid, name);
int propertyCount = wrapper.read(Types.VAR_INT);
while (propertyCount-- > 0) {
String propertyName = wrapper.read(Types.STRING);
String propertyValue = wrapper.read(Types.STRING);
String propertySignature = wrapper.read(Types.OPTIONAL_STRING);
gameProfile.properties.add(new GameProfileStorage.Property(propertyName, propertyValue, propertySignature));
}
GameProfile.Property[] properties = wrapper.read(Types.PROFILE_PROPERTY_ARRAY);
for (GameProfile.Property property : properties) {
gameProfile.properties.add(new GameProfileStorage.Property(property.name(), property.value(), property.signature()));
}
int gamemode = wrapper.read(Types.VAR_INT);
int ping = wrapper.read(Types.VAR_INT);
@@ -657,10 +654,10 @@ public class PlayerPacketRewriter1_8 extends RewriterBase<Protocol1_8To1_7_6_10>
handler(wrapper -> {
final boolean jump = wrapper.read(Types.BOOLEAN);
final boolean unmount = wrapper.read(Types.BOOLEAN);
short flags = 0;
byte flags = 0;
if (jump) flags += 0x01;
if (unmount) flags += 0x02;
wrapper.write(Types.UNSIGNED_BYTE, flags);
wrapper.write(Types.BYTE, flags);
if (!unmount) {
return;
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -42,166 +42,172 @@ import java.util.logging.Level;
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 vehicles = new Int2IntArrayMap();
private final Int2ObjectMap<UUID> entityIdToUUID = new Int2ObjectArrayMap<>();
private final Object2IntMap<UUID> entityUUIDToId = new Object2IntOpenHashMap<>();
private final List<EntityData> entityData = new ArrayList<>();
private final List<EntityData> entityData = new ArrayList<>();
public Integer spectatingClientEntityId;
private int clientEntityGameMode;
public Integer spectatingClientEntityId;
private int clientEntityGameMode;
public EntityTracker1_8(UserConnection connection) {
super(connection, EntityTypes1_8.EntityType.PLAYER);
}
public EntityTracker1_8(UserConnection connection) {
super(connection, EntityTypes1_8.EntityType.PLAYER);
}
@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));
}
}
@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));
}
}
@Override
public void removeEntity(int entityId) {
super.removeEntity(entityId);
@Override
public void removeEntity(int entityId) {
super.removeEntity(entityId);
if (entityIdToUUID.containsKey(entityId)) {
final UUID playerId = entityIdToUUID.remove(entityId);
final VirtualHologramEntity hologram = holograms.get(entityId);
if (hologram != null) {
hologram.deleteEntity();
holograms.remove(entityId);
}
entityUUIDToId.removeInt(playerId);
user().get(PlayerSessionStorage.class).getPlayerEquipment().remove(playerId);
}
}
if (entityIdToUUID.containsKey(entityId)) {
final UUID playerId = entityIdToUUID.remove(entityId);
@Override
public void clearEntities() {
super.clearEntities();
vehicles.clear();
}
entityUUIDToId.removeInt(playerId);
user().get(PlayerSessionStorage.class).getPlayerEquipment().remove(playerId);
}
}
@Override
public void setClientEntityId(int entityId) {
if (Objects.equals(this.spectatingClientEntityId, clientEntityIdOrNull())) {
this.spectatingClientEntityId = entityId;
}
super.setClientEntityId(entityId);
}
@Override
public void clearEntities() {
super.clearEntities();
vehicles.clear();
}
public Integer clientEntityIdOrNull() {
return this.hasClientEntityId() ? this.clientEntityId() : null;
}
@Override
public void setClientEntityId(int entityId) {
if (Objects.equals(this.spectatingClientEntityId, clientEntityIdOrNull())) {
this.spectatingClientEntityId = entityId;
}
super.setClientEntityId(entityId);
}
public void addPlayer(final int entityId, final UUID uuid) {
entityUUIDToId.put(uuid, entityId);
entityIdToUUID.put(entityId, uuid);
}
public Integer clientEntityIdOrNull() {
return this.hasClientEntityId() ? this.clientEntityId() : null;
}
public UUID getPlayerUUID(final int entityId) {
return entityIdToUUID.get(entityId);
}
public void addPlayer(final int entityId, final UUID uuid) {
entityUUIDToId.put(uuid, entityId);
entityIdToUUID.put(entityId, uuid);
}
public int getPlayerEntityId(final UUID uuid) {
return entityUUIDToId.getOrDefault(uuid, -1);
}
public UUID getPlayerUUID(final int entityId) {
return entityIdToUUID.get(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 int getPlayerEntityId(final UUID uuid) {
return entityUUIDToId.getOrDefault(uuid, -1);
}
public int getPassenger(int vehicleId) {
return vehicles.getOrDefault(vehicleId, -1);
}
public int getVehicle(final int passengerId) {
for (Map.Entry<Integer, Integer> vehicle : vehicles.int2IntEntrySet()) {
if (vehicle.getValue() == passengerId) {
return vehicle.getValue();
}
}
return -1;
}
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 int getPassenger(int vehicleId) {
return vehicles.getOrDefault(vehicleId, -1);
}
entityAction.sendToServer(Protocol1_8To1_7_6_10.class);
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send sneak packet", e);
}
}
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 void setPassenger(final int vehicleId, final int passengerId) {
if (vehicleId == this.spectatingClientEntityId && this.spectatingClientEntityId != this.clientEntityId()) {
startSneaking();
setSpectating(this.clientEntityId());
}
entityAction.sendToServer(Protocol1_8To1_7_6_10.class);
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send sneak packet", e);
}
}
if (vehicleId == -1) {
vehicles.remove(getVehicle(passengerId));
} else if (passengerId == -1) {
vehicles.remove(vehicleId);
} else {
vehicles.put(vehicleId, passengerId);
}
}
public void setPassenger(final int vehicleId, final int passengerId) {
if (vehicleId == this.spectatingClientEntityId && this.spectatingClientEntityId != this.clientEntityId()) {
startSneaking();
setSpectating(this.clientEntityId());
}
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
if (vehicleId == -1) {
vehicles.remove(getVehicle(passengerId));
} else if (passengerId == -1) {
vehicles.remove(vehicleId);
} else {
vehicles.put(vehicleId, passengerId);
}
}
attachEntity.scheduleSend(Protocol1_8To1_7_6_10.class);
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send attach packet", e);
}
}
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
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);
}
}
attachEntity.scheduleSend(Protocol1_8To1_7_6_10.class);
} catch (Exception e) {
ViaRewind.getPlatform().getLogger().log(Level.SEVERE, "Failed to send attach packet", e);
}
}
public Int2ObjectMap<VirtualHologramEntity> getHolograms() {
return holograms;
}
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 boolean isSpectator() {
return clientEntityGameMode == 3;
}
public Int2ObjectMap<VirtualHologramEntity> getHolograms() {
return holograms;
}
public void setClientEntityGameMode(int clientEntityGameMode) {
this.clientEntityGameMode = clientEntityGameMode;
}
public boolean isSpectator() {
return clientEntityGameMode == 3;
}
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 void setClientEntityGameMode(int clientEntityGameMode) {
this.clientEntityGameMode = clientEntityGameMode;
}
public List<EntityData> getEntityData() {
return entityData;
}
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;
}
}
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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,7 +28,6 @@ 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.*;
@@ -204,7 +203,7 @@ public class WitherBossBar implements BossBar {
entityData.add(new EntityData(3, EntityDataTypes1_8.BYTE, (byte) 1));
entityData.add(new EntityData(6, EntityDataTypes1_8.FLOAT, health * 300f));
addMob.write(Types1_8.ENTITY_DATA_LIST, entityData);
addMob.write(Types.ENTITY_DATA_LIST1_8, entityData);
addMob.scheduleSend(Protocol1_9To1_8.class);
}
@@ -228,7 +227,7 @@ public class WitherBossBar implements BossBar {
entityData.add(new EntityData(2, EntityDataTypes1_8.STRING, title));
entityData.add(new EntityData(6, EntityDataTypes1_8.FLOAT, health * 300f));
setEntityData.write(Types1_8.ENTITY_DATA_LIST, entityData);
setEntityData.write(Types.ENTITY_DATA_LIST1_8, entityData);
setEntityData.scheduleSend(Protocol1_9To1_8.class);
}
@@ -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-2025 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
@@ -107,7 +107,7 @@ public class BlockItemPacketRewriter1_9 extends VRBlockItemRewriter<ClientboundP
});
protocol.registerClientbound(ClientboundPackets1_9.CONTAINER_SET_SLOT, wrapper -> {
final byte windowId = wrapper.passthrough(Types.UNSIGNED_BYTE).byteValue();
final byte windowId = wrapper.passthrough(Types.BYTE);
final short slot = wrapper.passthrough(Types.SHORT);
final Item item = wrapper.passthrough(Types.ITEM1_8);
@@ -131,14 +131,14 @@ public class BlockItemPacketRewriter1_9 extends VRBlockItemRewriter<ClientboundP
});
protocol.registerServerbound(ServerboundPackets1_8.CONTAINER_CLOSE, wrapper -> {
final short windowId = wrapper.passthrough(Types.UNSIGNED_BYTE);
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.BYTE); // Window id
map(Types.SHORT); // Slot
map(Types.BYTE); // Button
map(Types.SHORT); // Action number
@@ -146,7 +146,7 @@ public class BlockItemPacketRewriter1_9 extends VRBlockItemRewriter<ClientboundP
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 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")) {
@@ -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-2025 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,6 +26,7 @@ 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.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.EulerAngle;
import com.viaversion.viaversion.api.minecraft.Vector;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
@@ -36,8 +37,6 @@ import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.api.type.types.version.Types1_9;
import com.viaversion.viaversion.libs.fastutil.ints.IntArrayList;
import com.viaversion.viaversion.libs.fastutil.ints.IntList;
import com.viaversion.viaversion.protocols.v1_8to1_9.data.EntityDataIndex1_9;
@@ -62,19 +61,27 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
@Override
protected void registerPackets() {
registerJoinGame1_8(ClientboundPackets1_9.LOGIN);
registerRemoveEntities(ClientboundPackets1_9.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_9.LOGIN, wrapper -> {
final int entityId = wrapper.passthrough(Types.INT);
wrapper.passthrough(Types.UNSIGNED_BYTE); // Game mode
final int dimension = wrapper.passthrough(Types.BYTE);
trackPlayer(wrapper.user(), entityId);
final ClientWorld clientWorld = wrapper.user().getClientWorld(Protocol1_9To1_8.class);
clientWorld.setEnvironment(dimension);
});
protocol.registerClientbound(ClientboundPackets1_9.SET_ENTITY_DATA, wrapper -> {
final int entityId = wrapper.passthrough(Types.VAR_INT);
if (!tracker(wrapper.user()).hasEntity(entityId)) {
wrapper.cancel();
return;
}
final List<EntityData> entityData = wrapper.read(Types1_9.ENTITY_DATA_LIST);
final List<EntityData> entityData = wrapper.read(Types.ENTITY_DATA_LIST1_9);
handleEntityData(entityId, entityData, wrapper.user());
wrapper.write(Types1_8.ENTITY_DATA_LIST, entityData);
wrapper.write(Types.ENTITY_DATA_LIST1_8, entityData);
});
protocol.registerClientbound(ClientboundPackets1_9.ADD_ENTITY, new PacketHandlers() {
@@ -97,10 +104,11 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
handler(wrapper -> {
final int entityId = wrapper.get(Types.VAR_INT, 0);
final int entityType = wrapper.get(Types.BYTE, 0);
final EntityTypes1_9.EntityType type = EntityTypes1_9.getTypeFromId(entityType, true);
int data = wrapper.get(Types.INT, 3);
final EntityTypes1_9.EntityType type = EntityTypes1_9.ObjectType.getEntityType(entityType, data);
// Cancel new entities which can't be handled properly
if (type == EntityTypes1_9.EntityType.AREA_EFFECT_CLOUD || type == EntityTypes1_9.EntityType.SPECTRAL_ARROW || type == EntityTypes1_9.EntityType.DRAGON_FIREBALL) {
if (type == null || type == EntityTypes1_9.EntityType.AREA_EFFECT_CLOUD || type == EntityTypes1_9.EntityType.SPECTRAL_ARROW || type == EntityTypes1_9.EntityType.DRAGON_FIREBALL) {
wrapper.cancel();
return;
}
@@ -115,8 +123,6 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
wrapper.set(Types.INT, 1, y);
}
int data = wrapper.get(Types.INT, 3);
if (type.isOrHasParent(EntityTypes1_9.EntityType.ARROW) && data != 0) {
wrapper.set(Types.INT, 3, --data);
}
@@ -194,10 +200,10 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
map(Types.SHORT); // Velocity x
map(Types.SHORT); // Velocity y
map(Types.SHORT); // Velocity z
map(Types1_9.ENTITY_DATA_LIST, Types1_8.ENTITY_DATA_LIST); // Entity data
map(Types.ENTITY_DATA_LIST1_9, Types.ENTITY_DATA_LIST1_8); // Entity data
handler(getTrackerHandler(Types.UNSIGNED_BYTE, 0));
handler(getMobSpawnRewriter(Types1_8.ENTITY_DATA_LIST));
handler(getMobSpawnRewriter(Types.ENTITY_DATA_LIST1_8));
}
});
@@ -227,9 +233,9 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
map(Types.BYTE); // Yaw
map(Types.BYTE); // Pitch
create(Types.SHORT, (short) 0); // Current item
map(Types1_9.ENTITY_DATA_LIST, Types1_8.ENTITY_DATA_LIST); // Entity data
map(Types.ENTITY_DATA_LIST1_9, Types.ENTITY_DATA_LIST1_8); // Entity data
handler(getTrackerAndDataHandler(Types1_8.ENTITY_DATA_LIST, EntityTypes1_9.EntityType.PLAYER));
handler(getTrackerAndDataHandler(Types.ENTITY_DATA_LIST1_8, EntityTypes1_9.EntityType.PLAYER));
}
});
@@ -325,11 +331,12 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
public void register() {
handler(wrapper -> {
final EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
final int vehicle = tracker.getVehicle(tracker.clientEntityId());
if (vehicle == -1) {
final Integer vehicle = tracker.getVehicle(tracker.clientEntityId());
if (vehicle == null) {
wrapper.cancel();
}
wrapper.write(Types.VAR_INT, vehicle);
} else {
wrapper.write(Types.VAR_INT, vehicle);
}
});
map(Types.DOUBLE, Protocol1_9To1_8.DOUBLE_TO_INT_TIMES_32); // X
map(Types.DOUBLE, Protocol1_9To1_8.DOUBLE_TO_INT_TIMES_32); // Y
@@ -340,6 +347,7 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
if (wrapper.isCancelled()) {
return;
}
final PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
double x = wrapper.get(Types.INT, 0) / 32d;
double y = wrapper.get(Types.INT, 1) / 32d;
@@ -348,6 +356,10 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
});
create(Types.BOOLEAN, true);
handler(wrapper -> {
if (wrapper.isCancelled()) {
return;
}
final int entityId = wrapper.get(Types.VAR_INT, 0);
final EntityType type = wrapper.user().getEntityTracker(Protocol1_9To1_8.class).entityType(entityId);
if (type == EntityTypes1_9.EntityType.BOAT) {
@@ -623,11 +635,11 @@ public class EntityPacketRewriter1_9 extends VREntityRewriter<ClientboundPackets
@Override
public EntityTypes1_9.EntityType typeFromId(int type) {
return EntityTypes1_9.getTypeFromId(type, false);
return EntityTypes1_9.EntityType.findById(type);
}
@Override
public EntityTypes1_9.EntityType objectTypeFromId(int type) {
return EntityTypes1_9.getTypeFromId(type, true);
public EntityTypes1_9.EntityType objectTypeFromId(int type, int data) {
return EntityTypes1_9.ObjectType.getEntityType(type, data);
}
}
@@ -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-2025 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,6 +21,7 @@ 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.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_9;
import com.viaversion.viaversion.api.minecraft.item.Item;
@@ -30,7 +31,6 @@ 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.version.Types1_8;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
@@ -176,7 +176,8 @@ public class PlayerPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
final int dimension = wrapper.get(Types.INT, 0);
if (world.setEnvironment(dimension)) {
protocol.getEntityRewriter().clearEntities(wrapper.user());
final EntityTracker tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
tracker.clearEntities();
wrapper.user().get(BossBarStorage.class).reset();
}
});
@@ -280,14 +281,14 @@ public class PlayerPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
map(Types.DOUBLE); // Z
map(Types.BOOLEAN); // On ground
handler(wrapper -> {
wrapper.user().get(PlayerPositionTracker.class).sendAnimations();
final PlayerPositionTracker pos = wrapper.user().get(PlayerPositionTracker.class);
if (pos.getConfirmId() != -1) {
final PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
storage.sendAnimations();
if (storage.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));
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());
}
@@ -300,13 +301,15 @@ public class PlayerPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
map(Types.FLOAT); // Pitch
map(Types.BOOLEAN); // On ground
handler(wrapper -> {
wrapper.user().get(PlayerPositionTracker.class).sendAnimations();
final PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
storage.sendAnimations();
if (storage.getConfirmId() != -1) {
return;
}
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));
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());
}
@@ -320,7 +323,7 @@ public class PlayerPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
final float pitch = wrapper.passthrough(Types.FLOAT);
final boolean onGround = wrapper.passthrough(Types.BOOLEAN);
PlayerPositionTracker storage = wrapper.user().get(PlayerPositionTracker.class);
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) {
@@ -419,9 +422,9 @@ public class PlayerPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
final float forward = wrapper.passthrough(Types.FLOAT);
final EntityTracker1_9 tracker = wrapper.user().getEntityTracker(Protocol1_9To1_8.class);
final int vehicle = tracker.getVehicle(tracker.clientEntityId());
final Integer vehicle = tracker.getVehicle(tracker.clientEntityId());
if (vehicle != -1 && tracker.entityType(vehicle) == EntityTypes1_9.EntityType.BOAT) {
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);
@@ -468,7 +471,7 @@ public class PlayerPacketRewriter1_9 extends RewriterBase<Protocol1_9To1_8> {
final List<EntityData> entityData = new ArrayList<>();
entityData.add(new EntityData(10, EntityDataTypes1_8.BYTE, (byte) flags));
updateSkin.write(Types1_8.ENTITY_DATA_LIST, entityData);
updateSkin.write(Types.ENTITY_DATA_LIST1_8, entityData);
updateSkin.scheduleSend(Protocol1_9To1_8.class);
});
}
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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
@@ -74,11 +74,11 @@ public class EntityTracker1_9 extends EntityTrackerBase {
return false;
}
public int getVehicle(final int passenger) {
public Integer getVehicle(final int passenger) {
for (Map.Entry<Integer, IntList> vehicle : vehicles.int2ObjectEntrySet()) {
if (vehicle.getValue().contains(passenger)) return vehicle.getKey();
}
return -1;
return null;
}
public Int2IntMap getStatus() {
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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,8 +24,8 @@ import com.viaversion.viaversion.api.minecraft.item.DataItem;
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.libs.mcstructs.core.TextFormatting;
import com.viaversion.viaversion.libs.mcstructs.text.ATextComponent;
import com.viaversion.viaversion.libs.mcstructs.text.TextComponent;
import com.viaversion.viaversion.libs.mcstructs.text.TextFormatting;
import com.viaversion.viaversion.libs.mcstructs.text.components.StringComponent;
import com.viaversion.viaversion.libs.mcstructs.text.components.TranslationComponent;
import com.viaversion.viaversion.libs.mcstructs.text.serializer.TextComponentSerializer;
@@ -90,7 +90,7 @@ public class WindowTracker extends StoredObject {
openWindow.write(Types.UNSIGNED_BYTE, windowId);
openWindow.write(Types.STRING, "minecraft:brewing_stand");
ATextComponent title = new StringComponent().
TextComponent title = new StringComponent().
append(new TranslationComponent("container.brewing")).
append(new StringComponent(": " + TextFormatting.DARK_GRAY)).
append(new StringComponent(amount + " " + TextFormatting.DARK_RED)).
@@ -103,7 +103,7 @@ public class WindowTracker extends StoredObject {
Item[] items = user.get(WindowTracker.class).getBrewingItems(windowId);
for (int i = 0; i < items.length; i++) {
PacketWrapper setSlot = PacketWrapper.create(ClientboundPackets1_8.CONTAINER_SET_SLOT, user);
setSlot.write(Types.UNSIGNED_BYTE, windowId);
setSlot.write(Types.BYTE, (byte) windowId);
setSlot.write(Types.SHORT, (short) i);
setSlot.write(Types.ITEM1_8, items[i]);
setSlot.scheduleSend(Protocol1_9To1_8.class);
@@ -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-2025 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
@@ -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-2025 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
@@ -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-2025 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,7 +24,7 @@ import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonParser;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.rewriter.text.JsonNBTComponentRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import java.util.logging.Level;
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
@Deprecated
public class ChatUtil {
private static final Pattern UNUSED_COLOR_PATTERN = Pattern.compile("(?>(?>§[0-fk-or])*(§r|\\Z))|(?>(?>§[0-f])*(§[0-f]))");
private static final ComponentRewriter<ClientboundPacketType> LEGACY_REWRITER = new ComponentRewriter<ClientboundPacketType>(null, ComponentRewriter.ReadType.JSON) {
private static final JsonNBTComponentRewriter<ClientboundPacketType> LEGACY_REWRITER = new JsonNBTComponentRewriter<>(null, JsonNBTComponentRewriter.ReadType.JSON) {
@Override
protected void handleTranslate(JsonObject object, String translate) {
String text = Protocol1_12_2To1_13.MAPPINGS.getMojangTranslation().get(translate);
@@ -29,7 +29,6 @@ emulate-world-border: true
always-show-original-mob-name: true
#
# The particle to show the world border for the 1.8+ world border for 1.7.x clients
# sees https://wiki.vg/index.php?title=Protocol&oldid=7368#Particle_2
world-border-particle: 'fireworksSpark'
#
# If enabled, 1.8 players on 1.9+ servers can use /offhand to switch items between their main hand and offhand.
@@ -207,28 +207,28 @@
"data": "-1"
},
"198:0": {
"id": "50",
"data": "5"
"id": "160",
"data": "0"
},
"198:1": {
"id": "50",
"data": "5"
"id": "160",
"data": "0"
},
"198:2": {
"id": "50",
"data": "4"
"id": "160",
"data": "0"
},
"198:3": {
"id": "50",
"data": "3"
"id": "160",
"data": "0"
},
"198:4": {
"id": "50",
"data": "2"
"id": "160",
"data": "0"
},
"198:5": {
"id": "50",
"data": "1"
"id": "160",
"data": "0"
},
"204": {
"id": "43",
@@ -251,4 +251,4 @@
"data": "0"
}
}
}
}
-21
View File
@@ -1,21 +0,0 @@
plugins {
id "vr.platform-conventions"
}
repositories {
maven {
name = "FabricMC"
url "https://maven.fabricmc.net/"
}
}
dependencies {
compileOnly(annotationProcessor("net.fabricmc:fabric-loader:0.11.3"))
compileOnly(annotationProcessor("org.apache.logging.log4j:log4j-api:2.17.1"))
}
processResources {
filesMatching("fabric.mod.json") {
expand("version": project.version, "description": project.description)
}
}
+5
View File
@@ -0,0 +1,5 @@
dependencies {
compileOnly(project(":viarewind-common"))
compileOnly("net.fabricmc:fabric-loader:0.11.3")
compileOnly("org.apache.logging.log4j:log4j-api:2.17.1")
}
Loaded 100 of 116 files, more files were not shown because too many files have changed in this diff. Show more