Compare commits

..

37 commits

Author SHA1 Message Date
Oth3r
597092b6be beta for snapshot 2025-03-12 18:45:52 -05:00
Oth3r
0c0f68e5bc add max minecraft version 2025-03-12 18:44:28 -05:00
Oth3r
c81b9f1c77 1.20.5-pre2 2025-03-12 18:44:15 -05:00
Oth3r
7a101e8a59 1.20.5 port 2025-03-12 18:43:43 -05:00
Oth3r
07fcbd54a2 Merge remote-tracking branch 'origin/snapshot' into snapshot
# Conflicts:
#	build.gradle
#	gradle.properties
#	src/main/java/one/oth3r/sit/Sit.java
#	src/main/java/one/oth3r/sit/SitClient.java
#	src/main/resources/fabric.mod.json
2025-03-12 18:25:46 -05:00
Oth3r
6da67e67b0 v1.1.4+1.20.5-pre1 2024-04-10 14:06:33 -05:00
Oth3r
28a46e9743 remove modmenu 2024-04-10 14:05:42 -05:00
Oth3r
d61031b821 fix merge errors 2024-04-10 14:05:36 -05:00
Oth3r
c6fb594d1f Merge branch 'master' into snapshot
# Conflicts:
#	gradle.properties
#	src/main/java/one/oth3r/sit/ModMenu.java
#	src/main/java/one/oth3r/sit/Sit.java
#	src/main/java/one/oth3r/sit/SitClient.java
2024-04-10 12:12:42 -05:00
Oth3r
aac7476f52 s1.1.3+24w03b 2024-01-22 17:57:18 -06:00
Oth3r
189ae2d2b5 new packet system 1.20.5 2024-01-22 17:56:34 -06:00
Oth3r
7365b31f66 Merge branch 'master' into snapshot
# Conflicts:
#	gradle.properties
#	src/main/java/one/oth3r/sit/ModMenu.java
#	src/main/resources/fabric.mod.json
2024-01-17 14:10:45 -06:00
Oth3r
90422345bc s1.1.0+1.20.3-pre1-1.20.3-rc1 2023-11-30 18:13:20 -06:00
Oth3r
021f979749 -modmenu 2023-11-30 18:12:37 -06:00
Oth3r
4c9432fd18 Merge branch '1.20-1.20.1' into snapshot
# Conflicts:
#	build.gradle
#	gradle.properties
#	src/main/java/one/oth3r/sit/Events.java
#	src/main/java/one/oth3r/sit/ModMenu.java
#	src/main/resources/fabric.mod.json
2023-11-30 18:05:27 -06:00
Oth3r
eb3e10f738 s1.0.3+1.20.3-pre1 2023-11-20 12:10:38 -06:00
Oth3r
87e293d1d2 s1.0.3+23w46a 2023-11-16 18:10:53 -06:00
Oth3r
601fca3269 s1.0.3+23w45a 2023-11-08 14:01:09 -06:00
Oth3r
483255fe01 s1.0.3+23w44a 2023-11-01 14:15:46 -05:00
Oth3r
1b2adc2c7b v1.0.3+23w43b 2023-10-27 09:38:44 -05:00
Oth3r
a44a038feb v1.0.3+23w43a 2023-10-25 11:02:29 -05:00
Oth3r
879f755f19 s1.0.3+23w42a 2023-10-18 13:04:37 -05:00
Oth3r
3dc94270f6 fix the new blocklist 2023-10-18 13:02:57 -05:00
Oth3r
5f1564a53a b1.0.3+23w41a 2023-10-12 22:20:43 -05:00
Oth3r
fc7b734ef6 test for a strict list of blocks allowed above a sit entity 2023-10-12 22:20:06 -05:00
Oth3r
65e051c465 1.20.3 fixes 2023-10-12 22:19:34 -05:00
Oth3r
1dab3c8000 b1.0.2+1.20.2-rc1-1.20.2-rc2 2023-09-18 15:18:37 -05:00
Oth3r
c2819b08eb b1.0.2+1.20.2-rc1 2023-09-16 12:33:50 -05:00
Oth3r
8d5b0fb27a b1.0.2+1.20.2-pre4 2023-09-13 12:38:24 -05:00
Oth3r
f3b9e82cb4 b1.0.2+1.20.2-pre3 2023-09-12 12:41:58 -05:00
Oth3r
4b679b4126 b1.0.2+1.20.2-pre2 2023-09-07 14:26:09 -05:00
Oth3r
7b3b914934 b1.0.2+1.20.2-pre1 2023-09-05 16:46:36 -05:00
Oth3r
f4c29773d0 b1.0.2+23w35a 2023-09-01 14:17:37 -05:00
Oth3r
997c7c131a b1.0.2+23w33a 2023-08-17 12:38:17 -05:00
Oth3r
59875d0f6d b1.0.2+23w32a 2023-08-09 17:08:00 -05:00
Oth3r
68cf4532b4 b1.0.2+23w31a 2023-08-08 21:36:33 -05:00
Oth3r
ac7a373dd8 1.20.2 shifts everything down by .25 2023-08-08 21:35:05 -05:00
68 changed files with 625 additions and 1219 deletions

View file

@ -5,7 +5,7 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
Please fill out the sections below to help identify and fix the bug. Please fill out the sections below to help identify and fix the bug
- type: textarea - type: textarea
id: description id: description
attributes: attributes:

View file

@ -1,26 +0,0 @@
name: Feature Request
description: Suggest a new feature for Sit!
title: '[Feature Request]: '
body:
- type: textarea
id: description
attributes:
label: Description
description: A description of the problem or missing capability
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe a solution
description: If you have a solution in mind, please describe it.
- type: textarea
id: alternatives
attributes:
label: Describe alternatives
description: Have you considered any alternative solutions or workarounds?
- type: markdown
attributes:
value: >-
This template was generated with [Issue Forms
Creator](https://issue-forms-creator.netlify.app)

View file

@ -1,125 +0,0 @@
name: Crowdin Download Action
permissions:
contents: write
pull-requests: write
on:
workflow_dispatch:
inputs:
localization_branch_name:
description: 'The branch to create for the translations PR.'
required: true
default: 'crowdin/translations'
pull_request_base_branch:
description: 'The base branch for the pull request.'
required: true
default: 'dev'
jobs:
download-translations:
runs-on: ubuntu-latest
steps:
# Checkout the BASE branch first. The PR branch will be created later.
- name: Checkout Base Branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.pull_request_base_branch }}
- name: Configure Git User
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Synchronize with Crowdin (Download Only)
uses: crowdin/github-action@v2
with:
upload_sources: false
upload_translations: false
download_translations: true
create_pull_request: false
localization_branch_name: ${{ github.event.inputs.localization_branch_name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
rename-files:
needs: download-translations
runs-on: ubuntu-latest
steps:
- name: Checkout Localization Branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.localization_branch_name }}
- name: Configure Git User
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Rename JSON Files to Lowercase
env:
TARGET_DIR: "src/main/resources/assets/sit-oth3r/lang/"
run: |
echo "Starting renaming process for JSON files within $TARGET_DIR..."
if [ ! -d "$TARGET_DIR" ]; then
echo "Warning: Target directory '$TARGET_DIR' does not exist. Skipping rename."
exit 0
fi
find "$TARGET_DIR" -type f -name '*[A-Z]*.json' | while IFS= read -r file; do
original_path="$file"
dir_name=$(dirname "$original_path")
base_name=$(basename "$original_path")
new_base_name=$(echo "$base_name" | tr '[:upper:]' '[:lower:]')
new_path="$dir_name/$new_base_name"
if [ "$original_path" != "$new_path" ]; then
if [ -e "$new_path" ] && [ ! "$(readlink -f "$original_path")" = "$(readlink -f "$new_path")" ]; then
echo "::warning file=$original_path::Cannot rename '$original_path' to '$new_path' because it already exists. Skipping."
else
git mv "$original_path" "$new_path"
fi
fi
done
echo "JSON file renaming complete."
- name: Commit Renamed Files
run: |
echo "Committing renamed files..."
git add -A
git commit -m "Rename JSON translation files to lowercase for consistency"
echo "Renames committed."
- name: Push Changes to Localization Branch
run: |
echo "Pushing combined changes to ${{ github.event.inputs.localization_branch_name }}..."
git push origin ${{ github.event.inputs.localization_branch_name }}
create-pr:
needs: [ download-translations, rename-files ]
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.localization_branch_name }}
- name: Set up Git config
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
- name: Install GitHub CLI
run: sudo apt-get install gh -y
- name: Authenticate GitHub CLI
run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token
- name: Create Pull Request
run: |
gh pr create \
--title "Update translations from Crowdin" \
--body "This PR includes:\n- New translations from Crowdin\n- Renamed translation files to lowercase" \
--head ${{ github.event.inputs.localization_branch_name }} \
--base ${{ github.event.inputs.pull_request_base_branch }} \
--label "localization"

View file

@ -1,24 +0,0 @@
name: Crowdin Upload Action
on:
push:
paths: [ "src/main/resources/assets/sit-oth3r/lang/en_us.json"]
branches: [ dev ]
workflow_dispatch:
jobs:
crowdin-upload:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Crowdin push
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: false
download_translations: false
env:
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}

View file

