22 Commits
Author SHA1 Message Date
dependabot[bot] 5e1cf69ebe Update Gradle wrapper (#107)
Bumps the all-dependencies group with 1 update: [gradle-wrapper](https://github.com/gradle/gradle).


Updates `gradle-wrapper` from 9.7.1 to 9.8.2
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.7.1...v9.8.2)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.8.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-11-01 14:00:45 +01:00
dependabot[bot] 18988d97c0 Update GH actions (#108)
Bumps the all-dependencies group with 3 updates in the / directory: [gradle/actions/setup-gradle](https://github.com/gradle/actions), [actions/setup-java](https://github.com/actions/setup-java) and [actions/upload-artifact](https://github.com/actions/upload-artifact).


Updates `gradle/actions/setup-gradle` from 6.3.0 to 6.4.0
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/9c971963bec38e04b3d30dcc455b5382be2fdbfb...3f5f9adaf7d9fecd50b5935e54106014257a94e6)

Updates `actions/setup-java` from 6.0.0 to 6.1.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/dd06d9cba3e5552c54d9f8ea23572deb30010f7c...b843ebf9b913146b38da2eaa7aeddf76074ae1ad)

Updates `actions/upload-artifact` from 7.0.1 to 7.0.2
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a...cf430e030ddbb5b0abf93d22962f4752f3646cd9)

