TrueOG branch

This commit is contained in:
NotAlexNoyle committed 2025-07-02 05:13:55 -04:00
1 parent 3617463982
commit 8fd88a6473
454 files changed
+10710 -4667

No files matched your search

-12
View File
@@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # sprax
open_collective: # Replace with a single Open Collective username
ko_fi: spraxdev
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
-28
View File
@@ -1,28 +0,0 @@
---
name: Bug report
about: Create a report and help BetterChairs and its community
title: ''
labels: ''
assignees: ''
---
* **Server Version**: <!-- *(Run `/version`)* -->
* **Plugin Version**: <!-- *(Run `/version BetterChairs`)* -->
**Describe the bug**
A clear and concise description of the bug.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to ...
2. Click on ....
3. ...
**Screenshots, Videos, Logs or Errors**
If applicable, add screenshots to help explain your problem.
If possible, try uploading images or large logs as an attachment instead of somewhere else to ensure its availability.
**Additional context**
Add any other context about the problem here.
-17
View File
@@ -1,17 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.
-14
View File
@@ -1,14 +0,0 @@
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "maven"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
-162
View File
@@ -1,162 +0,0 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Build with Maven
on:
push:
branches: [ main ]
pull_request:
types: [ opened, synchronize, reopened ]
jobs:
# Compile the project
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure maven's settings.xml (mirrors, deployment credentials)
uses: whelk-io/maven-settings-xml-action@v22
with:
mirrors: >
[
{
"id": "Sonatype-Nexus-Snapshots-mirror",
"name": "Sonatype-Nexus-Snapshots-Repository [Mirror]",
"url": "https://repo.sprax2013.de/repository/sonatype-nexus-snapshots/",
"mirrorOf": "sonatype-nexus-snapshots"
},
{
"id": "Central-mirror",
"name": "Central-Repository [Mirror]",
"url": "https://repo.sprax2013.de/repository/central/",
"mirrorOf": "central"
},
{
"id": "SpigotMC-Snapshots-mirror",
"name": "SpigotMC-Snapshots-Repository [Mirror]",
"url": "https://repo.sprax2013.de/repository/SpigotMC-Snapshots/",
"mirrorOf": "SpigotMC,SpigotMC-repo,spigotmc,spigotmc-repo,spigot-repo,spigotmc-snapshots"
},
{
"id": "SpigotMC-Releases-mirror",
"name": "SpigotMC-Releases-Repository [Mirror]",
"url": "https://repo.sprax2013.de/repository/SpigotMC-Releases/",
"mirrorOf": "spigotmc-releases"
},
{
"id": "Minecraft-Libraries-mirror",
"name": "Minecraft-Libraries-Repository [Mirror]",
"url": "https://repo.sprax2013.de/repository/Minecraft-Libraries/",
"mirrorOf": "minecraft-libraries"
}
]
# Use Java 8 to compile old Spigot version
- uses: actions/setup-java@v4
with:
java-version: 8
distribution: temurin
overwrite-settings: false
cache: maven
- name: Compile Spigot versions (1.8 – 1.16.5)
uses: SpraxDev/Action-SpigotMC@v5
with:
versions: 1.8, 1.8.3, 1.8.8, 1.9.2, 1.9.4, 1.10.2, 1.11.2, 1.12.2, 1.13, 1.13.2, 1.14.4, 1.15.2, 1.16.1, 1.16.3, 1.16.5
# Use Java 16 for Spigot 1.17
- uses: actions/setup-java@v4
with:
java-version: 16
distribution: temurin
overwrite-settings: false
- name: Compile Spigot versions (1.17)
uses: SpraxDev/Action-SpigotMC@v5
with:
versions: '1.17'
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
overwrite-settings: false
- name: Compile Spigot versions (1.18.1 – 1.20.4)
uses: SpraxDev/Action-SpigotMC@v5
with:
versions: 1.18.1, 1.18.2, 1.19, 1.19.2, 1.19.3, 1.19.4, 1.20.1, 1.20.2, 1.20.4
remapped: true
# Use Java 21 for everything else
- uses: actions/setup-java@v4
with:
java-version: 21
distribution: temurin
overwrite-settings: false
- name: Compile Spigot versions (1.20.6 – 1.21.3)
uses: SpraxDev/Action-SpigotMC@v5
with:
versions: 1.20.6, 1.21.1, 1.21.3, 1.21.4, 1.21.5
remapped: true
# Compile the project using maven
- name: Build with Maven
run: 'mvn -B -Duser.name="GitHub Runner on $GITHUB_REPOSITORY (id=$GITHUB_RUN_ID)" clean package'
# Upload the .jar file
- name: 'Upload Build Artifact: BetterChairs.jar'
uses: actions/upload-artifact@v4
with:
name: BetterChairs
path: ./modules/betterchairs-plugin/target/BetterChairs*.jar
# Run static code analysis
- name: 'SonarCloud.io (static code analysis)'
if: ${{ env.SONAR_TOKEN != null }}
run: 'mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# Check if the versions inside `pom.xml`, CHANGELOG.md and `./docs/version.txt`
# match and that everything has been edited correctly when pushing a new release version
check-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Extract version from the pom.xml and compare to docs/version.txt
id: version_diff # Outputs 'same' or 'diff'
run: mkdir -p docs && echo $(grep --max-count=1 '<version>' pom.xml | awk -F '>' '{ print $2 }' | awk -F '<' '{ print $1 }') >> docs/version_new.txt && diff -q --ignore-space-change --strip-trailing-cr --ignore-blank-lines docs/version.txt docs/version_new.txt 2>&1 && echo "result=same" >> $GITHUB_OUTPUT || echo "result=diff" >> $GITHUB_OUTPUT
- name: Check if extracted version matches docs/version.txt
if: ${{ steps.version_diff.outputs.result != 'same' }}
uses: unsplash/comment-on-pr@master
with:
msg: "Versions in `pom.xml` and `docs/version.txt` are not the same! Please use the same version in both files."
check_for_duplicate_msg: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check if version from docs/version.txt is inside CHANGELOG.md
id: inside_changelog # Outputs 'yes' or 'no'
run: verTxt=$(cat docs/version.txt) && grep -q "## Version ${verTxt}" CHANGELOG.md && echo "result=yes" >> $GITHUB_OUTPUT || echo "result=no" >> $GITHUB_OUTPUT
- name: Check if extracted version matches docs/version.txt
if: ${{ steps.inside_changelog.outputs.result != 'yes' }}
uses: unsplash/comment-on-pr@master
with:
msg: "`CHANGELOG.md` is missing changes for version in `docs/version.txt`!"
check_for_duplicate_msg: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Fail Action when versions (from above) are not the same
if: ${{ steps.version_diff.outputs.result != 'same' }}
run: echo "The versions inside pom.xml and docs/version.txt are not the same!" && exit -1
- name: Fail Action when docs/version.txt not inside CHANGELOG.md
if: ${{ steps.inside_changelog.outputs.result != 'yes' }}
run: echo "CHANGELOG.md is missing changes for version in docs/version.txt!" && exit -1
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>BetterChairs</name>
<comment></comment>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
+3 -19
View File
@@ -1,24 +1,8 @@
# Change Log
<!-- Template
## 'Version major.minor.patch' or 'Unreleased'
_yyyy-mm-dd_ [GitHub Diff](https://github.com/SpraxDev/BetterChairs/compare/prev-tag-name...curr-tag-name)
### Added
### Breaking Changes
### Changed
* Line 1
* Line 2
-->
## Version 1.14.0
_2025-03-31_ [GitHub Diff](https://github.com/SpraxDev/BetterChairs/compare/v1.13.0...v1.14.0)
### Added
* Support for Minecraft 1.21.5
## Version 1.13.0
_2024-12-16_ [GitHub Diff](https://github.com/SpraxDev/BetterChairs/compare/v1.12.0...v1.13.0)
## Version 1.13-OG:
* Removed support for 1.20.6+
* Builds with gradle 8.14.2 instead of maven
### Added
* Support for Minecraft 1.21.4
-76
View File
@@ -1,76 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at developer@sprax2013.de. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
-59
View File
@@ -1,59 +0,0 @@
# Contributing to BetterChairs
We love your input!
We want to make contributing to this project as easy and transparent as possible, whether it's:
* Reporting a bug
* Discussing the current state of the code
* Submitting a fix
* Proposing new features
## We Develop with GitHub
We use GitHub to host code, to track issues and feature requests, as well as accept pull requests.
## We Use [GitHub Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
Pull requests are the best way to propose changes to the codebase (we use [GitHub Flow](https://guides.github.com/introduction/flow/index.html)).
We actively welcome your pull requests:
1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation.
5. Ensure the test suite passes.
6. Issue that pull request!
## Any contributions you make will be under the MIT Software License
In short, when you submit code changes, your submissions are understood to be under the same
[MIT License](https://choosealicense.com/licenses/mit/) that covers the project.
Feel free to contact the maintainers if that's a concern.
## Report bugs using GitHub's [issues](https://github.com/SpraxDev/BetterChairs/issues)
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/SpraxDev/BetterChairs/issues/new/choose) – it's that easy!
## Write bug reports with detail, background, and sample code
Make sure to provide all the relevant information needed to reproduce the bug you are reporting. You can upload logs, images or videos if needed.
**Great Bug Reports** tend to have:
* A quick summary and/or background
* Steps to reproduce
* Be specific!
* Give sample code if you can – Try to make it as universal as possible, so is quickly understood.
* What you expected would happen
* What actually happens
* Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
People *love* thorough bug reports. I'm not even kidding.
## Use a Consistent Coding Style
* spaces for indentation rather than tabs
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at developer@sprax2013.de.
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined
by other members of the project's leadership.
## References
This document was adapted from [briandk](https://gist.github.com/briandk/3d2e8b3ec8daf5a27a62), who originally adapted it from Facebook's Draft.
+178
View File
@@ -0,0 +1,178 @@
plugins {
id("java")
id("java-library")
id("com.diffplug.spotless") version "7.0.4"
id("com.gradleup.shadow") version "8.3.6"
eclipse
}
group = "de.sprax2013"
version = "1.13-OG"
val pluginName = "BetterChairs"
allprojects {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
maven("https://repo.codemc.io/repository/maven-public/")
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
maven("https://repo.sprax2013.de/repository/maven-snapshots/")
maven("https://repo.sprax2013.de/repository/maven-releases/")
maven("https://repo.purpurmc.org/snapshots")
}
}
subprojects {
apply(plugin = "java")
apply(plugin = "java-library")
apply(plugin = "com.diffplug.spotless")
apply(plugin = "com.gradleup.shadow")
apply(plugin = "eclipse")
java {
sourceCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(17)
vendor = JvmVendorSpec.GRAAL_VM
}
}
tasks.withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters")
options.compilerArgs.add("-Xlint:deprecation")
options.encoding = "UTF-8"
options.isFork = true
}
spotless {
java {
removeUnusedImports()
palantirJavaFormat()
}
kotlinGradle {
ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) }
target("build.gradle.kts", "settings.gradle.kts")
}
}
tasks.named("spotlessCheck") {
dependsOn("spotlessApply")
}
}
project(":modules:betterchairs-api") {
dependencies {
compileOnly("org.spigotmc:spigot-api:1.8-R0.1-SNAPSHOT")
api("de.sprax2013.lime:lime-spigot-api:0.0.4-SNAPSHOT")
api("de.tr7zw:item-nbt-api:2.15.0")
api("com.github.cryptomorin:XSeries:13.3.0")
compileOnly("org.jetbrains:annotations:26.0.2")
}
}
project(":modules:betterchairs-plugin") {
val apiVersion = "1.8"
tasks.named<ProcessResources>("processResources") {
val props = mapOf(
"version" to version,
"apiVersion" to apiVersion,
"pluginName" to pluginName
)
inputs.properties(props)
filesMatching("plugin.yml") { expand(props) }
from(rootProject.file("LICENSE")) { into("/") }
}
tasks.jar { archiveClassifier.set("part") }
tasks.shadowJar {
exclude("META-INF/**", "LICENSE")
minimize()
archiveClassifier.set("")
archiveBaseName.set("BetterChairs")
destinationDirectory.set(rootProject.layout.buildDirectory.dir("libs"))
relocate("betterchairs.nms", "de.sprax2013.betterchairs.nms")
relocate("de.sprax2013.lime", "de.sprax2013.betterchairs.third_party.de.sprax2013.lime")
relocate("de.tr7zw.changeme.nbtapi", "de.sprax2013.betterchairs.third_party.de.tr7zw.nbtapi")
relocate("com.cryptomorin.xseries", "de.sprax2013.betterchairs.third_party.com.cryptomorin.xseries")
}
tasks.build {
dependsOn(tasks.spotlessApply)
dependsOn(tasks.shadowJar)
}
dependencies {
compileOnly("org.spigotmc:spigot-api:1.8-R0.1-SNAPSHOT")
compileOnly("me.clip:placeholderapi:2.11.6")
implementation(project(":modules:betterchairs-api"))
listOf(
"v1_19_R3",
"v1_19_R2", "v1_19_R1", "v1_19_0", "v1_18_R2", "v1_18_R1",
"v1_17_R1", "v1_16_R3", "v1_16_R2", "v1_16_R1", "v1_15_R1",
"v1_14_R1", "v1_13_R2", "v1_13_R1", "v1_12_R1", "v1_11_R1",
"v1_10_R1", "v1_9_R2", "v1_9_R1", "v1_8_R3", "v1_8_R2", "v1_8_R1"
).forEach {
implementation(project(":modules:nms:betterchairs-$it"))
}
compileOnly("org.jetbrains:annotations:26.0.2")
}
}
val nmsVersions = mapOf(
"betterchairs-v1_8_R1" to "1.8-R0.1-SNAPSHOT",
"betterchairs-v1_8_R2" to "1.8.3-R0.1-SNAPSHOT",
"betterchairs-v1_8_R3" to "1.8.8-R0.1-SNAPSHOT",
"betterchairs-v1_9_R1" to "1.9.2-R0.1-SNAPSHOT",
"betterchairs-v1_9_R2" to "1.9.4-R0.1-SNAPSHOT",
"betterchairs-v1_10_R1" to "1.10.2-R0.1-SNAPSHOT",
"betterchairs-v1_11_R1" to "1.11.2-R0.1-SNAPSHOT",
"betterchairs-v1_12_R1" to "1.12.2-R0.1-SNAPSHOT",
"betterchairs-v1_13_R1" to "1.13-R0.1-SNAPSHOT",
"betterchairs-v1_13_R2" to "1.13.2-R0.1-SNAPSHOT",
"betterchairs-v1_14_R1" to "1.14.4-R0.1-SNAPSHOT",
"betterchairs-v1_15_R1" to "1.15.2-R0.1-SNAPSHOT",
"betterchairs-v1_16_R1" to "1.16.1-R0.1-SNAPSHOT",
"betterchairs-v1_16_R2" to "1.16.3-R0.1-SNAPSHOT",
"betterchairs-v1_16_R3" to "1.16.5-R0.1-SNAPSHOT",
"betterchairs-v1_17_R1" to "1.17-R0.1-SNAPSHOT",
"betterchairs-v1_18_R1" to "1.18.1-R0.1-SNAPSHOT",
"betterchairs-v1_18_R2" to "1.18.2-R0.1-SNAPSHOT",
"betterchairs-v1_19_0" to "1.19-R0.1-SNAPSHOT",
"betterchairs-v1_19_R1" to "1.19.2-R0.1-SNAPSHOT",
"betterchairs-v1_19_R2" to "1.19.3-R0.1-SNAPSHOT",
"betterchairs-v1_19_R3" to "1.19.4-R0.1-SNAPSHOT",
)
project(":modules:nms:betterchairs-v1_19_R1") {
dependencies {
compileOnly(project(":modules:nms:betterchairs-v1_19_0"))
}
}
subprojects
.filter { it.path.startsWith(":modules:nms:") }
.forEach { nms ->
nms.dependencies {
"compileOnly"(project(":modules:betterchairs-api"))
val ver = nmsVersions.getValue(nms.name)
"compileOnly"("org.spigotmc:spigot-api:$ver")
val mojangMapped = ver.startsWith("1.19")
if (mojangMapped) {
"compileOnly"("org.spigotmc:spigot:$ver:remapped-mojang")
} else {
"compileOnly"("org.spigotmc:spigot:$ver")
}
}
nms.tasks.withType<PublishToMavenRepository>().configureEach { enabled = false }
}
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored Executable
+251
View File
@@ -0,0 +1,251 @@
#!/bin/sh
#
# Copyright © 2015-2021 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.
# You may obtain a copy of the License at
#
# https://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.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# 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
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# 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 -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
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
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=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# 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" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
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 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" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+94
View File
@@ -0,0 +1,94 @@
@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
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -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
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
</classpath>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>modules</name>
<comment></comment>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
@@ -0,0 +1,13 @@
#
#Wed Jul 02 05:13:16 EDT 2025
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+96
View File
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry output="bin/main" kind="src" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-spigot-api/0.0.4-SNAPSHOT/lime-spigot-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/29689f4d8039bc2abf8e5562c5c09927f9bfc51f/item-nbt-api-2.15.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/52fa821ba619524cac58be6d7260e72b42ae3a0a/item-nbt-api-2.15.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d079530d2976ecfae96e2e132e9b8323738d6b02/XSeries-13.3.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d664a667493ae640b7a62c8add20572437a4f52d/XSeries-13.3.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/spigotmc/spigot-api/1.8-R0.1-SNAPSHOT/spigot-api-1.8-R0.1-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-api/0.0.4-SNAPSHOT/lime-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/26.0.2/bfa27b5e683363963c8d5e2fec39d755295cbb82/annotations-26.0.2-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/26.0.2/c7ce3cdeda3d18909368dfe5977332dfad326c6d/annotations-26.0.2.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/net/md-5/bungeecord-chat/1.8-SNAPSHOT/bungeecord-chat-1.8-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/avaje/ebean/2.8.1/ebean-2.8.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/junit/junit/4.10/junit-4.10.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/javax/persistence/persistence-api/1.0/persistence-api-1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/code/gson/gson/2.3.1/gson-2.3.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/jetbrains/annotations/24.1.0/annotations-24.1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
</classpath>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>betterchairs-api</name>
<comment></comment>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
@@ -0,0 +1,13 @@
#
#Wed Jul 02 05:13:18 EDT 2025
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -0,0 +1,2 @@
Manifest-Version: 1.0
-81
View File
@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs</artifactId>
<version>1.14.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>betterchairs-api</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.2</version>
<executions>
<execution>
<phase>site</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<links>
<link>https://hub.spigotmc.org/javadocs/spigot/</link>
</links>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.9.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.21.0</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>de.sprax2013.lime</groupId>
<artifactId>lime-spigot-api</artifactId>
<version>0.0.4-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.tr7zw</groupId>
<artifactId>item-nbt-api</artifactId>
<version>2.15.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.cryptomorin</groupId>
<artifactId>XSeries</artifactId>
<version>13.3.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
@@ -13,7 +13,8 @@ import org.jetbrains.annotations.NotNull;
* as soon the player leaves the chair
*/
public class Chair {
private static final String ERR_MANAGER_NOT_AVAILABLE = "ChairManager is not available yet - Did BetterChairs successfully enable?";
private static final String ERR_MANAGER_NOT_AVAILABLE =
"ChairManager is not available yet - Did BetterChairs successfully enable?";
protected final Block block;
protected final Entity chairEntity;
@@ -48,11 +49,9 @@ public class Chair {
public @NotNull ChairType getType() {
if (ChairManager.getInstance() == null) throw new IllegalStateException(ERR_MANAGER_NOT_AVAILABLE);
if (ChairManager.getInstance().chairNMS.isStair(this.block))
return ChairType.STAIR;
if (ChairManager.getInstance().chairNMS.isStair(this.block)) return ChairType.STAIR;
if (ChairManager.getInstance().chairNMS.isSlab(this.block))
return ChairType.SLAB;
if (ChairManager.getInstance().chairNMS.isSlab(this.block)) return ChairType.SLAB;
return ChairType.CUSTOM;
}
@@ -2,16 +2,6 @@ package de.sprax2013.betterchairs;
import de.sprax2013.betterchairs.events.PlayerEnterChairEvent;
import de.sprax2013.betterchairs.events.PlayerLeaveChairEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
@@ -23,6 +13,15 @@ import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* This class should be instantiated as soon as possible inside
@@ -75,7 +74,10 @@ public class ChairManager {
* @see #create(Player, Block, double)
*/
public boolean create(Player player, Block block) {
return create(player, block, ChairUtils.getSitOffset(block, !Settings.SIT_ON_ARROWS.getValueAsBoolean(), this.chairNMS));
return create(
player,
block,
ChairUtils.getSitOffset(block, !Settings.SIT_ON_ARROWS.getValueAsBoolean(), this.chairNMS));
}
/**
@@ -92,7 +94,8 @@ public class ChairManager {
if (!Bukkit.isPrimaryThread()) throw new IllegalStateException(Messages.ERR_ASYNC_API_CALL);
if (isOccupied(block)) return false;
Entity chairEntity = instance.chairNMS.spawnChairEntity(block.getLocation().add(0.5, yOffset, 0.5),
Entity chairEntity = instance.chairNMS.spawnChairEntity(
block.getLocation().add(0.5, yOffset, 0.5),
ChairNMS.getRegenerationAmplifier(player),
!Settings.SIT_ON_ARROWS.getValueAsBoolean());
@@ -269,7 +272,8 @@ public class ChairManager {
Boolean value = this.disabled.get(uuid);
if (value == null) {
value = Settings.REMEMBER_IF_PLAYER_DISABLED_CHAIRS.getValueAsBoolean() && new File(this.disabledForDir, uuid.toString()).exists();
value = Settings.REMEMBER_IF_PLAYER_DISABLED_CHAIRS.getValueAsBoolean()
&& new File(this.disabledForDir, uuid.toString()).exists();
if (!value) {
value = Settings.HAVE_CHAIRS_DISABLED_FOR_PLAYER_BY_DEFAULT.getValueAsBoolean();
}
@@ -295,7 +299,7 @@ public class ChairManager {
}
if (directlyWriteToFile) {
onQuit(uuid); // Write changes to file
onQuit(uuid); // Write changes to file
}
}
@@ -19,7 +19,7 @@ import org.jetbrains.annotations.Nullable;
* </ul>
*/
public abstract class ChairNMS {
public static final int REGENERATION_EFFECT_DURATION = 3 * 20; // In Ticks
public static final int REGENERATION_EFFECT_DURATION = 3 * 20; // In Ticks
/**
* Spawns an Entity that is/has:
@@ -83,10 +83,10 @@ public abstract class ChairNMS {
}
public static int getRegenerationAmplifier(Player p) {
if (!Settings.REGENERATION_ENABLED.getValueAsBoolean() ||
Settings.REGENERATION_AMPLIFIER.getValueAsInt() <= 0 ||
(Settings.REGENERATION_CHECK_PERMISSION.getValueAsBoolean() &&
!p.hasPermission(ChairManager.plugin.getName() + ".regeneration"))) return -1;
if (!Settings.REGENERATION_ENABLED.getValueAsBoolean()
|| Settings.REGENERATION_AMPLIFIER.getValueAsInt() <= 0
|| (Settings.REGENERATION_CHECK_PERMISSION.getValueAsBoolean()
&& !p.hasPermission(ChairManager.plugin.getName() + ".regeneration"))) return -1;
return Settings.REGENERATION_AMPLIFIER.getValueAsInt() - 1;
}
@@ -1,5 +1,7 @@
package de.sprax2013.betterchairs;
public enum ChairType {
STAIR, SLAB, CUSTOM
STAIR,
SLAB,
CUSTOM
}
@@ -66,11 +66,15 @@ public class ChairUtils {
nbt.setBoolean("NoGravity", true);
}
} catch (Throwable ex) {
ChairManager.getLogger().warning("Could not apply chair modifications (" + ex.getClass().getSimpleName() + ": " + ex.getMessage() + ")!");
ChairManager.getLogger()
.warning("Could not apply chair modifications ("
+ ex.getClass().getSimpleName() + ": " + ex.getMessage() + ")!");
}
});
} catch (Throwable ex) {
ChairManager.getLogger().warning("Could not apply chair modifications (" + ex.getClass().getSimpleName() + ": " + ex.getMessage() + ")!");
ChairManager.getLogger()
.warning("Could not apply chair modifications ("
+ ex.getClass().getSimpleName() + ": " + ex.getMessage() + ")!");
}
}
@@ -102,22 +106,27 @@ public class ChairUtils {
}
public static boolean didChairEntityMove(Location expected, double actualX, double actualY, double actualZ) {
return actualX != expected.getX() ||
actualY != expected.getY() ||
actualZ != expected.getZ();
return actualX != expected.getX() || actualY != expected.getY() || actualZ != expected.getZ();
}
public static void applyRegeneration(HumanEntity p, int regenerationAmplifier) {
if (regenerationAmplifier >= 0 && !p.hasPotionEffect(PotionEffectType.REGENERATION)) {
p.addPotionEffect(new PotionEffect(
PotionEffectType.REGENERATION, ChairNMS.REGENERATION_EFFECT_DURATION, regenerationAmplifier,
false, false), true);
p.addPotionEffect(
new PotionEffect(
PotionEffectType.REGENERATION,
ChairNMS.REGENERATION_EFFECT_DURATION,
regenerationAmplifier,
false,
false),
true);
}
}
public static double getSitOffset(Block block, boolean sitsOnArmorStand, ChairNMS chairNMS) {
double yOffset = (!chairNMS.isStair(block) && !chairNMS.isSlab(block)) ||
(chairNMS.isSlab(block) && chairNMS.isSlabTop(block)) ? 0.5 : 0;
double yOffset = (!chairNMS.isStair(block) && !chairNMS.isSlab(block))
|| (chairNMS.isSlab(block) && chairNMS.isSlabTop(block))
? 0.5
: 0;
XMaterial blockType = XMaterial.matchXMaterial(block.getType());
@@ -3,29 +3,33 @@ package de.sprax2013.betterchairs;
import de.sprax2013.lime.configuration.Config;
import de.sprax2013.lime.configuration.ConfigEntry;
import de.sprax2013.lime.configuration.validation.StringEntryValidator;
import net.md_5.bungee.api.ChatColor;
import java.io.File;
import java.util.Objects;
import net.md_5.bungee.api.ChatColor;
public class Messages {
private static final int LATEST_VERSION = 1;
public static final String ERR_ASYNC_API_CALL = "Async API call";
public static final String ERR_ANOTHER_PLUGIN_PREVENTING_SPAWN = "Looks like another plugin is preventing BetterChairs from spawning chairs";
public static final String ERR_ANOTHER_PLUGIN_PREVENTING_SPAWN =
"Looks like another plugin is preventing BetterChairs from spawning chairs";
public static final String ERR_NOT_CUSTOM_ENTITY = "The provided Entity is not an instance of '%s'";
private static final Config config = new Config(
new File(Objects.requireNonNull(ChairManager.getPlugin()).getDataFolder(), "messages.yml"), Settings.HEADER)
new File(Objects.requireNonNull(ChairManager.getPlugin()).getDataFolder(), "messages.yml"),
Settings.HEADER)
.withVersion(LATEST_VERSION, 0, "version", () -> "You shouldn't make any changes to this")
.withCommentEntry("ToggleChairs", "What should we tell players when they enable or disable chairs for themselves");
.withCommentEntry(
"ToggleChairs", "What should we tell players when they enable or disable chairs for themselves");
private static final ConfigEntry PREFIX = config.createEntry(
"General.Prefix", "&7[&2" + Objects.requireNonNull(ChairManager.getPlugin()).getName() + "&7]",
"General.Prefix",
"&7[&2" + Objects.requireNonNull(ChairManager.getPlugin()).getName() + "&7]",
"The prefix that can be used in all other messages")
.setEntryValidator(StringEntryValidator.get());
public static final ConfigEntry NO_PERMISSION = config.createEntry(
"General.NoPermission", "${Prefix} &cYou do not have permission to use this command!",
"General.NoPermission",
"${Prefix} &cYou do not have permission to use this command!",
"What should we tell players that are not allowed to use an command?")
.setEntryValidator(StringEntryValidator.get())
.setLegacyKey(0, "Cant use message");
@@ -46,17 +50,20 @@ public class Messages {
.setEntryValidator(StringEntryValidator.get());
public static final ConfigEntry USE_ALREADY_OCCUPIED = config.createEntry(
"ChairUse.AlreadyOccupied", "${Prefix} &cThis chair is already occupied",
"ChairUse.AlreadyOccupied",
"${Prefix} &cThis chair is already occupied",
"What should we tell players when an chair is already occupied")
.setEntryValidator(StringEntryValidator.get())
.setLegacyKey(0, "Message to send if the chairs is occupied");
public static final ConfigEntry USE_NEEDS_SIGNS = config.createEntry(
"ChairUse.NeedsSignsOnBothSides", "${Prefix} &cA chair needs a sign attached to it on both sides",
"ChairUse.NeedsSignsOnBothSides",
"${Prefix} &cA chair needs a sign attached to it on both sides",
"What should we tell players when an chair is missing signs on both sides")
.setEntryValidator(StringEntryValidator.get())
.setLegacyKey(0, "Message to send if the chairs need sign or chair");
public static final ConfigEntry USE_NOW_SITTING = config.createEntry(
"ChairUse.NowSitting", "${Prefix} &cYou are taking a break now",
"ChairUse.NowSitting",
"${Prefix} &cYou are taking a break now",
"What should we tell players when he/she is now sitting")
.setEntryValidator(StringEntryValidator.get());
@@ -73,8 +80,7 @@ public class Messages {
}
public static String getString(ConfigEntry cfgEntry) {
return ChatColor.translateAlternateColorCodes('&',
Objects.requireNonNull(cfgEntry.getValueAsString()))
return ChatColor.translateAlternateColorCodes('&', Objects.requireNonNull(cfgEntry.getValueAsString()))
.replace("${Prefix}", getPrefix());
}
@@ -3,7 +3,6 @@ package de.sprax2013.betterchairs;
import de.sprax2013.lime.configuration.Config;
import de.sprax2013.lime.configuration.ConfigEntry;
import de.sprax2013.lime.configuration.validation.IntEntryValidator;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -11,22 +10,22 @@ import java.util.Objects;
public class Settings {
private static final int LATEST_VERSION = 3;
protected static final String HEADER = "BetterChairs Remastered\n\n" +
"Support: https://Sprax.me/Discord\n" +
"Updates and Information:\n" +
"Statistics: https://bstats.org/plugin/bukkit/BetterChairs%20Remastered/8214\n" +
"Information for developers: https://github.com/SpraxDev/BetterChairs/wiki";
protected static final String HEADER = "BetterChairs Remastered\n\n" + "Support: https://Sprax.me/Discord\n"
+ "Updates and Information:\n"
+ "Statistics: https://bstats.org/plugin/bukkit/BetterChairs%20Remastered/8214\n"
+ "Information for developers: https://github.com/SpraxDev/BetterChairs/wiki";
private static final Config config = new Config(
new File(Objects.requireNonNull(ChairManager.getPlugin()).getDataFolder(), "config.yml"), HEADER)
new File(Objects.requireNonNull(ChairManager.getPlugin()).getDataFolder(), "config.yml"), HEADER)
.withVersion(LATEST_VERSION, 0, "version", () -> "You shouldn't make any changes to this");
public static final ConfigEntry SIT_ON_ARROWS = config.createEntry(
"Chairs.SitOnArrows", false,
"Enabling this makes BetterChairs use Arrows instead of ArmorStands.\n" +
"ArmorStands are made invisible so the player doesn't see anything of the magic happening when sitting.\n" +
"But Spigot can be very unreliable on some versions (e.g. players instantly stopping to sit)\n\n" +
"If you are experiencing issues with ArmorStands, enable this option.")
"Chairs.SitOnArrows",
false,
"Enabling this makes BetterChairs use Arrows instead of ArmorStands.\n"
+ "ArmorStands are made invisible so the player doesn't see anything of the magic happening when sitting.\n"
+ "But Spigot can be very unreliable on some versions (e.g. players instantly stopping to sit)\n\n"
+ "If you are experiencing issues with ArmorStands, enable this option.")
.setLegacyKey(2, "UseArmorStands", value -> {
if (value == null) {
return false;
@@ -39,33 +38,36 @@ public class Settings {
return !Boolean.parseBoolean(value.toString());
});
public static final ConfigEntry ALLOWED_DISTANCE_TO_CHAIR = config.createEntry(
"Chairs.AllowedDistanceToChair", -1,
"Chairs.AllowedDistanceToChair",
-1,
"Allowed distance a player is allowed to have when trying to sit? (-1 to ignore)")
.setEntryValidator(IntEntryValidator.get())
.setLegacyKey(0, "Distance of the stairs");
public static final ConfigEntry AUTO_ROTATE_PLAYER = config.createEntry(
"Chairs.AutoRotatePlayer", true,
"Should a player automatically look forward when starting to sit")
"Chairs.AutoRotatePlayer", true, "Should a player automatically look forward when starting to sit")
.setLegacyKey(0, "AutoTurn");
public static final ConfigEntry NEEDS_EMPTY_HANDS = config.createEntry(
"Chairs.NeedEmptyHands", true,
"Does a player need his hands empty when trying to sit?")
"Chairs.NeedEmptyHands", true, "Does a player need his hands empty when trying to sit?")
.setLegacyKey(0, "No item in hand");
public static final ConfigEntry NEEDS_SIGNS = config.createEntry(
"Chairs.NeedsSignsOnBothSides", false,
"Chairs.NeedsSignsOnBothSides",
false,
"Does a chair need signs on both sides attached to be detected as an chair")
.setLegacyKey(0, "Need to sign or chair on each side");
public static final ConfigEntry IGNORES_INTERACT_PREVENTION = config.createEntry(
"Chairs.IgnoreOtherPluginsPreventingInteract", false,
"Enable this if you want players to be able to sit on chairs\n" +
"while other plugins (like WorldGuard or PlotSquared) are not\n" +
"allowing interactions/use with the chair blocks.");
"Chairs.IgnoreOtherPluginsPreventingInteract",
false,
"Enable this if you want players to be able to sit on chairs\n"
+ "while other plugins (like WorldGuard or PlotSquared) are not\n"
+ "allowing interactions/use with the chair blocks.");
public static final ConfigEntry HAVE_CHAIRS_DISABLED_FOR_PLAYER_BY_DEFAULT = config.createEntry(
"Chairs.HaveChairsDisabledForPlayerByDefault", false,
"This requires players to use /toggleChairs or /BetterChairs toggle\n" +
"before they can right-click on chair blocks.");
"Chairs.HaveChairsDisabledForPlayerByDefault",
false,
"This requires players to use /toggleChairs or /BetterChairs toggle\n"
+ "before they can right-click on chair blocks.");
public static final ConfigEntry REMEMBER_IF_PLAYER_DISABLED_CHAIRS = config.createEntry(
"Chairs.RememberIfPlayerDisabledChairsAfterRelogin", true,
"Chairs.RememberIfPlayerDisabledChairsAfterRelogin",
true,
"Enable this if you want BetterChairs to remember a player who used /bc <toggle|on|off> after a plugin reload or him rejoining")
.setLegacyKey(1, null, (value) -> {
if (value != null) {
@@ -76,64 +78,66 @@ public class Settings {
});
public static final ConfigEntry CHAIR_NEED_AIR_ABOVE = config.createEntry(
"Chairs.Position.NeedAirAbove", true,
"Chairs.Position.NeedAirAbove",
true,
"Set to false, if you do not care about a player suffocating while sitting");
public static final ConfigEntry CHAIR_ALLOW_AIR_BELOW = config.createEntry(
"Chairs.Position.AllowAirBelow", true,
"Set to false, to force chairs to have a block below them");
"Chairs.Position.AllowAirBelow", true, "Set to false, to force chairs to have a block below them");
public static final ConfigEntry USE_STAIRS = config.createEntry(
"Chairs.UseStairs", true, "Can stairs be chairs?");
public static final ConfigEntry USE_STAIRS = config.createEntry("Chairs.UseStairs", true, "Can stairs be chairs?");
public static final ConfigEntry USE_SLABS = config.createEntry(
"Chairs.UseSlabs", false, "Can half slabs be chairs too?")
.setLegacyKey(0, "Use slab");
public static final ConfigEntry LEAVING_CHAIR_TELEPORT_TO_OLD_LOCATION = config.createEntry(
"Chairs.LeavingChair.TeleportPlayerToOldLocation", true,
"Chairs.LeavingChair.TeleportPlayerToOldLocation",
true,
"Should a player be teleported to its original position when leaving a chair");
public static final ConfigEntry LEAVING_CHAIR_KEEP_HEAD_ROTATION = config.createEntry(
"Chairs.LeavingChair.KeepHeadRotation", true,
"Chairs.LeavingChair.KeepHeadRotation",
true,
"Should a player keep his head rotation when teleported to its original position");
public static final ConfigEntry ALLOW_SWITCHING_SEATS = config.createEntry(
"Chairs.AllowSwitchingSeats", false,
"This controls whether players can switch seats while already sitting.\n" +
"If '" + LEAVING_CHAIR_TELEPORT_TO_OLD_LOCATION.getKey() + "' is set,\n" +
"the player will be teleported to the *first* location they startet sitting at.");
"Chairs.AllowSwitchingSeats",
false,
"This controls whether players can switch seats while already sitting.\n" + "If '"
+ LEAVING_CHAIR_TELEPORT_TO_OLD_LOCATION.getKey() + "' is set,\n"
+ "the player will be teleported to the *first* location they startet sitting at.");
public static final ConfigEntry MSG_ALREADY_OCCUPIED = config.createEntry(
"Chairs.Messages.AlreadyOccupied", false,
"Chairs.Messages.AlreadyOccupied",
false,
"Should the player receive a message when the chair is already occupied")
.setLegacyKey(0, "Send message if the chairs is already occupied");
public static final ConfigEntry MSG_NEEDS_SIGNS = config.createEntry(
"Chairs.Messages.NeedsSignsOnBothSides", false,
"Chairs.Messages.NeedsSignsOnBothSides",
false,
"Should the player receive a message when a chair is missing signs on both sided")
.setLegacyKey(0, "Send message if the Chairs need sign or chair");
public static final ConfigEntry MSG_NOW_SITTING = config.createEntry(
"Chairs.Messages.NowSitting", false,
"Should the player receive a message when he starts sitting")
"Chairs.Messages.NowSitting", false, "Should the player receive a message when he starts sitting")
.setLegacyKey(0, "Send message when player sit");
public static final ConfigEntry REGENERATION_ENABLED = config.createEntry(
"Chairs.Regeneration.Enabled", false,
"Should player receive regeneration effect when sitting?")
"Chairs.Regeneration.Enabled", false, "Should player receive regeneration effect when sitting?")
.setLegacyKey(0, "Regen when sit");
public static final ConfigEntry REGENERATION_CHECK_PERMISSION = config.createEntry(
"Chairs.Regeneration.CheckPermission", true,
"Chairs.Regeneration.CheckPermission",
true,
"Should only players with the permission 'BetterChairs.regeneration' get the effect?");
public static final ConfigEntry REGENERATION_AMPLIFIER = config.createEntry(
"Chairs.Regeneration.Amplifier", 1, "What amplifier should be applied?")
.setEntryValidator(IntEntryValidator.get())
.setLegacyKey(0, "Amplifier");
public static final ConfigEntry WORLD_FILTER_ENABLED = config.createEntry(
"Filter.Worlds.Enabled", false,
"Should we only enable chairs in specific worlds?");
public static final ConfigEntry WORLD_FILTER_ENABLED =
config.createEntry("Filter.Worlds.Enabled", false, "Should we only enable chairs in specific worlds?");
public static final ConfigEntry WORLD_FILTER_AS_BLACKLIST = config.createEntry(
"Filter.Worlds.UseAsBlacklist", false,
"Should be the list below be used as blacklist or whitelist?");
"Filter.Worlds.UseAsBlacklist", false, "Should be the list below be used as blacklist or whitelist?");
public static final ConfigEntry WORLD_FILTER_NAMES = config.createEntry(
"Filter.Worlds.Names", new String[]{"worldname", "worldname2"},
"Filter.Worlds.Names",
new String[] {"worldname", "worldname2"},
"List of all enabled/disabled worlds")
.setLegacyKey(0, "Disable world", value -> {
if (value instanceof List) {
@@ -150,31 +154,32 @@ public class Settings {
return null;
});
public static final ConfigEntry MATERIAL_FILTER_ENABLED = config.createEntry(
"Filter.Blocks.Enabled", false,
"Should we only enable specific blocks as chairs?");
public static final ConfigEntry MATERIAL_FILTER_ENABLED =
config.createEntry("Filter.Blocks.Enabled", false, "Should we only enable specific blocks as chairs?");
public static final ConfigEntry MATERIAL_FILTER_ALLOW_ALL_TYPES = config.createEntry(
"Filter.Blocks.AllowAllTypes", false,
"Setting this to true, won't check if a chair\n" +
"is a stair or slab but only look if it is in the list below\n\n" +
"This is kinda experimental.\nEnabling overwrites 'UseStairs' and 'UseSlabs' further above");
"Filter.Blocks.AllowAllTypes",
false,
"Setting this to true, won't check if a chair\n"
+ "is a stair or slab but only look if it is in the list below\n\n"
+ "This is kinda experimental.\nEnabling overwrites 'UseStairs' and 'UseSlabs' further above");
public static final ConfigEntry MATERIAL_FILTER_AS_BLACKLIST = config.createEntry(
"Filter.Blocks.UseAsBlacklist", false,
"Should be the list below be used as blacklist or whitelist?");
"Filter.Blocks.UseAsBlacklist", false, "Should be the list below be used as blacklist or whitelist?");
public static final ConfigEntry MATERIAL_FILTER_NAMES = config.createEntry(
"Filter.Blocks.Names", new String[]{"blockname", "blockname2"},
"List of all enabled/disabled block types\n\n" +
"The names from Minecraft do not always work\n" +
"Full list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html");
"Filter.Blocks.Names",
new String[] {"blockname", "blockname2"},
"List of all enabled/disabled block types\n\n" + "The names from Minecraft do not always work\n"
+ "Full list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html");
public static final ConfigEntry UPDATER_ENABLED = config.createEntry(
"Updater.CheckForUpdates", true,
"Updater.CheckForUpdates",
true,
"Should we check for new versions and report to the console? (Recommended)")
.setLegacyKey(0, "Update Checker");
public static final ConfigEntry UPDATER_NOTIFY_ON_JOIN = config.createEntry(
"Updater.NotifyOnJoin", true,
() -> "Should be notify admins when they join the server? (Permission: " +
ChairManager.getPlugin().getName() + ".updater)");
"Updater.NotifyOnJoin",
true,
() -> "Should be notify admins when they join the server? (Permission: "
+ ChairManager.getPlugin().getName() + ".updater)");
private Settings() {
throw new IllegalStateException("Utility class");
+222
View File
@@ -0,0 +1,222 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry output="bin/main" kind="src" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry output="bin/main" kind="src" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<classpathentry kind="src" path="/betterchairs-api">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_19_R3">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_19_R2">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_19_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_19_0">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_18_R2">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_18_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_17_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_16_R3">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_16_R2">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_16_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_15_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_14_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_13_R2">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_13_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_12_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_11_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_10_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_9_R2">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_9_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_8_R3">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_8_R2">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="/betterchairs-v1_8_R1">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/spigotmc/spigot-api/1.8-R0.1-SNAPSHOT/spigot-api-1.8-R0.1-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/me/clip/placeholderapi/2.11.6/placeholderapi-2.11.6.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-spigot-api/0.0.4-SNAPSHOT/lime-spigot-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-api/0.0.4-SNAPSHOT/lime-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/26.0.2/bfa27b5e683363963c8d5e2fec39d755295cbb82/annotations-26.0.2-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/26.0.2/c7ce3cdeda3d18909368dfe5977332dfad326c6d/annotations-26.0.2.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/net/md-5/bungeecord-chat/1.8-SNAPSHOT/bungeecord-chat-1.8-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/avaje/ebean/2.8.1/ebean-2.8.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/29689f4d8039bc2abf8e5562c5c09927f9bfc51f/item-nbt-api-2.15.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/52fa821ba619524cac58be6d7260e72b42ae3a0a/item-nbt-api-2.15.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d079530d2976ecfae96e2e132e9b8323738d6b02/XSeries-13.3.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d664a667493ae640b7a62c8add20572437a4f52d/XSeries-13.3.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/junit/junit/4.10/junit-4.10.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/javax/persistence/persistence-api/1.0/persistence-api-1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/code/gson/gson/2.3.1/gson-2.3.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/jetbrains/annotations/24.1.0/annotations-24.1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
</classpath>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>betterchairs-plugin</name>
<comment></comment>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
@@ -0,0 +1,13 @@
#
#Wed Jul 02 05:13:18 EDT 2025
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Christian Koop
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@@ -0,0 +1,43 @@
name: BetterChairs
description: Players can sit on chairs and everywhere the admin wants them to be able to.
version: unspecified
api-version: '1.19'
main: de.sprax2013.betterchairs.BetterChairsPlugin
softdepend:
- PlaceholderAPI
author: SpraxDev
authors: [ BlackScarx ]
website: https://github.com/SpraxDev/BetterChairs
commands:
BetterChairs:
description: 'Toggle, Reload or Reset BetterChairs'
toggleChairs:
description: 'Allows individual players to disabled chairs for them'
aliases: [ bct ]
permission: BetterChairs.cmd.toggle
sit:
description: 'Allows a player to sit on the ground'
permission: BetterChairs.cmd.sit
permissions:
BetterChairs.use:
description: Allows players to sit on chairs
default: true
BetterChairs.regeneration:
description: Grants regeneration to a player when sitting
BetterChairs.updater:
description: Notifies players about updates when joining the server
BetterChairs.cmd.toggle:
description: Allows individual players to disabled chairs for them
default: true
BetterChairs.cmd.sit:
description: Allows a player to sit on the ground
default: true
BetterChairs.cmd.reset:
description: Allows admins to eject all players from their chairs
BetterChairs.cmd.reload:
description: Allows admins to reload the plugin's configuration files
@@ -0,0 +1,211 @@
package de.sprax2013.betterchairs;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getManager;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
// TODO: Put all strings into messages.yml
// TODO: Split file into smaller ones
public class BetterChairsCommand implements CommandExecutor, TabCompleter {
private final String permsSit, permsToggle, permsReload, permsReset;
protected BetterChairsCommand(JavaPlugin plugin) {
this.permsSit = plugin.getName() + ".cmd.sit";
this.permsToggle = plugin.getName() + ".cmd.toggle";
this.permsReload = plugin.getName() + ".cmd.reload";
this.permsReset = plugin.getName() + ".cmd.reset";
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (!sender.hasPermission(this.permsToggle)
&& !sender.hasPermission(this.permsReload)
&& !sender.hasPermission(this.permsReset)
&& !sender.hasPermission(this.permsSit)) {
sender.sendMessage(Messages.getString(Messages.NO_PERMISSION));
}
boolean showHelp = false;
if (cmd.getName().equalsIgnoreCase("toggleChairs")) {
if (args.length > 0) {
if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off")) {
handleToggleChairs(sender, args[0].equalsIgnoreCase("off"));
} else if (args[0].equalsIgnoreCase("status")) {
if (!(sender instanceof Player)) {
sender.sendMessage(Messages.getPrefix() + " §cOnly players may toggle chairs");
return true;
}
sender.sendMessage(Messages.getString(
getManager().hasChairsDisabled((Player) sender)
? Messages.TOGGLE_STATUS_DISABLED
: Messages.TOGGLE_STATUS_ENABLED));
} else {
showHelp = true;
}
} else {
handleToggleChairs(sender);
}
} else if (cmd.getName().equalsIgnoreCase("sit")) {
if (!(sender instanceof Player)) {
sender.sendMessage(Messages.getPrefix() + " §cOnly players are able to sit");
return true;
}
Player p = (Player) sender;
Block b = null;
if (p.getLocation().getBlock().getType().isSolid()) {
b = p.getLocation().getBlock();
} else if (p.getLocation()
.getBlock()
.getRelative(BlockFace.DOWN)
.getType()
.isSolid()) {
b = p.getLocation().getBlock().getRelative(BlockFace.DOWN);
}
if (b != null) {
getManager().create(p, b);
} else {
sender.sendMessage(Messages.getPrefix() + " §cYou need to be on solid ground");
}
} else if (args.length >= 1) {
if (args[0].equalsIgnoreCase("toggle")) {
handleToggleChairs(sender);
} else if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("off")) {
handleToggleChairs(sender, args[0].equalsIgnoreCase("off"));
} else if (args[0].equalsIgnoreCase("status")) {
if (!(sender instanceof Player)) {
sender.sendMessage(Messages.getPrefix() + " §cOnly players may toggle chairs");
return true;
}
sender.sendMessage(Messages.getString(
getManager().hasChairsDisabled((Player) sender)
? Messages.TOGGLE_STATUS_DISABLED
: Messages.TOGGLE_STATUS_ENABLED));
} else if (args[0].equalsIgnoreCase("reload") || args[0].equalsIgnoreCase("rl")) {
if (sender.hasPermission(this.permsReload)) {
if (Messages.reload()) {
sender.sendMessage(Messages.getPrefix() + " §aSuccessfully reloaded §6messages.yml§a!");
} else {
sender.sendMessage(Messages.getPrefix()
+ " §cCould not reload §6messages.yml §7- §cCheck server logs for more information");
}
if (Settings.reload()) {
sender.sendMessage(Messages.getPrefix() + " §aSuccessfully reloaded §6config.yml§a!");
} else {
sender.sendMessage(Messages.getPrefix()
+ " §cCould not reload §6config.yml §7- §cCheck server logs for more information");
}
} else {
sender.sendMessage(Messages.getString(Messages.NO_PERMISSION));
}
} else if (args[0].equalsIgnoreCase("reset")) {
if (sender.hasPermission(this.permsReset)) {
int chairCount = getManager().destroyAll(true);
if (chairCount > 0) {
sender.sendMessage(Messages.getPrefix() + " §aSuccessfully removed §6" + chairCount
+ " players§a from their chairs");
} else {
sender.sendMessage(Messages.getPrefix() + " §4There are no chairs that could be removed");
}
} else {
sender.sendMessage(Messages.getString(Messages.NO_PERMISSION));
}
} else {
showHelp = true;
}
} else {
showHelp = true;
}
if (showHelp) {
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName()
+ " toggle §7(§eor §3/bct§7, §3/toggleChairs§7)"); // TODO: allow player(+ @a,@r,@p) as arg
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName()
+ " on§7/§3off §7(§eor §3/bct on§7/§3off§7)"); // TODO: allow player(+ @a,@r,@p) as arg
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName() + " reload§7/§3rl");
sender.sendMessage(
Messages.getPrefix() + " §3/" + cmd.getName() + " reset"); // TODO: allow player(+ @a,@r,@p) as arg
}
return true;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] args) {
List<String> result = new ArrayList<>();
if (!cmd.getName().equalsIgnoreCase("sit")) {
if (args.length == 1) {
String arg = args[0].toLowerCase();
if (sender.hasPermission(this.permsToggle)) {
if ("toggle".startsWith(arg)) {
result.add("toggle");
}
if ("on".startsWith(arg)) {
result.add("on");
}
if ("off".startsWith(arg)) {
result.add("off");
}
if ("status".startsWith(arg)) {
result.add("status");
}
}
if (!cmd.getName().equalsIgnoreCase("toggleChairs")) {
if ("reload".startsWith(arg) && sender.hasPermission(this.permsReload)) {
result.add("reload");
}
if ("reset".startsWith(arg) && sender.hasPermission(this.permsReset)) {
result.add("reset");
}
}
}
}
return result;
}
private void handleToggleChairs(CommandSender sender) {
handleToggleChairs(sender, sender instanceof Player && !getManager().hasChairsDisabled((Player) sender));
}
private void handleToggleChairs(CommandSender sender, boolean disableChairs) {
if (!sender.hasPermission(this.permsToggle)) {
sender.sendMessage(Messages.getString(Messages.NO_PERMISSION));
return;
}
if (!(sender instanceof Player)) {
sender.sendMessage(Messages.getPrefix() + " §cOnly players may toggle chairs");
return;
}
getManager().setChairsDisabled((Player) sender, disableChairs);
sender.sendMessage(Messages.getString(disableChairs ? Messages.TOGGLE_DISABLED : Messages.TOGGLE_ENABLED));
}
}
@@ -0,0 +1,220 @@
package de.sprax2013.betterchairs;
import de.sprax2013.lime.spigot.LimeDevUtilitySpigot;
import de.sprax2013.lime.spigot.nms.NmsVersionDetector;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.material.Stairs;
import org.bukkit.material.Step;
import org.bukkit.material.WoodenStep;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
public class BetterChairsPlugin extends JavaPlugin {
private static BetterChairsPlugin plugin;
private static ChairManager chairManager;
@Override
public void onEnable() {
plugin = this;
LimeDevUtilitySpigot.init(this); // Initialize LimeDevUtility
MinecraftVersion.disableUpdateCheck();
MinecraftVersion.getLogger().setLevel(Level.WARNING); // Hide info messages from NBT-API
ChairNMS chairNMS = getNewNMSInstance();
if (chairNMS.getListener() != null) {
Bukkit.getPluginManager().registerEvents(chairNMS.getListener(), this);
}
// Should be initiated as soon as possible (required in API submodule)
chairManager = new ChairManager(this, chairNMS);
// Init configuration files
Settings.reload();
Messages.reload();
// Start Updater
new Updater(this);
// Register Bukkit Event Listener
Bukkit.getPluginManager().registerEvents(new EventListener(), this);
// Register CommandExecutor
BetterChairsCommand cmdExecutor = new BetterChairsCommand(this);
getCommand(getName()).setExecutor(cmdExecutor);
getCommand("toggleChairs").setExecutor(cmdExecutor);
getCommand("sit").setExecutor(cmdExecutor);
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new PlaceholderApiExpansion(this).register();
}
}
@Override
public void onDisable() {
if (getManager() != null) {
getManager().destroyAll(true, true);
for (Player online : Bukkit.getOnlinePlayers()) {
getManager().onQuit(online.getUniqueId());
}
Settings.reset();
Messages.reset();
}
chairManager = null;
ChairManager.instance = null;
ChairManager.plugin = null;
}
/**
* Instantiates an ChairNMS <i>class</i> depending on the server version
*
* @return new instance of {@code ChairNMS}, never null
*/
@NotNull
private ChairNMS getNewNMSInstance() {
String version = NmsVersionDetector.detect().orElse(null);
try {
assert version != null;
return (ChairNMS) Class.forName("betterchairs.nms." + version + "." + version)
.getConstructors()[0]
.newInstance();
} catch (Exception ignore) {
getLogger()
.warning("Your server version (" + (version != null ? version : "UNKNOWN")
+ ") is not fully supported - Loading fallback...");
// Loading fallback when NMS not available
return new ChairNMS() {
// Surrounding some code with try-catch because this is meant to be a fallback
// So in theory it should even work on 1.4.7 servers (please don't try >_<)
@Override
@NotNull
public Entity spawnChairEntity(
@NotNull Location loc, int regenerationAmplifier, boolean useArmorStand) {
Entity chairEntity;
if (useArmorStand) {
chairEntity = loc.getWorld().spawn(loc, ArmorStand.class);
} else {
chairEntity = loc.getWorld().spawn(loc, Arrow.class);
}
ChairUtils.applyChairProtections(chairEntity);
// TODO: Support regeneration effect without overwriting #tick()
return chairEntity;
}
@Override
public void killChairEntity(@NotNull Entity entity) {
entity.remove();
}
@Override
public Listener getListener() {
return new Listener() {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onManipulate(PlayerArmorStandManipulateEvent e) {
if (getManager().isChair(e.getRightClicked())) {
e.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onDamage(EntityDamageEvent e) {
if (e.getEntity() instanceof ArmorStand
&& getManager().isChair(e.getEntity())) {
e.setCancelled(true);
}
}
};
}
@Override
public boolean isStair(@NotNull Block block) {
return block.getState().getData() instanceof Stairs;
}
@Override
public boolean isStairUpsideDown(@NotNull Block block) {
try {
return ((Stairs) block.getState().getData()).isInverted();
} catch (Exception ignore) {
// Feature not supported on this version of the Bukkit-api
}
return false;
}
@Override
@NotNull
public BlockFace getBlockRotation(@NotNull Block block) {
return ChairUtils.getBlockRotationLegacy(block);
}
@Override
public boolean isSlab(@NotNull Block block) {
return (block.getState().getData() instanceof Step
|| block.getState().getData() instanceof WoodenStep)
&& !block.getType().name().equals("DOUBLE_STEP")
&& !block.getType().name().equals("WOOD_DOUBLE_STEP");
}
@Override
public boolean isSlabTop(@NotNull Block block) {
if (block.getState().getData() instanceof Step) {
return ((Step) block.getState().getData()).isInverted();
} else if (block.getState().getData() instanceof WoodenStep) {
return ((WoodenStep) block.getState().getData()).isInverted();
}
return false;
}
@Override
public boolean hasEmptyMainHand(@NotNull Player player) {
return player.getInventory().getItemInHand().getType() == Material.AIR;
}
@Override
public boolean isChair(@NotNull Entity entity) {
// We cannot check using NMS when fallback NMS does not use NMS to spawn an ArmorStand
// Other plugins preventing our ArmorStand from spawning can thus not be prevented from such
// behavior
return false;
}
};
}
}
protected static ChairManager getManager() {
return chairManager;
}
public static BetterChairsPlugin getInstance() {
return plugin;
}
}
@@ -0,0 +1,400 @@
package de.sprax2013.betterchairs;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getInstance;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getManager;
import com.cryptomorin.xseries.XMaterial;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.spigotmc.event.entity.EntityDismountEvent;
public class EventListener implements Listener {
private static final List<XMaterial> WALL_SIGN_MATERIALS = Arrays.asList(
XMaterial.ACACIA_WALL_SIGN,
XMaterial.BAMBOO_WALL_SIGN,
XMaterial.BIRCH_WALL_SIGN,
XMaterial.CHERRY_WALL_SIGN,
XMaterial.CRIMSON_WALL_SIGN,
XMaterial.DARK_OAK_WALL_SIGN,
XMaterial.JUNGLE_WALL_SIGN,
XMaterial.MANGROVE_WALL_SIGN,
XMaterial.OAK_WALL_SIGN,
XMaterial.SPRUCE_WALL_SIGN,
XMaterial.WARPED_WALL_SIGN);
private List<Material> filteredMaterials;
public EventListener() {
Runnable task = () -> {
if (Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()) {
getMaterialFilter(); // Populate list to make sure invalid materials are logged
}
};
// Make sure that our list is up-to-date, after reloading the settings
Settings.getConfig().addListener(() -> {
this.filteredMaterials = null;
task.run();
});
task.run();
}
private List<Material> getMaterialFilter() {
if (this.filteredMaterials == null) {
this.filteredMaterials = new ArrayList<>();
List<String> names = Settings.MATERIAL_FILTER_NAMES.getValueAsStringList();
if (names != null) {
for (String name : names) {
Optional<XMaterial> xMat = XMaterial.matchXMaterial(name);
Material mat = null;
if (xMat.isPresent()) {
mat = xMat.get().parseMaterial();
}
if (mat != null) {
this.filteredMaterials.add(mat);
} else {
ChairManager.getLogger()
.warning(() -> "Invalid block type '" + name + "' in "
+ Settings.MATERIAL_FILTER_NAMES.getKey());
}
}
}
}
return this.filteredMaterials;
}
/* Spawn and Destroy Chairs */
/**
* If a player is interacting with a valid block to be used as a Chair,
* we spawn a {@link Chair} and set the player as passenger of its {@link Entity}
*/
@EventHandler(priority = EventPriority.HIGH)
private void onInteract(PlayerInteractEvent e) {
if (e.isCancelled() && !Settings.IGNORES_INTERACT_PREVENTION.getValueAsBoolean()) return;
if (e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
Chair chairTheCurrentPlayerIsSittingIn = getManager().getChair(e.getPlayer());
// Check Player
if (!e.getClickedBlock().getWorld().equals(e.getPlayer().getLocation().getWorld())) return; // Happens sometimes
if (e.getPlayer().isSneaking()) return;
if (getManager().hasChairsDisabled(e.getPlayer())) return;
if (chairTheCurrentPlayerIsSittingIn != null
&& // This also destroys zombie chair on old spigot versions
!Settings.ALLOW_SWITCHING_SEATS.getValueAsBoolean()) {
return;
}
if (e.getPlayer().getVehicle() != null && !Settings.ALLOW_SWITCHING_SEATS.getValueAsBoolean())
return; // Already sitting on something else
if (!e.getPlayer().hasPermission(BetterChairsPlugin.getInstance().getName() + ".use")) return;
if (Settings.NEEDS_EMPTY_HANDS.getValueAsBoolean()
&& !getManager().chairNMS.hasEmptyMainHand(e.getPlayer())) return;
// Is world disabled?
if (Settings.WORLD_FILTER_ENABLED.getValueAsBoolean()) {
boolean worldInFilter = Objects.requireNonNull(Settings.WORLD_FILTER_NAMES.getValueAsStringList())
.contains(e.getPlayer().getWorld().getName());
// World on Blacklist or not on Whitelist
if (worldInFilter == Settings.WORLD_FILTER_AS_BLACKLIST.getValueAsBoolean()) return;
}
/* Check Block */
if ((!Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()
|| !Settings.MATERIAL_FILTER_ALLOW_ALL_TYPES.getValueAsBoolean())
&& !getManager().chairNMS.isStair(e.getClickedBlock())
&& !getManager().chairNMS.isSlab(e.getClickedBlock())) return; // Not a Stair or Slab
if (!e.getClickedBlock().getRelative(BlockFace.UP).isEmpty()
&& Settings.CHAIR_NEED_AIR_ABOVE.getValueAsBoolean()) return; // Needs air above chair
if (e.getClickedBlock().getRelative(BlockFace.DOWN).isEmpty()
&& !Settings.CHAIR_ALLOW_AIR_BELOW.getValueAsBoolean()) return; // Does not allow air below chair
// Block type disabled in config?
if (!Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()
|| (Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()
&& !Settings.MATERIAL_FILTER_ALLOW_ALL_TYPES.getValueAsBoolean())) {
if ((!Settings.USE_STAIRS.getValueAsBoolean()
&& getManager().chairNMS.isStair(e.getClickedBlock()))
|| (!Settings.USE_SLABS.getValueAsBoolean()
&& getManager().chairNMS.isSlab(e.getClickedBlock()))) return;
if (getManager().chairNMS.isStair(e.getClickedBlock())
&& getManager().chairNMS.isStairUpsideDown(e.getClickedBlock())) return; // Stair but upside down
}
if (Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()) {
boolean blockInFilter =
getMaterialFilter().contains(e.getClickedBlock().getType());
// Block type on Blacklist or not on Whitelist
if (blockInFilter == Settings.MATERIAL_FILTER_AS_BLACKLIST.getValueAsBoolean()) return;
}
// Check Chair
if (getManager().isOccupied(e.getClickedBlock())) {
if (Settings.MSG_ALREADY_OCCUPIED.getValueAsBoolean()
&& (chairTheCurrentPlayerIsSittingIn == null
|| !chairTheCurrentPlayerIsSittingIn.getBlock().equals(e.getClickedBlock()))) {
e.getPlayer().sendMessage(Messages.getString(Messages.USE_ALREADY_OCCUPIED));
}
return;
}
// Check if Chair needs Signs
if (Settings.NEEDS_SIGNS.getValueAsBoolean()) {
BlockFace rotation = getManager().chairNMS.getBlockRotation(e.getClickedBlock());
BlockFace side1 =
(rotation == BlockFace.NORTH || rotation == BlockFace.SOUTH) ? BlockFace.WEST : BlockFace.NORTH;
BlockFace side2 =
(rotation == BlockFace.NORTH || rotation == BlockFace.SOUTH) ? BlockFace.EAST : BlockFace.SOUTH;
Block block1 = e.getClickedBlock().getRelative(side1);
Block block2 = e.getClickedBlock().getRelative(side2);
// Are WALL_SIGNs placed?
if (!WALL_SIGN_MATERIALS.contains(XMaterial.matchXMaterial(block1.getType()))
|| !WALL_SIGN_MATERIALS.contains(XMaterial.matchXMaterial(block2.getType()))) {
if (Settings.MSG_NEEDS_SIGNS.getValueAsBoolean()) {
e.getPlayer().sendMessage(Messages.getString(Messages.USE_NEEDS_SIGNS));
}
return; // No
}
// Block rotation changed between versions (both options needed for backwards compatibility)
boolean signOption1 = side1
!= getManager().chairNMS.getBlockRotation(block1).getOppositeFace()
|| side2 != getManager().chairNMS.getBlockRotation(block2).getOppositeFace();
boolean signOption2 = side2
!= getManager().chairNMS.getBlockRotation(block1).getOppositeFace()
|| side1 != getManager().chairNMS.getBlockRotation(block2).getOppositeFace();
// Are they attached to the chair?
if (!signOption1 && !signOption2) {
if (Settings.MSG_NEEDS_SIGNS.getValueAsBoolean()) {
e.getPlayer().sendMessage(Messages.getString(Messages.USE_NEEDS_SIGNS));
}
return; // No
}
}
// Check the distance to the chair
if (Settings.ALLOWED_DISTANCE_TO_CHAIR.getValueAsInt() > 0
&& e.getPlayer()
.getLocation()
.distance(e.getClickedBlock()
.getLocation()
// Use block center for distance calculation
.add(
e.getClickedBlock().getX() > 0 ? 0.5 : -0.5,
0,
e.getClickedBlock().getZ() > 0 ? 0.5 : -0.5))
> Settings.ALLOWED_DISTANCE_TO_CHAIR.getValueAsInt()) {
return;
}
boolean createChairOnNextTick = false;
Chair currentChair = getManager().getChair(e.getPlayer());
if (currentChair != null) {
createChairOnNextTick = true;
getManager().destroy(currentChair, true, true);
}
Runnable createChairTask = () -> {
// Spawn Chair
if (getManager().create(e.getPlayer(), e.getClickedBlock())) {
e.setCancelled(true);
if (Settings.MSG_NOW_SITTING.getValueAsBoolean()) {
e.getPlayer().sendMessage(Messages.getString(Messages.USE_NOW_SITTING));
}
}
};
if (createChairOnNextTick) {
Bukkit.getScheduler().scheduleSyncDelayedTask(getInstance(), createChairTask);
} else {
createChairTask.run();
}
}
/**
* This Event only works in latest spigot-1.8.8 and newer
*/
@EventHandler(priority = EventPriority.MONITOR)
private void onDismount(EntityDismountEvent e) {
Chair c = getManager().getChair(e.getDismounted());
if (c != null) {
getManager().destroy(c, true);
}
}
/**
* Check if a player is sitting on a chair when logging out<br>
* Using {@link EventPriority#LOWEST} so other plugins have the right {@link Location}
* after the player leaving the chair
*/
@EventHandler(priority = EventPriority.LOWEST)
private void onQuit(PlayerQuitEvent e) {
Entity vehicle = e.getPlayer().getVehicle();
Chair c = getManager().getChair(vehicle);
if (c != null) {
getManager().destroy(c, true, true);
}
}
@EventHandler(priority = EventPriority.MONITOR)
private void onQuitMonitor(PlayerQuitEvent e) {
getManager().onQuit(e.getPlayer().getUniqueId());
}
/* Protect Chairs */
@EventHandler(priority = EventPriority.HIGHEST)
public void onEntitySpawn(EntitySpawnEvent e) {
if (!e.isCancelled()) return;
if (getManager().isChair(e.getEntity())) {
e.setCancelled(false);
}
}
/**
* Prevent a chair's Entity to be teleported by accident
*/
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onTeleport(EntityTeleportEvent e) {
if (getManager().isChair(e.getEntity())) {
// We don't want our Entity used as a chair to be teleported by accident
e.setCancelled(true);
}
}
/**
* Check if another plugin insists on a chair's Entity to be teleported<br>
* if so, destroy the chair
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onTeleportMonitor(EntityTeleportEvent e) {
Chair chair = getManager().getChair(e.getEntity());
if (chair != null) {
getManager().destroy(chair, true);
}
}
/**
* Protect a chair's block from being destroyed while a player is sitting on it
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
private void onBlockBreak(BlockBreakEvent e) {
if (getManager().isOccupied(e.getBlock())) {
e.setCancelled(true);
}
}
/**
* Check if another plugin insists on breaking a chair's block<br>
* if so, destroy the chair too
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onBlockBreakMonitor(BlockBreakEvent e) {
Chair chair = getManager().getChair(e.getBlock());
if (chair != null) {
getManager().destroy(chair, true);
}
}
/**
* Check if a piston tries to move a chair's block
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
private void onPistonExtend(BlockPistonExtendEvent e) {
for (Block b : e.getBlocks()) {
if (getManager().isOccupied(b)) {
e.setCancelled(true);
break;
}
}
}
/**
* Check if another plugin insists on a chair's block being moved by an piston<br>
* if so, destroy the chair
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onPistonExtendMonitor(BlockPistonExtendEvent e) {
for (Block b : e.getBlocks()) {
Chair chair = getManager().getChair(b);
if (chair != null) {
getManager().destroy(chair, true);
}
}
}
/**
* Check if a piston tries to move a chair's block
*/
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
private void onPistonRetract(BlockPistonRetractEvent e) {
for (Block b : e.getBlocks()) {
if (getManager().isOccupied(b)) {
e.setCancelled(true);
break;
}
}
}
/**
* Check if another plugin insists on a chair's block being moved by an piston<br>
* if so, destroy the chair
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
private void onPistonRetractMonitor(BlockPistonRetractEvent e) {
for (Block b : e.getBlocks()) {
Chair chair = getManager().getChair(b);
if (chair != null) {
getManager().destroy(chair, true);
}
}
}
}
@@ -0,0 +1,63 @@
package de.sprax2013.betterchairs;
import java.util.Arrays;
import java.util.List;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
public class PlaceholderApiExpansion extends PlaceholderExpansion {
private final BetterChairsPlugin plugin;
public PlaceholderApiExpansion(BetterChairsPlugin plugin) {
this.plugin = plugin;
}
@Override
public @NotNull String getIdentifier() {
return this.plugin.getName();
}
@Override
public @NotNull String getVersion() {
return "1.0.0";
}
@Override
public @NotNull String getAuthor() {
return this.plugin.getDescription().getAuthors().get(0);
}
@Override
public boolean persist() {
return true;
}
@Override
public @NotNull List<String> getPlaceholders() {
return Arrays.asList("chairs_enabled", "sitting");
}
@Override
public String onRequest(OfflinePlayer player, @NotNull String placeholder) {
if (placeholder.equalsIgnoreCase("chairs_enabled")) {
if (ChairManager.getInstance() == null) {
return Boolean.TRUE.toString();
}
return Boolean.valueOf(!ChairManager.getInstance().hasChairsDisabled(player))
.toString();
}
if (placeholder.equalsIgnoreCase("sitting")) {
if (ChairManager.getInstance() == null || player.getPlayer() == null) {
return Boolean.FALSE.toString();
}
return Boolean.valueOf(ChairManager.getInstance().getChair(player.getPlayer()) != null)
.toString();
}
return null;
}
}
@@ -0,0 +1,225 @@
package de.sprax2013.betterchairs;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Timer;
import java.util.TimerTask;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Nullable;
public class Updater implements Listener {
public static final String VERSION_TXT_URL = "https://spraxdev.github.io/BetterChairs/version.txt";
public static final String MODRINTH_URL = "https://modrinth.com/plugin/betterchairs";
public static final String HANGAR_URL = "https://hangar.papermc.io/Sprax/BetterChairs";
public static final String SPIGOT_MC_URL = "https://r.spiget.org/84809";
public static final String GITHUB_URL = "https://github.com/SpraxDev/BetterChairs/releases";
public static final String CHANGELOG_URL = "https://github.com/SpraxDev/BetterChairs/blob/main/CHANGELOG.md";
private final JavaPlugin plugin;
private Timer timer;
private String newerVersion;
public Updater(JavaPlugin plugin) {
this.plugin = plugin;
Settings.getConfig().addListener(this::reInit);
reInit();
}
private void reInit() {
if (Settings.UPDATER_ENABLED.getValueAsBoolean()) {
if (this.timer != null) return;
this.timer = new Timer(true);
this.timer.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
if (Updater.this.plugin.isEnabled() && Settings.UPDATER_ENABLED.getValueAsBoolean()) {
try {
checkForUpdates();
} catch (Exception ex) {
ChairManager.getLogger()
.warning("Could not check for updates"
+ (ex.getMessage() == null ? "!" : ": " + ex.getMessage()));
}
} else {
Updater.this.timer.cancel();
}
}
},
2000,
1000 * 60 * 60 * 3); // Check every 3h
Bukkit.getPluginManager().registerEvents(this, this.plugin);
} else if (this.timer != null) {
// Stop Update-Timer
HandlerList.unregisterAll(this);
this.timer.cancel();
this.timer = null;
}
}
private void checkForUpdates() throws IOException {
URL website = new URL(VERSION_TXT_URL);
URLConnection connection = website.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder versionTxt = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null) {
versionTxt.append(inputLine.trim());
}
in.close();
String versionStr = versionTxt.toString().split("\n")[0];
String currVersion = this.plugin.getDescription().getVersion();
if (isNewerVersion(currVersion, versionStr)) {
this.newerVersion = versionStr;
ChairManager.getLogger()
.info(() -> String.format(
"Found a new update v%s -> v%s — Download the update from: %nmodrinth: %s%nHangar: %s%nSpigotMC: %s%nGitHub: %s%n%nChangelog: %s",
currVersion,
versionStr,
MODRINTH_URL,
HANGAR_URL,
SPIGOT_MC_URL,
GITHUB_URL,
getChangelogUrl(versionStr)));
} else {
this.newerVersion = null;
}
}
@EventHandler
private void onJoin(PlayerJoinEvent e) {
if (this.newerVersion == null) return;
if (!Settings.UPDATER_ENABLED.getValueAsBoolean()) return;
if (!Settings.UPDATER_NOTIFY_ON_JOIN.getValueAsBoolean()) return;
if (!e.getPlayer().hasPermission(this.plugin.getName() + ".updater")) return;
e.getPlayer()
.spigot()
.sendMessage(new ComponentBuilder("[")
.color(ChatColor.GRAY)
.append(BetterChairsPlugin.getInstance().getName())
.color(ChatColor.GOLD)
.append("] ")
.color(ChatColor.GRAY)
.append("Found a new update v"
+ this.plugin.getDescription().getVersion() + " -> v" + this.newerVersion)
.color(ChatColor.YELLOW)
.append(" [modrinth] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, MODRINTH_URL))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on modrinth")))
.append(" [Hangar] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, HANGAR_URL))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on Hangar")))
.append(" [SpigotMC] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, SPIGOT_MC_URL))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on SpigotMC")))
.append("[GitHub] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, GITHUB_URL))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on GitHub")))
.append("[Changelog]")
.color(ChatColor.DARK_GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, getChangelogUrl(this.newerVersion)))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§aClick to see the Changelogs at GitHub.com")))
.create());
}
@EventHandler
private void onPluginDisable(PluginDisableEvent e) {
if (e.getPlugin() == this.plugin) {
this.timer.cancel();
}
}
/**
* Check if {@code ver1} is newer that {@code ver2}.<br>
* Expects <a href="https://semver.org/">SemVer</a>
*
* @return true, if {@code ver1} is newer than {@code ver2}, false otherwise
*/
public boolean isNewerVersion(String ver1, String ver2) {
int[] ver1Num;
int[] ver2Num;
String[] ver1Args = ver1.split("-")[0].split("\\.");
String[] ver2Args = ver2.split("-")[0].split("\\.");
ver1Num = new int[ver1Args.length];
for (int i = 0; i < ver1Args.length; i++) {
ver1Num[i] = Integer.parseInt(ver1Args[i]);
}
ver2Num = new int[ver2Args.length];
for (int i = 0; i < ver2Args.length; i++) {
ver2Num[i] = Integer.parseInt(ver2Args[i]);
}
for (int i = 0; i < Math.max(ver1Num.length, ver2Num.length); i++) {
int left = i < ver1Num.length ? ver1Num[i] : 0;
int right = i < ver2Num.length ? ver2Num[i] : 0;
if (left != right) {
return left < right;
}
}
if (ver1.contains("-")) {
if (!ver2.contains("-"))
return true; // true, if they have same SemVer but ver1 has a suffix attached while ver2 does not
String suffix1 = ver1.substring(ver1.lastIndexOf('-'));
String suffix2 = ver2.substring(ver2.lastIndexOf('-'));
return !suffix1.equals(suffix2); // true, if versions have suffix like '-SNAPSHOT' while being same SemVer
}
return false; // Same version
}
private static String getChangelogUrl(@Nullable String semVersion) {
if (semVersion != null) {
return CHANGELOG_URL + "#version-" + semVersion.replace(".", "");
}
return CHANGELOG_URL;
}
}
@@ -0,0 +1,2 @@
Manifest-Version: 1.0
@@ -0,0 +1,2 @@
Manifest-Version: 1.0
-340
View File
@@ -1,340 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs</artifactId>
<version>1.14.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>betterchairs-plugin</artifactId>
<build>
<finalName>${pluginName}-v${project.parent.version}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>betterchairs.nms</pattern>
<shadedPattern>de.sprax2013.betterchairs.nms</shadedPattern>
</relocation>
<relocation>
<pattern>de.sprax2013.lime</pattern>
<shadedPattern>de.sprax2013.betterchairs.third_party.de.sprax2013.lime</shadedPattern>
</relocation>
<relocation>
<pattern>de.tr7zw.changeme.nbtapi</pattern>
<shadedPattern>de.sprax2013.betterchairs.third_party.de.tr7zw.nbtapi</shadedPattern>
</relocation>
<relocation>
<pattern>com.cryptomorin.xseries</pattern>
<shadedPattern>de.sprax2013.betterchairs.third_party.com.cryptomorin.xseries</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>de.sprax2013.betterchairs.third_party.org.bstats</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
<configuration>
<minimizeJar>true</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${project.parent.groupId}.${project.parent.artifactId}.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
<exclude>LICENSE</exclude>
</excludes>
</filter>
<filter>
<artifact>org.jetbrains:annotations</artifact>
<excludes>
<exclude>**</exclude>
</excludes>
</filter>
<filter>
<artifact>de.sprax2013:betterchairs-v*</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.6</version>
<scope>provided</scope>
</dependency>
<!-- Modules -->
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-api</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_21_R4</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_21_R3</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_21_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_21_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_20_R4</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_20_R3</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_20_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_20_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_19_R3</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_19_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_19_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_18_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_18_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_17_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_16_R3</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_16_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_16_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_15_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_14_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_13_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_13_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_12_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_11_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_10_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_9_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_9_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_8_R3</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_8_R2</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-v1_8_R1</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
@@ -1,5 +1,9 @@
package de.sprax2013.betterchairs;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getManager;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.Command;
@@ -9,11 +13,6 @@ import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.ArrayList;
import java.util.List;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getManager;
// TODO: Put all strings into messages.yml
// TODO: Split file into smaller ones
public class BetterChairsCommand implements CommandExecutor, TabCompleter {
@@ -29,10 +28,10 @@ public class BetterChairsCommand implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (!sender.hasPermission(this.permsToggle) &&
!sender.hasPermission(this.permsReload) &&
!sender.hasPermission(this.permsReset) &&
!sender.hasPermission(this.permsSit)) {
if (!sender.hasPermission(this.permsToggle)
&& !sender.hasPermission(this.permsReload)
&& !sender.hasPermission(this.permsReset)
&& !sender.hasPermission(this.permsSit)) {
sender.sendMessage(Messages.getString(Messages.NO_PERMISSION));
}
@@ -49,9 +48,9 @@ public class BetterChairsCommand implements CommandExecutor, TabCompleter {
}
sender.sendMessage(Messages.getString(
getManager().hasChairsDisabled((Player) sender) ?
Messages.TOGGLE_STATUS_DISABLED :
Messages.TOGGLE_STATUS_ENABLED));
getManager().hasChairsDisabled((Player) sender)
? Messages.TOGGLE_STATUS_DISABLED
: Messages.TOGGLE_STATUS_ENABLED));
} else {
showHelp = true;
}
@@ -70,7 +69,11 @@ public class BetterChairsCommand implements CommandExecutor, TabCompleter {
if (p.getLocation().getBlock().getType().isSolid()) {
b = p.getLocation().getBlock();
} else if (p.getLocation().getBlock().getRelative(BlockFace.DOWN).getType().isSolid()) {
} else if (p.getLocation()
.getBlock()
.getRelative(BlockFace.DOWN)
.getType()
.isSolid()) {
b = p.getLocation().getBlock().getRelative(BlockFace.DOWN);
}
@@ -91,21 +94,23 @@ public class BetterChairsCommand implements CommandExecutor, TabCompleter {
}
sender.sendMessage(Messages.getString(
getManager().hasChairsDisabled((Player) sender) ?
Messages.TOGGLE_STATUS_DISABLED :
Messages.TOGGLE_STATUS_ENABLED));
getManager().hasChairsDisabled((Player) sender)
? Messages.TOGGLE_STATUS_DISABLED
: Messages.TOGGLE_STATUS_ENABLED));
} else if (args[0].equalsIgnoreCase("reload") || args[0].equalsIgnoreCase("rl")) {
if (sender.hasPermission(this.permsReload)) {
if (Messages.reload()) {
sender.sendMessage(Messages.getPrefix() + " §aSuccessfully reloaded §6messages.yml§a!");
} else {
sender.sendMessage(Messages.getPrefix() + " §cCould not reload §6messages.yml §7- §cCheck server logs for more information");
sender.sendMessage(Messages.getPrefix()
+ " §cCould not reload §6messages.yml §7- §cCheck server logs for more information");
}
if (Settings.reload()) {
sender.sendMessage(Messages.getPrefix() + " §aSuccessfully reloaded §6config.yml§a!");
} else {
sender.sendMessage(Messages.getPrefix() + " §cCould not reload §6config.yml §7- §cCheck server logs for more information");
sender.sendMessage(Messages.getPrefix()
+ " §cCould not reload §6config.yml §7- §cCheck server logs for more information");
}
} else {
sender.sendMessage(Messages.getString(Messages.NO_PERMISSION));
@@ -115,7 +120,8 @@ public class BetterChairsCommand implements CommandExecutor, TabCompleter {
int chairCount = getManager().destroyAll(true);
if (chairCount > 0) {
sender.sendMessage(Messages.getPrefix() + " §aSuccessfully removed §6" + chairCount + " players§a from their chairs");
sender.sendMessage(Messages.getPrefix() + " §aSuccessfully removed §6" + chairCount
+ " players§a from their chairs");
} else {
sender.sendMessage(Messages.getPrefix() + " §4There are no chairs that could be removed");
}
@@ -130,10 +136,13 @@ public class BetterChairsCommand implements CommandExecutor, TabCompleter {
}
if (showHelp) {
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName() + " toggle §7(§eor §3/bct§7, §3/toggleChairs§7)"); // TODO: allow player(+ @a,@r,@p) as arg
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName() + " on§7/§3off §7(§eor §3/bct on§7/§3off§7)"); // TODO: allow player(+ @a,@r,@p) as arg
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName()
+ " toggle §7(§eor §3/bct§7, §3/toggleChairs§7)"); // TODO: allow player(+ @a,@r,@p) as arg
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName()
+ " on§7/§3off §7(§eor §3/bct on§7/§3off§7)"); // TODO: allow player(+ @a,@r,@p) as arg
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName() + " reload§7/§3rl");
sender.sendMessage(Messages.getPrefix() + " §3/" + cmd.getName() + " reset"); // TODO: allow player(+ @a,@r,@p) as arg
sender.sendMessage(
Messages.getPrefix() + " §3/" + cmd.getName() + " reset"); // TODO: allow player(+ @a,@r,@p) as arg
}
return true;
@@ -3,8 +3,7 @@ package de.sprax2013.betterchairs;
import de.sprax2013.lime.spigot.LimeDevUtilitySpigot;
import de.sprax2013.lime.spigot.nms.NmsVersionDetector;
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -25,8 +24,6 @@ import org.bukkit.material.WoodenStep;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.logging.Level;
public class BetterChairsPlugin extends JavaPlugin {
private static BetterChairsPlugin plugin;
private static ChairManager chairManager;
@@ -35,9 +32,9 @@ public class BetterChairsPlugin extends JavaPlugin {
public void onEnable() {
plugin = this;
LimeDevUtilitySpigot.init(this); // Initialize LimeDevUtility
LimeDevUtilitySpigot.init(this); // Initialize LimeDevUtility
MinecraftVersion.disableUpdateCheck();
MinecraftVersion.getLogger().setLevel(Level.WARNING); // Hide info messages from NBT-API
MinecraftVersion.getLogger().setLevel(Level.WARNING); // Hide info messages from NBT-API
ChairNMS chairNMS = getNewNMSInstance();
@@ -67,18 +64,6 @@ public class BetterChairsPlugin extends JavaPlugin {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new PlaceholderApiExpansion(this).register();
}
// Load bStats
try {
Metrics bStats = new Metrics(this, 8214);
// Custom chart: NMS Version
String nmsVersion = NmsVersionDetector.detect().orElse(Bukkit.getServer().getBukkitVersion());
bStats.addCustomChart(new SimplePie("nms_version", () -> nmsVersion));
} catch (Exception ex) {
// Does not work on Spigot 1.8.0 (gson is missing)
getLogger().warning("Could not load bStats (" + ex.getClass().getSimpleName() + "): " + ex.getMessage());
}
}
@Override
@@ -110,9 +95,13 @@ public class BetterChairsPlugin extends JavaPlugin {
try {
assert version != null;
return (ChairNMS) Class.forName("betterchairs.nms." + version + "." + version).getConstructors()[0].newInstance();
return (ChairNMS) Class.forName("betterchairs.nms." + version + "." + version)
.getConstructors()[0]
.newInstance();
} catch (Exception ignore) {
getLogger().warning("Your server version (" + (version != null ? version : "UNKNOWN") + ") is not fully supported - Loading fallback...");
getLogger()
.warning("Your server version (" + (version != null ? version : "UNKNOWN")
+ ") is not fully supported - Loading fallback...");
// Loading fallback when NMS not available
return new ChairNMS() {
@@ -121,7 +110,8 @@ public class BetterChairsPlugin extends JavaPlugin {
@Override
@NotNull
public Entity spawnChairEntity(@NotNull Location loc, int regenerationAmplifier, boolean useArmorStand) {
public Entity spawnChairEntity(
@NotNull Location loc, int regenerationAmplifier, boolean useArmorStand) {
Entity chairEntity;
if (useArmorStand) {
@@ -154,8 +144,8 @@ public class BetterChairsPlugin extends JavaPlugin {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onDamage(EntityDamageEvent e) {
if (e.getEntity() instanceof ArmorStand &&
getManager().isChair(e.getEntity())) {
if (e.getEntity() instanceof ArmorStand
&& getManager().isChair(e.getEntity())) {
e.setCancelled(true);
}
}
@@ -186,10 +176,10 @@ public class BetterChairsPlugin extends JavaPlugin {
@Override
public boolean isSlab(@NotNull Block block) {
return (block.getState().getData() instanceof Step ||
block.getState().getData() instanceof WoodenStep) &&
!block.getType().name().equals("DOUBLE_STEP") &&
!block.getType().name().equals("WOOD_DOUBLE_STEP");
return (block.getState().getData() instanceof Step
|| block.getState().getData() instanceof WoodenStep)
&& !block.getType().name().equals("DOUBLE_STEP")
&& !block.getType().name().equals("WOOD_DOUBLE_STEP");
}
@Override
@@ -211,7 +201,8 @@ public class BetterChairsPlugin extends JavaPlugin {
@Override
public boolean isChair(@NotNull Entity entity) {
// We cannot check using NMS when fallback NMS does not use NMS to spawn an ArmorStand
// Other plugins preventing our ArmorStand from spawning can thus not be prevented from such behavior
// Other plugins preventing our ArmorStand from spawning can thus not be prevented from such
// behavior
return false;
}
@@ -1,6 +1,14 @@
package de.sprax2013.betterchairs;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getInstance;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getManager;
import com.cryptomorin.xseries.XMaterial;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -20,15 +28,6 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.spigotmc.event.entity.EntityDismountEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getInstance;
import static de.sprax2013.betterchairs.BetterChairsPlugin.getManager;
public class EventListener implements Listener {
private static final List<XMaterial> WALL_SIGN_MATERIALS = Arrays.asList(
XMaterial.ACACIA_WALL_SIGN,
@@ -41,15 +40,14 @@ public class EventListener implements Listener {
XMaterial.MANGROVE_WALL_SIGN,
XMaterial.OAK_WALL_SIGN,
XMaterial.SPRUCE_WALL_SIGN,
XMaterial.WARPED_WALL_SIGN
);
XMaterial.WARPED_WALL_SIGN);
private List<Material> filteredMaterials;
public EventListener() {
Runnable task = () -> {
if (Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()) {
getMaterialFilter(); // Populate list to make sure invalid materials are logged
getMaterialFilter(); // Populate list to make sure invalid materials are logged
}
};
@@ -80,8 +78,9 @@ public class EventListener implements Listener {
if (mat != null) {
this.filteredMaterials.add(mat);
} else {
ChairManager.getLogger().warning(() -> "Invalid block type '" + name +
"' in " + Settings.MATERIAL_FILTER_NAMES.getKey());
ChairManager.getLogger()
.warning(() -> "Invalid block type '" + name + "' in "
+ Settings.MATERIAL_FILTER_NAMES.getKey());
}
}
}
@@ -107,15 +106,16 @@ public class EventListener implements Listener {
if (!e.getClickedBlock().getWorld().equals(e.getPlayer().getLocation().getWorld())) return; // Happens sometimes
if (e.getPlayer().isSneaking()) return;
if (getManager().hasChairsDisabled(e.getPlayer())) return;
if (chairTheCurrentPlayerIsSittingIn != null && // This also destroys zombie chair on old spigot versions
if (chairTheCurrentPlayerIsSittingIn != null
&& // This also destroys zombie chair on old spigot versions
!Settings.ALLOW_SWITCHING_SEATS.getValueAsBoolean()) {
return;
}
if (e.getPlayer().getVehicle() != null &&
!Settings.ALLOW_SWITCHING_SEATS.getValueAsBoolean()) return; // Already sitting on something else
if (e.getPlayer().getVehicle() != null && !Settings.ALLOW_SWITCHING_SEATS.getValueAsBoolean())
return; // Already sitting on something else
if (!e.getPlayer().hasPermission(BetterChairsPlugin.getInstance().getName() + ".use")) return;
if (Settings.NEEDS_EMPTY_HANDS.getValueAsBoolean() &&
!getManager().chairNMS.hasEmptyMainHand(e.getPlayer())) return;
if (Settings.NEEDS_EMPTY_HANDS.getValueAsBoolean()
&& !getManager().chairNMS.hasEmptyMainHand(e.getPlayer())) return;
// Is world disabled?
if (Settings.WORLD_FILTER_ENABLED.getValueAsBoolean()) {
@@ -127,32 +127,33 @@ public class EventListener implements Listener {
}
/* Check Block */
if ((!Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean() ||
!Settings.MATERIAL_FILTER_ALLOW_ALL_TYPES.getValueAsBoolean()) &&
!getManager().chairNMS.isStair(e.getClickedBlock()) &&
!getManager().chairNMS.isSlab(e.getClickedBlock())) return; // Not a Stair or Slab
if ((!Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()
|| !Settings.MATERIAL_FILTER_ALLOW_ALL_TYPES.getValueAsBoolean())
&& !getManager().chairNMS.isStair(e.getClickedBlock())
&& !getManager().chairNMS.isSlab(e.getClickedBlock())) return; // Not a Stair or Slab
if (!e.getClickedBlock().getRelative(BlockFace.UP).isEmpty() &&
Settings.CHAIR_NEED_AIR_ABOVE.getValueAsBoolean()) return; // Needs air above chair
if (!e.getClickedBlock().getRelative(BlockFace.UP).isEmpty()
&& Settings.CHAIR_NEED_AIR_ABOVE.getValueAsBoolean()) return; // Needs air above chair
if (e.getClickedBlock().getRelative(BlockFace.DOWN).isEmpty() &&
!Settings.CHAIR_ALLOW_AIR_BELOW.getValueAsBoolean()) return; // Does not allow air below chair
if (e.getClickedBlock().getRelative(BlockFace.DOWN).isEmpty()
&& !Settings.CHAIR_ALLOW_AIR_BELOW.getValueAsBoolean()) return; // Does not allow air below chair
// Block type disabled in config?
if (!Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean() ||
(Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean() &&
!Settings.MATERIAL_FILTER_ALLOW_ALL_TYPES.getValueAsBoolean())) {
if ((!Settings.USE_STAIRS.getValueAsBoolean() && getManager().chairNMS.isStair(e.getClickedBlock())) ||
(!Settings.USE_SLABS.getValueAsBoolean() && getManager().chairNMS.isSlab(e.getClickedBlock())))
return;
if (!Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()
|| (Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()
&& !Settings.MATERIAL_FILTER_ALLOW_ALL_TYPES.getValueAsBoolean())) {
if ((!Settings.USE_STAIRS.getValueAsBoolean()
&& getManager().chairNMS.isStair(e.getClickedBlock()))
|| (!Settings.USE_SLABS.getValueAsBoolean()
&& getManager().chairNMS.isSlab(e.getClickedBlock()))) return;
if (getManager().chairNMS.isStair(e.getClickedBlock()) &&
getManager().chairNMS.isStairUpsideDown(e.getClickedBlock())) return; // Stair but upside down
if (getManager().chairNMS.isStair(e.getClickedBlock())
&& getManager().chairNMS.isStairUpsideDown(e.getClickedBlock())) return; // Stair but upside down
}
if (Settings.MATERIAL_FILTER_ENABLED.getValueAsBoolean()) {
boolean blockInFilter = getMaterialFilter()
.contains(e.getClickedBlock().getType());
boolean blockInFilter =
getMaterialFilter().contains(e.getClickedBlock().getType());
// Block type on Blacklist or not on Whitelist
if (blockInFilter == Settings.MATERIAL_FILTER_AS_BLACKLIST.getValueAsBoolean()) return;
@@ -160,7 +161,9 @@ public class EventListener implements Listener {
// Check Chair
if (getManager().isOccupied(e.getClickedBlock())) {
if (Settings.MSG_ALREADY_OCCUPIED.getValueAsBoolean() && (chairTheCurrentPlayerIsSittingIn == null || !chairTheCurrentPlayerIsSittingIn.getBlock().equals(e.getClickedBlock()))) {
if (Settings.MSG_ALREADY_OCCUPIED.getValueAsBoolean()
&& (chairTheCurrentPlayerIsSittingIn == null
|| !chairTheCurrentPlayerIsSittingIn.getBlock().equals(e.getClickedBlock()))) {
e.getPlayer().sendMessage(Messages.getString(Messages.USE_ALREADY_OCCUPIED));
}
@@ -171,15 +174,17 @@ public class EventListener implements Listener {
if (Settings.NEEDS_SIGNS.getValueAsBoolean()) {
BlockFace rotation = getManager().chairNMS.getBlockRotation(e.getClickedBlock());
BlockFace side1 = (rotation == BlockFace.NORTH || rotation == BlockFace.SOUTH) ? BlockFace.WEST : BlockFace.NORTH;
BlockFace side2 = (rotation == BlockFace.NORTH || rotation == BlockFace.SOUTH) ? BlockFace.EAST : BlockFace.SOUTH;
BlockFace side1 =
(rotation == BlockFace.NORTH || rotation == BlockFace.SOUTH) ? BlockFace.WEST : BlockFace.NORTH;
BlockFace side2 =
(rotation == BlockFace.NORTH || rotation == BlockFace.SOUTH) ? BlockFace.EAST : BlockFace.SOUTH;
Block block1 = e.getClickedBlock().getRelative(side1);
Block block2 = e.getClickedBlock().getRelative(side2);
// Are WALL_SIGNs placed?
if (!WALL_SIGN_MATERIALS.contains(XMaterial.matchXMaterial(block1.getType())) ||
!WALL_SIGN_MATERIALS.contains(XMaterial.matchXMaterial(block2.getType()))) {
if (!WALL_SIGN_MATERIALS.contains(XMaterial.matchXMaterial(block1.getType()))
|| !WALL_SIGN_MATERIALS.contains(XMaterial.matchXMaterial(block2.getType()))) {
if (Settings.MSG_NEEDS_SIGNS.getValueAsBoolean()) {
e.getPlayer().sendMessage(Messages.getString(Messages.USE_NEEDS_SIGNS));
}
@@ -188,10 +193,12 @@ public class EventListener implements Listener {
}
// Block rotation changed between versions (both options needed for backwards compatibility)
boolean signOption1 = side1 != getManager().chairNMS.getBlockRotation(block1).getOppositeFace() ||
side2 != getManager().chairNMS.getBlockRotation(block2).getOppositeFace();
boolean signOption2 = side2 != getManager().chairNMS.getBlockRotation(block1).getOppositeFace() ||
side1 != getManager().chairNMS.getBlockRotation(block2).getOppositeFace();
boolean signOption1 = side1
!= getManager().chairNMS.getBlockRotation(block1).getOppositeFace()
|| side2 != getManager().chairNMS.getBlockRotation(block2).getOppositeFace();
boolean signOption2 = side2
!= getManager().chairNMS.getBlockRotation(block1).getOppositeFace()
|| side1 != getManager().chairNMS.getBlockRotation(block2).getOppositeFace();
// Are they attached to the chair?
if (!signOption1 && !signOption2) {
@@ -204,13 +211,17 @@ public class EventListener implements Listener {
}
// Check the distance to the chair
if (Settings.ALLOWED_DISTANCE_TO_CHAIR.getValueAsInt() > 0 &&
e.getPlayer().getLocation()
.distance(e.getClickedBlock().getLocation()
// Use block center for distance calculation
.add(e.getClickedBlock().getX() > 0 ? 0.5 : -0.5, 0,
e.getClickedBlock().getZ() > 0 ? 0.5 : -0.5)) >
Settings.ALLOWED_DISTANCE_TO_CHAIR.getValueAsInt()) {
if (Settings.ALLOWED_DISTANCE_TO_CHAIR.getValueAsInt() > 0
&& e.getPlayer()
.getLocation()
.distance(e.getClickedBlock()
.getLocation()
// Use block center for distance calculation
.add(
e.getClickedBlock().getX() > 0 ? 0.5 : -0.5,
0,
e.getClickedBlock().getZ() > 0 ? 0.5 : -0.5))
> Settings.ALLOWED_DISTANCE_TO_CHAIR.getValueAsInt()) {
return;
}
@@ -1,11 +1,10 @@
package de.sprax2013.betterchairs;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
public class PlaceholderApiExpansion extends PlaceholderExpansion {
private final BetterChairsPlugin plugin;
@@ -46,7 +45,8 @@ public class PlaceholderApiExpansion extends PlaceholderExpansion {
return Boolean.TRUE.toString();
}
return Boolean.valueOf(!ChairManager.getInstance().hasChairsDisabled(player)).toString();
return Boolean.valueOf(!ChairManager.getInstance().hasChairsDisabled(player))
.toString();
}
if (placeholder.equalsIgnoreCase("sitting")) {
@@ -54,7 +54,8 @@ public class PlaceholderApiExpansion extends PlaceholderExpansion {
return Boolean.FALSE.toString();
}
return Boolean.valueOf(ChairManager.getInstance().getChair(player.getPlayer()) != null).toString();
return Boolean.valueOf(ChairManager.getInstance().getChair(player.getPlayer()) != null)
.toString();
}
return null;
@@ -1,5 +1,12 @@
package de.sprax2013.betterchairs;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Timer;
import java.util.TimerTask;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
@@ -14,14 +21,6 @@ import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Timer;
import java.util.TimerTask;
public class Updater implements Listener {
public static final String VERSION_TXT_URL = "https://spraxdev.github.io/BetterChairs/version.txt";
@@ -50,22 +49,25 @@ public class Updater implements Listener {
if (this.timer != null) return;
this.timer = new Timer(true);
this.timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (Updater.this.plugin.isEnabled() && Settings.UPDATER_ENABLED.getValueAsBoolean()) {
try {
checkForUpdates();
} catch (Exception ex) {
ChairManager.getLogger()
.warning("Could not check for updates" +
(ex.getMessage() == null ? "!" : ": " + ex.getMessage()));
this.timer.scheduleAtFixedRate(
new TimerTask() {
@Override
public void run() {
if (Updater.this.plugin.isEnabled() && Settings.UPDATER_ENABLED.getValueAsBoolean()) {
try {
checkForUpdates();
} catch (Exception ex) {
ChairManager.getLogger()
.warning("Could not check for updates"
+ (ex.getMessage() == null ? "!" : ": " + ex.getMessage()));
}
} else {
Updater.this.timer.cancel();
}
}
} else {
Updater.this.timer.cancel();
}
}
}, 2000, 1000 * 60 * 60 * 3); // Check every 3h
},
2000,
1000 * 60 * 60 * 3); // Check every 3h
Bukkit.getPluginManager().registerEvents(this, this.plugin);
} else if (this.timer != null) {
@@ -96,8 +98,15 @@ public class Updater implements Listener {
this.newerVersion = versionStr;
ChairManager.getLogger()
.info(() -> String.format("Found a new update v%s -> v%s — Download the update from: %nmodrinth: %s%nHangar: %s%nSpigotMC: %s%nGitHub: %s%n%nChangelog: %s",
currVersion, versionStr, MODRINTH_URL, HANGAR_URL, SPIGOT_MC_URL, GITHUB_URL, getChangelogUrl(versionStr)));
.info(() -> String.format(
"Found a new update v%s -> v%s — Download the update from: %nmodrinth: %s%nHangar: %s%nSpigotMC: %s%nGitHub: %s%n%nChangelog: %s",
currVersion,
versionStr,
MODRINTH_URL,
HANGAR_URL,
SPIGOT_MC_URL,
GITHUB_URL,
getChangelogUrl(versionStr)));
} else {
this.newerVersion = null;
}
@@ -110,32 +119,47 @@ public class Updater implements Listener {
if (!Settings.UPDATER_NOTIFY_ON_JOIN.getValueAsBoolean()) return;
if (!e.getPlayer().hasPermission(this.plugin.getName() + ".updater")) return;
e.getPlayer().spigot().sendMessage(
new ComponentBuilder("[").color(ChatColor.GRAY)
.append(BetterChairsPlugin.getInstance().getName()).color(ChatColor.GOLD)
.append("] ").color(ChatColor.GRAY)
.append("Found a new update v" +
this.plugin.getDescription().getVersion() + " -> v" + this.newerVersion).color(ChatColor.YELLOW)
e.getPlayer()
.spigot()
.sendMessage(new ComponentBuilder("[")
.color(ChatColor.GRAY)
.append(BetterChairsPlugin.getInstance().getName())
.color(ChatColor.GOLD)
.append("] ")
.color(ChatColor.GRAY)
.append("Found a new update v"
+ this.plugin.getDescription().getVersion() + " -> v" + this.newerVersion)
.color(ChatColor.YELLOW)
.append(" [modrinth] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, MODRINTH_URL))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§2Click to visit the download page on modrinth")))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on modrinth")))
.append(" [Hangar] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, HANGAR_URL))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§2Click to visit the download page on Hangar")))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on Hangar")))
.append(" [SpigotMC] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, SPIGOT_MC_URL))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§2Click to visit the download page on SpigotMC")))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on SpigotMC")))
.append("[GitHub] ")
.color(ChatColor.GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, GITHUB_URL))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§2Click to visit the download page on GitHub")))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§2Click to visit the download page on GitHub")))
.append("[Changelog]")
.color(ChatColor.DARK_GREEN)
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, getChangelogUrl(this.newerVersion)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText("§aClick to see the Changelogs at GitHub.com")))
.event(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
TextComponent.fromLegacyText("§aClick to see the Changelogs at GitHub.com")))
.create());
}
@@ -185,10 +209,10 @@ public class Updater implements Listener {
String suffix1 = ver1.substring(ver1.lastIndexOf('-'));
String suffix2 = ver2.substring(ver2.lastIndexOf('-'));
return !suffix1.equals(suffix2); // true, if versions have suffix like '-SNAPSHOT' while being same SemVer
return !suffix1.equals(suffix2); // true, if versions have suffix like '-SNAPSHOT' while being same SemVer
}
return false; // Same version
return false; // Same version
}
private static String getChangelogUrl(@Nullable String semVersion) {
@@ -1,9 +1,9 @@
name: ${pluginName}
description: Players can sit on chairs and everywhere the admin wants them to be able to.
version: ${project.parent.version}
api-version: '1.13'
version: ${version}
api-version: '1.19'
main: ${project.parent.groupId}.${project.parent.artifactId}.BetterChairsPlugin
main: de.sprax2013.betterchairs.BetterChairsPlugin
softdepend:
- PlaceholderAPI
@@ -16,8 +16,7 @@ commands:
description: 'Toggle, Reload or Reset BetterChairs'
toggleChairs:
description: 'Allows individual players to disabled chairs for them'
aliases:
- bct
aliases: [ bct ]
permission: ${pluginName}.cmd.toggle
sit:
description: 'Allows a player to sit on the ground'
@@ -41,3 +40,4 @@ permissions:
description: Allows admins to eject all players from their chairs
${pluginName}.cmd.reload:
description: Allows admins to reload the plugin's configuration files
Binary file not shown.
+2
View File
@@ -0,0 +1,2 @@
Manifest-Version: 1.0
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
</classpath>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>nms</name>
<comment></comment>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
@@ -0,0 +1,13 @@
#
#Wed Jul 02 05:13:18 EDT 2025
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry output="bin/main" kind="src" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/spigotmc/spigot-api/1.10.2-R0.1-SNAPSHOT/spigot-api-1.10.2-R0.1-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/spigotmc/spigot/1.10.2-R0.1-SNAPSHOT/spigot-1.10.2-R0.1-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-spigot-api/0.0.4-SNAPSHOT/lime-spigot-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/29689f4d8039bc2abf8e5562c5c09927f9bfc51f/item-nbt-api-2.15.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/52fa821ba619524cac58be6d7260e72b42ae3a0a/item-nbt-api-2.15.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d079530d2976ecfae96e2e132e9b8323738d6b02/XSeries-13.3.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d664a667493ae640b7a62c8add20572437a4f52d/XSeries-13.3.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/net/md-5/bungeecord-chat/1.10-SNAPSHOT/bungeecord-chat-1.10-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/code/gson/gson/2.3.1/gson-2.3.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/avaje/ebean/2.8.1/ebean-2.8.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-api/0.0.4-SNAPSHOT/lime-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/jetbrains/annotations/24.1.0/annotations-24.1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/junit/junit/4.10/junit-4.10.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/javax/persistence/persistence-api/1.0/persistence-api-1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
</classpath>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>betterchairs-v1_10_R1</name>
<comment></comment>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
@@ -0,0 +1,13 @@
#
#Wed Jul 02 05:13:18 EDT 2025
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
@@ -0,0 +1,67 @@
package betterchairs.nms.v1_10_R1;
import de.sprax2013.betterchairs.ChairUtils;
import de.sprax2013.betterchairs.CustomChairEntity;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityArmorStand;
import net.minecraft.server.v1_10_R1.EntityHuman;
import net.minecraft.server.v1_10_R1.World;
import org.bukkit.Location;
class CustomArmorStand extends EntityArmorStand implements CustomChairEntity {
private boolean remove = false;
private final int regenerationAmplifier;
private final Location expectedLocation;
/**
* @param regenerationAmplifier provide a negative value to disable regeneration
*/
public CustomArmorStand(World world, double d0, double d1, double d2, int regenerationAmplifier) {
super(world, d0, d1, d2);
this.regenerationAmplifier = regenerationAmplifier;
this.expectedLocation = new Location(null, d0, d1, d2);
}
@Override
public void markAsRemoved() {
this.remove = true;
}
@Override
public void g(float f, float f2) {
if (this.remove) return; // If the ArmorStand is being removed, no need to bother
if (this.ticksLived % 10 == 0) return; // Only run every 10 ticks
Entity passenger = this.passengers.isEmpty() ? null : this.passengers.get(0);
if (!(passenger instanceof EntityHuman)) {
this.remove = true;
this.getBukkitEntity().remove();
return;
}
// Rotate the ArmorStand together with its passenger
this.setYawPitch(passenger.yaw, 0);
if (ChairUtils.didChairEntityMove(this.expectedLocation, this.locX, this.locY, this.locZ)) {
this.enderTeleportTo(
this.expectedLocation.getX(),
Math.min(this.locY, this.expectedLocation.getY()),
this.expectedLocation.getZ());
}
ChairUtils.applyRegeneration(((EntityHuman) passenger).getBukkitEntity(), this.regenerationAmplifier);
}
@Override
public void die() {
// Prevents the ArmorStand from getting killed unexpectedly
if (shouldDie()) super.die();
}
private boolean shouldDie() {
return this.remove || this.passengers.isEmpty() || !(this.passengers.get(0) instanceof EntityHuman);
}
}
@@ -0,0 +1,56 @@
package betterchairs.nms.v1_10_R1;
import de.sprax2013.betterchairs.ChairUtils;
import de.sprax2013.betterchairs.CustomChairEntity;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.EntityHuman;
import net.minecraft.server.v1_10_R1.EntityTippedArrow;
import net.minecraft.server.v1_10_R1.World;
class CustomArrow extends EntityTippedArrow implements CustomChairEntity {
private boolean remove = false;
private final int regenerationAmplifier;
/**
* @param regenerationAmplifier provide a negative value to disable regeneration
*/
public CustomArrow(World world, double d0, double d1, double d2, int regenerationAmplifier) {
super(world, d0, d1, d2);
this.regenerationAmplifier = regenerationAmplifier;
}
@Override
public void markAsRemoved() {
this.remove = true;
}
@Override
public void m() {
if (this.remove) return; // If the entity is being removed, no need to bother
if (this.ticksLived % 10 == 0) return; // Only run every 10 ticks
Entity passenger = this.passengers.isEmpty() ? null : this.passengers.get(0);
if (!(passenger instanceof EntityHuman)) {
this.remove = true;
this.getBukkitEntity().remove();
return;
}
// Rotate the entity together with its passenger
this.setYawPitch(passenger.yaw, 0);
ChairUtils.applyRegeneration(((EntityHuman) passenger).getBukkitEntity(), this.regenerationAmplifier);
}
@Override
public void die() {
// Prevents the ArmorStand from getting killed unexpectedly
if (shouldDie()) super.die();
}
private boolean shouldDie() {
return this.remove || this.passengers.isEmpty() || !(this.passengers.get(0) instanceof EntityHuman);
}
}
@@ -0,0 +1,103 @@
package betterchairs.nms.v1_10_R1;
import de.sprax2013.betterchairs.ChairManager;
import de.sprax2013.betterchairs.ChairNMS;
import de.sprax2013.betterchairs.ChairUtils;
import de.sprax2013.betterchairs.CustomChairEntity;
import de.sprax2013.betterchairs.Messages;
import java.util.Objects;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.WorldServer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_10_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.material.Stairs;
import org.bukkit.material.Step;
import org.bukkit.material.WoodenStep;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
public class v1_10_R1 extends ChairNMS {
@Override
public @NotNull org.bukkit.entity.Entity spawnChairEntity(
@NotNull Location loc, int regenerationAmplifier, boolean useArmorStand) {
WorldServer nmsWorld = ((CraftWorld) Objects.requireNonNull(loc.getWorld())).getHandle();
Entity nmsEntity;
if (useArmorStand) {
nmsEntity = new CustomArmorStand(nmsWorld, loc.getX(), loc.getY(), loc.getZ(), regenerationAmplifier);
} else {
nmsEntity = new CustomArrow(nmsWorld, loc.getX(), loc.getY() + .3, loc.getZ() + .25, regenerationAmplifier);
}
org.bukkit.entity.Entity bukkitEntity = nmsEntity.getBukkitEntity();
ChairUtils.applyChairProtections(bukkitEntity);
if (!nmsWorld.addEntity(nmsEntity, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
ChairManager.getLogger().warning(Messages.ERR_ANOTHER_PLUGIN_PREVENTING_SPAWN);
}
return bukkitEntity;
}
@Override
public void killChairEntity(@NotNull org.bukkit.entity.Entity entity) {
Entity nmsEntity = ((CraftEntity) entity).getHandle();
if (!(nmsEntity instanceof CustomChairEntity)) {
throw new IllegalArgumentException(
String.format(Messages.ERR_NOT_CUSTOM_ENTITY, CustomChairEntity.class.getName()));
}
((CustomChairEntity) nmsEntity).markAsRemoved();
entity.remove();
}
@Override
public boolean isStair(@NotNull Block block) {
return block.getState().getData() instanceof Stairs;
}
@Override
public boolean isStairUpsideDown(@NotNull Block block) {
return ((Stairs) block.getState().getData()).isInverted();
}
@Override
public @NotNull BlockFace getBlockRotation(@NotNull Block block) {
return ChairUtils.getBlockRotationLegacy(block);
}
@Override
public boolean isSlab(@NotNull Block block) {
return (block.getState().getData() instanceof Step || block.getState().getData() instanceof WoodenStep)
&& block.getType() != Material.DOUBLE_STEP
&& block.getType() != Material.WOOD_DOUBLE_STEP;
}
@Override
public boolean isSlabTop(@NotNull Block block) {
if (block.getState().getData() instanceof Step) {
return ((Step) block.getState().getData()).isInverted();
}
return ((WoodenStep) block.getState().getData()).isInverted();
}
@Override
public boolean hasEmptyMainHand(@NotNull Player player) {
return player.getInventory().getItemInMainHand().getType() == Material.AIR;
}
@Override
public boolean isChair(@NotNull org.bukkit.entity.Entity entity) {
return ((CraftEntity) entity).getHandle() instanceof CustomChairEntity;
}
}
@@ -0,0 +1,2 @@
Manifest-Version: 1.0
-49
View File
@@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>betterchairs</artifactId>
<groupId>de.sprax2013</groupId>
<version>1.14.0</version>
<relativePath>../../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>betterchairs-v1_10_R1</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.4</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>de.sprax2013</groupId>
<artifactId>betterchairs-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -32,7 +32,7 @@ class CustomArmorStand extends EntityArmorStand implements CustomChairEntity {
@Override
public void g(float f, float f2) {
if (this.remove) return; // If the ArmorStand is being removed, no need to bother
if (this.ticksLived % 10 == 0) return; // Only run every 10 ticks
if (this.ticksLived % 10 == 0) return; // Only run every 10 ticks
Entity passenger = this.passengers.isEmpty() ? null : this.passengers.get(0);
@@ -46,7 +46,10 @@ class CustomArmorStand extends EntityArmorStand implements CustomChairEntity {
this.setYawPitch(passenger.yaw, 0);
if (ChairUtils.didChairEntityMove(this.expectedLocation, this.locX, this.locY, this.locZ)) {
this.enderTeleportTo(this.expectedLocation.getX(), Math.min(this.locY, this.expectedLocation.getY()), this.expectedLocation.getZ());
this.enderTeleportTo(
this.expectedLocation.getX(),
Math.min(this.locY, this.expectedLocation.getY()),
this.expectedLocation.getZ());
}
ChairUtils.applyRegeneration(((EntityHuman) passenger).getBukkitEntity(), this.regenerationAmplifier);
@@ -28,7 +28,7 @@ class CustomArrow extends EntityTippedArrow implements CustomChairEntity {
@Override
public void m() {
if (this.remove) return; // If the entity is being removed, no need to bother
if (this.ticksLived % 10 == 0) return; // Only run every 10 ticks
if (this.ticksLived % 10 == 0) return; // Only run every 10 ticks
Entity passenger = this.passengers.isEmpty() ? null : this.passengers.get(0);
@@ -5,6 +5,7 @@ import de.sprax2013.betterchairs.ChairNMS;
import de.sprax2013.betterchairs.ChairUtils;
import de.sprax2013.betterchairs.CustomChairEntity;
import de.sprax2013.betterchairs.Messages;
import java.util.Objects;
import net.minecraft.server.v1_10_R1.Entity;
import net.minecraft.server.v1_10_R1.WorldServer;
import org.bukkit.Location;
@@ -20,12 +21,11 @@ import org.bukkit.material.Step;
import org.bukkit.material.WoodenStep;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@SuppressWarnings("unused")
public class v1_10_R1 extends ChairNMS {
@Override
public @NotNull org.bukkit.entity.Entity spawnChairEntity(@NotNull Location loc, int regenerationAmplifier, boolean useArmorStand) {
public @NotNull org.bukkit.entity.Entity spawnChairEntity(
@NotNull Location loc, int regenerationAmplifier, boolean useArmorStand) {
WorldServer nmsWorld = ((CraftWorld) Objects.requireNonNull(loc.getWorld())).getHandle();
Entity nmsEntity;
@@ -52,7 +52,8 @@ public class v1_10_R1 extends ChairNMS {
Entity nmsEntity = ((CraftEntity) entity).getHandle();
if (!(nmsEntity instanceof CustomChairEntity)) {
throw new IllegalArgumentException(String.format(Messages.ERR_NOT_CUSTOM_ENTITY, CustomChairEntity.class.getName()));
throw new IllegalArgumentException(
String.format(Messages.ERR_NOT_CUSTOM_ENTITY, CustomChairEntity.class.getName()));
}
((CustomChairEntity) nmsEntity).markAsRemoved();
@@ -76,10 +77,9 @@ public class v1_10_R1 extends ChairNMS {
@Override
public boolean isSlab(@NotNull Block block) {
return (block.getState().getData() instanceof Step ||
block.getState().getData() instanceof WoodenStep) &&
block.getType() != Material.DOUBLE_STEP &&
block.getType() != Material.WOOD_DOUBLE_STEP;
return (block.getState().getData() instanceof Step || block.getState().getData() instanceof WoodenStep)
&& block.getType() != Material.DOUBLE_STEP
&& block.getType() != Material.WOOD_DOUBLE_STEP;
}
@Override
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry output="bin/main" kind="src" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/spigotmc/spigot-api/1.11.2-R0.1-SNAPSHOT/spigot-api-1.11.2-R0.1-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/spigotmc/spigot/1.11.2-R0.1-SNAPSHOT/spigot-1.11.2-R0.1-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-spigot-api/0.0.4-SNAPSHOT/lime-spigot-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/29689f4d8039bc2abf8e5562c5c09927f9bfc51f/item-nbt-api-2.15.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/de.tr7zw/item-nbt-api/2.15.0/52fa821ba619524cac58be6d7260e72b42ae3a0a/item-nbt-api-2.15.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry sourcepath="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d079530d2976ecfae96e2e132e9b8323738d6b02/XSeries-13.3.0-sources.jar" kind="lib" path="/home/notalexnoyle/.gradle/caches/modules-2/files-2.1/com.github.cryptomorin/XSeries/13.3.0/d664a667493ae640b7a62c8add20572437a4f52d/XSeries-13.3.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/net/md-5/bungeecord-chat/1.10-SNAPSHOT/bungeecord-chat-1.10-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/com/google/code/gson/gson/2.3.1/gson-2.3.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/avaje/ebean/2.8.1/ebean-2.8.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/de/sprax2013/lime/lime-api/0.0.4-SNAPSHOT/lime-api-0.0.4-SNAPSHOT.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/jetbrains/annotations/24.1.0/annotations-24.1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/junit/junit/4.10/junit-4.10.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/javax/persistence/persistence-api/1.0/persistence-api-1.0.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/home/notalexnoyle/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar">
<attributes>
<attribute name="gradle_used_by_scope" value=""/>
</attributes>
</classpathentry>
</classpath>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>betterchairs-v1_11_R1</name>
<comment></comment>
<projects/>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments/>
</buildCommand>
</buildSpec>
<linkedResources/>
<filteredResources/>
</projectDescription>
@@ -0,0 +1,13 @@
#
#Wed Jul 02 05:13:18 EDT 2025
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
org.eclipse.jdt.core.compiler.source=17
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
Loaded 100 of 454 files, more files were not shown because too many files have changed in this diff. Show more