@ -1,68 +1,46 @@
<img src="https://github.com/Oth3r/oth3r.github.io/blob/main/mod_data/Sit!/media/banner.png?raw=true" width="50%" style="margin-bottom: 10px; max-width:400px;"> # Sit!
[![github](https://img.shields.io/github/issues/oth3r/Sit?logo=github?label=Issues)](https://github.com/Oth3r/Sit/releases) [![Crowdin](https://badges.crowdin.net/oth3r-sit/localized.svg)](https://crowdin.com/project/oth3r-sit) [![discord](https://dcbadge.vercel.app/api/server/Mec6yNQ9B7?style=flat)](https://discord.gg/Mec6yNQ9B7)
[![github](https://img.shields.io/github/issues/oth3r/Sit?logo=github?label=Issues)](https://github.com/Oth3r/Sit/releases) [![Crowdin](https://badges.crowdin.net/oth3r-sit/localized.svg)](https://crowdin.com/project/oth3r-sit) [![discord](https://dcbadge.vercel.app/api/server/https://discord.gg/AVSTHCAUvn?style=flat)](https://www.oth3r.one/discord)
[![modrinth](https://img.shields.io/modrinth/dt/sit!?label=Modrinth&logo=modrinth)](https://modrinth.com/mod/sit!) [![curseforge](https://cf.way2muchnoise.eu/892424.svg)](https://www.curseforge.com/minecraft/mc-mods/Sit1) [![modrinth](https://img.shields.io/modrinth/dt/sit!?label=Modrinth&logo=modrinth)](https://modrinth.com/mod/sit!) [![curseforge](https://cf.way2muchnoise.eu/892424.svg)](https://www.curseforge.com/minecraft/mc-mods/Sit1)
**Sit!** is a minecraft mod that adds sitting in vanilla minecraft.
### **Sit!** is a vanilla+ mod that adds sitting in minecraft. Sit on **stairs**, **slabs**, **carpets** by default, and sit on everything else using the config!
* Sit on **stairs**, **slabs**, **carpets** by default, and sit on everything else by tweaking the config! You can also customize hand restrictions to stop accidentally sitting down!
* You can also customize **hand restrictions** to stop accidentally sitting down! The mod also has full Geyser support! Enjoy sitting with everyone, weather they are on Bedrock or Java!
* The mod also has full **Geyser** support! Enjoy sitting with everyone, whether they are on Bedrock or Java!
* If Sit! clients join a Sit! server they can use **their own hand settings** to sit.
### Where to install? ### Where to install?
**Sit!** works on the server, without the players needing to install the mod *(singleplayer included!)*. **Sit!** works on the server (singleplayer included), also with support for clients that join in to use their own settings to sit.
\
[Fabric API](https://modrinth.com/mod/fabric-api) and [OtterLib](https://modrinth.com/mod/otterlib) is required to for the mod to load.
### Help localize Sit! on [Crowdin](https://crowdin.com/project/oth3r-sit)! ## Help localize Sit! on [Crowdin](https://crowdin.com/project/oth3r-sit)!
Sit! is currently in English, Traditional Chinese, Italian, Brazilian Portuguese, and Turkish! Help expand this list via Crowdin so reach more people! ![overview](https://github.com/Oth3r/Sit/blob/master/media/overview.gif?raw=true)
## Check out my other Projects! ## Check out my other Projects!
[![Caligo badge](https://github.com/Oth3r/Caligo/blob/master/media/promo_badge.png?raw=true)](https://modrinth.com/mod/caligo)
<a href="https://modrinth.com/mod/caligo"> [![DirectionHUD badge](https://github.com/Oth3r/DirectionHUD/blob/master/media/mod-badge.png?raw=true)](https://modrinth.com/mod/directionhud)
<img src="https://github.com/Oth3r/Caligo/blob/master/media/promo_badge.png?raw=true" alt="Caligo badge" [![DirectionHUD Spigot badge](https://github.com/Oth3r/DirectionHUD/blob/master/media/plugin-badge.png?raw=true)](https://modrinth.com/plugin/directionhud-plugin)
style="margin-right: 5px;">
</a>
<a href="https://modrinth.com/mod/directionhud">
<img src="https://github.com/Oth3r/DirectionHUD/blob/master/media/mod-badge.png?raw=true" alt="Directionhud badge"
style="margin-right: 5px;">
</a>
<a href="https://modrinth.com/mod/more-heart-types">
<img src="https://github.com/Oth3r/MoreHeartTypes/blob/master/media/Badge.png?raw=true" alt="More Heart Types badge"
style="">
</a>
# Features # Features
### 🤚 Hand Restrictions ### Hand Restrictions
Don't want to accidentally sit down? Set custom restrictions for each hand in the config! Don't want to accidentally sit down? Set custom restrictions for each hand in the config!
\
Use **player unique** hand restrictions when connecting to a `Sit!` server on a `Sit!` Client!
<img src="https://github.com/Oth3r/oth3r.github.io/blob/main/mod_data/Sit!/media/desc/hand_restrictions.gif?raw=true" width="100%" style="margin-bottom: 10px;max-width:600px;" * Per player hand restrictions when connecting to a `Sit!` server on a `Sit!` Client!
alt="per player hand restriction showcase">
### 🟩 Custom Blocks ![hand restrictions](https://github.com/Oth3r/Sit/blob/master/media/hand-restrictions.gif?raw=true)
Want to sit on _**EVERY**_ block? With the config you can add more sitting options!
\
With the new config system, block tags and custom blockstates can be used to mass select blocks at ease.
<img src="https://github.com/Oth3r/oth3r.github.io/blob/main/mod_data/Sit!/media/desc/custom_blocks.gif?raw=true" width="100%" style="margin-bottom: 10px; max-width:600px;" ### Custom Blocks
alt="players sitting on a vast range of blocks"> Want to sit on _**EVERY**_ block? With the config you can add more options to sit on! Custom block states are also supported.
### ⌨️ Keybinds ![custom blocks](https://github.com/Oth3r/Sit/blob/master/media/custom-blocks.gif?raw=true)
Don't want to sit with the **just** the hand? Use a keybind or type a command to sit instead!
<img src="https://github.com/Oth3r/oth3r.github.io/blob/main/mod_data/Sit!/media/desc/keybinds.gif?raw=true" width="100%" style="margin-bottom: 10px; max-width:600px;" ### Customizable Config
alt="setting keybinds for the sit mod, and sitting by using them"> Configure to your hearts desire with the in-game config with **[ModMenu](https://modrinth.com/mod/modmenu)** & **[YetAnotherConfigLib](https://modrinth.com/mod/yacl)**, or use the provided config file for servers!
### 📃 Customizable Config ![config](https://github.com/Oth3r/Sit/blob/master/media/config.gif?raw=true)
Don't like the default settings? Go wild in the config for yourself or your players! ![custom blocks config](https://github.com/Oth3r/Sit/blob/master/media/custom-blocks-config.png?raw=true)
<img src="https://github.com/Oth3r/oth3r.github.io/blob/main/mod_data/Sit!/media/desc/config.gif?raw=true" width="100%" style="margin-bottom: 10px; max-width:600px;"
alt="the Sit! config wiki page">
## Future Goals ## Future Goals
* NeoForge Port * Forge Port (probably NeoForge 1.21)
* Full config via [OtterLib](https://modrinth.com/mod/otterlib) * Custom dismounting logic
* better config (coming soon!)
* keybindings (next update)

View file

@ -1,7 +1,8 @@
plugins { plugins {
id 'fabric-loom' version "1.10-SNAPSHOT" id 'fabric-loom' version '1.10-SNAPSHOT'
id 'maven-publish' id 'maven-publish'
id "me.modmuss50.mod-publish-plugin" version "0.8.4" id 'com.modrinth.minotaur' version '2.+'
id 'net.darkhax.curseforgegradle' version '1.1.+'
id 'co.uzzu.dotenv.gradle' version '4.0.0' id 'co.uzzu.dotenv.gradle' version '4.0.0'
} }
@ -13,9 +14,8 @@ base {
} }
repositories { repositories {
mavenLocal() maven { url "https://maven.terraformersmc.com/releases/" }
maven { url = "https://maven.terraformersmc.com/releases/" } maven { url "https://maven.isxander.dev/releases" }
maven { url = "https://maven.isxander.dev/releases" }
} }
loom { loom {
@ -30,20 +30,16 @@ dependencies {
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}" modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}"
modImplementation "one.oth3r:otterlib:${project.otterlib_version}"
} }
processResources { processResources {
filteringCharset = "UTF-8" filteringCharset "UTF-8"
var replaceProperties = [ var replaceProperties = [
version : project.version, version : project.version,
minecraft_version : minecraft_version, minecraft_version : minecraft_version,
min_minecraft_version : min_minecraft_version, min_minecraft_version : min_minecraft_version,
max_minecraft_version : max_minecraft_version, max_minecraft_version : max_minecraft_version,
otterlib_version : otterlib_version,
otterlib_max_version : otterlib_max_version,
loader_version : loader_version loader_version : loader_version
] ]
@ -90,35 +86,33 @@ publishing {
} }
} }
publishMods { import com.modrinth.minotaur.dependencies.ModDependency
modrinth {
token = env.fetchOrNull('MODRINTH')
projectId = 'EsYqsGV4'
versionNumber = project.mod_version
versionName = "v${project.mod_version} [Fabric]"
versionType = "beta"
uploadFile = remapJar
gameVersions = [project.minecraft_version]
loaders = ['fabric', 'quilt']
dependencies = [
new ModDependency('P7dR8mSH', 'required'),
new ModDependency('mOgUt4GM', 'optional')
]
changelog = file('changelog.md').text changelog = file('changelog.md').text
type = STABLE }
file = remapJar.archiveFile import net.darkhax.curseforgegradle.TaskPublishCurseForge
modLoaders.add("fabric")
modLoaders.add("quilt")
version = mod_version tasks.register('publishCurseForge', TaskPublishCurseForge) {
displayName = "v${mod_version} [Fabric]" apiToken = env.fetchOrNull('CURSEFORGE')
curseforge { def mainFile = upload(892424, remapJar)
accessToken = env.fetchOrNull('CURSEFORGE') mainFile.changelog = file('changelog.md')
projectId = "892424" mainFile.displayName = "v${project.mod_version} [Fabric]"
projectSlug = "sit1" mainFile.addModLoader("fabric", 'quilt')
minecraftVersions.addAll(minecraft_versions.split(",").toList()) mainFile.releaseType = "beta"
mainFile.addEnvironment("client", "server")
requires("fabric-api", "otterlib")
announcementTitle = "Download from CurseForge"
}
modrinth {
accessToken = env.fetchOrNull('MODRINTH')
projectId = "EsYqsGV4"
minecraftVersions.addAll(minecraft_versions.split(",").toList())
requires("fabric-api", "otterlib")
announcementTitle = "Download from Modrinth"
}
} }

View file

@ -1,18 +1,2 @@
# v1.2.4.3 # v1.2.3
* added a max OtterLib version as the beta will have breaking changes between major versions * fixed not being able to sit when the Y level was below 0
# v1.2.4.2
* fixed language file not loading (reverted uppercase locales)
* fixed block checking having a hardcoded player reach - now uses player reach (1.20.6+)
* fixed block and item tag check logic for cases with only not(!) tags
# v1.2.4.1
* removed unused assets
* enabled file logging for easier debugging
# v1.2.4.0
Small changelog but big update!
\
Switching to OtterLib will allow for a simplified main mod and lead to more unified mod development across my projects! Download OtterLib today: [Link](https://modrinth.com/mod/otterlib)
* make sitting via hand execute the `/sit` command, to allow for universal sitting permission control
* switch to using OtterLib for file management, config screen management, and more to come

View file

@ -1,12 +0,0 @@
"project_id_env": "CROWDIN_PROJECT_ID"
"api_token_env": "CROWDIN_PERSONAL_TOKEN"
"base_path": "."
"base_url": "https://api.crowdin.com"
"preserve_hierarchy": true
files: [
{
"source": "src/main/resources/assets/sit-oth3r/lang/en_us.json",
"translation": "src/main/resources/assets/sit-oth3r/lang/%locale_with_underscore%.json",
}
]

View file

@ -4,21 +4,17 @@ org.gradle.parallel=true
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/develop # check these on https://fabricmc.net/develop
min_minecraft_version=1.21.6 min_minecraft_version=1.21.5-beta.2
max_minecraft_version=1.21.6 max_minecraft_version=1.21.5
minecraft_versions=1.21.6 minecraft_version=1.21.5-pre2
yarn_mappings=1.21.5-pre2+build.2
minecraft_version=1.21.6 loader_version=0.16.10
yarn_mappings=1.21.6+build.1
loader_version=0.16.14
# Mod Properties # Mod Properties
mod_version=1.2.4.3+1.21.6 mod_version=1.2.3+1.21.5-pre2-1.21.5
maven_group=one.oth3r maven_group=one.oth3r
file_name=sit! file_name=sit!
# Dependencies # Dependencies
fabric_version=0.127.0+1.21.6 fabric_version=0.118.6+1.21.5
modmenu_version=15.0.0-beta.1 modmenu_version=13.0.0-beta.1
otterlib_version=0.1.2.1+1.21.6-fabric
otterlib_max_version=0.2.0.0+1.21.6-fabric

Binary file not shown.

View file

@ -1,7 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View file

@ -1,18 +1,8 @@
package one.oth3r.sit; package one.oth3r.sit;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.Identifier;
import one.oth3r.otterlib.client.screen.ConfigScreen;
import one.oth3r.otterlib.client.screen.utl.CustomImage;
import one.oth3r.otterlib.client.screen.utl.SimpleButton;
import one.oth3r.sit.file.FileData;
import one.oth3r.sit.utl.Data; import one.oth3r.sit.utl.Data;
import one.oth3r.sit.utl.Events; import one.oth3r.sit.utl.Events;
import one.oth3r.sit.utl.Utl;
import java.net.URI;
import java.util.List;
public class SitClient implements ClientModInitializer { public class SitClient implements ClientModInitializer {
@ -22,18 +12,5 @@ public class SitClient implements ClientModInitializer {
Events.registerClient(); Events.registerClient();
} }
public static Screen getConfigScreen(Screen parent) {
return new ConfigScreen(parent, Utl.lang("sit!.screen.config"),
new CustomImage(Identifier.of(Data.MOD_ID, "textures/gui/banner.png"),128, 72),
List.of(
SimpleButton.Templates.fileEditor(Utl.lang("config.server"), FileData.getServerConfig(), new CustomImage(Identifier.of(Data.MOD_ID, "server_button"),246,26)).build(),
SimpleButton.Templates.fileEditor(Utl.lang("config.sitting"), FileData.getSittingConfig(), new CustomImage(Identifier.of(Data.MOD_ID, "sitting_button"), 246, 26)).build()
),
List.of(
SimpleButton.Templates.warning(Utl.lang("sit!.gui.button.issues")).openLink("https://github.com/Oth3r/Sit/issues").build(),
new SimpleButton.Builder(Utl.lang("sit!.gui.button.website")).openLink("https://modrinth.com/mod/sit!").build(),
SimpleButton.Templates.done(Utl.lang("gui.done")).build(),
SimpleButton.Templates.donate(Utl.lang("sit!.gui.button.donate")).openLink(URI.create("https://ko-fi.com/oth3r")).build()
));
}
} }

View file

@ -14,7 +14,6 @@ import one.oth3r.sit.utl.Data;
import one.oth3r.sit.utl.Logic; import one.oth3r.sit.utl.Logic;
import one.oth3r.sit.utl.Utl; import one.oth3r.sit.utl.Utl;
import java.awt.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class SitCommand { public class SitCommand {
@ -50,7 +49,7 @@ public class SitCommand {
if (player == null) { if (player == null) {
if (args[0].equalsIgnoreCase("reload")) { if (args[0].equalsIgnoreCase("reload")) {
Logic.reload(); Logic.reload();
Data.LOGGER.info(Utl.lang("sit!.chat.reloaded").toString()); Data.LOGGER.info(Utl.lang("sit!.chat.reloaded").getString());
} }
return 1; return 1;
} }
@ -76,7 +75,7 @@ public class SitCommand {
if (args[0].equalsIgnoreCase("reload")) { if (args[0].equalsIgnoreCase("reload")) {
Logic.reload(); Logic.reload();
player.sendMessage(Utl.messageTag().append(Utl.lang("sit!.chat.reloaded").color(Color.GREEN)).b()); player.sendMessage(Utl.messageTag().append(Utl.lang("sit!.chat.reloaded").formatted(Formatting.GREEN)));
} }
if (args[0].equalsIgnoreCase("purgeChairEntities")) Utl.Entity.purge(player,true); if (args[0].equalsIgnoreCase("purgeChairEntities")) Utl.Entity.purge(player,true);

View file

@ -9,7 +9,6 @@ import net.minecraft.util.Identifier;
import one.oth3r.sit.utl.Utl; import one.oth3r.sit.utl.Utl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects;
public class CustomBlock { public class CustomBlock {
@ -91,38 +90,18 @@ public class CustomBlock {
} }
// a boolean to check if one of the blocks are in a filtered tag // a boolean to check if one of the blocks are in a filtered tag
// & a switch for if there is only not(!) tags boolean tagCheck = false;
boolean tagCheck = false, hasPositiveTags = false;
// for all the entered tags
for (String tag : blockTags) { for (String tag : blockTags) {
// substring to remove # and if needed, ! // substring to remove # and if needed, !
if (tag.startsWith("!")) { // if there is a math for the NOT(!) tag, return false
// if there is a match for the NOT(!) tag, return false if (tag.startsWith("!") && blockState.isIn(TagKey.of(Registries.BLOCK.getKey(), Identifier.of(tag.substring(2))))) return false;
Identifier id = Identifier.tryParse(tag.substring(2)); // if there is a match, return true
if (id != null && blockState.isIn(TagKey.of(Registries.BLOCK.getKey(), id))) return false; if (blockState.isIn(TagKey.of(Registries.BLOCK.getKey(), Identifier.tryParse(tag.substring(1))))) tagCheck = true;
} else {
// flip the hasPositiveTags boolean
hasPositiveTags = true;
// if there is a match, return true
Identifier id = Identifier.tryParse(tag.substring(1));
if (id != null && blockState.isIn(TagKey.of(Registries.BLOCK.getKey(), id))) tagCheck = true;
}
} }
// if there were any required tags, return whether we matched one // not returning true in the loop because there might be a (!) not tag that the block might fall into, after the block was already in another tag
// if there were only not(!) tags, and we didn't violate any, return true return tagCheck;
return hasPositiveTags? tagCheck : true;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
CustomBlock that = (CustomBlock) o;
return Objects.equals(blockIds, that.blockIds) && Objects.equals(blockTags, that.blockTags) && Objects.equals(blockStates, that.blockStates);
}
@Override
public int hashCode() {
return Objects.hash(blockIds, blockTags, blockStates);
} }
} }

View file

@ -0,0 +1,101 @@
package one.oth3r.sit.file;
import net.fabricmc.loader.api.FabricLoader;
import one.oth3r.sit.utl.Data;
import one.oth3r.sit.utl.Utl;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public interface CustomFile <T extends CustomFile<T>> {
void reset();
/**
* saves the current instance to file
*/
default void save() {
if (!getFile().exists()) {
Data.LOGGER.info(String.format("Creating new `%s`", getFile().getName()));
}
try (BufferedWriter writer = Files.newBufferedWriter(getFile().toPath(), StandardCharsets.UTF_8)) {
writer.write(Utl.getGson().toJson(this));
} catch (Exception e) {
Data.LOGGER.error(String.format("ERROR SAVING '%s`: %s", getFile().getName(), e.getMessage()));
}
}
/**
* loads the file to the current instance using updateFromReader()
*/
default void load() {
File file = getFile();
if (!file.exists()) fileNotExist();
// try reading the file
try (BufferedReader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
updateFromReader(reader);
} catch (Exception e) {
Data.LOGGER.error(String.format("ERROR LOADING '%s`: %s", file.getName(),e.getMessage()));
}
}
default void updateFromReader(BufferedReader reader) {
// try to read the json
T file;
try {
file = Utl.getGson().fromJson(reader, getFileClass());
} catch (Exception e) {
throw new NullPointerException();
}
// throw null if the fileData is null or version is null
if (file == null) throw new NullPointerException();
// update the instance
file.update();
// load the file to the current object
loadFileData(file);
}
@NotNull
Class<T> getFileClass();
/**
* loads the data from the file object into the current object
* @param newFile the file to take the properties from
*/
void loadFileData(T newFile);
/**
* updates the file based on the version number of the current instance
*/
void update();
/**
* logic for the file not existing when loading, defaults to saving
*/
default void fileNotExist() {
// try to make the config directory
try {
Files.createDirectories(Paths.get(getDirectory()));
} catch (Exception e) {
Data.LOGGER.error("Failed to create config directory. Canceling all config loading...");
return;
}
save();
}
String getFileName();
default String getDirectory() {
return FabricLoader.getInstance().getConfigDir().toFile()+"/";
}
default File getFile() {
return new File(getDirectory()+getFileName());
}
}

View file

@ -7,7 +7,6 @@ import net.minecraft.registry.tag.TagKey;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects;
public class CustomItem { public class CustomItem {
@SerializedName("item-ids") @SerializedName("item-ids")
@ -22,11 +21,6 @@ public class CustomItem {
this.itemTags = itemTags; this.itemTags = itemTags;
} }
public CustomItem(CustomItem customItem) {
this.itemIDs = new ArrayList<>(customItem.itemIDs);
this.itemTags = new ArrayList<>(customItem.itemTags);
}
public ArrayList<String> getItemIDs() { public ArrayList<String> getItemIDs() {
return itemIDs; return itemIDs;
} }
@ -51,38 +45,21 @@ public class CustomItem {
} }
// a boolean to check if one of the items are in a filtered tag // a boolean to check if one of the items are in a filtered tag
// & a switch for if there is only not(!) tags boolean tagCheck = false;
boolean tagCheck = false, hasPositiveTags = false;
// check the custom item tags
for (String tag : itemTags) { for (String tag : itemTags) {
// substring to remove # and if needed, "!" // substring to remove # and if needed, "!"
// if a NOT tag
if (tag.startsWith("!")) { if (tag.startsWith("!")) {
// if there is a math for the NOT(!) tag, return false // if there is a math for the NOT(!) tag, return false
Identifier id = Identifier.tryParse(tag.substring(2)); if (itemStack.isIn(TagKey.of(Registries.ITEM.getKey(), Identifier.of(tag.substring(2))))) return false;
if (id != null && itemStack.isIn(TagKey.of(Registries.ITEM.getKey(), id))) return false;
} else {
// flip the hasPositiveTags boolean
hasPositiveTags = true;
// else (normal tag), if there is a match, set tagCheck to true
Identifier id = Identifier.tryParse(tag.substring(1));
if (id != null && itemStack.isIn(TagKey.of(Registries.ITEM.getKey(), id))) tagCheck = true;
} }
// else (normal tag), if there is a match, set tagCheck to true
else if (itemStack.isIn(TagKey.of(Registries.ITEM.getKey(), Identifier.of(tag.substring(1))))) tagCheck = true;
} }
// if there were any required tags, return whether we matched one // not returning true in the loop because there might be a (!) not tag that the item might fall into, after the item was already in another tag
// if there were only not(!) tags, and we didn't violate any, return true return tagCheck;
return hasPositiveTags? tagCheck : true;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
CustomItem that = (CustomItem) o;
return Objects.equals(itemIDs, that.itemIDs) && Objects.equals(itemTags, that.itemTags);
}
@Override
public int hashCode() {
return Objects.hash(itemIDs, itemTags);
} }
} }

View file

@ -3,7 +3,6 @@ package one.oth3r.sit.file;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class HandSetting { public class HandSetting {
@ -22,11 +21,6 @@ public class HandSetting {
this.filter = filter; this.filter = filter;
} }
public HandSetting(HandSetting handSetting) {
this.sittingRequirement = handSetting.sittingRequirement;
this.filter = new Filter(handSetting.filter);
}
public SittingRequirement getSittingRequirement() { public SittingRequirement getSittingRequirement() {
return sittingRequirement; return sittingRequirement;
} }
@ -58,12 +52,6 @@ public class HandSetting {
this.customItems = customItems; this.customItems = customItems;
} }
public Filter(Filter filter) {
this.invert = filter.invert;
this.presets = new Presets(filter.presets);
this.customItems = new CustomItem(filter.customItems);
}
public Boolean isInverted() { public Boolean isInverted() {
return invert; return invert;
} }
@ -92,12 +80,6 @@ public class HandSetting {
this.usable = usable; this.usable = usable;
} }
public Presets(Presets presets) {
this.block = presets.block;
this.food = presets.food;
this.usable = presets.usable;
}
public boolean isBlock() { public boolean isBlock() {
return block; return block;
} }
@ -109,42 +91,6 @@ public class HandSetting {
public boolean isUsable() { public boolean isUsable() {
return usable; return usable;
} }
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Presets presets = (Presets) o;
return block == presets.block && food == presets.food && usable == presets.usable;
}
@Override
public int hashCode() {
return Objects.hash(block, food, usable);
}
} }
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Filter filter = (Filter) o;
return Objects.equals(invert, filter.invert) && Objects.equals(presets, filter.presets) && Objects.equals(customItems, filter.customItems);
}
@Override
public int hashCode() {
return Objects.hash(invert, presets, customItems);
}
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
HandSetting that = (HandSetting) o;
return sittingRequirement == that.sittingRequirement && Objects.equals(sittingRequirementOptions, that.sittingRequirementOptions) && Objects.equals(filter, that.filter);
}
@Override
public int hashCode() {
return Objects.hash(sittingRequirement, sittingRequirementOptions, filter);
} }
} }

View file

@ -4,7 +4,6 @@ import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import net.minecraft.text.MutableText; import net.minecraft.text.MutableText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import one.oth3r.otterlib.chat.CTxT;
import one.oth3r.sit.Sit; import one.oth3r.sit.Sit;
import one.oth3r.sit.utl.Data; import one.oth3r.sit.utl.Data;
@ -21,19 +20,14 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class LangReader { public class LangReader {
private static final Map<String, String> defaultLangMap = new HashMap<>();
private static final Map<String, String> languageMap = new HashMap<>(); private static final Map<String, String> languageMap = new HashMap<>();
private final String translationKey; private final String translationKey;
private final Object[] placeholders; private final Object[] placeholders;
public LangReader(String translationKey, Object... placeholders) { public LangReader(String translationKey, Object... placeholders) {
this.translationKey = translationKey; this.translationKey = translationKey;
this.placeholders = placeholders; this.placeholders = placeholders;
} }
public MutableText getTxT() {
public CTxT getTxT() {
String translated = getLanguageValue(translationKey); String translated = getLanguageValue(translationKey);
if (placeholders != null && placeholders.length > 0) { if (placeholders != null && placeholders.length > 0) {
//removed all double \\ and replaces with \ //removed all double \\ and replaces with \
@ -41,8 +35,7 @@ public class LangReader {
String regex = "%\\d*\\$?[dfs]"; String regex = "%\\d*\\$?[dfs]";
Matcher anyMatch = Pattern.compile(regex).matcher(translated); Matcher anyMatch = Pattern.compile(regex).matcher(translated);
Matcher endMatch = Pattern.compile(regex+"$").matcher(translated); Matcher endMatch = Pattern.compile(regex+"$").matcher(translated);
//Arraylist with all the %(#$)[dfs]
// Arraylist with all the %(#$)[dfs]
ArrayList<String> matches = new ArrayList<>(); ArrayList<String> matches = new ArrayList<>();
while (anyMatch.find()) { while (anyMatch.find()) {
String match = anyMatch.group(); String match = anyMatch.group();
@ -58,7 +51,7 @@ public class LangReader {
} }
//if there are placeholders specified, and the split is more than 1, it will replace %(dfs) with the placeholder objects //if there are placeholders specified, and the split is more than 1, it will replace %(dfs) with the placeholder objects
if (parts.length > 1) { if (parts.length > 1) {
CTxT txt = new CTxT(""); MutableText txt = Text.empty();
int i = 0; int i = 0;
for (String match : matches) { for (String match : matches) {
int get = i; int get = i;
@ -69,56 +62,47 @@ public class LangReader {
} }
if (parts.length != i) txt.append(parts[i]); if (parts.length != i) txt.append(parts[i]);
//convert the obj into txt //convert the obj into txt
txt.append(getTxTFromObj(placeholders[get])); Object obj = placeholders[get];
if (obj instanceof Text) txt.append((Text) obj);
else txt.append(String.valueOf(obj));
i++; i++;
} }
if (parts.length != i) txt.append(parts[i]); if (parts.length != i) txt.append(parts[i]);
return new CTxT(txt); return txt;
} }
} }
return new CTxT(translated); return Text.empty().append(translated);
} }
private CTxT getTxTFromObj(Object obj) {
if (obj instanceof CTxT) return (((CTxT) obj));
else if (obj instanceof Text) return new CTxT((MutableText) obj);
else return new CTxT(String.valueOf(obj));
}
public static LangReader of(String translationKey, Object... placeholders) { public static LangReader of(String translationKey, Object... placeholders) {
return new LangReader(translationKey, placeholders); return new LangReader(translationKey, placeholders);
} }
public static void loadLanguageFile() { public static void loadLanguageFile() {
Type tToken = new TypeToken<Map<String, String>>(){}.getType(); ClassLoader classLoader = Sit.class.getClassLoader();
try { try {
// load the config language InputStream inputStream = classLoader.getResourceAsStream("assets/sit-oth3r/lang/" + FileData.getServerConfig().getLang() +".json");
Reader selectionReader = new InputStreamReader(getInputStream(false), StandardCharsets.UTF_8);
languageMap.putAll(new Gson().fromJson(selectionReader, tToken)); // if the input stream is null, the language file wasn't found
// load the default language as well (fallback) if (inputStream == null) {
Reader defaultReader = new InputStreamReader(getInputStream(true), StandardCharsets.UTF_8); // try loading the default language file
defaultLangMap.putAll(new Gson().fromJson(defaultReader, tToken)); inputStream = classLoader.getResourceAsStream("assets/sit-oth3r/lang/" + new ServerConfig().getLang() +".json");
Data.LOGGER.error("COULDN'T LOAD THE LANGUAGE FILE. RESETTING TO en_us.");
}
// if the input stream is still null, throw an exception
if (inputStream == null) throw new IllegalArgumentException("UNABLE TO LOAD THE ENGLISH LANGUAGE FILE.");
Type type = new TypeToken<Map<String, String>>(){}.getType();
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
languageMap.putAll(new Gson().fromJson(reader, type));
// close the input stream
inputStream.close();
} catch (Exception e) { } catch (Exception e) {
Data.LOGGER.info("ERROR WITH LANGUAGE FILE - PLEASE REPORT WITH THE ERROR LOG"); Data.LOGGER.error(e.getMessage());
Data.LOGGER.info(e.getMessage());
} }
} }
private static InputStream getInputStream(boolean english) {
ClassLoader classLoader = Sit.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("assets/sit-oth3r/lang/"+FileData.getServerConfig().getLang()+".json");
// make null if english
if (english) inputStream = null;
// if it cant read (null), try again, but with the english file
if (inputStream == null) inputStream = classLoader.getResourceAsStream("assets/sit-oth3r/lang/"+new ServerConfig().getLang()+".json");
// if null after that, throw an exception
if (inputStream == null) throw new IllegalArgumentException("CANT LOAD THE LANGUAGE FILE. SIT! WILL BREAK.");
return inputStream;
}
public static String getLanguageValue(String key) { public static String getLanguageValue(String key) {
return languageMap.getOrDefault(key, defaultLangMap.getOrDefault(key, key)); return languageMap.getOrDefault(key, key);
} }
} }

View file

@ -1,13 +1,10 @@
package one.oth3r.sit.file; package one.oth3r.sit.file;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import one.oth3r.otterlib.file.CustomFile;
import one.oth3r.otterlib.file.FileSettings;
import one.oth3r.sit.utl.Data; import one.oth3r.sit.utl.Data;
import one.oth3r.sit.utl.Utl; import one.oth3r.sit.utl.Utl;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -16,18 +13,15 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import java.util.Properties; import java.util.Properties;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ServerConfig implements CustomFile<ServerConfig> { public class ServerConfig implements CustomFile<ServerConfig> {
@SerializedName("version") @SerializedName("version")
private Double version = 2.3; private Double version = 2.2;
@SerializedName("lang") @SerializedName("lang")
private String lang = "en_us"; private String lang = "en_us";
@ -57,7 +51,7 @@ public class ServerConfig implements CustomFile<ServerConfig> {
public ServerConfig() {} public ServerConfig() {}
public ServerConfig(ServerConfig serverConfig) { public ServerConfig(ServerConfig serverConfig) {
copyFileData(serverConfig); loadFileData(serverConfig);
} }
public ServerConfig(Double version, String lang, boolean keepActive, boolean sitWhileSeated, public ServerConfig(Double version, String lang, boolean keepActive, boolean sitWhileSeated,
@ -157,23 +151,9 @@ public class ServerConfig implements CustomFile<ServerConfig> {
public boolean isFullBlocks() { public boolean isFullBlocks() {
return fullBlocks; return fullBlocks;
} }
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
PresetBlocks that = (PresetBlocks) o;
return stairs == that.stairs && slabs == that.slabs && carpets == that.carpets && fullBlocks == that.fullBlocks;
}
@Override
public int hashCode() {
return Objects.hash(stairs, slabs, carpets, fullBlocks);
}
} }
public static class YDifferenceLimit { public static class YDifferenceLimit {
@SerializedName("enabled")
private boolean enabled = false;
@SerializedName("above") @SerializedName("above")
private Double above = 1.0; private Double above = 1.0;
@SerializedName("below") @SerializedName("below")
@ -182,24 +162,14 @@ public class ServerConfig implements CustomFile<ServerConfig> {
public YDifferenceLimit() { public YDifferenceLimit() {
} }
public YDifferenceLimit(Double above, Double below, boolean enabled) { public YDifferenceLimit(Double above, Double below) {
this.above = above; this.above = above;
this.below = below; this.below = below;
this.enabled = enabled;
} }
public YDifferenceLimit(YDifferenceLimit yDifferenceLimit) { public YDifferenceLimit(YDifferenceLimit yDifferenceLimit) {
this.above = yDifferenceLimit.above; this.above = yDifferenceLimit.above;
this.below = yDifferenceLimit.below; this.below = yDifferenceLimit.below;
this.enabled = yDifferenceLimit.enabled;
}
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
} }
public Double getAbove() { public Double getAbove() {
@ -217,36 +187,11 @@ public class ServerConfig implements CustomFile<ServerConfig> {
public void setBelow(Double below) { public void setBelow(Double below) {
this.below = below; this.below = below;
} }
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
YDifferenceLimit that = (YDifferenceLimit) o;
return Objects.equals(above, that.above) && Objects.equals(below, that.below);
}
@Override
public int hashCode() {
return Objects.hash(above, below);
}
}
@Override
public FileSettings getFileSettings() {
return new FileSettings(Data.LOGGER);
}
/**
* the path to the file - including the extension ex. usr/config/custom-file.json
*/
@Override
public Path getFilePath() {
return Paths.get(Data.CONFIG_DIR, "server-config.json");
} }
@Override @Override
public void reset() { public void reset() {
copyFileData(new ServerConfig()); loadFileData(new ServerConfig());
} }
@Override @Override
@ -254,13 +199,8 @@ public class ServerConfig implements CustomFile<ServerConfig> {
return ServerConfig.class; return ServerConfig.class;
} }
/**
* loads the data from the file object into the current object - DEEP COPY
*
* @param newFile the file to take the properties from
*/
@Override @Override
public void copyFileData(ServerConfig newFile) { public void loadFileData(ServerConfig newFile) {
this.version = newFile.version; this.version = newFile.version;
this.lang = newFile.lang; this.lang = newFile.lang;
this.keepActive = newFile.keepActive; this.keepActive = newFile.keepActive;
@ -276,28 +216,28 @@ public class ServerConfig implements CustomFile<ServerConfig> {
this.interactionBlocks = newFile.interactionBlocks.stream().map(CustomBlock::new).collect(Collectors.toCollection(ArrayList::new)); this.interactionBlocks = newFile.interactionBlocks.stream().map(CustomBlock::new).collect(Collectors.toCollection(ArrayList::new));
} }
/**
* updates the file based on the version number of the current instance
*
* @param json
*/
@Override @Override
public void update(JsonElement json) { public void update() {
/// update to 2.1, just a new list, nothing to change /// update to 2.1, just a new list, nothing to change
/// update to 2.2, new settings, no changes /// update to 2.2, new settings, no changes
if (version >= 2.0 && version <= 2.1) { if (version >= 2.0 && version <= 2.1) {
version = 2.2; version = 2.2;
} }
if (version == 2.2) {
// make sure that the lang is all lowercase
version = 2.3;
this.lang = this.lang.substring(0,3)+this.lang.substring(3).toLowerCase();
}
} }
@Override @Override
public void createDirectory() { public String getFileName() {
CustomFile.super.createDirectory(); return "server-config.json";
}
@Override
public String getDirectory() {
return Data.CONFIG_DIR;
}
@Override
public void fileNotExist() {
CustomFile.super.fileNotExist();
// try checking the old/legacy config directory for the file // try checking the old/legacy config directory for the file
if (Legacy.getLegacyFile().exists()) { if (Legacy.getLegacyFile().exists()) {
Data.LOGGER.info("Updating Sit!.properties to sit!/config.json"); Data.LOGGER.info("Updating Sit!.properties to sit!/config.json");
@ -305,25 +245,6 @@ public class ServerConfig implements CustomFile<ServerConfig> {
} }
} }
@Override
public ServerConfig clone() {
ServerConfig clone = new ServerConfig();
clone.copyFileData(this);
return clone;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
ServerConfig that = (ServerConfig) o;
return Objects.equals(version, that.version) && Objects.equals(lang, that.lang) && Objects.equals(keepActive, that.keepActive) && Objects.equals(sitWhileSeated, that.sitWhileSeated) && Objects.equals(presetBlocks, that.presetBlocks) && Objects.equals(yDifferenceLimit, that.yDifferenceLimit) && Objects.equals(customEnabled, that.customEnabled) && Objects.equals(sittingBlocks, that.sittingBlocks) && Objects.equals(blacklistedBlocks, that.blacklistedBlocks) && Objects.equals(interactionBlocks, that.interactionBlocks);
}
@Override
public int hashCode() {
return Objects.hash(version, lang, langOptions, keepActive, sitWhileSeated, presetBlocks, yDifferenceLimit, customEnabled, sittingBlocks, blacklistedBlocks, interactionBlocks);
}
protected static class Legacy { protected static class Legacy {
/** /**
* gets the legacy file, from the old directory for fabric, and the same one for spigot * gets the legacy file, from the old directory for fabric, and the same one for spigot

View file

@ -3,7 +3,6 @@ package one.oth3r.sit.file;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects;
public class SittingBlock extends CustomBlock { public class SittingBlock extends CustomBlock {
@SerializedName("sitting-height") @SerializedName("sitting-height")
@ -28,17 +27,4 @@ public class SittingBlock extends CustomBlock {
super(sittingBlock); super(sittingBlock);
this.sittingHeight = sittingBlock.sittingHeight; this.sittingHeight = sittingBlock.sittingHeight;
} }
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
SittingBlock that = (SittingBlock) o;
return Objects.equals(sittingHeight, that.sittingHeight);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), sittingHeight);
}
} }

View file

@ -1,17 +1,10 @@
package one.oth3r.sit.file; package one.oth3r.sit.file;
import com.google.common.base.Objects;
import com.google.gson.JsonElement;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import one.oth3r.otterlib.file.CustomFile;
import one.oth3r.otterlib.file.FileSettings;
import one.oth3r.sit.utl.Data; import one.oth3r.sit.utl.Data;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SittingConfig implements CustomFile<SittingConfig> { public class SittingConfig implements CustomFile<SittingConfig> {
@SerializedName("version") @SerializedName("version")
@ -36,7 +29,7 @@ public class SittingConfig implements CustomFile<SittingConfig> {
} }
public SittingConfig(SittingConfig sittingConfig) { public SittingConfig(SittingConfig sittingConfig) {
copyFileData(sittingConfig); loadFileData(sittingConfig);
} }
public Double getVersion() { public Double getVersion() {
@ -71,19 +64,9 @@ public class SittingConfig implements CustomFile<SittingConfig> {
return offHand; return offHand;
} }
@Override
public FileSettings getFileSettings() {
return new FileSettings(Data.LOGGER);
}
@Override
public Path getFilePath() {
return Paths.get(Data.CONFIG_DIR, "sitting-config.json");
}
@Override @Override
public void reset() { public void reset() {
copyFileData(new SittingConfig()); loadFileData(new SittingConfig());
} }
@Override @Override
@ -92,35 +75,24 @@ public class SittingConfig implements CustomFile<SittingConfig> {
} }
@Override @Override
public void copyFileData(SittingConfig sittingConfig) { public void loadFileData(SittingConfig newFile) {
this.version = sittingConfig.version; this.version = newFile.version;
this.enabled = sittingConfig.enabled; this.enabled = newFile.enabled;
this.handSitting = sittingConfig.handSitting; this.handSitting = newFile.handSitting;
this.mainHand = new HandSetting(sittingConfig.mainHand); this.mainHand = newFile.mainHand;
this.offHand = new HandSetting(sittingConfig.offHand); this.offHand = newFile.offHand;
} }
@Override @Override
public void update(JsonElement jsonElement) { public void update() {}
@Override
public String getFileName() {
return "sitting-config.json";
} }
@Override @Override
public SittingConfig clone() { public String getDirectory() {
SittingConfig clone = new SittingConfig(); return Data.CONFIG_DIR;
clone.copyFileData(this);
return clone;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
SittingConfig that = (SittingConfig) o;
return Objects.equal(version, that.version) && Objects.equal(enabled, that.enabled) && Objects.equal(handSitting, that.handSitting) && Objects.equal(mainHand, that.mainHand) && Objects.equal(offHand, that.offHand);
}
@Override
public int hashCode() {
return Objects.hashCode(version, enabled, handSitting, mainHand, offHand);
} }
} }

View file

@ -6,21 +6,19 @@ import net.minecraft.server.command.ReloadCommand;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import one.oth3r.sit.file.FileData;
import one.oth3r.sit.utl.Data; import one.oth3r.sit.utl.Data;
import one.oth3r.sit.utl.Logic;
import one.oth3r.sit.utl.Utl; import one.oth3r.sit.utl.Utl;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.awt.*;
@Mixin(ReloadCommand.class) @Mixin(ReloadCommand.class)
public class ReloadCommandMixin { public class ReloadCommandMixin {
@Inject(at = @At("TAIL"), method = "register") @Inject(at = @At("TAIL"), method = "register")
private static void register(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo ci) { private static void register(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo ci) {
Logic.reload(); FileData.loadFiles();
// make sure the server isn't null // make sure the server isn't null
MinecraftServer server = Data.getServer(); MinecraftServer server = Data.getServer();
@ -29,7 +27,7 @@ public class ReloadCommandMixin {
// send a reloaded message to all players with permissions // send a reloaded message to all players with permissions
for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) { for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) {
if (player.isCreativeLevelTwoOp()) { if (player.isCreativeLevelTwoOp()) {
player.sendMessage(Utl.messageTag().append(Utl.lang("sit!.chat.reloaded").color(Color.GREEN)).b()); player.sendMessage(Utl.messageTag().append(Utl.lang("sit!.chat.reloaded").formatted(Formatting.GREEN)));
} }
} }
} }

View file

@ -0,0 +1,28 @@
package one.oth3r.sit.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import java.util.function.Supplier;
public class ClickableImageWidget extends ButtonWidget {
private final Identifier image;
public ClickableImageWidget(int x, int y, int width, int height, Tooltip tooltip, Identifier image, ButtonWidget.PressAction onPress) {
super(x, y, width, height, Text.empty(), onPress, Supplier::get);
this.image = image;
this.setTooltip(tooltip);
}
@Override
protected void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
context.drawTexture(RenderLayer::getGuiTextured, image,
this.getX(), this.getY(), 0.0f, 0.0f, this.getWidth(), this.getHeight(), this.getWidth(), this.getHeight());
}
}

View file

@ -0,0 +1,77 @@
package one.oth3r.sit.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ConfirmLinkScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.ColorHelper;
import one.oth3r.sit.file.FileData;
import one.oth3r.sit.utl.Data;
import java.net.URI;
public class ConfigScreen extends Screen {
protected final Screen parent;
public ConfigScreen(Screen parent) {
super(Text.translatable("sit!.screen.config"));
this.parent = parent;
}
@Override
protected void init() {
int startY = this.height / 4 + 48;
int spacing = 36;
TextureButtonWidget serverConfigButton = this.addDrawableChild(new TextureButtonWidget.Builder(Text.translatable("config.server"),
(button) -> client.setScreen(new UnderConstructionScreen(this, FileData.getServerConfig())), false)
.dimensions(250,30).texture(Identifier.of(Data.MOD_ID, "server_button"), 246, 26).build());
serverConfigButton.setPosition(this.width / 2 - (serverConfigButton.getWidth()/2), startY);
TextureButtonWidget sittingConfigButton = this.addDrawableChild(new TextureButtonWidget.Builder(Text.translatable("config.sitting"),
(button) -> client.setScreen(new UnderConstructionScreen(this, FileData.getSittingConfig())), false)
.dimensions(250,30).texture(Identifier.of(Data.MOD_ID, "sitting_button"), 246, 26).build());
sittingConfigButton.setPosition(this.width / 2 - (sittingConfigButton.getWidth()/2), startY+36);
TextureButtonWidget issuesButton = this.addDrawableChild(new TextureButtonWidget.Builder(Text.translatable("sit!.gui.button.issues"),
ConfirmLinkScreen.opening(this, URI.create("https://github.com/Oth3r/Sit/issues")), true)
.dimensions(20,20).texture(Identifier.of(Data.MOD_ID, "issues"), 15, 15).build());
issuesButton.setPosition(this.width / 2 - 125, startY + 72 + 12);
this.addDrawableChild(ButtonWidget.builder(Text.translatable("sit!.gui.button.website"),
ConfirmLinkScreen.opening(this, URI.create("https://modrinth.com/mod/sit!"))
).dimensions(this.width / 2 - 100, startY + 72 + 12, 98, 20).build());
this.addDrawableChild(ButtonWidget.builder(Text.translatable("gui.done"), (button) -> {
close();
}).dimensions(this.width / 2 + 2, startY + 72 + 12, 98, 20).build());
TextureButtonWidget donateButton = this.addDrawableChild(new TextureButtonWidget.Builder(Text.translatable("sit!.gui.button.donate"),
ConfirmLinkScreen.opening(this, URI.create("https://Ko-fi.com/oth3r")), true)
.dimensions(20,20).texture(Identifier.of(Data.MOD_ID, "donate"), 15, 15).build());
donateButton.setPosition(this.width / 2 + 105, startY + 72 + 12);
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
// todo fade in like the title screen on first load?
renderBanner(context,width/2 - 64,this.height / 4 -38,1);
}
@Override
public void close() {
this.client.setScreen(parent);
}
private void renderBanner(DrawContext context, int x, int y, float alpha) {
context.drawTexture(RenderLayer::getGuiTextured,Identifier.of(Data.MOD_ID, "textures/gui/banner.png"),
x, y, 0.0f, 0.0f, 128, 72, 128, 72, ColorHelper.getWhite(alpha));
}
}

View file

@ -2,11 +2,10 @@ package one.oth3r.sit.screen;
import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi; import com.terraformersmc.modmenu.api.ModMenuApi;
import one.oth3r.sit.SitClient;
public class ModMenu implements ModMenuApi { public class ModMenu implements ModMenuApi {
@Override @Override
public ConfigScreenFactory<?> getModConfigScreenFactory() { public ConfigScreenFactory<?> getModConfigScreenFactory() {
return SitClient::getConfigScreen; return ConfigScreen::new;
} }
} }

View file

@ -0,0 +1,86 @@
package one.oth3r.sit.screen;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
public class TextureButtonWidget extends ButtonWidget {
//todo gray support
protected final Identifier texture;
protected final int textureWidth;
protected final int textureHeight;
protected final boolean tooltip;
TextureButtonWidget(int width, int height, Text message, int textureWidth, int textureHeight, Identifier texture, ButtonWidget.PressAction onPress, @Nullable ButtonWidget.NarrationSupplier narrationSupplier, boolean tooltip) {
super(0, 0, width, height, message, onPress, narrationSupplier == null ? DEFAULT_NARRATION_SUPPLIER : narrationSupplier);
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.texture = texture;
this.tooltip = tooltip;
if (tooltip) setTooltip(Tooltip.of(message));
}
@Override
public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
super.renderWidget(context, mouseX, mouseY, delta);
int x = this.getX() + this.getWidth() / 2 - this.textureWidth / 2;
int y = this.getY() + this.getHeight() / 2 - this.textureHeight / 2;
context.drawGuiTexture(RenderLayer::getGuiTextured, this.texture, x, y, this.textureWidth, this.textureHeight);
}
@Override
public void drawMessage(DrawContext context, TextRenderer textRenderer, int color) {
if (!this.tooltip) super.drawMessage(context, textRenderer, color);
}
public static class Builder {
private final Text text;
private final ButtonWidget.PressAction onPress;
private final boolean hideText;
private int width = 150;
private int height = 20;
@Nullable
private Identifier texture;
private int textureWidth;
private int textureHeight;
@Nullable
ButtonWidget.NarrationSupplier narrationSupplier;
public Builder(Text text, ButtonWidget.PressAction onPress, boolean hideText) {
this.text = text;
this.onPress = onPress;
this.hideText = hideText;
}
public Builder dimensions(int width, int height) {
this.width = width;
this.height = height;
return this;
}
public Builder texture(Identifier texture, int width, int height) {
this.texture = texture;
this.textureWidth = width;
this.textureHeight = height;
return this;
}
public Builder narration(ButtonWidget.NarrationSupplier narrationSupplier) {
this.narrationSupplier = narrationSupplier;
return this;
}
public TextureButtonWidget build() {
if (this.texture == null) {
throw new IllegalStateException("Sprite not set");
}
return new TextureButtonWidget(width,height,text,textureWidth,textureHeight,texture,onPress,narrationSupplier,hideText);
}
}
}

View file

@ -0,0 +1,79 @@
package one.oth3r.sit.screen;
import net.minecraft.client.gui.screen.ConfirmLinkScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import one.oth3r.sit.file.CustomFile;
import one.oth3r.sit.file.SittingConfig;
import one.oth3r.sit.utl.Data;
import one.oth3r.sit.utl.Utl;
import java.net.URI;
import java.nio.file.Paths;
public class UnderConstructionScreen<T extends CustomFile<T>> extends Screen {
protected final Screen parent;
protected T file;
public UnderConstructionScreen(Screen parent, T file) {
super(Text.translatable("sit!.screen.config"));
this.parent = parent;
this.file = file;
}
@Override
protected void init() {
int startY = this.height / 5-4;
ButtonWidget foxPNG = this.addDrawableChild(new ClickableImageWidget(70,70,140,140, Tooltip.of(Text.of("Art by @bunnestbun")),
Identifier.of(Data.MOD_ID, "textures/gui/fox.png"), ConfirmLinkScreen.opening(this, URI.create("https://www.instagram.com/bunnestbun/"))));
foxPNG.setPosition(this.width / 2 - (foxPNG.getWidth()/2), startY-35);
ButtonWidget openFileButton = this.addDrawableChild(new ButtonWidget.Builder(Text.translatable("sit!.gui.button.file"),
(button) -> Util.getOperatingSystem().open(this.file.getFile()))
.dimensions(0, 0, 118 ,20).build());
openFileButton.setPosition(this.width / 2 - 70, startY+110);
TextureButtonWidget folderButton = this.addDrawableChild(new TextureButtonWidget.Builder(Text.translatable("sit!.gui.button.folder"),
(button) -> Util.getOperatingSystem().open(Paths.get(this.file.getFile().getParent())), true)
.dimensions(20,20).texture(Identifier.of(Data.MOD_ID, "folder"), 15, 15).build());
folderButton.setPosition(this.width / 2 + 50, startY + 110);
TextureButtonWidget resetButton = this.addDrawableChild(new TextureButtonWidget.Builder(Text.translatable("sit!.gui.button.reset"),
(button) -> {
this.file.reset();
this.file.save();
}, true)
.dimensions(20,20).texture(Identifier.of(Data.MOD_ID, "reset_file"), 15, 15).build());
resetButton.setPosition(this.width / 2 -70, startY + 135);
ButtonWidget revertButton = this.addDrawableChild(new ButtonWidget.Builder(Text.translatable("sit!.gui.button.revert"),
(button) -> this.file.save())
.dimensions(0, 0, 118,20).build());
revertButton.setPosition(this.width / 2 - 48, startY+135);
ButtonWidget saveExitButton = this.addDrawableChild(new ButtonWidget.Builder(Text.translatable("sit!.gui.button.save"),
(button) -> {
this.file.load();
this.file.save();
// send the settings to the server if editing the sitting file and on a supported server
if (this.file instanceof SittingConfig && Data.isSupportedServer()) {
Utl.sendSettingsPackets();
}
this.client.setScreen(parent);
})
.dimensions(0, 0, 140,20).build());
saveExitButton.setPosition(this.width / 2 - 70, startY+168);
}
@Override
public void close() {
this.client.setScreen(parent);
}
}

View file

@ -1,8 +1,5 @@
package one.oth3r.sit.utl; package one.oth3r.sit.utl;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
@ -17,19 +14,17 @@ import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import one.oth3r.sit.SitClient; import net.minecraft.util.Formatting;
import one.oth3r.sit.command.SitCommand; import one.oth3r.sit.command.SitCommand;
import one.oth3r.sit.file.FileData; import one.oth3r.sit.file.FileData;
import one.oth3r.sit.file.LangReader; import one.oth3r.sit.file.LangReader;
import one.oth3r.sit.file.SittingConfig; import one.oth3r.sit.file.SittingConfig;
import one.oth3r.sit.packet.SitPayloads; import one.oth3r.sit.packet.SitPayloads;
import one.oth3r.sit.screen.ConfigScreen;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.awt.*;
public class Events { public class Events {
private static class Keybindings { private static class Keybindings {
@ -59,7 +54,7 @@ public class Events {
ClientPlayerEntity player = client.player; ClientPlayerEntity player = client.player;
while (config__key.wasPressed()) { while (config__key.wasPressed()) {
client.setScreen(SitClient.getConfigScreen(client.currentScreen)); client.setScreen(new ConfigScreen(client.currentScreen));
} }
/// anything below uses the player object, make sure it's not null /// anything below uses the player object, make sure it's not null
@ -75,11 +70,11 @@ public class Events {
// just send the sit command // just send the sit command
if (Data.isInGame()) { if (Data.isInGame()) {
if (Data.isSupportedServer()) { if (Data.isSupportedServer()) {
player.networkHandler.sendChatCommand("sit"); player.networkHandler.sendCommand("sit");
} else { } else {
// unsupported server message if not in a Sit! server // unsupported server message if not in a Sit! server
player.sendMessage(Utl.lang("sit!.chat.unsupported") player.sendMessage(Utl.lang("sit!.chat.unsupported")
.color(Color.RED).b(), true); .formatted(Formatting.RED), true);
} }
} }
} }
@ -104,7 +99,7 @@ public class Events {
ServerPlayNetworking.send(context.player(),new SitPayloads.ResponsePayload(SitPayloads.ResponsePayload.VERSION)); ServerPlayNetworking.send(context.player(),new SitPayloads.ResponsePayload(SitPayloads.ResponsePayload.VERSION));
// log the receiving of the packet from the player // log the receiving of the packet from the player
Data.LOGGER.info(Utl.lang("sit!.console.player_settings",context.player().getName().getString()).toString()); Data.LOGGER.info(Utl.lang("sit!.console.player_settings",context.player().getName().getString()).getString());
}))); })));
} }
@ -114,7 +109,7 @@ public class Events {
// only update when needed // only update when needed
if (!Data.isSupportedServer()) { if (!Data.isSupportedServer()) {
Data.setSupportedServer(true); Data.setSupportedServer(true);
Data.LOGGER.info(Utl.lang("sit!.console.connected",payload.value()).toString()); Data.LOGGER.info(Utl.lang("sit!.console.connected",payload.value()).getString());
} }
})); }));
} }
@ -184,19 +179,7 @@ public class Events {
if (player == null || player.isSpectator()) return ActionResult.PASS; if (player == null || player.isSpectator()) return ActionResult.PASS;
// consume if sitting, if not pass // consume if sitting, if not pass
ActionResult result = Logic.canSit(player,hitResult.getBlockPos(),hitResult) ? ActionResult.CONSUME : ActionResult.PASS; return Logic.sit(player,hitResult.getBlockPos(),hitResult) ? ActionResult.CONSUME : ActionResult.PASS;
// todo test
if (result.equals(ActionResult.CONSUME)) {
try {
CommandDispatcher<ServerCommandSource> dispatcher = Data.getServer().getCommandSource().getDispatcher();
ParseResults<ServerCommandSource> parse = dispatcher.parse("sit", player.getCommandSource());
dispatcher.execute(parse);
} catch (CommandSyntaxException e) {
Data.LOGGER.error("Error executing sit command for player {}", player.getName().getString());
}
}
return result;
}); });
}); });

View file

@ -1,101 +1,55 @@
package one.oth3r.sit.utl; package one.oth3r.sit.utl;
import net.minecraft.block.BlockState; import net.minecraft.block.*;
import net.minecraft.entity.decoration.DisplayEntity; import net.minecraft.entity.decoration.DisplayEntity;
import net.minecraft.registry.Registries;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.MutableText; import net.minecraft.text.MutableText;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import one.oth3r.sit.file.*; import one.oth3r.sit.file.FileData;
import one.oth3r.sit.file.ServerConfig;
import one.oth3r.sit.file.SittingConfig;
import one.oth3r.sit.file.HandSetting;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.awt.*;
public class Logic { public class Logic {
public static boolean sit(ServerPlayerEntity player, BlockPos blockPos, @Nullable BlockHitResult hitResult) {
/**
* checks if the player can sit at the block specified
* @param player the player that's going to sit
* @param blockPos the position that the player is going to sit at
* @param hitResult nullable, not null if the player is sitting with their hand
* @return true if the player can sit with the conditions provided
*/
public static boolean canSit(ServerPlayerEntity player, BlockPos blockPos, @Nullable BlockHitResult hitResult) {
// cant sit if crouching // cant sit if crouching
if (player.isSneaking()) return false; if (player.isSneaking()) return false;
// if sitting on a sit entity and sit while seated off, false // if sitting on a sit entity and sit while seated off, false
if (!FileData.getServerConfig().canSitWhileSeated() && Data.getSitEntity(player) != null) return false; if (!FileData.getServerConfig().canSitWhileSeated() && Data.getSitEntity(player) != null) return false;
ServerWorld serverWorld = player.getWorld(); // if hit result isnt null (check the hands of the player) & the player hand checker returns false (can't sit with the items in the hand), quit
BlockState blockState = serverWorld.getBlockState(blockPos); if (hitResult != null) {
if (!checkHands(player)) return false;
// is a bed?
if (blockState.isIn(TagKey.of(Registries.BLOCK.getKey(), Identifier.tryParse("minecraft:beds")))) {
// hit result == null means mod right?
if (hitResult != null && !Registries.ITEM.getId(player.getStackInHand(Hand.MAIN_HAND).getItem()).toString().equals("minecraft:cookie"))
return false;
// behave normally otherwise
} else {
// if hit result isnt null (check the hands of the player) & the player hand checker returns false (can't sit with the items in the hand), quit
if (hitResult != null) {
if (!checkHands(player)) return false;
}
} }
// check if the block is in the right y level limits from the config // check if the block is in the right y level limits from the config
if (!checkYLimits(player, blockPos)) return false; if (!checkYLimits(player, blockPos)) return false;
Double sitHeight = Utl.getSittingHeight(player, blockPos, hitResult); ServerWorld serverWorld = player.getServerWorld();
BlockState blockState = serverWorld.getBlockState(blockPos);
// if the sit height is null, it's not a sittable block Double sitHeight = Utl.getSittingHeight(blockState,player,blockPos,hitResult);
if (sitHeight == null)
return false; // if the sit height is null, its not a sittable block
if (sitHeight == null) return false;
DisplayEntity.TextDisplayEntity entity = Utl.Entity.create(serverWorld,blockPos,sitHeight); DisplayEntity.TextDisplayEntity entity = Utl.Entity.create(serverWorld,blockPos,sitHeight);
// checks if the player can sit if (!checkPlayerSitAbility(entity)) return false;
return checkPlayerSitAbility(entity);
}
/** Utl.Entity.spawnSit(player, entity);
* makes the player attempt to sit at the position provided (checks if the player can sit before)
* @param player the player that is sitting
* @param blockPos the pos the player is going to sit at
* @param hitResult nullable, not null if the player is sitting with their hand
* @return true if sitting was successful
*/
public static boolean sit(ServerPlayerEntity player, BlockPos blockPos, @Nullable BlockHitResult hitResult) {
if (!canSit(player, blockPos, hitResult)) return false;
// assets
ServerWorld serverWorld = player.getWorld();
Double sitHeight = Utl.getSittingHeight(player,blockPos,hitResult);
// shouldn't be null because we already checked, but do another check to clear IDE errors
assert sitHeight != null;
// spawn the entity and make the player sit
Utl.Entity.spawnSit(player, Utl.Entity.create(serverWorld,blockPos,sitHeight));
return true; return true;
} }
/**
* makes the player attempt to sit at the block they are looking at (range of 5)
* @param player the player who is trying to sit
* @return true if sitting was successful
*/
public static boolean sitLooking(ServerPlayerEntity player) { public static boolean sitLooking(ServerPlayerEntity player) {
return sit(player, Utl.getBlockPosPlayerIsLookingAt(player.getWorld(),player, return sit(player, Utl.getBlockPosPlayerIsLookingAt(player.getServerWorld(),player,5),null);
Utl.getPlayerReach(player)),null);
} }
/** /**
@ -128,11 +82,6 @@ public class Logic {
* check if the Y-level of the block is within the limits of the player, bounds are set in the {@link ServerConfig} * check if the Y-level of the block is within the limits of the player, bounds are set in the {@link ServerConfig}
*/ */
public static boolean checkYLimits(ServerPlayerEntity player, BlockPos blockPos) { public static boolean checkYLimits(ServerPlayerEntity player, BlockPos blockPos) {
ServerConfig.YDifferenceLimit yDifferenceLimit = FileData.getServerConfig().getYDifferenceLimit();
// check if enabled
if (!yDifferenceLimit.isEnabled()) return true;
double playerY = player.getBlockY(); double playerY = player.getBlockY();
double blockY = blockPos.getY(); double blockY = blockPos.getY();
// if the block is above the eye height // if the block is above the eye height
@ -143,6 +92,9 @@ public class Logic {
// get the height difference (positive) // get the height difference (positive)
double heightDifference = Math.abs(playerY - blockY); double heightDifference = Math.abs(playerY - blockY);
// get the config limits
ServerConfig.YDifferenceLimit yDifferenceLimit = FileData.getServerConfig().getYDifferenceLimit();
return (isAbove? yDifferenceLimit.getAbove() : yDifferenceLimit.getBelow()) >= heightDifference; return (isAbove? yDifferenceLimit.getAbove() : yDifferenceLimit.getBelow()) >= heightDifference;
} }
@ -170,7 +122,7 @@ public class Logic {
// get the new entity // get the new entity
DisplayEntity.TextDisplayEntity sitEntity = Data.getSpawnList().get(player); DisplayEntity.TextDisplayEntity sitEntity = Data.getSpawnList().get(player);
// spawn and ride the entity // spawn and ride the entity
player.getWorld().spawnEntity(sitEntity); player.getServerWorld().spawnEntity(sitEntity);
player.startRiding(sitEntity); player.startRiding(sitEntity);
// add the entity to the list // add the entity to the list
Data.addSitEntity(player, sitEntity); Data.addSitEntity(player, sitEntity);
@ -203,7 +155,7 @@ public class Logic {
// get the poses to check above the block // get the poses to check above the block
BlockPos pos1 = new BlockPos(pos).add(0,1,0), pos2 = new BlockPos(pos).add(0,2,0), posBelow = new BlockPos(pos); BlockPos pos1 = new BlockPos(pos).add(0,1,0), pos2 = new BlockPos(pos).add(0,2,0), posBelow = new BlockPos(pos);
// doesn't check 2 blocks above if not sitting above .80 of the block // doesn't check 2 blocks above if not sitting above .80 of the block
if (pos.getY() > (entity.getY()-Utl.Entity.Y_ADJUSTMENT) - .80) { if (pos.getY() > entity.getY() - .80) {
pos2 = pos2.add(0,-1,0); pos2 = pos2.add(0,-1,0);
posBelow = posBelow.add(0,-1,0); posBelow = posBelow.add(0,-1,0);
} }
@ -220,7 +172,6 @@ public class Logic {
public static void reload() { public static void reload() {
FileData.loadFiles(); FileData.loadFiles();
FileData.saveFiles(); FileData.saveFiles();
LangReader.loadLanguageFile();
} }
/** /**
@ -248,11 +199,11 @@ public class Logic {
// send the player the actionbar message // send the player the actionbar message
return Utl.lang("sit!.chat.toggle_sit", return Utl.lang("sit!.chat.toggle_sit",
Utl.lang(messageKey).color(config.getEnabled()? Color.GREEN : Color.RED)).b(); Utl.lang(messageKey).formatted(messageColor));
} else { } else {
// unsupported server message if not in a Sit! server // unsupported server message if not in a Sit! server
return Utl.lang("sit!.chat.unsupported") return Utl.lang("sit!.chat.unsupported")
.color(Color.RED).b(); .formatted(Formatting.RED);
} }
} }

View file

@ -10,17 +10,17 @@ import net.minecraft.block.*;
import net.minecraft.block.enums.BlockHalf; import net.minecraft.block.enums.BlockHalf;
import net.minecraft.block.enums.SlabType; import net.minecraft.block.enums.SlabType;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.decoration.DisplayEntity; import net.minecraft.entity.decoration.DisplayEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.consume.UseAction; import net.minecraft.item.consume.UseAction;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TextColor;
import net.minecraft.util.*; import net.minecraft.util.*;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult; import net.minecraft.util.hit.HitResult;
@ -28,13 +28,11 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext; import net.minecraft.world.RaycastContext;
import net.minecraft.world.World; import net.minecraft.world.World;
import one.oth3r.otterlib.chat.CTxT;
import one.oth3r.sit.file.*; import one.oth3r.sit.file.*;
import one.oth3r.sit.packet.SitPayloads; import one.oth3r.sit.packet.SitPayloads;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -43,9 +41,6 @@ import java.util.List;
public class Utl { public class Utl {
private static double BED_HEIGHT = 0.5625;
private static double DRIED_GHAST_HEIGHT = 0.625;
/** /**
* check if a block is obstructed (no collision) * check if a block is obstructed (no collision)
* @return true if not obstructed * @return true if not obstructed
@ -158,26 +153,16 @@ public class Utl {
/** /**
* gets the sitting height for the provided blockstate, via memory loaded config from Data * gets the sitting height for the provided blockstate, via memory loaded config from Data
* @param blockState the state of the block
* @param player the player to * @param player the player to
* @param blockPos the pos of the block * @param blockPos the pos of the block
* @param hit nullable, for the player interaction check * @param hit nullable, for the player interaction check
* @return null if not a valid block * @return null if not a valid block
*/ */
public static Double getSittingHeight(ServerPlayerEntity player, BlockPos blockPos, @Nullable BlockHitResult hit) { public static Double getSittingHeight(BlockState blockState, ServerPlayerEntity player, BlockPos blockPos, @Nullable BlockHitResult hit) {
ServerWorld serverWorld = player.getWorld();
ServerConfig config = FileData.getServerConfig(); ServerConfig config = FileData.getServerConfig();
BlockState blockState = serverWorld.getBlockState(blockPos);
Block block = blockState.getBlock(); Block block = blockState.getBlock();
// check bed first
if (blockState.isIn(TagKey.of(Registries.BLOCK.getKey(), Identifier.tryParse("minecraft:beds")))) {
return BED_HEIGHT;
}
// why not sit on the dried ghast?
if (Registries.BLOCK.getEntry(block).getIdAsString().equals("minecraft:dried_ghast"))
return DRIED_GHAST_HEIGHT;
// make sure that the block that is being sit on has no interaction when hand sitting // make sure that the block that is being sit on has no interaction when hand sitting
if (hit != null && blockIsInList(config.getInteractionBlocks(), blockState)) { if (hit != null && blockIsInList(config.getInteractionBlocks(), blockState)) {
return null; return null;
@ -223,7 +208,7 @@ public class Utl {
/** /**
* the customizable y height of the entity, as some versions have different sitting heights on the entity * the customizable y height of the entity, as some versions have different sitting heights on the entity
*/ */
public static final double Y_ADJUSTMENT = 0; private static final double Y_ADJUSTMENT = 0;
/** /**
* checks if the entity's block is still there, & is valid * checks if the entity's block is still there, & is valid
@ -233,7 +218,7 @@ public class Utl {
// get the blockstate // get the blockstate
BlockState blockState = player.getWorld().getBlockState(blockPos); BlockState blockState = player.getWorld().getBlockState(blockPos);
// check if the block is still there & the block is a valid sit block (by checking if there is a sit height for the block) // check if the block is still there & the block is a valid sit block (by checking if there is a sit height for the block)
return !blockState.isAir() && getSittingHeight(player,blockPos,null) != null; return !blockState.isAir() && getSittingHeight(blockState,player,blockPos,null) != null;
} }
/** /**
@ -242,9 +227,9 @@ public class Utl {
public static BlockPos getBlockPos(DisplayEntity.TextDisplayEntity entity) { public static BlockPos getBlockPos(DisplayEntity.TextDisplayEntity entity) {
// the entity Y level, adjusted // the entity Y level, adjusted
// the adjustment - is the opposite of the offset applied in Entity.create() // the adjustment - is the opposite of the offset applied in Entity.create()
int entityBlockY = (int) (Math.floor(entity.getY() + (Y_ADJUSTMENT*-1))); double entityY = entity.getBlockY() + (Y_ADJUSTMENT*-1);
// get the block pos // get the block pos
BlockPos pos = new BlockPos(entity.getBlockX(),entityBlockY,entity.getBlockZ()); BlockPos pos = new BlockPos(entity.getBlockX(),(int)entityY,entity.getBlockZ());
// if above the block, subtract 1 // if above the block, subtract 1
if (isAboveBlockHeight(entity)) { if (isAboveBlockHeight(entity)) {
pos = pos.add(0,-1,0); pos = pos.add(0,-1,0);
@ -319,7 +304,7 @@ public class Utl {
/// FYI it cant purge an entity from a disconnected player or unloaded chunks /// FYI it cant purge an entity from a disconnected player or unloaded chunks
// get a list of sit entities // get a list of sit entities
List<? extends DisplayEntity.TextDisplayEntity> list = player.getWorld() List<? extends DisplayEntity.TextDisplayEntity> list = player.getServerWorld()
.getEntitiesByType(TypeFilter.instanceOf(DisplayEntity.TextDisplayEntity.class), .getEntitiesByType(TypeFilter.instanceOf(DisplayEntity.TextDisplayEntity.class),
entity -> entity.getName().getString().equals(Data.ENTITY_NAME)); entity -> entity.getName().getString().equals(Data.ENTITY_NAME));
@ -334,32 +319,26 @@ public class Utl {
// send a message if needed // send a message if needed
if (message) { if (message) {
player.sendMessage(messageTag() player.sendMessage(messageTag().append(Utl.lang("sit!.chat.purged",Utl.lang("sit!.chat.purged.total",count).styled(
.append(lang("sit!.chat.purged",lang("sit!.chat.purged.total",count).color(Color.gray).b()).color(Color.GREEN)).b()); style -> style.withColor(Colors.LIGHT_GRAY).withItalic(true)
)).styled(
style -> style.withColor(Colors.GREEN)
)));
} }
} }
} }
public static CTxT messageTag() { public static MutableText messageTag() {
return new CTxT("Sit!").btn(true).color(Color.decode("#c400ff")).append(" "); return Text.literal("[").append(Text.literal("Sit!").styled(
style -> style.withColor(TextColor.parse("#c400ff").result().orElse(TextColor.fromFormatting(Formatting.DARK_PURPLE))))
).append("] ");
} }
/** /**
* gets a MutableText using the language key, if on server, using the custom lang reader * gets a MutableText using the language key, if on server, using the custom lang reader
*/ */
public static CTxT lang(String key, Object... args) { public static MutableText lang(String key, Object... args) {
if (Data.isClient()) { if (Data.isClient()) return Text.translatable(key, args);
// we have to first convert all the CTxT's to the built version because minecraft lang reader doesn't know how to process it
// make a array with the same size of the args
Object[] fixedArgs = new Object[args.length];
// for every arg, build & add if CTxT or just add if not
for (var i = 0; i < args.length; i++) {
if (args[i] instanceof CTxT) fixedArgs[i] = ((CTxT) args[i]).b();
else fixedArgs[i] = args[i];
}
// return the translated text
return new CTxT(Text.translatable(key,fixedArgs));
}
else return LangReader.of(key, args).getTxT(); else return LangReader.of(key, args).getTxT();
} }
@ -390,8 +369,7 @@ public class Utl {
* sends the settings packets to the server, if client & in game * sends the settings packets to the server, if client & in game
*/ */
public static void sendSettingsPackets() { public static void sendSettingsPackets() {
if (Data.isClient() && Data.isInGame() && if (Data.isClient() && Data.isInGame()) {
ClientPlayNetworking.canSend(SitPayloads.SettingsPayload.ID)) {
ClientPlayNetworking.send(new SitPayloads.SettingsPayload(Utl.getGson().toJson(FileData.getSittingConfig()))); ClientPlayNetworking.send(new SitPayloads.SettingsPayload(Utl.getGson().toJson(FileData.getSittingConfig())));
} }
} }
@ -496,13 +474,4 @@ public class Utl {
return new BlockPos(player.getBlockPos()); return new BlockPos(player.getBlockPos());
} }
public static double getPlayerReach(PlayerEntity player) {
// use the BLOCK_INTERACTION_RANGE attribute if available
if (player.getAttributeInstance(EntityAttributes.BLOCK_INTERACTION_RANGE) != null) {
return player.getAttributeValue(EntityAttributes.BLOCK_INTERACTION_RANGE);
}
// fallback to 5
return 5;
}
} }

View file

@ -1,4 +1,5 @@
{ {
"category.sit!": "Sit!",
"config.entry.exclusion": "Setze ein `!` vor einen Eintrag um ihn auszuschließen!", "config.entry.exclusion": "Setze ein `!` vor einen Eintrag um ihn auszuschließen!",
"config.entry.example": "Beispiel eingeben: %s", "config.entry.example": "Beispiel eingeben: %s",
"config.server": "Server Konfiguration", "config.server": "Server Konfiguration",
@ -68,8 +69,13 @@
"key.sit!.sit": "Sitzen", "key.sit!.sit": "Sitzen",
"key.sit!.config": "Konfiguration öffnen", "key.sit!.config": "Konfiguration öffnen",
"sit!.screen.config": "Sit! Konfiguration", "sit!.screen.config": "Sit! Konfiguration",
"sit!.gui.button.file": "Datei öffnen",
"sit!.gui.button.folder": "Ordner öffnen",
"sit!.gui.button.reset": "Zurücksetzen",
"sit!.gui.button.issues": "Probleme", "sit!.gui.button.issues": "Probleme",
"sit!.gui.button.donate": "Spenden", "sit!.gui.button.donate": "Spenden",
"sit!.gui.button.revert": "Änderungen rückgängig machen",
"sit!.gui.button.save": "Speichern und schließen",
"sit!.gui.button.website": "Website", "sit!.gui.button.website": "Website",
"sit!.console.connected": "Verbunden mit Sit! Server: %s", "sit!.console.connected": "Verbunden mit Sit! Server: %s",
"sit!.console.player_settings": "Benutzerdefinierte Sitzungseinstellungen von %s erhalten!", "sit!.console.player_settings": "Benutzerdefinierte Sitzungseinstellungen von %s erhalten!",

View file

@ -1,4 +0,0 @@
{
"config.sitting": "Ρύθμιση καθίσματος",
"config.sitting.hand.filter.block.description": "Το προεπιλεγμένο φίλτρο του μπλοκ."
}

View file

@ -91,8 +91,13 @@
"key.sit!.config": "Open Config", "key.sit!.config": "Open Config",
"sit!.screen.config": "Sit! Config", "sit!.screen.config": "Sit! Config",
"sit!.gui.button.file": "Open File",
"sit!.gui.button.folder": "Open Folder",
"sit!.gui.button.reset": "Reset",
"sit!.gui.button.issues": "Issues", "sit!.gui.button.issues": "Issues",
"sit!.gui.button.donate": "Donate", "sit!.gui.button.donate": "Donate",
"sit!.gui.button.revert": "Revert Changes",
"sit!.gui.button.save": "Save and Close",
"sit!.gui.button.website": "Website", "sit!.gui.button.website": "Website",
"sit!.console.connected": "Connected to Sit! server: %s", "sit!.console.connected": "Connected to Sit! server: %s",

View file

@ -1,76 +0,0 @@
{
"config.entry.exclusion": "Pon un `!` delante de una entrada para excluirla!",
"config.entry.example": "Ejemplo: %s",
"config.server": "Configuración del Servidor",
"config.server.description": "Configura los ajustes del lado del servidor.",
"config.server.lang": "Idioma",
"config.server.lang.description": "El idioma utilizado para el mod Sit!",
"config.server.keep-active": "Mantener activo",
"config.server.keep-active.description": "Alterna entre si la entidad sentada deberia quedarse, inclsuo si el jugador / server se desconecta.\nSi esta en flaso, el jugador no estara sentado al entrar nuevamente",
"config.server.sit-while-seated": "Siéntate mientras estás sentado",
"config.server.sit-while-seated.description": "Activa la capacidad de sentarse en otro sitio/bloque mientras aun estes sentado.",
"config.server.preset-blocks": "Bloques predefinidos",
"config.server.preset-blocks.description": "Alterna para los bloques por defecto de Sit!",
"config.server.preset-blocks.stairs": "Escaleras",
"config.server.preset-blocks.slabs": "Losas",
"config.server.preset-blocks.carpets": "Alfombras",
"config.server.preset-blocks.full-blocks": "Bloques Solidos",
"config.server.custom-enabled": "Personalizados",
"config.server.custom-enabled.description": "Activa el uso de bloques personalizados para sentarse.",
"config.server.custom-blocks": "Bloques personalizados",
"config.server.custom-blocks.description": "La lista de bloques par sentarse personalizados.",
"config.server.custom-block.block-ids": "ID de bloque",
"config.server.custom-block.block-ids.description": "Las ID de los bloques custom para sentarse",
"config.server.custom-block.block-tags": "Etiquetas de los bloques",
"config.server.custom-block.block-tags.description": "Los tags de los bloques custom para sentarse",
"config.server.custom-block.blockstates": "Estados de bloque",
"config.server.custom-block.blockstates.description": "El Estado de bloque que el bloque debe de tener para ser un bloque custom.",
"config.server.custom-block.sitting-height": "Altura de sentarse",
"config.server.custom-block.sitting-height.description": "La altura a la que el jugador se sienta en un bloque custom.",
"config.server.blacklisted-blocks": "Bloques en lista negra",
"config.server.blacklisted-blocks.description": "La lista de bloques en los que no podras sentarte.",
"config.sitting": "Configuracion de sentarse",
"config.sitting.description": "Configura la habilidad de sentarse, en el server cada jugador puede tener su propia configuracion de sentarse cuando usan el mod.",
"config.sitting.enabled": "Habilitado",
"config.sitting.enabled.description": "Alterna la habilidad de sentarse",
"config.sitting.hand-sitting": "Sentarse con la mano",
"config.sitting.hand-sitting.description": "Alterna habilidad de sentarse usando interacciones con la mano",
"config.sitting.hand.main": "Mano dominante",
"config.sitting.hand.main.description": "mano dominante",
"config.sitting.hand.off": "Mano Secundaria",
"config.sitting.hand.off.description": "mano secundaria",
"config.sitting.hand.description": "Configura las %s opciones de sentarse.",
"config.sitting.hand.requirement": "Requisitos para sentarse",
"config.sitting.hand.requirement.description": "El requerimiento de la mano para sentarse. Ej, si vacío, la mano debe estar vacía para sentarse",
"config.sitting.hand.requirement.description.none": "Sin requisitos para sentarse.",
"config.sitting.hand.requirement.description.empty": "La mano debe estar vacía para sentarse.",
"config.sitting.hand.requirement.description.filter": "Solo usar interacciones de mano si el item en la mano se encuentra en el filtro.",
"config.sitting.hand.filter": "Filtro",
"config.sitting.hand.filter.description": "La lista de items para el requisito de mano.",
"config.sitting.hand.filter.block": "Bloques",
"config.sitting.hand.filter.block.description": "El filtro de bloques por defecto.",
"config.sitting.hand.filter.food": "Comidas",
"config.sitting.hand.filter.food.description": "El filtro de comidas por defecto.",
"config.sitting.hand.filter.usable": "Usables",
"config.sitting.hand.filter.usable.description": "El filtro de usables por defecto. (Tridentes, Escudos, Arcos)",
"config.sitting.hand.filter.custom-items": "Items personalizados",
"config.sitting.hand.filter.custom-items.description": "Una lista de items personalizados para añadir al filtro.",
"config.sitting.hand.filter.custom-tags": "Etiquetas personalizadas",
"config.sitting.hand.filter.custom-tags.description": "Una lista de etiquetas personalizadas para añadir al filtro.",
"sit!.chat.toggle_sit": "%s Sentandose!",
"sit!.chat.toggle_sit.on": "Activado",
"sit!.chat.toggle_sit.off": "Desactivado",
"sit!.chat.unsupported": "Sit! no esta disponible en este servidor.",
"sit!.chat.reloaded": "¡Recargando la configuración!",
"sit!.chat.purged": "¡Se purgaron todas las entidades Sit! cargadas! %s",
"sit!.chat.purged.total": "(%s removido)",
"key.sit!.toggle": "Alternar Sentarse",
"key.sit!.sit": "Sentarse",
"key.sit!.config": "Abrir configuración",
"sit!.screen.config": "Configuracion de Sit!",
"sit!.gui.button.issues": "Problemas",
"sit!.gui.button.donate": "Donar",
"sit!.gui.button.website": "Sitio web ",
"sit!.console.player_settings": "¡Se recibió configuraciones personalizadas dé %s!",
"modmenu.descriptionTranslation.sit-oth3r": "¡Añade la capacidad de sentarse a Minecraft! Configuración extensa para restricciones de mano y bloques sentables.\n ¡Los jugadores pueden tener su propia configuración cuando usan Sit! del lado del cliente en un servidor!"
}

View file

@ -1,77 +0,0 @@
{
"config.entry.exclusion": "Placez un `!` devant une entrée pour l'exclure!",
"config.entry.example": "Exemple d'entrée : %s",
"config.server": "Configuration du Serveur",
"config.server.description": "Configure les paramètres côté serveur.",
"config.server.lang": "Langue",
"config.server.lang.description": "La langue utilisée pour le mod Sit!",
"config.server.keep-active": "Garder actif",
"config.server.keep-active.description": "Active ou désactive si l'entité Sit! doit rester, même si le joueur / serveur est hors ligne.\nLorsqu'il est faux, le joueur ne sera pas assis lors de la reconnexion.",
"config.server.sit-while-seated": "Sit en étant assis",
"config.server.sit-while-seated.description": "Active/désactive la possibilité de s'asseoir sur un autre bloc Sit! en étant déjà assis.",
"config.server.preset-blocks": "Blocs de présélection",
"config.server.preset-blocks.description": "Active ou désactive les blocs Sit! par défaut.",
"config.server.preset-blocks.stairs": "Escalier",
"config.server.preset-blocks.slabs": "Dalles",
"config.server.preset-blocks.carpets": "Tapis",
"config.server.preset-blocks.full-blocks": "Blocs complets",
"config.server.custom-enabled": "Personnalisé",
"config.server.custom-enabled.description": "Active ou désactive l'utilisation de blocs personnalisés pour s'asseoir.",
"config.server.custom-blocks": "Blocs personnalisés",
"config.server.custom-blocks.description": "La liste des blocs personnalisés.",
"config.server.custom-block.block-ids": "ID des blocs",
"config.server.custom-block.block-ids.description": "L'ID du ou des blocs pour le bloc de siège personnalisé.",
"config.server.custom-block.block-tags": "Tags des blocs",
"config.server.custom-block.block-tags.description": "Le ou les tags de blocs pour le bloc de siège personnalisé.",
"config.server.custom-block.blockstates": "États de bloc",
"config.server.custom-block.blockstates.description": "Les états de bloc que le bloc doit avoir pour être un bloc de siège personnalisé.",
"config.server.custom-block.sitting-height": "Hauteur assise",
"config.server.custom-block.sitting-height.description": "La hauteur du joueur en position assise sur un bloc personnalisé.",
"config.server.blacklisted-blocks": "Blocs blacklistés",
"config.server.blacklisted-blocks.description": "La liste des blocs sur lesquels on ne peut pas s'asseoir.",
"config.sitting": "Configuration de la position assise",
"config.sitting.description": "Configure la position assise, sur le serveur, chaque joueur peut avoir sa propre configuration assise quand il utilise le mod.",
"config.sitting.enabled": "Activé",
"config.sitting.enabled.description": "Active/désactive la possibilité de s'asseoir.",
"config.sitting.hand-sitting": "S'asseoir avec la main",
"config.sitting.hand-sitting.description": "Active/désactive la possibilité de s'asseoir à l'aide d'interactions à la main.",
"config.sitting.hand.main": "Main principale",
"config.sitting.hand.main.description": "main principale",
"config.sitting.hand.off": "Main secondaire",
"config.sitting.hand.off.description": "main secondaire",
"config.sitting.hand.description": "Configure les paramètres d'assise de %s.",
"config.sitting.hand.requirement": "Exigences de la position assise",
"config.sitting.hand.requirement.description": "Le besoin de la main pour s'asseoir. Par exemple, si le champ est EMPTY, la main doit être vide",
"config.sitting.hand.requirement.description.none": "Pas de condition pour s'asseoir.",
"config.sitting.hand.requirement.description.empty": "La main doit être vide pour s'asseoir.",
"config.sitting.hand.requirement.description.filter": "La main ne peut s'asseoir que si l'objet dans la main correspond à l'un des filtres.",
"config.sitting.hand.filter": "Filtre",
"config.sitting.hand.filter.description": "La liste des objets pour le filtre de la main requise.",
"config.sitting.hand.filter.block": "Blocs",
"config.sitting.hand.filter.block.description": "Filtre par défaut des blocs.",
"config.sitting.hand.filter.food": "Nourriture",
"config.sitting.hand.filter.food.description": "Le filtre par défaut des aliments.",
"config.sitting.hand.filter.usable": "Utilisables",
"config.sitting.hand.filter.usable.description": "Le filtre par défaut des utilisables. (Tridents, Boucliers, Arcs)",
"config.sitting.hand.filter.custom-items": "Objets personnalisés",
"config.sitting.hand.filter.custom-items.description": "Une liste des objets personnalisés à ajouter au filtre.",
"config.sitting.hand.filter.custom-tags": "Tags Personnalisés",
"config.sitting.hand.filter.custom-tags.description": "Une liste de tags personnalisés à ajouter au filtre",
"sit!.chat.toggle_sit": "S'asseoir avec %s",
"sit!.chat.toggle_sit.on": "Activé",
"sit!.chat.toggle_sit.off": "Désactivé",
"sit!.chat.unsupported": "Sit! n'est pas disponible sur ce serveur.",
"sit!.chat.reloaded": "Configuration rechargée!",
"sit!.chat.purged": "Toutes les entités Sit chargées ont été purgées ! %s",
"sit!.chat.purged.total": "(%s supprimé)",
"key.sit!.toggle": "Activer/désactiver la position assise",
"key.sit!.sit": "S'asseoir",
"key.sit!.config": "Ouvrir la configuration",
"sit!.screen.config": "Sit! Config",
"sit!.gui.button.issues": "Problèmes",
"sit!.gui.button.donate": "Faire un don",
"sit!.gui.button.website": "Site web",
"sit!.console.connected": "Connecté au serveur Sit! : %s",
"sit!.console.player_settings": "Reçu les paramètres de séance personnalisés de %s!",
"modmenu.descriptionTranslation.sit-oth3r": "- Ajoute la possibilité de s'asseoir dans Minecraft! Personnalisation infinie des restrictions de main et des blocs assis. \n- Les joueurs peuvent avoir leurs propres paramètres d'assise en utilisant le client Sit! sur le serveur!"
}

View file

@ -1,4 +1,5 @@
{ {
"category.sit!": "Sit!",
"config.entry.exclusion": "Metti un `!` davanti a un campo per escluderlo!", "config.entry.exclusion": "Metti un `!` davanti a un campo per escluderlo!",
"config.entry.example": "Esempio campo: %s", "config.entry.example": "Esempio campo: %s",
"config.server": "Configura Server", "config.server": "Configura Server",
@ -68,8 +69,13 @@
"key.sit!.sit": "Siediti", "key.sit!.sit": "Siediti",
"key.sit!.config": "Apri Impostazioni", "key.sit!.config": "Apri Impostazioni",
"sit!.screen.config": "Impostazioni Sit!", "sit!.screen.config": "Impostazioni Sit!",
"sit!.gui.button.file": "Apri File",
"sit!.gui.button.folder": "Apri Cartella",
"sit!.gui.button.reset": "Resetta",
"sit!.gui.button.issues": "Problemi", "sit!.gui.button.issues": "Problemi",
"sit!.gui.button.donate": "Dona", "sit!.gui.button.donate": "Dona",
"sit!.gui.button.revert": "Annulla i Cambiamenti",
"sit!.gui.button.save": "Salva ed Esci",
"sit!.gui.button.website": "Sito Web", "sit!.gui.button.website": "Sito Web",
"sit!.console.connected": "Connesso al server Sit!: %s", "sit!.console.connected": "Connesso al server Sit!: %s",
"sit!.console.player_settings": "Ricevute impostazioni custom da %s!", "sit!.console.player_settings": "Ricevute impostazioni custom da %s!",

View file

@ -1,52 +0,0 @@
{
"config.entry.exclusion": "Umieść `!` przed wpisem, aby go wykluczyć!",
"config.entry.example": "%s",
"config.server": "Konfiguracja Serwera",
"config.server.lang": "Język",
"config.server.lang.description": "Język używany w modzie Sit!",
"config.server.preset-blocks.stairs": "Schody",
"config.server.preset-blocks.slabs": "Pół bloki",
"config.server.preset-blocks.carpets": "Dywany",
"config.server.preset-blocks.full-blocks": "Pełne bloki",
"config.server.custom-enabled": "Niestandardowe",
"config.server.custom-enabled.description": "Przełącza użycie niestandardowych bloków do siadania.",
"config.server.custom-blocks": "Niestandardowe Bloki",
"config.server.custom-blocks.description": "Lista niestandardowych bloków, na których można siadać.",
"config.server.custom-block.block-ids": "ID bloków",
"config.server.custom-block.block-ids.description": "ID niestandardowych bloków do siadania.",
"config.server.custom-block.sitting-height": "Wysokość siedzenia",
"config.server.custom-block.sitting-height.description": "Wysokość siedzenia gracza na niestandardowym bloku.",
"config.server.blacklisted-blocks": "Bloki na czarnej liście",
"config.server.blacklisted-blocks.description": "Lista bloków, na których nie można siadać",
"config.sitting.description": "Konfiguruje możliwość siadania. Na serwerze, każdy gracz może używać swoich ustawień moda.",
"config.sitting.enabled": "Włączono",
"config.sitting.enabled.description": "Przełącza możliwość siadania.",
"config.sitting.hand-sitting.description": "Przełącza możliwość siadania, używając ręki.",
"config.sitting.hand.main": "Główna ręka",
"config.sitting.hand.main.description": "główna ręka",
"config.sitting.hand.off": "Pomocnicza ręka",
"config.sitting.hand.off.description": "pomocnicza ręka",
"config.sitting.hand.filter": "Filtr",
"config.sitting.hand.filter.description": "Lista przedmiotów do filtra",
"config.sitting.hand.filter.block": "Bloki",
"config.sitting.hand.filter.block.description": "Domyślny filtr bloków.",
"config.sitting.hand.filter.food": "Jedzenie",
"config.sitting.hand.filter.food.description": "Domyślny filtr żywności.",
"config.sitting.hand.filter.usable": "Narzędzia",
"config.sitting.hand.filter.usable.description": "Domyślny filtr przedmiotów, które mogą być używane. (Trójzęby, Tarcze, Łuki)",
"config.sitting.hand.filter.custom-items": "Niestandardowe przedmioty",
"config.sitting.hand.filter.custom-items.description": "Lista niestandardowych przedmiotów dodanych do filtra.",
"sit!.chat.toggle_sit.on": "Włączone",
"sit!.chat.toggle_sit.off": "Wyłączone",
"sit!.chat.unsupported": "Sit! nie jest zainstalowane na tym serwerze.",
"sit!.chat.reloaded": "Przeładowano ustawienia!",
"sit!.chat.purged.total": "(Usunięto %s)",
"key.sit!.toggle": "Przełącz możliwość siadania",
"key.sit!.config": "Otwórz ustawienia",
"sit!.screen.config": "Konfiguracja Sit!",
"sit!.gui.button.donate": "Wesprzyj",
"sit!.gui.button.website": "Strona",
"sit!.console.connected": "Połączono z serwerem wspierającym Sit!: %s",
"sit!.console.player_settings": "Otrzymano niestandardowe ustawienia z: %s!",
"modmenu.descriptionTranslation.sit-oth3r": "Dodaje siadanie na bloki do Minecraft! Nieskończona możliwość konfiguracji. Gracze sami mogą wybrać swoje preferencje, gdy używają Sit! na swoim kliencie!"
}

View file

@ -1,4 +1,5 @@
{ {
"category.sit!": "Sit!",
"config.entry.exclusion": "Coloque um `!` antes de uma entrada para excluí-la!", "config.entry.exclusion": "Coloque um `!` antes de uma entrada para excluí-la!",
"config.entry.example": "Exemplo de entrada: %s", "config.entry.example": "Exemplo de entrada: %s",
"config.server": "Configuração do Servidor", "config.server": "Configuração do Servidor",
@ -68,8 +69,13 @@
"key.sit!.sit": "Sentar", "key.sit!.sit": "Sentar",
"key.sit!.config": "Abrir Configuração", "key.sit!.config": "Abrir Configuração",
"sit!.screen.config": "Configuração do Sit!", "sit!.screen.config": "Configuração do Sit!",
"sit!.gui.button.file": "Abrir Arquivo",
"sit!.gui.button.folder": "Abrir Pasta",
"sit!.gui.button.reset": "Reiniciar",
"sit!.gui.button.issues": "Problemas", "sit!.gui.button.issues": "Problemas",
"sit!.gui.button.donate": "Doar", "sit!.gui.button.donate": "Doar",
"sit!.gui.button.revert": "Reverter Alterações",
"sit!.gui.button.save": "Salvar e Fechar",
"sit!.gui.button.website": "Website", "sit!.gui.button.website": "Website",
"sit!.console.connected": "Conectado ao servidor Sit!: %s", "sit!.console.connected": "Conectado ao servidor Sit!: %s",
"sit!.console.player_settings": "Recebidas configurações de sentar personalizadas de %s!", "sit!.console.player_settings": "Recebidas configurações de sentar personalizadas de %s!",

View file

@ -1,77 +0,0 @@
{
"config.entry.exclusion": "Pôr um '!' à frente de uma entrada para a excluir!",
"config.entry.example": "Exemplo de uma entrada: %s",
"config.server": "Configuração do Servidor",
"config.server.description": "Configura as definições no lado do servidor.",
"config.server.lang": "Idioma",
"config.server.lang.description": "O idioma utilizado para o mod Sit!.",
"config.server.keep-active": "Manter ativo",
"config.server.keep-active.description": "Alterna se a entidade Sit! deve permanecer, mesmo se o jogador/servidor estiver offline.\nQuando falso, o jogador não estará sentado ao entrar novamente.",
"config.server.sit-while-seated": "Sentar enquanto está sentado",
"config.server.sit-while-seated.description": "Alterna a habilidade de sentar noutro bloco Sit! enquanto está sentado.",
"config.server.preset-blocks": "Blocos predefinidos",
"config.server.preset-blocks.description": "Alterna para os blocos Sit! padrão.",
"config.server.preset-blocks.stairs": "Escadas",
"config.server.preset-blocks.slabs": "Degraus",
"config.server.preset-blocks.carpets": "Tapetes",
"config.server.preset-blocks.full-blocks": "Blocos inteiros",
"config.server.custom-enabled": "Personalizado",
"config.server.custom-enabled.description": "Alterna o uso de blocos personalizados para sentar.",
"config.server.custom-blocks": "Blocos personalizados",
"config.server.custom-blocks.description": "A lista de blocos personalizados para sentar.",
"config.server.custom-block.block-ids": "IDs dos blocos",
"config.server.custom-block.block-ids.description": "Os IDs dos blocos para o bloco personalizado para sentar.",
"config.server.custom-block.block-tags": "Etiquetas de blocos",
"config.server.custom-block.block-tags.description": "A(s) etiqueta(s) de blocos para o bloco personalizado para sentar.",
"config.server.custom-block.blockstates": "Blockstates",
"config.server.custom-block.blockstates.description": "Os blockstates indicam que o bloco deve ser um bloco personalizado para sentar.",
"config.server.custom-block.sitting-height": "Altura para sentar",
"config.server.custom-block.sitting-height.description": "A altura a que o jogador se senta no bloco personalizado.",
"config.server.blacklisted-blocks": "Blocos na lista negra",
"config.server.blacklisted-blocks.description": "A lista de blocos em que não é permitido sentar.",
"config.sitting": "Definições de sentar",
"config.sitting.description": "Define a habilidade de sentar. No servidor, cada jogador pode ter a sua própria configuração de sentar quando usam o mod.",
"config.sitting.enabled": "Ativado",
"config.sitting.enabled.description": "Alterna a habilidade de sentar.",
"config.sitting.hand-sitting": "Sentar com a mão",
"config.sitting.hand-sitting.description": "Alterna a habilidade de sentar ao utilizar interações da mão.",
"config.sitting.hand.main": "Mão principal",
"config.sitting.hand.main.description": "mão principal",
"config.sitting.hand.off": "Outra Mão",
"config.sitting.hand.off.description": "outra mão",
"config.sitting.hand.description": "Configura as definições de sentar %s .",
"config.sitting.hand.requirement": "Requisitos para sentar",
"config.sitting.hand.requirement.description": "O requisito da mão para sentar. Ex.: Se \"EMPTY\", a mão tem de estar vazia",
"config.sitting.hand.requirement.description.none": "Sem requisitos para sentar.",
"config.sitting.hand.requirement.description.empty": "A mão tem de estar vazia para sentar.",
"config.sitting.hand.requirement.description.filter": "A mão pode apenas sentar se o item na mão corresponde a um dos filtros.",
"config.sitting.hand.filter": "Filtro",
"config.sitting.hand.filter.description": "A lista de itens para o filtro de requisitos para a mão.",
"config.sitting.hand.filter.block": "Blocos",
"config.sitting.hand.filter.block.description": "O filtro padrão para blocos.",
"config.sitting.hand.filter.food": "Alimentos",
"config.sitting.hand.filter.food.description": "O filtro padrão para alimentos.",
"config.sitting.hand.filter.usable": "Utilidades",
"config.sitting.hand.filter.usable.description": "O filtro padrão de utilidades. (Tridentes, Escudos, Setas)",
"config.sitting.hand.filter.custom-items": "Itens personalizados",
"config.sitting.hand.filter.custom-items.description": "A lista de itens personalizados a adicionar ao filtro.",
"config.sitting.hand.filter.custom-tags": "Etiquetas personalizadas",
"config.sitting.hand.filter.custom-tags.description": "A lista de etiquetas de itens personalizadas a adicionar ao filtro.",
"sit!.chat.toggle_sit": "%s está sentado!",
"sit!.chat.toggle_sit.on": "Ativado",
"sit!.chat.toggle_sit.off": "Desativado",
"sit!.chat.unsupported": "Sit! não está disponível neste servidor.",
"sit!.chat.reloaded": "Definições recarregadas!",
"sit!.chat.purged": "Foram eliminadas todas as entidades Sit! carregadas! %s",
"sit!.chat.purged.total": "(%s removido)",
"key.sit!.toggle": "Alternar sentar",
"key.sit!.sit": "Sentar",
"key.sit!.config": "Abrir definições",
"sit!.screen.config": "Definições do Sit!",
"sit!.gui.button.issues": "Problemas",
"sit!.gui.button.donate": "Doar",
"sit!.gui.button.website": "Website",
"sit!.console.connected": "Conectado ao servidor Sit!: %s",
"sit!.console.player_settings": "Recebidas definições de sentar personalizadas de %s!",
"modmenu.descriptionTranslation.sit-oth3r": "Adiciona a função de sentar ao Minecraft! Personalização ilimitada para restrições de mão e blocos possíveis de sentar.\nOs jogadores podem ter as suas próprias definições ao usar o cliente Sit! no servidor!"
}

View file

@ -1,77 +0,0 @@
{
"config.entry.exclusion": "Поместите `!` перед записью, чтобы исключить её!",
"config.entry.example": "Пример ввода: %s",
"config.server": "Конфигурация сервера",
"config.server.description": "Настраивает параметры сервера.",
"config.server.lang": "Язык",
"config.server.lang.description": "Язык, используемый модом Sit!",
"config.server.keep-active": "Оставить активным",
"config.server.keep-active.description": "Переключает, должна ли сущность Sit! оставаться, даже если игрок / сервер не находится в сети. \nЕсли значение false, игрок не будет сидеть при повторном входе в систему.",
"config.server.sit-while-seated": "Пересаживание на другой блок",
"config.server.sit-while-seated.description": "Переключает возможность сесть на другой блок Sit!, когда вы уже сидите.",
"config.server.preset-blocks": "Предустановленные блоки",
"config.server.preset-blocks.description": "Переключатели для стандартных блоков Sit!",
"config.server.preset-blocks.stairs": "Ступеньки",
"config.server.preset-blocks.slabs": "Полублоки",
"config.server.preset-blocks.carpets": "Ковры",
"config.server.preset-blocks.full-blocks": "Полные блоки",
"config.server.custom-enabled": "Пользовательский",
"config.server.custom-enabled.description": "Переключает использование пользовательских блоков для сидения.",
"config.server.custom-blocks": "Пользовательские блоки",
"config.server.custom-blocks.description": "Список пользовательских блоков для сидения.",
"config.server.custom-block.block-ids": "ID блоков",
"config.server.custom-block.block-ids.description": "ID блоков для пользовательского блока для сидения.",
"config.server.custom-block.block-tags": "Теги блока",
"config.server.custom-block.block-tags.description": "Тег(и) блоков для пользовательского блока для сидения.",
"config.server.custom-block.blockstates": "Блокстатусы",
"config.server.custom-block.blockstates.description": "Блокстатусы которые должны быть у блока, чтобы быть пользовательским блоком для сидения.",
"config.server.custom-block.sitting-height": "Высота сидения",
"config.server.custom-block.sitting-height.description": "Высота сидящего игрока на пользовательском блоке.",
"config.server.blacklisted-blocks": "Черный список блоков",
"config.server.blacklisted-blocks.description": "Список блоков, на которых запрещено сидеть.",
"config.sitting": "Конфигурация сидения",
"config.sitting.description": "Настраивает способность сидеть, на сервере каждый игрок может иметь свою собственную конфигурацию при использовании мода.",
"config.sitting.enabled": "Включено",
"config.sitting.enabled.description": "Переключает возможность сидеть.",
"config.sitting.hand-sitting": "Сидение рукой",
"config.sitting.hand-sitting.description": "Переключает возможность сидеть используя взаимодействия рукой.",
"config.sitting.hand.main": "Главная рука",
"config.sitting.hand.main.description": "главная рука",
"config.sitting.hand.off": "Левая рука",
"config.sitting.hand.off.description": "левая рука",
"config.sitting.hand.description": "Настраивает параметры сидения %s.",
"config.sitting.hand.requirement": "Требование к сидению",
"config.sitting.hand.requirement.description": "Требование к руке для посадки. Те, если EMPTY, рука должна быть пустой",
"config.sitting.hand.requirement.description.none": "Нет требований для сидения.",
"config.sitting.hand.requirement.description.empty": "Чтобы сидеть, рука должна быть пустой.",
"config.sitting.hand.requirement.description.filter": "Чтобы сидеть, предмет в руке должен соответствовать одному из фильтров.",
"config.sitting.hand.filter": "Фильтр",
"config.sitting.hand.filter.description": "Список предметов для фильтра требований руки.",
"config.sitting.hand.filter.block": "Блоки",
"config.sitting.hand.filter.block.description": "Фильтр блоков по умолчанию.",
"config.sitting.hand.filter.food": "Еда",
"config.sitting.hand.filter.food.description": "Фильтр еды по умолчанию.",
"config.sitting.hand.filter.usable": "Используемые",
"config.sitting.hand.filter.usable.description": "Стандартный фильтр используемых. (Трезубцы, Щиты, Луки)",
"config.sitting.hand.filter.custom-items": "Пользовательские предметы",
"config.sitting.hand.filter.custom-items.description": "Список пользовательских предметов для добавления в фильтр.",
"config.sitting.hand.filter.custom-tags": "Пользовательские теги",
"config.sitting.hand.filter.custom-tags.description": "Список пользовательских тегов предметов для добавления в фильтр.",
"sit!.chat.toggle_sit": "%s Сел!",
"sit!.chat.toggle_sit.on": "Включено",
"sit!.chat.toggle_sit.off": "Отключено",
"sit!.chat.unsupported": "Sit! не доступен на этом сервере.",
"sit!.chat.reloaded": "Конфигурация перезагружена!",
"sit!.chat.purged": "Очистил все загруженные сущности Sit! %s",
"sit!.chat.purged.total": "(%s убрано)",
"key.sit!.toggle": "Переключить возможность сидеть",
"key.sit!.sit": "Сесть",
"key.sit!.config": "Открыть Конфигурацию",
"sit!.screen.config": "Конфигурация Sit!",
"sit!.gui.button.issues": "Баг‑трекер",
"sit!.gui.button.donate": "Пожертвовать",
"sit!.gui.button.website": "Веб-сайт",
"sit!.console.connected": "Подключено к серверу Sit!: %s",
"sit!.console.player_settings": "Получены пользовательские настройки сидения от %s!",
"modmenu.descriptionTranslation.sit-oth3r": "Добавляет возможность сидеть в Minecraft! Бесконечная кастомизация ограничений для рук и блоков, на которых можно сидеть.\nИгроки могут настраивать свои параметры сидения при использовании клиента Sit! на сервере!"
}

View file

@ -1,4 +1,5 @@
{ {
"category.sit!": "Sit!",
"config.entry.exclusion": "Bir girdiyi hariç tutmak için önüne '!' koyun!", "config.entry.exclusion": "Bir girdiyi hariç tutmak için önüne '!' koyun!",
"config.entry.example": "Girdi örneği: %s", "config.entry.example": "Girdi örneği: %s",
"config.server": "Sunucu Ayarları", "config.server": "Sunucu Ayarları",
@ -68,8 +69,13 @@
"key.sit!.sit": "Otur", "key.sit!.sit": "Otur",
"key.sit!.config": "Ayarlandırmaları aç", "key.sit!.config": "Ayarlandırmaları aç",
"sit!.screen.config": "Sit! Ayarlandırmaları", "sit!.screen.config": "Sit! Ayarlandırmaları",
"sit!.gui.button.file": "Dosya Aç",
"sit!.gui.button.folder": "Klasörü Aç",
"sit!.gui.button.reset": "Sıfırla",
"sit!.gui.button.issues": "Sorunlar", "sit!.gui.button.issues": "Sorunlar",
"sit!.gui.button.donate": "Bağış yap", "sit!.gui.button.donate": "Bağış yap",
"sit!.gui.button.revert": "Değişiklikleri Geri Al",
"sit!.gui.button.save": "Kaydet ve Kapat",
"sit!.gui.button.website": "İnternet Sitesi", "sit!.gui.button.website": "İnternet Sitesi",
"sit!.console.connected": "Sit! sunucusuna bağlanıldı: %s", "sit!.console.connected": "Sit! sunucusuna bağlanıldı: %s",
"sit!.console.player_settings": "Özel oturma ayarları %s alındı!", "sit!.console.player_settings": "Özel oturma ayarları %s alındı!",

View file

@ -1,24 +0,0 @@
{
"config.server": "Конфігурація сервера",
"config.server.lang": "Мова",
"config.server.lang.description": "Мова, що використовується для моду Sit!.",
"config.server.preset-blocks.stairs": "Сходи",
"config.server.preset-blocks.carpets": "Килими",
"config.server.preset-blocks.full-blocks": "Повні блоки",
"config.server.custom-enabled": "Користувацький",
"config.server.custom-blocks": "Користувацькі блоки",
"config.server.custom-block.block-ids": "ID блоків",
"config.sitting": "Sit! Конфігурація",
"config.sitting.enabled": "Ввімкнено",
"config.sitting.enabled.description": "Вмикає/Вимикає можливість сидіти.",
"config.sitting.hand.main": "Основна рука",
"config.sitting.hand.main.description": "основна рука",
"config.sitting.hand.off": "Ліва Рука",
"config.sitting.hand.off.description": "ліва рука",
"config.sitting.hand.description": "Налаштовує %s налаштування сидіння.",
"config.sitting.hand.filter": "Фільтр",
"config.sitting.hand.filter.block": "Блоки",
"config.sitting.hand.filter.food": "Їжа",
"config.sitting.hand.filter.custom-items": "Користувацькі предмети",
"config.sitting.hand.filter.custom-tags": "Користувацькі теги"
}

View file

@ -1,4 +1,5 @@
{ {
"category.sit!": "Sit!",
"config.entry.exclusion": "在条目前加上“!”以排除。", "config.entry.exclusion": "在条目前加上“!”以排除。",
"config.entry.example": "条目示例:%s", "config.entry.example": "条目示例:%s",
"config.server": "服务端配置", "config.server": "服务端配置",
@ -68,8 +69,13 @@
"key.sit!.sit": "坐下", "key.sit!.sit": "坐下",
"key.sit!.config": "打开配置", "key.sit!.config": "打开配置",
"sit!.screen.config": "Sit! 配置", "sit!.screen.config": "Sit! 配置",
"sit!.gui.button.file": "打开文件",
"sit!.gui.button.folder": "打开文件夹",
"sit!.gui.button.reset": "重置",
"sit!.gui.button.issues": "问题反馈", "sit!.gui.button.issues": "问题反馈",
"sit!.gui.button.donate": "赞助", "sit!.gui.button.donate": "赞助",
"sit!.gui.button.revert": "还原更改",
"sit!.gui.button.save": "保存并关闭",
"sit!.gui.button.website": "网站", "sit!.gui.button.website": "网站",
"sit!.console.connected": "已连接到 Sit! 服务器: %s", "sit!.console.connected": "已连接到 Sit! 服务器: %s",
"sit!.console.player_settings": "已从 %s 获得自定义坐下设置。", "sit!.console.player_settings": "已从 %s 获得自定义坐下设置。",

View file

@ -1,4 +1,5 @@
{ {
"category.sit!": "Sit!",
"config.entry.exclusion": "在條目前方加上 `!` 以排除它!", "config.entry.exclusion": "在條目前方加上 `!` 以排除它!",
"config.entry.example": "條目範例: %s", "config.entry.example": "條目範例: %s",
"config.server": "伺服器設定", "config.server": "伺服器設定",
@ -68,8 +69,13 @@
"key.sit!.sit": "坐下", "key.sit!.sit": "坐下",
"key.sit!.config": "開啟設定", "key.sit!.config": "開啟設定",
"sit!.screen.config": "坐下! 設定", "sit!.screen.config": "坐下! 設定",
"sit!.gui.button.file": "開啟檔案",
"sit!.gui.button.folder": "開啟資料夾",
"sit!.gui.button.reset": "重置",
"sit!.gui.button.issues": "問題", "sit!.gui.button.issues": "問題",
"sit!.gui.button.donate": "贊助", "sit!.gui.button.donate": "贊助",
"sit!.gui.button.revert": "還原變更",
"sit!.gui.button.save": "儲存並關閉",
"sit!.gui.button.website": "網站", "sit!.gui.button.website": "網站",
"sit!.console.connected": "已連線至 Sit! 伺服器: %s", "sit!.console.connected": "已連線至 Sit! 伺服器: %s",
"sit!.console.player_settings": "已從 %s 收到自訂坐下設定!", "sit!.console.player_settings": "已從 %s 收到自訂坐下設定!",

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 985 B

View file

@ -2,15 +2,14 @@
"schemaVersion": 1, "schemaVersion": 1,
"id": "sit-oth3r", "id": "sit-oth3r",
"version": "${version}", "version": "${version}",
"name": "Sit! - Virt Edition", "name": "Sit!",
"description": "Adds sitting to minecraft! Endless customizability for hand restrictions and sittable blocks.\n Players can have their own sitting settings when using the Sit! client on the server!\n Contains bed cookie patch.", "description": "Adds sitting to minecraft! Endless customizability for hand restrictions and sittable blocks.\n Players can have their own sitting settings when using the Sit! client on the server!",
"authors": [ "authors": [
"Oth3r", "Oth3r"
"Virt"
], ],
"contact": { "contact": {
"homepage": "https://copeberg.org/virt/Sit", "homepage": "https://modrinth.com/mod/sit!",
"sources": "https://copeberg.org/virt/Sit" "sources": "https://github.com/Oth3r/Sit"
}, },
"license": "LGPL-3.0-only", "license": "LGPL-3.0-only",
"icon": "assets/sit-oth3r/icon.png", "icon": "assets/sit-oth3r/icon.png",
@ -29,8 +28,7 @@
"depends": { "depends": {
"fabricloader": ">=0.14.21", "fabricloader": ">=0.14.21",
"minecraft": ">=${min_minecraft_version} <=${max_minecraft_version}", "minecraft": ">=${min_minecraft_version} <=${max_minecraft_version}",
"fabric": "*", "fabric": "*"
"otterlib": ">=${otterlib_version} <${otterlib_max_version}"
}, },
"suggests": { "suggests": {
"modmenu": "*" "modmenu": "*"
@ -39,4 +37,4 @@
"mixins": [ "mixins": [
"sit!.mixins.json" "sit!.mixins.json"
] ]
} }