---
updated-dependencies:
- dependency-name: gradle/actions/setup-gradle
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-dependencies
- dependency-name: actions/setup-java
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-dependencies
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-11-01 14:00:27 +01:00
Florian Reuth 15045d2188 Update BaseProject
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-09-28 17:51:38 +02:00
dependabot[bot] ee905820eb Update deps (#105)
Bumps the all-dependencies group with 2 updates in the / directory: de.florianreuth.baseproject and [gradle-wrapper](https://github.com/gradle/gradle).


Updates `de.florianreuth.baseproject` from 3.0.0 to 3.0.2

Updates `gradle-wrapper` from 9.7.0 to 9.7.1
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.7.0...v9.7.1)

---
updated-dependencies:
- dependency-name: de.florianreuth.baseproject
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-dependencies
- dependency-name: gradle-wrapper
  dependency-version: 9.7.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-28 12:17:59 +02:00
Florian Reuth c62c7ed62a 26.3
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-09-18 17:18:58 +02:00
dependabot[bot] 53bde6ba43 [ci skip] Update GH actions (#104)
Bumps the all-dependencies group with 2 updates: [gradle/actions/setup-gradle](https://github.com/gradle/actions) and [actions/setup-java](https://github.com/actions/setup-java).


Updates `gradle/actions/setup-gradle` from 6.2.0 to 6.3.0
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/v6.2.0...9c971963bec38e04b3d30dcc455b5382be2fdbfb)

Updates `actions/setup-java` from 5.6.0 to 6.0.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v5.6.0...dd06d9cba3e5552c54d9f8ea23572deb30010f7c)

---
updated-dependencies:
- dependency-name: gradle/actions/setup-gradle
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-dependencies
- dependency-name: actions/setup-java
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-02 15:29:30 +02:00
dependabot[bot] 3eac764559 Update deps (#102)
Bumps the all-dependencies group with 2 updates in the / directory: io.papermc.hangar-publish-plugin and [gradle-wrapper](https://github.com/gradle/gradle).


Updates `io.papermc.hangar-publish-plugin` from 0.1.3 to 0.1.4

Updates `gradle-wrapper` from 9.3.0 to 9.7.0
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](https://github.com/gradle/gradle/compare/v9.3.0...v9.7.0)

---
updated-dependencies:
- dependency-name: io.papermc.hangar-publish-plugin
  dependency-version: 0.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-dependencies
- dependency-name: gradle-wrapper
  dependency-version: 9.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-19 16:16:00 +02:00
Florian Reuth 34ce9102e1 Sync publish workflow as well
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-08-19 16:13:47 +02:00
dependabot[bot] d63b405bdb [ci skip] Update GH actions (#101)
Bumps the all-dependencies group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [gradle/actions/setup-gradle](https://github.com/gradle/actions), [actions/setup-java](https://github.com/actions/setup-java) and [gradle/actions](https://github.com/gradle/actions).


Updates `actions/checkout` from 4 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Commits](https://github.com/actions/checkout/compare/v4...v7)

Updates `gradle/actions/setup-gradle` from 6.2.0 to 6.3.0
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/3f131e8634966bd73d06cc69884922b02e6faf92...9c971963bec38e04b3d30dcc455b5382be2fdbfb)

Updates `actions/setup-java` from 4 to 5
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v4...v5)

Updates `gradle/actions` from 4 to 6
- [Release notes](https://github.com/gradle/actions/releases)
- [Commits](https://github.com/gradle/actions/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-dependencies
- dependency-name: gradle/actions/setup-gradle
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: all-dependencies
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-dependencies
- dependency-name: gradle/actions
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-19 16:10:24 +02:00
Florian Reuth dc51b8899c Update BaseProject
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-08-19 16:09:54 +02:00
Florian Reuth d3b6a41bc6 Update GH files
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-08-19 16:04:47 +02:00
Dreeam bcfa25eec9 Add support for Minecraft 26.1+; Bump Java version to 17 (#97) 2026-07-28 18:28:57 +02:00
Florian Reuth e68e15dd9f 26.2
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-06-19 21:54:41 +02:00
Florian Reuth 788d87086e 26.1.1
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-04-02 20:53:51 +02:00
Florian Reuth 03a6fe6c2a Update my name
Signed-off-by: Florian Reuth <git@florianreuth.de>
2026-02-07 16:29:22 +01:00
FlorianMichael 54523d7de9 Gradle 9.3.0
Signed-off-by: FlorianMichael <git@florianmichael.de>
2026-01-18 13:36:14 +01:00
FlorianMichael 33c3c4c641 Prepare for next year (2026) 2025-12-29 00:20:14 +01:00
FlorianMichael 5a0f6621cf Start 1.5.5 cycle 2025-12-12 16:18:00 +01:00
FlorianMichael ba47756eb8 ViaRewind Legacy Support 1.5.4 2025-12-12 16:16:45 +01:00
FlorianMichael e700bca43e Gradle 9.2.0 2025-11-03 16:18:55 +01:00
FlorianMichael 91b9f6d9b7 [ci skip] Reformat all files 2025-10-28 20:18:48 +01:00
xUS4R 2494d08d3e Fix ladder bounding boxes (#95) 2025-10-28 20:16:49 +01:00
34 changed files with 871 additions and 311 deletions

No files matched your search

+2 -2
View File
@@ -1,2 +1,2 @@
github: FlorianMichael
custom: ['https://florianmichael.de/donate', 'https://creeper123123321.github.io/#donate']
github: florianreuth
custom: ['https://florianreuth.de/donate', 'https://creeper123123321.github.io/#donate']
+22
View File
@@ -0,0 +1,22 @@
version: 2
updates:
- package-ecosystem: "gradle"
cooldown:
default-days: 7
directory: "/"
schedule:
interval: "monthly"
groups:
all-dependencies:
patterns:
- "*"
- package-ecosystem: "github-actions"
cooldown:
default-days: 7
directory: "/"
schedule:
interval: "monthly"
groups:
all-dependencies:
patterns:
- "*"
+19 -8
View File
@@ -1,21 +1,32 @@
name: Build
on: [pull_request, push, workflow_dispatch]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-22.04
runs-on: ubuntu-26.04
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0
with:
cache-disabled: true
cache-provider: basic
- name: Set up Java
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
with:
distribution: 'temurin'
java-version: 17
java-version: 25
check-latest: true
- name: Build with Gradle
run: ./gradlew build
run: ./gradlew build --stacktrace
- name: Upload Artifacts to GitHub
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: Artifacts
path: build/libs/
if-no-files-found: error
+11 -7
View File
@@ -8,21 +8,25 @@ on:
jobs:
publish:
if: github.repository_owner == 'ViaVersion'
runs-on: ubuntu-22.04
runs-on: ubuntu-26.04
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0
with:
cache-disabled: true
cache-provider: basic
- name: Set up Java
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
with:
distribution: 'temurin'
java-version: 17
java-version: 25
check-latest: true
- name: Publish
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
run: ./gradlew build publishAllPublicationsToHangar
run: ./gradlew build publishAllPublicationsToHangar --stacktrace
+7
View File
@@ -0,0 +1,7 @@
plugins {
`kotlin-dsl`
}
dependencies {
implementation(libs.foojay.resolver.convention.plugin)
}
+10
View File
@@ -0,0 +1,10 @@
dependencyResolutionManagement {
repositories {
gradlePluginPortal()
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
@@ -0,0 +1,39 @@
plugins {
`java-library`
}
group = property("project_group") as String
version = property("project_version") as String
description = property("project_description") as String
if (project == rootProject) {
(findProperty("project_name") as String?)?.let { base.archivesName = it }
}
// The Kotlin plugin picks up the Java toolchain, so no Kotlin specific configuration is needed
val jvmVersion = (property("jvm_version") as String).toInt()
java {
toolchain.languageVersion = JavaLanguageVersion.of(jvmVersion)
sourceCompatibility = JavaVersion.toVersion(jvmVersion)
targetCompatibility = JavaVersion.toVersion(jvmVersion)
}
tasks.withType<JavaCompile>().configureEach {
options.encoding = "UTF-8"
options.compilerArgs.addAll(listOf("-nowarn", "-Xlint:-unchecked", "-Xlint:-deprecation"))
}
tasks.withType<Javadoc>().configureEach {
options.encoding = "UTF-8"
(options as StandardJavadocDocletOptions).apply {
addBooleanOption("Xdoclint:none", true)
quiet()
}
}
tasks.jar {
val projectName = project.name
from("LICENSE") {
rename { "LICENSE_$projectName" }
}
}
@@ -0,0 +1,60 @@
plugins {
`java-library`
`maven-publish`
signing
}
val projectName = property("project_name") as String
val ownerId = property("publish_owner_id") as String
val ownerName = property("publish_owner_name") as String
val ownerMail = property("publish_owner_mail") as String
val githubAccount = findProperty("publish_github_account") as String? ?: ownerId
val licenseName = findProperty("publish_license") as String? ?: "Apache-2.0"
val githubRepository = "github.com/$githubAccount/$projectName"
java {
withSourcesJar()
withJavadocJar()
}
publishing {
publications {
create<MavenPublication>("maven") {
groupId = project.group.toString()
artifactId = project.name
version = project.version.toString()
from(components["java"])
pom {
name = projectName
// Lazy so that a description set in the build script body is picked up
description = provider { project.description }
url = "https://$githubRepository"
licenses {
license {
name = licenseName
url = "https://$githubRepository/blob/main/LICENSE"
}
}
developers {
developer {
id = ownerId
name = ownerName
email = ownerMail
}
}
scm {
connection = "scm:git:git://$githubRepository.git"
developerConnection = "scm:git:ssh://$githubRepository.git"
url = "https://$githubRepository"
}
}
}
}
}
signing {
isRequired = false
sign(publishing.publications)
}
@@ -0,0 +1,14 @@
plugins {
id("org.gradle.toolchains.foojay-resolver-convention")
}
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
dependencyResolutionManagement {
// Repositories live in the settings only, a project or plugin declaring its own fails the build
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories {
mavenCentral()
maven("https://maven.florianreuth.de/releases")
}
}
@@ -0,0 +1,59 @@
package de.florianreuth.baseproject
import org.gradle.api.Project
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.ValueSource
import org.gradle.api.provider.ValueSourceParameters
import org.gradle.process.ExecOperations
import java.io.ByteArrayOutputStream
import javax.inject.Inject
/**
* Short hash of the latest commit, or "unknown" if Git is unavailable.
*/
fun Project.latestCommitHash(): String = runGitCommand(listOf("rev-parse", "--short", "HEAD"))
/**
* Message of the latest commit, or "unknown" if Git is unavailable.
*/
fun Project.latestCommitMessage(): String = runGitCommand(listOf("log", "-1", "--pretty=%B"))
/**
* Name of the current branch, or "unknown" if Git is unavailable.
*/
fun Project.branchName(): String = runGitCommand(listOf("rev-parse", "--abbrev-ref", "HEAD"))
/**
* Runs a Git command through a configuration-cache compatible [ValueSource].
*
* @param args the arguments passed to `git`
* @return the trimmed output, or "unknown" if the command fails or prints nothing
*/
fun Project.runGitCommand(args: List<String>): String {
return providers.of(GitCommand::class.java) { parameters.args.set(args) }.getOrNull() ?: "unknown"
}
abstract class GitCommand : ValueSource<String, GitCommand.GitCommandParameters> {
@get:Inject
abstract val execOperations: ExecOperations
interface GitCommandParameters : ValueSourceParameters {
val args: ListProperty<String>
}
override fun obtain(): String? {
try {
val output = ByteArrayOutputStream()
execOperations.exec {
commandLine = listOf("git") + parameters.args.get()
standardOutput = output
isIgnoreExitValue = true
}
return output.toString(Charsets.UTF_8).trim().takeIf { it.isNotBlank() }
} catch (_: Exception) {
return null
}
}
}
@@ -0,0 +1,78 @@
/*
* This file is part of BaseProject - https://github.com/florianreuth/BaseProject
* Copyright (C) 2024-2026 Florian Reuth <git@florianreuth.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.florianreuth.baseproject
import org.gradle.api.Project
import org.gradle.api.initialization.Settings
/**
* Includes `<rootProject.name>-<name>` for every name, located in the `<name>` folder.
*
* @param names the subproject folder names
*/
fun Settings.setupViaSubprojects(vararg names: String) {
names.forEach { name ->
include("${rootProject.name}-$name")
project(":${rootProject.name}-$name").projectDir = settingsDir.resolve(name)
}
}
/**
* Version, channel and changelog of a Modrinth / Hangar upload of a ViaVersion project.
*
* @property isRelease whether the project version has no pre-release suffix
* @property isMainBranch whether the current Git branch is the main branch
* @property version the project version, suffixed with the GitHub run number for non-releases
* @property changelog a link to the GitHub releases for releases, otherwise [commitChangelog]
* @property commitChangelog a link to and the message of the latest commit
*/
class ViaRelease(
val isRelease: Boolean,
val isMainBranch: Boolean,
val version: String,
val changelog: String,
val commitChangelog: String
) {
val modrinthVersionType: String
get() = if (isRelease) "release" else if (isMainBranch) "beta" else "alpha"
val hangarChannel: String
get() = if (isRelease) "Release" else if (isMainBranch) "Snapshot" else "Alpha"
}
/**
* Collects the release information from the project version and Git; the repository is `ViaVersion/<project_name>`.
*
* @param mainBranch the name of the branch releases are published from
* @return the release information of the current build
*/
fun Project.viaRelease(mainBranch: String): ViaRelease {
val baseVersion = version.toString()
val isRelease = !baseVersion.contains('-')
val repository = "https://github.com/ViaVersion/${property("project_name")}"
val commitHash = latestCommitHash()
val commitChangelog = "[$commitHash]($repository/commit/$commitHash) ${latestCommitMessage()}"
return ViaRelease(
isRelease = isRelease,
isMainBranch = branchName() == mainBranch,
version = if (isRelease) baseVersion else baseVersion + "+" + System.getenv("GITHUB_RUN_NUMBER"),
changelog = if (isRelease) "See [GitHub]($repository) for release notes." else commitChangelog,
commitChangelog = commitChangelog
)
}
@@ -0,0 +1,19 @@
plugins {
`maven-publish`
}
publishing {
repositories {
maven {
name = "Via"
url = uri("https://repo.viaversion.com/")
credentials {
username = findProperty("ViaUsername") as String?
password = findProperty("ViaPassword") as String?
}
authentication {
create<BasicAuthentication>("basic")
}
}
}
}
@@ -0,0 +1,8 @@
plugins {
id("publishing.viaversion")
}
// base.maven_publish reads these when applied, so it is applied only after they are set
extra["publish_github_account"] = "ViaVersion"
extra["publish_license"] = "GPL-3.0"
apply(plugin = "base.maven_publish")
+10 -28
View File
@@ -1,27 +1,15 @@
import de.florianmichael.baseproject.*
import de.florianreuth.baseproject.viaRelease
plugins {
`java-library`
id("io.papermc.hangar-publish-plugin")
id("de.florianmichael.baseproject.BaseProject")
alias(libs.plugins.hangar.publish)
id("base.java")
id("via.maven_publish")
}
repositories {
maven("https://repo.viaversion.com")
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
maven("https://repo.maven.apache.org/maven2/")
}
setupProject()
setupViaPublishing()
dependencies {
compileOnly("com.viaversion:viaversion-api:4.10.0")
compileOnly("org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT")
}
base {
archivesName.set("ViaRewind-Legacy-Support")
compileOnly(libs.viaversion.api)
compileOnly(libs.spigot.api)
}
tasks {
@@ -34,19 +22,13 @@ tasks {
}
}
val branch = branchName()
val baseVersion = version as String
val isRelease = !baseVersion.contains('-')
val suffixedVersion = if (isRelease) baseVersion else baseVersion + "+" + System.getenv("GITHUB_RUN_NUMBER")
val commitHash = latestCommitHash()
val changelogContent = "[${commitHash}](https://github.com/ViaVersion/iaRewind-Legacy-Support/commit/${commitHash}) ${latestCommitMessage()}"
val isMainBranch = branch == "master"
val release = viaRelease("master")
hangarPublish {
publications.register("plugin") {
version.set(suffixedVersion)
version.set(release.version)
id.set("ViaRewindLegacySupport")
channel.set(if (isRelease) "Release" else if (isMainBranch) "Snapshot" else "Alpha")
changelog.set(changelogContent)
channel.set(release.hangarChannel)
changelog.set(release.commitChangelog)
apiKey.set(System.getenv("HANGAR_TOKEN"))
platforms {
paper {
+7 -6
View File
@@ -4,15 +4,16 @@ org.gradle.parallel=true
org.gradle.configuration-cache=true
# Project Details
project_jvm_version=8
jvm_version=17
project_group=com.viaversion
project_version=1.5.3
project_name=ViaRewind-Legacy-Support
project_version=1.5.5-SNAPSHOT
project_description=Provides additional features for ViaRewind for Paper servers.
publishing_dev_id=FlorianMichael
publishing_dev_name=EnZaXD
publishing_dev_mail=florian.michael07@gmail.com
publish_owner_id=florianreuth
publish_owner_name=Florian Reuth
publish_owner_mail=git@florianreuth.de
# Hangar Publishing
minecraft_version_range=1.8-1.21.9
minecraft_version_range=1.8-26.3
+7
View File
@@ -0,0 +1,7 @@
[libraries]
foojay-resolver-convention-plugin = { module = "org.gradle.toolchains.foojay-resolver-convention:org.gradle.toolchains.foojay-resolver-convention.gradle.plugin", version = "1.0.0" }
viaversion-api = { module = "com.viaversion:viaversion-api", version = "5.10.0" }
spigot-api = { module = "org.spigotmc:spigot-api", version = "1.16.5-R0.1-SNAPSHOT" }
[plugins]
hangar-publish = { id = "io.papermc.hangar-publish-plugin", version = "0.1.4" }
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=a17ddd85a26b6a7f5ddb71ff8b05fc5104c0202c6e64782429790c933686c806
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
distributionSha256Sum=21bd5da2de49b642904077f38c0efdc7778e92b3ed0889392dca61b97e389607
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+3 -3
View File
@@ -20,7 +20,7 @@
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
# gradlew start up script for POSIX generated by Gradle.
#
# Important for running:
#
@@ -29,7 +29,7 @@
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
# ksh gradlew
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Vendored
+112 -93
View File
@@ -1,93 +1,112 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem gradlew startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables, and ensure extensions are enabled
setlocal EnableExtensions
@rem Catch executions from older scripts and ensure they exit cleanly.
@rem This can be removed once we can be reasonably confident that few people
@rem will be migrating directly to this new wrapper.
goto afterSafetyNet
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
goto exitWithErrorLevel
:afterSafetyNet
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
1>&2 echo.
1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
1>&2 echo.
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
1>&2 echo location of your Java installation.
"%COMSPEC%" /c exit 1
goto exitWithErrorLevel
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
1>&2 echo.
1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
1>&2 echo.
1>&2 echo Please set the JAVA_HOME variable in your environment to match the
1>&2 echo location of your Java installation.
"%COMSPEC%" /c exit 1
goto exitWithErrorLevel
:execute
@rem Setup the command line
@rem Execute gradlew
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel & goto exitWithErrorLevel
@rem This label must not be changed. We rely on old scripts being able to jump to this point.
:exitWithErrorLevel
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
"%COMSPEC%" /c exit %ERRORLEVEL%
+9 -10
View File
@@ -1,17 +1,16 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
plugins {
id("de.florianmichael.baseproject.BaseProject") version "1.1.1"
id("io.papermc.hangar-publish-plugin") version "0.1.3"
}
includeBuild("build-logic")
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
id("base.settings")
}
dependencyResolutionManagement {
repositories {
maven("https://repo.viaversion.com")
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
}
}
rootProject.name = "viarewind-legacy-support"
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,15 +19,15 @@
package com.viaversion.viarewind.legacysupport;
import com.viaversion.viarewind.legacysupport.feature.AnvilCostFix;
import com.viaversion.viarewind.legacysupport.feature.BlockCollisionChanges;
import com.viaversion.viarewind.legacysupport.versioninfo.VersionInformer;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viarewind.legacysupport.feature.AreaEffectCloudEmulator;
import com.viaversion.viarewind.legacysupport.feature.SlimeBounceEmulator;
import com.viaversion.viarewind.legacysupport.feature.BlockCollisionChanges;
import com.viaversion.viarewind.legacysupport.feature.BlockPlaceSoundEmulator;
import com.viaversion.viarewind.legacysupport.feature.BrewingInteractionEmulator;
import com.viaversion.viarewind.legacysupport.feature.ElytraVelocityEmulator;
import com.viaversion.viarewind.legacysupport.feature.EnchantingGuiEmulator;
import com.viaversion.viarewind.legacysupport.feature.BlockPlaceSoundEmulator;
import com.viaversion.viarewind.legacysupport.feature.SlimeBounceEmulator;
import com.viaversion.viarewind.legacysupport.versioninfo.VersionInformer;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@ package com.viaversion.viarewind.legacysupport.feature;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viarewind.legacysupport.util.NMSUtil;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
@@ -27,7 +28,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
import java.util.logging.Level;
public class AnvilCostFix implements Listener {
@EventHandler
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,10 +18,13 @@
package com.viaversion.viarewind.legacysupport.feature;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viarewind.legacysupport.util.NMSUtil;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.ArrayList;
import java.util.Set;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Particle;
@@ -31,10 +34,6 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.LingeringPotionSplashEvent;
import java.util.ArrayList;
import java.util.Set;
import java.util.stream.Collectors;
@SuppressWarnings("unchecked")
public class AreaEffectCloudEmulator implements Listener {
private final ArrayList<AreaEffectCloud> effectClouds = new ArrayList<>();
@@ -47,8 +46,8 @@ public class AreaEffectCloudEmulator implements Listener {
final Location location = cloud.getLocation();
final float radius = cloud.getRadius();
final Object data = NMSUtil.NEWER_THAN_V1_20_5
? cloud.getColor()
: null;
? cloud.getColor()
: null;
float area = (float) Math.PI * radius * radius;
@@ -68,11 +67,11 @@ public class AreaEffectCloudEmulator implements Listener {
affectedPlayers.stream().filter(player -> player.getWorld() == location.getWorld()).forEach(player -> {
player.spawnParticle(
cloud.getParticle(),
location.getX() + f3, location.getY(), location.getZ() + f6,
0,
r / 255f, g / 255f, b / 255f,
data
cloud.getParticle(),
location.getX() + f3, location.getY(), location.getZ() + f6,
0,
r / 255f, g / 255f, b / 255f,
data
);
});
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,25 +18,29 @@
package com.viaversion.viarewind.legacysupport.feature;
import com.viaversion.viarewind.legacysupport.util.NMSUtil;
import com.viaversion.viarewind.legacysupport.util.ReflectionUtil;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.viaversion.viarewind.legacysupport.util.ReflectionUtil.*;
import static com.viaversion.viarewind.legacysupport.util.NMSUtil.*;
import static com.viaversion.viarewind.legacysupport.util.NMSUtil.getNMSBlockClass;
import static com.viaversion.viarewind.legacysupport.util.ReflectionUtil.getFieldAccessible;
public class BlockCollisionChanges {
public static void fixLilyPad(final Logger logger, final ProtocolVersion serverVersion) {
try {
final Field boundingBoxField = getFieldAccessible(getNMSBlockClass("BlockWaterLily"), serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2) ? "a" : "b");
final String BlockWaterLilyClassName = NMSUtil.NEWER_THAN_V26_1 ? "LilyPadBlock" : "BlockWaterLily";
final String boundingBoxFieldName = NMSUtil.NEWER_THAN_V26_1 ? "SHAPE" : serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_3) ? "b" : "a";
final Field boundingBoxField = getFieldAccessible(getNMSBlockClass(BlockWaterLilyClassName), boundingBoxFieldName);
setBoundingBox(boundingBoxField.get(null), 0.0625, 0.0, 0.0625, 0.9375, 0.015625, 0.9375);
} catch (Exception ex) {
@@ -46,9 +50,10 @@ public class BlockCollisionChanges {
public static void fixCarpet(final Logger logger, final ProtocolVersion serverVersion) {
try {
final Class<?> blockCarpetClass = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_16_4) ? getNMSBlockClass("BlockCarpet") : getNMSBlockClass("CarpetBlock");
final String boundingBoxFieldName = NMSUtil.NEWER_THAN_V26_1 ? "SHAPE" : serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_3) ? "b" : "a";
final String blockCarpetClassName = serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_17) ? "CarpetBlock" : "BlockCarpet";
final Field boundingBoxField = getFieldAccessible(getNMSBlockClass(blockCarpetClassName), boundingBoxFieldName);
final Field boundingBoxField = getFieldAccessible(blockCarpetClass, serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2) ? "a" : "b");
setBoundingBox(boundingBoxField.get(0), 0.0D, -0.0000001D, 0.0D, 1.0D, 0.0000001D, 1.0D);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not fix carpet bounding box.", ex);
@@ -57,31 +62,45 @@ public class BlockCollisionChanges {
public static void fixLadder(final Logger logger, final ProtocolVersion serverVersion) {
try {
if(serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_5))
{
final Class<?> blockLadderClass = getNMSBlockClass("BlockLadder");
final Field shapesField = getFieldAccessible(blockLadderClass, "d"); // SHAPES field
shapesField.setAccessible(true);
if (serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_5)) {
final Class<?> blockLadderClass = getNMSBlockClass(NMSUtil.NEWER_THAN_V26_1 ? "LadderBlock" : "BlockLadder");
Class<?> blockClass = Class.forName("net.minecraft.world.level.block.Block");
Method boxZMethod = blockClass.getDeclaredMethod("boxZ", double.class, double.class, double.class);
boxZMethod.setAccessible(true);
Object voxelShape = boxZMethod.invoke(null, 16.0, 14.0, 16.0);
final Map<String, double[]> overrides = new HashMap<>();
overrides.put("EAST", new double[]{0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D});
overrides.put("WEST", new double[]{0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D});
overrides.put("SOUTH", new double[]{0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D});
overrides.put("NORTH", new double[]{0.0D, 0.0D, 0.875D, 1.0D, 1.0D, 1.0D});
Class<?> shapesClass = Class.forName("net.minecraft.world.phys.shapes.Shapes");
Class<?> voxelShapeInterface = Class.forName("net.minecraft.world.phys.shapes.VoxelShape");
Method rotateHorizontalMethod = shapesClass.getDeclaredMethod("rotateHorizontal", voxelShapeInterface);
rotateHorizontalMethod.setAccessible(true);
@SuppressWarnings("unchecked")
Map<Object, Object> rotatedMap = (Map<Object, Object>) rotateHorizontalMethod.invoke(null, voxelShape);
Map<Object, Object> shapesMap = null;
for (Field field : blockLadderClass.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
continue;
}
if (!Map.class.isAssignableFrom(field.getType())) {
continue;
}
field.setAccessible(true);
final Object value = field.get(null);
if (value instanceof Map<?, ?>) {
@SuppressWarnings("unchecked") final Map<Object, Object> casted = (Map<Object, Object>) value;
shapesMap = casted;
break;
}
}
@SuppressWarnings("unchecked")
Map<Object, Object> shapes = (Map<Object, Object>) shapesField.get(null);
shapes.clear();
shapes.putAll(rotatedMap);
}
else
{
boolean updated = false;
if (shapesMap != null) {
updated = updateShapesMap(shapesMap, overrides);
}
if (!updated) {
updated = updateShapeConstants(blockLadderClass, overrides);
}
if (!updated) {
throw new IllegalStateException("Could not adjust ladder shapes for modern versions");
}
} else {
final boolean pre1_12_2 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_12_2);
final boolean pre1_13_2 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_13_2);
final boolean pre1_16_4 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_16_4);
@@ -172,7 +191,7 @@ public class BlockCollisionChanges {
// Handle Paper voxel shape caching by clearing the cache
final Class<?> voxelShape = voxelShapeArray.getClass().getSuperclass();
final Field shape = getFieldAccessible(voxelShape, "a");
final Field shape = getFieldAccessible(voxelShape, NMSUtil.NEWER_THAN_V26_1 ? "shape" : "a");
final Field cachedShapeData = getFieldAccessible(shape.getType(), "cachedShapeData");
if (cachedShapeData == null) { // No Paper or too old version
return;
@@ -182,10 +201,207 @@ public class BlockCollisionChanges {
final Field isEmpty = getFieldAccessible(voxelShape, "isEmpty");
isEmpty.setBoolean(voxelShapeArray, true);
final Method initCache = ReflectionUtil.findMethod(voxelShape, new String[]{ "initCache", "moonrise$initCache" });
final Method initCache = ReflectionUtil.findMethod(voxelShape, new String[]{"initCache", "moonrise$initCache"});
if (initCache == null) {
throw new IllegalStateException("Could not find initCache method in " + voxelShape.getName());
}
initCache.invoke(voxelShapeArray);
}
private static boolean updateShapesMap(final Map<Object, Object> shapes, final Map<String, double[]> overrides) throws ReflectiveOperationException {
if (shapes == null) {
return false;
}
final Class<?> directionClass = Class.forName("net.minecraft.core.Direction");
final Class<?> shapesClass = Class.forName("net.minecraft.world.phys.shapes.Shapes");
final Class<?> blockClass = Class.forName("net.minecraft.world.level.block.Block");
Method shapesBoxMethod = ReflectionUtil.findMethod(shapesClass, new String[]{"box", "a"}, double.class, double.class, double.class, double.class, double.class, double.class);
if (shapesBoxMethod != null) {
shapesBoxMethod.setAccessible(true);
}
Method blockBoxMethod = ReflectionUtil.findMethod(blockClass, new String[]{"box", "a"}, double.class, double.class, double.class, double.class, double.class, double.class);
if (blockBoxMethod != null) {
blockBoxMethod.setAccessible(true);
}
Method shapesCreateMethod = null;
Constructor<?> aabbConstructor = null;
if (shapesBoxMethod == null) {
final Class<?> aabbClass = Class.forName("net.minecraft.world.phys.AABB");
shapesCreateMethod = ReflectionUtil.findMethod(shapesClass, new String[]{"create", "a"}, aabbClass);
if (shapesCreateMethod != null) {
shapesCreateMethod.setAccessible(true);
aabbConstructor = aabbClass.getDeclaredConstructor(double.class, double.class, double.class, double.class, double.class, double.class);
aabbConstructor.setAccessible(true);
}
}
final Method directionValueOf = directionClass.getMethod("valueOf", String.class);
directionValueOf.setAccessible(true);
boolean updated = false;
try {
for (Map.Entry<String, double[]> entry : overrides.entrySet()) {
final Object direction = directionValueOf.invoke(null, entry.getKey());
final Object voxelShape = createVoxelShape(shapesBoxMethod, blockBoxMethod, shapesCreateMethod, aabbConstructor, entry.getValue());
shapes.put(direction, voxelShape);
updated = true;
}
} catch (UnsupportedOperationException ex) {
return false;
}
return updated;
}
private static boolean updateShapeConstants(final Class<?> blockLadderClass, final Map<String, double[]> overrides) throws ReflectiveOperationException {
final Class<?> voxelShapeInterface = Class.forName("net.minecraft.world.phys.shapes.VoxelShape");
boolean updated = false;
for (Field field : blockLadderClass.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
continue;
}
field.setAccessible(true);
final Object shapeObject = field.get(null);
if (shapeObject == null) {
continue;
}
if (!voxelShapeInterface.isAssignableFrom(shapeObject.getClass())
&& !shapeObject.getClass().getSimpleName().contains("VoxelShape")) {
continue;
}
final double[] currentBounds = getBoundingBoxValues(shapeObject);
if (currentBounds == null) {
continue;
}
final String orientation = detectOrientation(currentBounds);
if (orientation == null) {
continue;
}
final double[] override = overrides.get(orientation);
if (override == null) {
continue;
}
setBoundingBox(shapeObject, override);
updated = true;
}
return updated;
}
private static double[] getBoundingBoxValues(final Object boundingBox) throws ReflectiveOperationException {
switch (boundingBox.getClass().getSimpleName()) {
case "AxisAlignedBB":
return getAxisAlignedBBValues(boundingBox);
case "VoxelShapeArray":
case "ArrayVoxelShape":
return getVoxelShapeArrayValues(boundingBox);
case "AABBVoxelShape":
return getAABBVoxelShapeValues(boundingBox);
default:
return null;
}
}
private static double[] getAABBVoxelShapeValues(final Object boundingBox) throws ReflectiveOperationException {
for (Field field : boundingBox.getClass().getFields()) {
if (field.getType().getSimpleName().equals("AxisAlignedBB")) {
return getBoundingBoxValues(field.get(boundingBox));
}
}
return null;
}
private static double[] getAxisAlignedBBValues(final Object boundingBox) throws ReflectiveOperationException {
final Field[] doubleFields = Arrays.stream(boundingBox.getClass().getDeclaredFields()).filter(f -> f.getType() == double.class && !Modifier.isStatic(f.getModifiers())).toArray(Field[]::new);
if (doubleFields.length < 6) {
throw new IllegalStateException("Invalid field count for " + boundingBox.getClass().getName() + ": " + doubleFields.length);
}
final double[] values = new double[6];
for (int i = 0; i < 6; i++) {
final Field currentField = doubleFields[i];
currentField.setAccessible(true);
values[i] = currentField.getDouble(boundingBox);
}
return values;
}
private static double[] getVoxelShapeArrayValues(final Object voxelShapeArray) throws ReflectiveOperationException {
final Field[] doubleListFields = Arrays.stream(voxelShapeArray.getClass().getDeclaredFields()).filter(f -> f.getType().getSimpleName().equals("DoubleList")).toArray(Field[]::new);
if (doubleListFields.length < 3) {
throw new IllegalStateException("Invalid field count for " + voxelShapeArray.getClass().getName() + ": " + doubleListFields.length);
}
final double[] values = new double[6];
for (int i = 0; i < 3; i++) {
final Field field = doubleListFields[i];
field.setAccessible(true);
final Object doubleList = field.get(voxelShapeArray);
if (doubleList == null) {
return null;
}
final Method getDouble = ReflectionUtil.findMethod(doubleList.getClass(), new String[]{"getDouble", "get"}, int.class);
if (getDouble == null) {
return null;
}
getDouble.setAccessible(true);
values[i] = ((Number) getDouble.invoke(doubleList, 0)).doubleValue();
values[i + 3] = ((Number) getDouble.invoke(doubleList, 1)).doubleValue();
}
return values;
}
private static String detectOrientation(final double[] bounds) {
final double epsilon = 1.0E-3;
final double minX = bounds[0];
final double minZ = bounds[2];
final double maxX = bounds[3];
final double maxZ = bounds[5];
if (minX <= epsilon && maxX <= 0.5D) {
return "EAST";
}
if (maxX >= 1.0D - epsilon && minX >= 0.5D) {
return "WEST";
}
if (minZ <= epsilon && maxZ <= 0.5D) {
return "SOUTH";
}
if (maxZ >= 1.0D - epsilon && minZ >= 0.5D) {
return "NORTH";
}
return null;
}
private static Object createVoxelShape(final Method shapesBoxMethod, final Method blockBoxMethod,
final Method shapesCreateMethod, final Constructor<?> aabbConstructor,
final double[] values) throws ReflectiveOperationException {
if (shapesBoxMethod != null) {
return shapesBoxMethod.invoke(null, values[0], values[1], values[2], values[3], values[4], values[5]);
}
if (shapesCreateMethod != null && aabbConstructor != null) {
final Object aabb = aabbConstructor.newInstance(values[0], values[1], values[2], values[3], values[4], values[5]);
return shapesCreateMethod.invoke(null, aabb);
}
if (blockBoxMethod != null) {
final double scale = 16.0D;
return blockBoxMethod.invoke(null,
values[0] * scale, values[1] * scale, values[2] * scale,
values[3] * scale, values[4] * scale, values[5] * scale);
}
throw new IllegalStateException("Unable to create voxel shape for ladder bounding box.");
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,9 +18,11 @@
package com.viaversion.viarewind.legacysupport.feature;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.lang.reflect.Method;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Sound;
@@ -36,11 +38,11 @@ import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.player.PlayerExpChangeEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import java.lang.reflect.Method;
import java.util.logging.Level;
import static com.viaversion.viarewind.legacysupport.util.ReflectionUtil.*;
import static com.viaversion.viarewind.legacysupport.util.NMSUtil.*;
import static com.viaversion.viarewind.legacysupport.util.NMSUtil.getBlockPositionClass;
import static com.viaversion.viarewind.legacysupport.util.NMSUtil.getGamePacketClass;
import static com.viaversion.viarewind.legacysupport.util.NMSUtil.getSoundCategoryClass;
import static com.viaversion.viarewind.legacysupport.util.NMSUtil.sendPacket;
import static com.viaversion.viarewind.legacysupport.util.ReflectionUtil.getMethod;
@SuppressWarnings("unchecked")
public class BlockPlaceSoundEmulator implements Listener {
@@ -81,52 +83,20 @@ public class BlockPlaceSoundEmulator implements Listener {
}
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent e) {
final Player player = e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_9)) return;
if (Via.getAPI().getServerVersion().lowestSupportedProtocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
player.playSound(e.getBlockPlaced().getLocation(), e.getBlock().getBlockData().getSoundGroup().getPlaceSound(), 1.0f, 0.8f);
} else {
try {
playBlockPlaceSoundNMS(player, e.getBlock());
} catch (Exception exception) {
Via.getPlatform().getLogger().log(Level.SEVERE, "Could not play block place sound.", exception);
}
}
}
private void onItemPickUp(Player player) {
final float volume = 0.2f;
final float pitch = (float) ((Math.random() - Math.random()) * 0.7f + 1.0f) * 2.0f;
playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, volume, pitch);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onExperienceOrbPickup(PlayerExpChangeEvent e) {
final float volume = 0.1f;
final float pitch = (float) (0.5f * ((Math.random() - Math.random()) * 0.7f + 1.8f));
playSound(e.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, volume, pitch);
}
private static void playSound(final Location loc, final Sound sound, final float volume, final float pitch) {
Bukkit.getOnlinePlayers().stream()
.filter(p -> p.getWorld() == loc.getWorld())
.filter(p -> p.getLocation().distanceSquared(loc) < (double) 16 * (double) 16)
.filter(p -> Via.getAPI().getPlayerVersion(p) <= 47)
.forEach(p -> {
if (isSoundCategory) {
p.playSound(loc, sound, SoundCategory.valueOf("PLAYERS"), volume, pitch);
} else {
p.playSound(loc, sound, volume, pitch);
}
});
.filter(p -> p.getWorld() == loc.getWorld())
.filter(p -> p.getLocation().distanceSquared(loc) < (double) 16 * (double) 16)
.filter(p -> Via.getAPI().getPlayerVersion(p) <= 47)
.forEach(p -> {
if (isSoundCategory) {
p.playSound(loc, sound, SoundCategory.valueOf("PLAYERS"), volume, pitch);
} else {
p.playSound(loc, sound, volume, pitch);
}
});
}
// 1.8.8 -> 1.16.5
private static void playBlockPlaceSoundNMS(Player player, Block block) throws Exception {
World world = block.getWorld();
@@ -198,13 +168,13 @@ public class BlockPlaceSoundEmulator implements Listener {
private static void playSound(Player player, Object soundEffect, Object soundCategory, double x, double y, double z, float volume, float pitch) {
try {
Object packet = getGamePacketClass("PacketPlayOutNamedSoundEffect").getConstructor(
soundEffect.getClass(), soundCategory.getClass(),
double.class, double.class, double.class,
float.class, float.class
soundEffect.getClass(), soundCategory.getClass(),
double.class, double.class, double.class,
float.class, float.class
).newInstance(
soundEffect, soundCategory,
x, y, z,
volume, pitch
soundEffect, soundCategory,
x, y, z,
volume, pitch
);
// Volume = 1
@@ -214,4 +184,35 @@ public class BlockPlaceSoundEmulator implements Listener {
ex.printStackTrace();
}
}
@EventHandler
public void onBlockPlace(BlockPlaceEvent e) {
final Player player = e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_9)) return;
if (Via.getAPI().getServerVersion().lowestSupportedProtocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
player.playSound(e.getBlockPlaced().getLocation(), e.getBlock().getBlockData().getSoundGroup().getPlaceSound(), 1.0f, 0.8f);
} else {
try {
playBlockPlaceSoundNMS(player, e.getBlock());
} catch (Exception exception) {
Via.getPlatform().getLogger().log(Level.SEVERE, "Could not play block place sound.", exception);
}
}
}
private void onItemPickUp(Player player) {
final float volume = 0.2f;
final float pitch = (float) ((Math.random() - Math.random()) * 0.7f + 1.0f) * 2.0f;
playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, volume, pitch);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onExperienceOrbPickup(PlayerExpChangeEvent e) {
final float volume = 0.1f;
final float pitch = (float) (0.5f * ((Math.random() - Math.random()) * 0.7f + 1.8f));
playSound(e.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, volume, pitch);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,8 @@ import com.viaversion.viarewind.legacysupport.util.NMSUtil;
import com.viaversion.viarewind.legacysupport.util.ReflectionUtil;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.lang.reflect.Method;
import java.util.logging.Level;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -30,9 +32,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.util.Vector;
import java.lang.reflect.Method;
import java.util.logging.Level;
@SuppressWarnings("unchecked")
public class ElytraVelocityEmulator implements Listener {
@@ -42,7 +41,7 @@ public class ElytraVelocityEmulator implements Listener {
if (nmsPlayer == null) return false;
try {
final Method getFlag = ReflectionUtil.getMethod(nmsPlayer.getClass(), "getFlag", int.class);
final Method getFlag = ReflectionUtil.findMethod(nmsPlayer.getClass(), new String[]{"getSharedFlag", "getFlag"}, int.class);
return (boolean) getFlag.invoke(nmsPlayer, 7);
} catch (Exception e) {
BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Failed to get player flag", e);
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@ package com.viaversion.viarewind.legacysupport.feature;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -31,8 +32,6 @@ import org.bukkit.inventory.EnchantingInventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import java.util.Map;
@SuppressWarnings("unchecked")
public class EnchantingGuiEmulator implements Listener {
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,26 +31,27 @@ import org.bukkit.util.Vector;
@SuppressWarnings({"unchecked", "DataFlowIssue"})
public class SlimeBounceEmulator implements Listener {
@EventHandler
public void onPlayerMove(PlayerMoveEvent e) {
if (e.getTo().getY() >= e.getFrom().getY()) return; // Only check upwards motion
@EventHandler
public void onPlayerMove(PlayerMoveEvent e) {
if (e.getTo().getY() >= e.getFrom().getY()) return; // Only check upwards motion
final Player player = e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_8)) return; // Only apply for 1.7 and below players
final Player player = e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_8))
return; // Only apply for 1.7 and below players
if (Math.floor(e.getTo().getY()) + 0.01 < e.getTo().getY()) return;
if (player.isSneaking()) return;
if (Math.floor(e.getTo().getY()) + 0.01 < e.getTo().getY()) return;
if (player.isSneaking()) return;
final Block block = e.getTo().clone().add(0, -0.1, 0).getBlock();
if (block.getType() != Material.SLIME_BLOCK) return;
final Block block = e.getTo().clone().add(0, -0.1, 0).getBlock();
if (block.getType() != Material.SLIME_BLOCK) return;
final Vector newVelocity = player.getVelocity();
final Vector newVelocity = player.getVelocity();
final double deltaY = (e.getTo().getY() - e.getFrom().getY());
if (deltaY >- 0.11) return; // Only bounce if the player is falling down
final double deltaY = (e.getTo().getY() - e.getFrom().getY());
if (deltaY > -0.11) return; // Only bounce if the player is falling down
newVelocity.setY(-deltaY * 1.05);
newVelocity.setY(-deltaY * 1.05);
player.setVelocity(newVelocity);
}
player.setVelocity(newVelocity);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,23 +19,23 @@ package com.viaversion.viarewind.legacysupport.util;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import static com.viaversion.viarewind.legacysupport.util.ReflectionUtil.failSafeGetClass;
public class NMSUtil {
public static final boolean NEWER_THAN_V26_1 = BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v26_1);
public static final boolean NEWER_THAN_V1_20_5 = BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_20_5);
public static final boolean NEWER_THAN_V1_17 = BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_17);
public static String nmsVersionPackage;
private static Field playerConnectionField;
public static final boolean NEWER_THAN_V1_20_5 = BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_20_5);
static {
if (BukkitPlugin.getInstance().getServerProtocol().olderThan(ProtocolVersion.v1_17)) {
nmsVersionPackage = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
@@ -43,7 +43,9 @@ public class NMSUtil {
}
public static Class<?> getBlockPositionClass() {
if (BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
if (NEWER_THAN_V26_1) {
return failSafeGetClass("net.minecraft.core.BlockPos");
} else if (NEWER_THAN_V1_17) {
return failSafeGetClass("net.minecraft.core.BlockPosition");
} else {
return getLegacyNMSClass("BlockPosition");
@@ -51,7 +53,7 @@ public class NMSUtil {
}
public static Class<?> getNMSBlockClass(final String name) {
if (BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
if (NEWER_THAN_V1_17) {
return failSafeGetClass("net.minecraft.world.level.block." + name);
} else {
return getLegacyNMSClass(name);
@@ -59,7 +61,9 @@ public class NMSUtil {
}
public static Class getSoundCategoryClass() { // Bypass generics
if (BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
if (NEWER_THAN_V26_1) {
return failSafeGetClass("net.minecraft.sounds.SoundSource");
} else if (NEWER_THAN_V1_17) {
return failSafeGetClass("net.minecraft.sounds.SoundCategory");
} else {
return getLegacyNMSClass("SoundCategory");
@@ -67,7 +71,7 @@ public class NMSUtil {
}
public static Class<?> getPacketClass() {
if (BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
if (NEWER_THAN_V1_17) {
return failSafeGetClass("net.minecraft.network.protocol.Packet");
} else {
return getLegacyNMSClass("Packet");
@@ -75,7 +79,7 @@ public class NMSUtil {
}
public static Class<?> getGamePacketClass(final String packet) {
if (BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
if (NEWER_THAN_V1_17) {
return failSafeGetClass("net.minecraft.network.protocol.game." + packet);
} else {
return getLegacyNMSClass(packet);
@@ -83,7 +87,9 @@ public class NMSUtil {
}
public static Class<?> getPlayerConnectionClass() {
if (BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
if (NEWER_THAN_V26_1) {
return failSafeGetClass("net.minecraft.server.network.ServerGamePacketListenerImpl");
} else if (NEWER_THAN_V1_17) {
return failSafeGetClass("net.minecraft.server.network.PlayerConnection");
} else {
return getLegacyNMSClass("PlayerConnection");
@@ -130,7 +136,7 @@ public class NMSUtil {
return;
}
try {
final Method sendPacket = ReflectionUtil.findMethod(playerConnection.getClass(), new String[] {"sendPacket", "a"}, getPacketClass());
final Method sendPacket = ReflectionUtil.findMethod(playerConnection.getClass(), new String[]{"sendPacket", "a"}, getPacketClass());
sendPacket.invoke(playerConnection, packet);
} catch (IllegalAccessException | InvocationTargetException | NullPointerException e) {
BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Failed to send packet to player", e);
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,7 +18,6 @@
package com.viaversion.viarewind.legacysupport.util;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -80,7 +79,8 @@ public class ReflectionUtil {
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException ignored) {} // Cache non-existing field too
} catch (NoSuchFieldException ignored) {
} // Cache non-existing field too
fieldCache.put(key, field);
return field;
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* Copyright (C) 2018-2025 ViaVersion and contributors
* Copyright (C) 2018-2026 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,8 +18,8 @@
package com.viaversion.viarewind.legacysupport.versioninfo;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viaversion.api.Via;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.FileConfiguration;
@@ -35,7 +35,7 @@ public class VersionInformer implements Listener {
public VersionInformer(final BukkitPlugin plugin, final FileConfiguration config) {
final String message = ChatColor.translateAlternateColorCodes('&', config.getString("versioninfo.message")).
replace("%version%", Bukkit.getVersion().split(" ")[2].replace(")", ""));
replace("%version%", Bukkit.getVersion().split(" ")[2].replace(")", ""));
this.versionMessage = message.split(System.lineSeparator());
maxVersion = config.getInt("versioninfo.max-version");
+1 -1
View File
@@ -4,7 +4,7 @@ description: ${description}
main: com.viaversion.viarewind.legacysupport.BukkitPlugin
api-version: 1.13
authors: [FlorianMichael/EnZaXD, Gerrygames]
authors: [EnZaXD, Gerrygames]
website: https://github.com/ViaVersion/ViaRewind-Legacy-Support
depend: [ViaRewind]