27 Commits
Author SHA1 Message Date
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
FlorianMichael 8593bd7d7c 1.5.3 Release 2025-10-03 14:16:52 +02:00
FlorianMichael 054f899180 Auto: Gradle 9.1.0 2025-09-22 21:46:11 +02:00
FlorianMichael 8329a04a5c Gradle 9.0.0 2025-08-03 01:49:00 +02:00
TechirionandDieu 2be0cfd5b5 BlockCollisionChanges: Add 1.21.5+ support (#93)
Co-authored-by: Dieu <info@l4b.org>
2025-07-27 16:14:45 +02:00
Beanes e83dd73a66 Fix anvil cost on 1.8 spigot for versions lower than 1.8 (#94)
* Fix anvil cost on 1.8 spigot

* Remove debugs
2025-07-27 16:12:52 +02:00
FlorianMichael b6f89c9893 Update build files 2025-06-27 14:52:56 +02:00
FlorianMichael c98f0f8970 Bump version to 1.5.3-SNAPSHOT 2025-06-27 14:42:25 +02:00
FlorianMichael 6602e3ff67 Auto: Gradle 8.14.1 2025-05-22 17:51:04 +02:00
FlorianMichael 7910288083 Auto: Gradle 8.14 2025-04-26 16:25:07 +02:00
Leah Anderson a2ccc0a7de [ci skip] Fix grammar in README.md (#89) 2025-03-28 17:24:35 +01:00
FlorianMichael f01f255b2b Auto: Gradle 8.13, .editorconfig 2025-02-25 18:44:28 +01:00
FlorianMichael e8dc069437 Auto: Gradle 8.12.1 2025-01-24 15:44:23 +01:00
FlorianMichael baac8ae938 1.5.2 Release 2025-01-19 14:38:57 +01:00
FlorianMichael e22e37d975 Gradle 8.12 2025-01-02 22:52:45 +01:00
FlorianMichael 6b495ebb20 Sync various build script changes from VR 2025-01-02 15:34:50 +01:00
FlorianMichael 2e6acfaf04 Remove maven local 2025-01-02 15:31:21 +01:00
FlorianMichael 9dd1dc8e4d Auto: 2025 2025-01-01 01:07:59 +01:00
Dreeam 3030d07fec Fix AreaEffectCloudEmulator spawn logic on 1.20.5+ servers (#83) 2024-07-19 09:06:35 +02:00
FlorianMichael 081c9c9a6f Fix version check in area effect cloud emulation 2024-07-19 08:54:12 +02:00
FlorianMichael 64039f847c Gradle 8.9 2024-07-14 20:56:34 +02:00
FlorianMichael 5380fc9c1b Support Paper 1.21, print proper exception
Closes https://github.com/ViaVersion/ViaRewind-Legacy-Support/issues/82
2024-07-14 20:48:50 +02:00
FlorianMichael 28f14ce635 Updated publishing version range 2024-07-14 20:46:14 +02:00
FlorianMichael 30725d9545 Bump version to 1.5.2-SNAPSHOT 2024-07-14 20:45:49 +02:00
29 changed files with 614 additions and 300 deletions

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
[*]
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = true
tab_width = 4
[*.java]
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
+1 -1
View File
@@ -1,2 +1,2 @@
github: FlorianMichael
custom: ['https://florianmichael.de/donate', 'https://viaversion.com/donate', 'https://creeper123123321.github.io/#donate']
custom: ['https://florianmichael.de/donate', 'https://creeper123123321.github.io/#donate']
+6 -13
View File
@@ -1,4 +1,4 @@
name: ViaRewind-Legacy-Support CI
name: Build
on: [pull_request, push, workflow_dispatch]
jobs:
@@ -7,22 +7,15 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
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
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/wrapper-validation-action@v1
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:
+9 -4
View File
@@ -4,6 +4,7 @@
build/
out/
classes/
.kotlin/
# Eclipse
@@ -12,11 +13,13 @@ classes/
# Idea
.idea/
!.idea/copyright/*
!.idea/scopes/*
*.iml
*.ipr
*.iws
# VScode
# VSCode
.settings/
.vscode/
@@ -26,6 +29,8 @@ bin/
# macOS
.DS_Store
.AppleDouble
.LSOverride
DS_Store
# Misc
run/
+1 -1
View File
@@ -29,7 +29,7 @@ Installing this plugin requires nothing more than putting it in your plugins fol
- The **Lily Pad** bounding box is being modified. This prevents 1.7.x-1.8.x from glitching if they try to walk over **Lily Pads**.
- The **Ladder** bounding box is being modified. This prevents 1.7.x-1.8.x from glitching if they try to climb **Ladders**.
- If a 1.7.x player opens an **Enchantment Table** this plugin takes Lapis Lazuli from his/her inventory and puts it in the **Enchantment Table**.
- If a 1.7.x player opens an **Enchantment Table** this plugin takes Lapis Lazuli from their inventory and puts it in the **Enchantment Table**.
- 1.7.x-1.8.x can interact with **Brewing Stands** to add/remove Blaze Powder to/from them.
- Play block placement and item pickup **sounds** to 1.7.x-1.8.x players.
- Velocity is applied during **Elytra flight** for players below 1.9.
-120
View File
@@ -1,120 +0,0 @@
plugins {
id "java-library"
id "maven-publish"
id "io.papermc.hangar-publish-plugin" version "0.1.2"
}
repositories {
mavenLocal()
maven {
url = uri("https://repo.viaversion.com")
}
maven {
url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
}
maven {
url = uri("https://repo.maven.apache.org/maven2/")
}
}
version = project.maven_version
group = project.maven_group
dependencies {
compileOnly "com.viaversion:viaversion-api:4.10.0"
compileOnly "org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT"
}
java.sourceCompatibility = JavaVersion.VERSION_1_8
processResources {
inputs.property "version", project.version
filesMatching("plugin.yml") {
expand "version": project.version
}
}
java {
withSourcesJar()
}
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
tasks.withType(Javadoc) {
options.encoding = "UTF-8"
}
// -----------------------------------------------------
// Publishing
def latestCommitHash() {
def byteOut = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = byteOut
}
return byteOut.toString('UTF-8').trim()
}
def latestCommitMessage() {
def byteOut = new ByteArrayOutputStream()
exec {
commandLine 'git', 'log', '-1', '--pretty=%B'
standardOutput = byteOut
}
return byteOut.toString('UTF-8').trim()
}
def branchName() {
def byteOut = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
standardOutput = byteOut
}
return byteOut.toString('UTF-8').trim()
}
def baseVersion = project.maven_version
def isRelease = !baseVersion.contains('-')
def suffixedVersion = isRelease ? baseVersion : baseVersion + "+" + System.getenv("GITHUB_RUN_NUMBER")
def commitHash = latestCommitHash()
def changelogContent = "[${commitHash}](https://github.com/ViaVersion/iaRewind-Legacy-Support/commit/${commitHash}) ${latestCommitMessage()}"
def branch = branchName()
def isMainBranch = branch == "master"
hangarPublish {
publications.register("plugin") {
version.set(suffixedVersion)
id.set("ViaRewindLegacySupport")
channel.set(isRelease ? "Release" : isMainBranch ? "Snapshot" : "Alpha")
changelog.set(changelogContent)
apiKey.set(System.getenv("HANGAR_TOKEN"))
platforms {
PAPER {
jar.set(tasks.jar.archiveFile)
platformVersions.set([property('mcVersionRange') as String])
dependencies.hangar("ViaVersion") {
required.set(true)
}
dependencies.hangar("ViaBackwards") {
required.set(false)
}
dependencies.hangar("ViaRewind") {
required.set(false)
}
}
}
}
}
+70
View File
@@ -0,0 +1,70 @@
import de.florianmichael.baseproject.*
plugins {
`java-library`
id("io.papermc.hangar-publish-plugin")
id("de.florianmichael.baseproject.BaseProject")
}
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")
}
tasks {
processResources {
val projectVersion = project.version
val projectDescription = project.description
filesMatching("plugin.yml") {
expand(mapOf("version" to projectVersion, "description" to projectDescription))
}
}
}
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"
hangarPublish {
publications.register("plugin") {
version.set(suffixedVersion)
id.set("ViaRewindLegacySupport")
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.set(true)
}
dependencies.hangar("ViaBackwards") {
required.set(false)
}
dependencies.hangar("ViaRewind") {
required.set(false)
}
}
}
}
}
tasks.named("publishPluginPublicationToHangar") {
notCompatibleWithConfigurationCache("")
}
+13 -5
View File
@@ -1,10 +1,18 @@
# gradle
# Gradle Properties
org.gradle.jvmargs=-Xmx8G
org.gradle.parallel=true
org.gradle.configuration-cache=true
# Project Details
project_jvm_version=8
# project
maven_version=1.5.1
maven_group=com.viaversion
project_group=com.viaversion
project_version=1.5.4
project_description=Provides additional features for ViaRewind for Paper servers.
mcVersionRange=1.8-1.20.6
publishing_dev_id=FlorianMichael
publishing_dev_name=EnZaXD
publishing_dev_mail=florian.michael07@gmail.com
# Hangar Publishing
minecraft_version_range=1.8-1.21.11
Binary file not shown.
+2 -1
View File
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionSha256Sum=df67a32e86e3276d011735facb1535f64d0d88df84fa87521e90becc2d735444
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+13 -14
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/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/.
@@ -84,7 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -112,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -145,7 +146,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -153,7 +154,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -170,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -202,16 +202,15 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
Vendored
+13 -12
View File
@@ -13,6 +13,8 @@
@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 ##########################################################################
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
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
@@ -57,22 +59,21 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
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
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%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
-1
View File
@@ -1 +0,0 @@
rootProject.name = "ViaRewind-Legacy-Support"
+17
View File
@@ -0,0 +1,17 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
plugins {
id("de.florianmichael.baseproject.BaseProject") version "1.1.1"
id("io.papermc.hangar-publish-plugin") version "0.1.3"
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
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-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,15 +18,16 @@
package com.viaversion.viarewind.legacysupport;
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.AnvilCostFix;
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;
@@ -58,6 +59,13 @@ public class BukkitPlugin extends JavaPlugin {
}
final FileConfiguration config = getConfig();
if (serverProtocol.equals(ProtocolVersion.v1_8)) {
if (config.getBoolean("anvil-cost-fix")) {
Bukkit.getPluginManager().registerEvents(new AnvilCostFix(), BukkitPlugin.this);
}
}
if (serverProtocol.newerThanOrEqualTo(ProtocolVersion.v1_8)) {
if (config.getBoolean("enchanting-gui-fix")) {
Bukkit.getPluginManager().registerEvents(new EnchantingGuiEmulator(), BukkitPlugin.this);
@@ -66,6 +74,7 @@ public class BukkitPlugin extends JavaPlugin {
Bukkit.getPluginManager().registerEvents(new SlimeBounceEmulator(), BukkitPlugin.this);
}
}
if (serverProtocol.newerThanOrEqualTo(ProtocolVersion.v1_9)) {
if (config.getBoolean("sound-fix")) {
Bukkit.getPluginManager().registerEvents(new BlockPlaceSoundEmulator(BukkitPlugin.this), BukkitPlugin.this);
@@ -0,0 +1,63 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* 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
* 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.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;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.Inventory;
public class AnvilCostFix implements Listener {
@EventHandler
public void onInventoryClickEvent(InventoryClickEvent event) {
Inventory inventory = event.getInventory();
if (inventory instanceof AnvilInventory) {
Bukkit.getScheduler().runTaskLater(BukkitPlugin.getInstance(), () -> {
for (HumanEntity entity : inventory.getViewers()) {
if (entity instanceof Player) {
refreshAnvilInventoryPlayer((Player) entity);
}
}
}, 1L);
}
}
public void refreshAnvilInventoryPlayer(Player player) {
Object nmsPlayer = NMSUtil.getNMSPlayer(player);
try {
Object activeContainer = nmsPlayer.getClass().getField("activeContainer").get(nmsPlayer);
if (activeContainer.getClass().getSimpleName().equals("ContainerAnvil")) {
Object cost = activeContainer.getClass().getField("a").get(activeContainer);
nmsPlayer.getClass().getMethod("setContainerData", activeContainer.getClass().getSuperclass(), int.class, int.class).invoke(nmsPlayer, activeContainer, cost, cost);
}
} catch (Exception e) {
BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Failed to refresh anvil inventory", e);
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* 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,9 +18,13 @@
package com.viaversion.viarewind.legacysupport.feature;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viarewind.legacysupport.util.NMSUtil;
import com.viaversion.viaversion.api.Via;
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;
@@ -30,21 +34,20 @@ 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<>();
public AreaEffectCloudEmulator(final BukkitPlugin plugin) {
Bukkit.getScheduler().runTaskTimer(plugin, () -> {
final Set<Player> affectedPlayers = Bukkit.getOnlinePlayers().stream().filter(p -> Via.getAPI().getPlayerProtocolVersion(p).newerThanOrEqualTo(ProtocolVersion.v1_8)).collect(Collectors.toSet());
final Set<Player> affectedPlayers = Bukkit.getOnlinePlayers().stream().filter(p -> Via.getAPI().getPlayerProtocolVersion(p).olderThanOrEqualTo(ProtocolVersion.v1_8)).collect(Collectors.toSet());
effectClouds.removeIf(e -> !e.isValid());
effectClouds.forEach(cloud -> {
final Location location = cloud.getLocation();
final float radius = cloud.getRadius();
final Object data = NMSUtil.NEWER_THAN_V1_20_5
? cloud.getColor()
: null;
float area = (float) Math.PI * radius * radius;
@@ -64,10 +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
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-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,17 +18,20 @@
package com.viaversion.viarewind.legacysupport.feature;
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 {
@@ -55,22 +58,62 @@ public class BlockCollisionChanges {
public static void fixLadder(final Logger logger, final ProtocolVersion serverVersion) {
try {
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);
final boolean pre1_20_2 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2);
if (serverVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_5)) {
final Class<?> blockLadderClass = getNMSBlockClass("BlockLadder");
final Class<?> blockLadderClass = getNMSBlockClass("BlockLadder");
final Map<String, double[]> overrides = new HashMap<String, double[]>();
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});
final Field boundingBoxEastField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "b" : pre1_13_2 ? "c" : pre1_16_4 ? "c" : pre1_20_2 ? "d" : "e");
final Field boundingBoxWestField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "c" : pre1_13_2 ? "o" : pre1_16_4 ? "d" : pre1_20_2 ? "e" : "f");
final Field boundingBoxSouthField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "d" : pre1_13_2 ? "p" : pre1_16_4 ? "e" : pre1_20_2 ? "f" : "g");
final Field boundingBoxNorthField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "e" : pre1_13_2 ? "q" : pre1_16_4 ? "f" : pre1_20_2 ? "g" : "h");
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;
}
}
setBoundingBox(boundingBoxEastField.get(null), 0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D);
setBoundingBox(boundingBoxWestField.get(null), 0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
setBoundingBox(boundingBoxSouthField.get(null), 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D);
setBoundingBox(boundingBoxNorthField.get(null), 0.0D, 0.0D, 0.875D, 1.0D, 1.0D, 1.0D);
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);
final boolean pre1_20_2 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2);
final Class<?> blockLadderClass = getNMSBlockClass("BlockLadder");
final Field boundingBoxEastField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "b" : pre1_13_2 ? "c" : pre1_16_4 ? "c" : pre1_20_2 ? "d" : "e");
final Field boundingBoxWestField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "c" : pre1_13_2 ? "o" : pre1_16_4 ? "d" : pre1_20_2 ? "e" : "f");
final Field boundingBoxSouthField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "d" : pre1_13_2 ? "p" : pre1_16_4 ? "e" : pre1_20_2 ? "f" : "g");
final Field boundingBoxNorthField = getFieldAccessible(blockLadderClass, pre1_12_2 ? "e" : pre1_13_2 ? "q" : pre1_16_4 ? "f" : pre1_20_2 ? "g" : "h");
setBoundingBox(boundingBoxEastField.get(null), 0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D);
setBoundingBox(boundingBoxWestField.get(null), 0.875D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D);
setBoundingBox(boundingBoxSouthField.get(null), 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.125D);
setBoundingBox(boundingBoxNorthField.get(null), 0.0D, 0.0D, 0.875D, 1.0D, 1.0D, 1.0D);
}
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not fix ladder bounding box.", ex);
}
@@ -154,7 +197,207 @@ public class BlockCollisionChanges {
final Field isEmpty = getFieldAccessible(voxelShape, "isEmpty");
isEmpty.setBoolean(voxelShapeArray, true);
final Method initCache = voxelShape.getDeclaredMethod("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-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,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-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-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* 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,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 {
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind-Legacy-Support - https://github.com/ViaVersion/ViaRewind-Legacy-Support
* 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
@@ -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-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
@@ -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-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
@@ -19,18 +19,18 @@ 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_V1_20_5 = BukkitPlugin.getInstance().getServerProtocol().newerThanOrEqualTo(ProtocolVersion.v1_20_5);
public static String nmsVersionPackage;
private static Field playerConnectionField;
@@ -128,7 +128,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-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.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-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,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");
+4 -1
View File
@@ -6,6 +6,9 @@ brewing-stand-gui-fix: true
# Automatically put lapis lazuli in enchanting tables for clients lower than 1.8
enchanting-gui-fix: true
#
# Fixes anvil cost on 1.8 servers for clients lower than 1.8
anvil-cost-fix: true
#
# Fix the lily pad bounding box to prevent clients lower than 1.9 from glitching
lily-pad-fix: true
#
@@ -33,4 +36,4 @@ versioninfo:
active: false
max-version: 47
interval: JOIN
message: '&7[&6Info&7] This server is running Minecraft %version%. The best gameplay experience is only guaranteed if you are using this version.'
message: '&7[&6Info&7] This server is running Minecraft %version%. The best gameplay experience is only guaranteed if you are using this version.'
+1
View File
@@ -1,5 +1,6 @@
name: ViaRewind-Legacy-Support
version: ${version}
description: ${description}
main: com.viaversion.viarewind.legacysupport.BukkitPlugin
api-version: 1.13