Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac3653dda7 | |||
| a08fd04751 | |||
| f5debe9ee1 | |||
| 1a84d2e670 | |||
| e96891275d | |||
| 9e342c6683 | |||
| 00f7f5ee2b | |||
| 77b9582c4a | |||
| 184048fd26 | |||
| 7ccca03023 | |||
| b34fa8237e | |||
| 42a4d18717 | |||
| 2d8d7f5784 | |||
| bf509bcded | |||
| ef6759a9ab | |||
| bc1483ea7a | |||
| 5768a60ba8 | |||
| 05434f422c | |||
| 21e9299352 | |||
| 83e7718346 | |||
| 5845b976c1 | |||
| 4ca94280ae | |||
| 4cc49c6d99 | |||
| 93c0258c7e | |||
| 43a5ea0385 | |||
| 678882a435 | |||
| 8e5884147f | |||
| b999cf9f5f | |||
| 847bcd54e0 | |||
| 15a55403ff | |||
| 482809df6e | |||
| 5db8ec4bd9 | |||
| d60cd46c15 | |||
| df40d4bdc9 | |||
| 0084883933 | |||
| 1d1e4ec70b | |||
| 1927a66d8e | |||
| 38442749e7 | |||
| 70dae5976d | |||
| b08756b4b3 | |||
| 5e658adad3 | |||
| 4d6e08312a | |||
| 9efe6499d0 | |||
| 319946e8c1 | |||
| 28ce6ae7b1 | |||
| af4a8a8731 | |||
| 7059c6a062 | |||
| 98a8b65665 | |||
| ac6b1e2377 | |||
| 0e964ae71c | |||
| ba6bd9f71c |
+76
-10
@@ -7,6 +7,20 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "**"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
force-release:
|
||||
description: "Force disable release if you enter 2, force release if you enter 1, default release if not released else skip release"
|
||||
required: false
|
||||
default: ""
|
||||
force-push:
|
||||
description: "Force disable push to repo if you enter 2, push to repo if you enter 1, default push if not released else skip push repo"
|
||||
required: false
|
||||
default: ""
|
||||
comments:
|
||||
description: "Add comments to release"
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
permissions: write-all
|
||||
|
||||
@@ -18,14 +32,14 @@ jobs:
|
||||
- name: Checkout Git Repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up JDK
|
||||
- name: Set Up JDK
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: zulu
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
@@ -36,33 +50,64 @@ jobs:
|
||||
- name: Apply All Patches
|
||||
run: ./gradlew --refresh-dependencies applyAllPatches
|
||||
|
||||
- name: CreateMojmapPaperclipJar
|
||||
- name: Build Paperclip Jar
|
||||
run: ./gradlew --refresh-dependencies createMojmapPaperclipJar
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: ${{ env.project_id_b }} CI Artifacts
|
||||
path: lophine-server/build/libs/*-paperclip-*-mojmap.jar
|
||||
|
||||
- name: SetENV
|
||||
- name: Set Environment
|
||||
if: github.event_name != 'pull_request'
|
||||
run: sh scripts/SetENV.sh
|
||||
|
||||
- name: Publish to repo
|
||||
if: github.event_name != 'pull_request' && env.flag_release == 'true' && false # do not push to any repo
|
||||
- name: Check If Release Exists
|
||||
if: github.event_name != 'pull_request' && env.flag_release == 'true'
|
||||
run: |
|
||||
git fetch --tags
|
||||
if [ -n "$(git tag -l "${{ env.tag }}")" ]; then
|
||||
echo "Release already exists"
|
||||
release_exists=true
|
||||
else
|
||||
echo "Release does not exist"
|
||||
release_exists=false
|
||||
fi
|
||||
if [ "$release_exists" == "true" ]; then
|
||||
counter=1
|
||||
while [ -n "$(git tag -l "${{ env.tag }}-${counter}")" ]; do
|
||||
counter=$((counter + 1))
|
||||
done
|
||||
echo "tag=${{ env.tag }}-${counter}" >> $GITHUB_ENV
|
||||
echo "release_count= - ${counter}" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "release_exists=${release_exists}" >> $GITHUB_ENV
|
||||
|
||||
- name: Publish To Repo
|
||||
if: (( github.event_name != 'pull_request' && env.flag_release == 'true' && env.release_exists != 'true' && !(inputs.force-push == '2')) || inputs.force-push == '1') && false # do not push to any repo
|
||||
continue-on-error: true
|
||||
run: ./gradlew --refresh-dependencies generateDevelopmentBundle publish -PpublishDevBundle=true
|
||||
env:
|
||||
PRIVATE_MAVEN_REPO_PASSWORD: ${{ secrets.PRIVATE_MAVEN_REPO_PASSWORD }}
|
||||
PRIVATE_MAVEN_REPO_USERNAME: ${{ secrets.PRIVATE_MAVEN_REPO_USERNAME }}
|
||||
|
||||
- name: Create Release
|
||||
if: github.event_name != 'pull_request' && env.flag_release == 'true'
|
||||
- name: Create Release - Pre Process
|
||||
if: ( github.event_name != 'pull_request' && env.flag_release == 'true' && env.release_exists != 'true' && !(inputs.force-release == '2')) || inputs.force-release == '1'
|
||||
run: |
|
||||
if [ ${{ inputs.comments }} == "" ]; then
|
||||
echo "No comments provided"
|
||||
echo "flag_comment=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "flag_comment=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Create Release - No Comment
|
||||
if: env.flag_comment == 'false'
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: ${{ env.tag }}
|
||||
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}
|
||||
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}${{ env.release_count }}
|
||||
body: |
|
||||
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [](https://github.com/LuminolMC/${{ env.project_id }}/releases/download/${{ env.tag }}/${{ env.jar }})
|
||||
This release is automatically compiled by GitHub Actions
|
||||
@@ -75,3 +120,24 @@ jobs:
|
||||
prerelease: ${{ env.pre }}
|
||||
makeLatest: ${{ env.make_latest }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create Release - With Comment
|
||||
if: env.flag_comment == 'true'
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
tag: ${{ env.tag }}
|
||||
name: ${{ env.project_id_b }} ${{ env.mcversion }} - ${{ env.commit_id }}${{ env.release_count }}
|
||||
body: |
|
||||
📦Version: `${{ env.mcversion }}` | Commit ${{ env.commit_id }} [](https://github.com/LuminolMC/${{ env.project_id }}/releases/download/${{ env.tag }}/${{ env.jar }})
|
||||
This release is automatically compiled by GitHub Actions
|
||||
### Comments
|
||||
> ${{ inputs.comments }}
|
||||
### Branch Info
|
||||
> ${{ github.ref_name }}
|
||||
### Commit Message
|
||||
${{ env.commit_msg }}
|
||||
artifacts: ${{ env.jar_dir }}
|
||||
generateReleaseNotes: true
|
||||
prerelease: ${{ env.pre }}
|
||||
makeLatest: ${{ env.make_latest }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ mcVersion=1.21.8
|
||||
release=2
|
||||
# 0 for skip release, 1 for pre-release, 2 for release
|
||||
|
||||
luminolRef=a2af823b646334cdc64abb32b859f394c55ce0cc
|
||||
luminolRef=a3c596e26bfdf197a1c0c7a536c8a2bf7f97c09d
|
||||
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.caching=true
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
// Luminol start - Dependenices insert
|
||||
implementation("com.electronwill.night-config:toml:3.8.2") // Night config
|
||||
implementation("com.github.luben:zstd-jni:1.5.4-1")
|
||||
@@ -276,14 +_,14 @@
|
||||
@@ -275,14 +_,14 @@
|
||||
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
|
||||
attributes(
|
||||
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||
@@ -70,7 +70,7 @@
|
||||
"Build-Number" to (build ?: ""),
|
||||
"Build-Time" to buildTime.toString(),
|
||||
"Git-Branch" to gitBranch,
|
||||
@@ -447,7 +_,7 @@
|
||||
@@ -446,7 +_,7 @@
|
||||
}
|
||||
|
||||
fill {
|
||||
|
||||
@@ -5,27 +5,27 @@ Subject: [PATCH] Rebrand to Lophine
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/ConfigManager.java b/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
||||
index 5e341cdc1c6ff75552140ab16bc9ccd237d896d0..a780214137d10f2faa92042b2f32c77a6598fa8d 100644
|
||||
index d8066afd5f3f2ea9a5dff87d853562e22268785c..f8b2364fa162a41304a99a4993354e33528ab801 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/ConfigManager.java
|
||||
@@ -22,6 +22,7 @@ public class ConfigManager {
|
||||
@@ -21,6 +21,7 @@ public class ConfigManager {
|
||||
|
||||
public static void initConfigs() {
|
||||
configfiles.put("luminol", ConfigsInstance.of(new File("luminol_config"), "luminol", "me.earthme.luminol.config.modules"));
|
||||
+ configfiles.put("lophine", ConfigsInstance.of(new File("lophine_config"), "lophine", "fun.bm.lophine.config.modules")); // add lophine config to global config
|
||||
configfiles.put("luminol", ConfigsInstance.of("luminol", "me.earthme.luminol.config.modules"));
|
||||
+ configfiles.put("lophine", ConfigsInstance.of("lophine", "fun.bm.lophine.config.modules")); // add lophine config to global config
|
||||
preLoad();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
index f164e41975adee8b68dbcb400007681c0b66a4f8..4e76fb3b1274f2fde734089b20458f6561c39700 100644
|
||||
index df5d926fb4401dd93d658fe14ae4d9d58cff68f9..b6d84fea596cfa78032151ab2f206b6b3d5dd197 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
|
||||
@@ -8,7 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "server_mod_name")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.MISC, name = "server_mod_name")
|
||||
public class ServerModNameConfig implements IConfigModule {
|
||||
@ConfigInfo(baseName = "name")
|
||||
@ConfigInfo(name = "name")
|
||||
- public static String serverModName = "Luminol";
|
||||
+ public static String serverModName = "Lophine";
|
||||
|
||||
@ConfigInfo(baseName = "vanilla_spoof")
|
||||
@ConfigInfo(name = "vanilla_spoof")
|
||||
public static boolean fakeVanilla = false;
|
||||
|
||||
@@ -5,26 +5,26 @@ Subject: [PATCH] Transformed Configs
|
||||
|
||||
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||
index 4e906e8e0ebd57b9f7000e4194280e3e3636e52c..14eefd162c9facd54a53718a7a0b1b0266e1ada8 100644
|
||||
index 4051384e82dba0416838c3c9889a6e368367b601..a5535b479cdcca870d0c8be6ed6fbcb32f266ac2 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
|
||||
@@ -11,6 +11,7 @@ public class CommandConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "enable", category = {"experiment", "force_the_data_command_to_be_enabled"})
|
||||
@ConfigInfo(baseName = "enable_data_command")
|
||||
@TransformedConfig(name = "enable", directory = {"experiment", "force_the_data_command_to_be_enabled"})
|
||||
@ConfigInfo(name = "enable_data_command")
|
||||
public static boolean data = false;
|
||||
+ @TransformedConfig(name = "command_block_enabled", category = {"experiment", "command"}, originInstance = "lophine")
|
||||
@TransformedConfig(name = "enabled", category = {"experiment", "force_enable_command_block_command_execution"})
|
||||
@ConfigInfo(baseName = "enable_command_block")
|
||||
public static boolean commandBlock = false;
|
||||
+ @TransformedConfig(name = "command_block_enabled", directory = {"experiment", "command"}, originInstance = "lophine")
|
||||
@TransformedConfig(name = "enabled", directory = {"experiment", "force_enable_command_block_command_execution"})
|
||||
@ConfigInfo(name = "enable_command_block", comments = """
|
||||
Force to enable command blocks.
|
||||
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||
index 192a67360db810934d02a15c955af3579e6f6b20..fbafc5a8aa2581301e62e12adb22169ab7fd8e19 100644
|
||||
index 35e6014f04093050a9a62b895b43e5c5d8c6a28e..11abfb884f972fd73ca4c13a6e309de1bcd23fd5 100644
|
||||
--- a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
|
||||
@@ -8,6 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.OPTIMIZATIONS, mainName = "force_disable_packet_limiter_of_paper")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.OPTIMIZATIONS, name = "force_disable_packet_limiter_of_paper")
|
||||
public class PaperPacketLimiterConfig implements IConfigModule {
|
||||
+ @TransformedConfig(name = "unlimit-packet", category = {"misc", "network"}, originInstance = "lophine")
|
||||
@TransformedConfig(name = "force_disable", category = {"misc", "force_disable_packet_limiter_of_paper"})
|
||||
@ConfigInfo(baseName = "force_disable")
|
||||
+ @TransformedConfig(name = "unlimit-packet", directory = {"misc", "network"}, originInstance = "lophine")
|
||||
@TransformedConfig(name = "force_disable", directory = {"misc", "force_disable_packet_limiter_of_paper"})
|
||||
@ConfigInfo(name = "force_disable")
|
||||
public static boolean forceDisable = false;
|
||||
|
||||
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/d93e9766d3797d130
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
||||
index 102de78be0eb82d6898b4104fad1bf5e8366f993..0f8c9d4932c8bbd619f21d4aa28b890e14439b46 100644
|
||||
index 3a6314ed7f62c6473ce9ddc9deeee2a32b9d2893..23a0f8100eb3162331161635e8051981c4e34aed 100644
|
||||
--- a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
||||
+++ b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
|
||||
@@ -17,12 +17,173 @@
|
||||
@@ -185,4 +185,3 @@ index 102de78be0eb82d6898b4104fad1bf5e8366f993..0f8c9d4932c8bbd619f21d4aa28b890e
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
\ No newline at end of file
|
||||
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 7 Jul 2025 16:30:54 +0800
|
||||
Subject: [PATCH] Add config to allow infinite trade
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
|
||||
index 79242037e868a140513f032e74e8594c0c6ff41c..050e89c3e95c7c3ef7ad98f8ef03ab206241a7e2 100644
|
||||
--- a/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -490,8 +490,15 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
}
|
||||
|
||||
private void resendOffersToTradingPlayer() {
|
||||
- MerchantOffers offers = this.getOffers();
|
||||
+ // Lophine start - infinite trade
|
||||
+ MerchantOffers offers = this.getOffers().copy();
|
||||
Player tradingPlayer = this.getTradingPlayer();
|
||||
+ if (fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade) {
|
||||
+ for (MerchantOffer merchantOffer : offers) {
|
||||
+ merchantOffer.maxUses = 524288;
|
||||
+ }
|
||||
+ }
|
||||
+ // Lophine end - infinite trade
|
||||
if (tradingPlayer != null && !offers.isEmpty()) {
|
||||
tradingPlayer.sendMerchantOffers(
|
||||
tradingPlayer.containerMenu.containerId,
|
||||
diff --git a/net/minecraft/world/item/trading/Merchant.java b/net/minecraft/world/item/trading/Merchant.java
|
||||
index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..0c7318a0ed214204f5493576c8a7b02fbe51c00b 100644
|
||||
--- a/net/minecraft/world/item/trading/Merchant.java
|
||||
+++ b/net/minecraft/world/item/trading/Merchant.java
|
||||
@@ -42,7 +42,14 @@ public interface Merchant {
|
||||
new SimpleMenuProvider((containerId, inventory, player1) -> new MerchantMenu(containerId, inventory, this), displayName)
|
||||
);
|
||||
if (optionalInt.isPresent()) {
|
||||
- MerchantOffers offers = this.getOffers();
|
||||
+ // Lophine start - infinite trade
|
||||
+ MerchantOffers offers = this.getOffers().copy();
|
||||
+ if (fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade) {
|
||||
+ for (MerchantOffer merchantOffer : offers) {
|
||||
+ merchantOffer.maxUses = 5242884;
|
||||
+ }
|
||||
+ }
|
||||
+ // Lophine end - infinite trade
|
||||
if (!offers.isEmpty()) {
|
||||
player.sendMerchantOffers(optionalInt.getAsInt(), offers, level, this.getVillagerXp(), this.showProgressBar(), this.canRestock());
|
||||
}
|
||||
diff --git a/net/minecraft/world/item/trading/MerchantOffer.java b/net/minecraft/world/item/trading/MerchantOffer.java
|
||||
index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..770f37d7158c7b4cec62783025f623a68c1f2457 100644
|
||||
--- a/net/minecraft/world/item/trading/MerchantOffer.java
|
||||
+++ b/net/minecraft/world/item/trading/MerchantOffer.java
|
||||
@@ -196,7 +196,7 @@ public class MerchantOffer {
|
||||
}
|
||||
|
||||
public boolean isOutOfStock() {
|
||||
- return this.uses >= this.maxUses;
|
||||
+ return (this.uses >= this.maxUses && !fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade); // Lophine - infinite trade
|
||||
}
|
||||
|
||||
public void setToOutOfStock() {
|
||||
+1
-1
@@ -48,7 +48,7 @@ index 11e6197dec541b28733715f0d7eaa4c7b834d632..de1263404395c28209234a556347284f
|
||||
AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0);
|
||||
this.level()
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 567d63ae589705e13403814b36e35d00c241a69e..3f4b1c54f9207ba1854a8c8da965cbaca5ea517d 100644
|
||||
index 0c6d48363cd65cd22b4cc0ab97be977e133b64be..e94687b3aa960f9c630f459fedc17bc01846eaf7 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1948,6 +1948,13 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
+2
-2
@@ -18,7 +18,7 @@ index 6868b915bf3deb85783a638d4441a15fea6da2dc..70740381c6501c1a518c52b24381edd1
|
||||
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
|
||||
if (rangeY != -1) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 8ec753fe9c84ffe1188f7e7ebb6895cf4bba9e39..ee4a459700d75676eae3422d4a0e10be73c45871 100644
|
||||
index f5539ca5964abb18124522a8aa7ce940517b2011..1258591aae1b926ee8085b1984d553b8d3a1df7e 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -147,7 +147,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
|
||||
@@ -30,7 +30,7 @@ index 8ec753fe9c84ffe1188f7e7ebb6895cf4bba9e39..ee4a459700d75676eae3422d4a0e10be
|
||||
// CraftBukkit start
|
||||
private static final int CURRENT_LEVEL = 2;
|
||||
public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first snapTo
|
||||
@@ -6472,4 +6472,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -6482,4 +6482,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
// Paper end - Expose entity id counter
|
||||
|
||||
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
|
||||
+2
-2
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config to enable function command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index af895859057ca303177ec3c8a07cf7534e62cca6..e0e9fcf3224f55f2ef31c8afca3154a5992f761b 100644
|
||||
index 11697e65a7f7871920ca7bad37de07f78a3da1f8..25ccbfa12d57d540195ecc16aa54a144f8ecc0e8 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -206,7 +206,9 @@ public class Commands {
|
||||
@@ -204,7 +204,9 @@ public class Commands {
|
||||
FillCommand.register(this.dispatcher, context);
|
||||
FillBiomeCommand.register(this.dispatcher, context);
|
||||
ForceLoadCommand.register(this.dispatcher);
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 2 Jul 2025 23:36:25 +0800
|
||||
Subject: [PATCH] Add config to enable datapack command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index e05f75b6bbd48d6fb7379926d68d5f8ed6014be9..af895859057ca303177ec3c8a07cf7534e62cca6 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -192,7 +192,9 @@ public class Commands {
|
||||
if(me.earthme.luminol.config.modules.experiment.CommandConfig.data) {
|
||||
DataCommands.register(this.dispatcher); // Folia - region threading - TODO
|
||||
}
|
||||
- //DataPackCommand.register(this.dispatcher, context); // Folia - region threading - TODO
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.datapack) {
|
||||
+ DataPackCommand.register(this.dispatcher, context); // Folia - region threading - TODO
|
||||
+ }
|
||||
//DebugCommand.register(this.dispatcher); // Folia - region threading - TODO
|
||||
DefaultGameModeCommands.register(this.dispatcher);
|
||||
//DialogCommand.register(this.dispatcher, context); // Folia - region threading - TODO
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 75027e73859c955a54034640f905cb5d91a6a2f4..b4b3ff86f7c4afb94fc4da5133746391a078a7fb 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2353,6 +2353,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
}
|
||||
|
||||
+ // Lophine start - region thread skip reload // TODO - add reload support
|
||||
+ public void saveDatapacks(Collection<String> selectedIds) {
|
||||
+ this.packRepository.setSelected(selectedIds, false); // Paper - add pendingReload flag to determine required pack loading - false as this is *after* a reload (see above)
|
||||
+ WorldDataConfiguration worldDataConfiguration = new WorldDataConfiguration(
|
||||
+ getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()
|
||||
+ );
|
||||
+ this.worldData.setDataConfiguration(worldDataConfiguration);
|
||||
+ }
|
||||
+ // Lophine end - region thread skip reload // TODO - add reload support
|
||||
+
|
||||
public CompletableFuture<Void> reloadResources(Collection<String> selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause cause) {
|
||||
// Paper end - Add ServerResourcesReloadedEvent
|
||||
CompletableFuture<Void> completableFuture = CompletableFuture.<ImmutableList>supplyAsync(
|
||||
diff --git a/net/minecraft/server/commands/ReloadCommand.java b/net/minecraft/server/commands/ReloadCommand.java
|
||||
index b540a3c3a02f7242578a63477e34b9063e86f1d2..9f0adf157872e1c68cd7752a24eacdc636e8d17a 100644
|
||||
--- a/net/minecraft/server/commands/ReloadCommand.java
|
||||
+++ b/net/minecraft/server/commands/ReloadCommand.java
|
||||
@@ -16,6 +16,12 @@ public class ReloadCommand {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static void reloadPacks(Collection<String> selectedIds, CommandSourceStack source) {
|
||||
+ // Lophine start - region thread skip reload // TODO - add reload support
|
||||
+ if (true) {
|
||||
+ source.getServer().saveDatapacks(selectedIds);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Lophine end - region thread skip reload // TODO - add reload support
|
||||
source.getServer().reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.COMMAND).exceptionally(throwable -> { // Paper - Add ServerResourcesReloadedEvent
|
||||
LOGGER.warn("Failed to execute reload", throwable);
|
||||
source.sendFailure(Component.translatable("commands.reload.failure"));
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 29 Sep 2025 22:56:03 +0800
|
||||
Subject: [PATCH] Add config to enable scoreboard command
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index 25ccbfa12d57d540195ecc16aa54a144f8ecc0e8..22d211bee83e3ef34d6ac81dd89c0e73924bee90 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -229,7 +229,11 @@ public class Commands {
|
||||
//RotateCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
SayCommand.register(this.dispatcher);
|
||||
//ScheduleCommand.register(this.dispatcher); // Folia - region threading
|
||||
- //ScoreboardCommand.register(this.dispatcher, context); // Folia - region threading
|
||||
+ // Lophine start - Add a config to enable scoreboard command
|
||||
+ if (fun.bm.lophine.config.modules.experiment.CommandConfig.scoreboard) {
|
||||
+ ScoreboardCommand.register(this.dispatcher, context); // Folia - region threading
|
||||
+ }
|
||||
+ // Lophine start - Add a config to enable scoreboard command
|
||||
SeedCommand.register(this.dispatcher, selection != Commands.CommandSelection.INTEGRATED);
|
||||
VersionCommand.register(this.dispatcher, selection != Commands.CommandSelection.INTEGRATED);
|
||||
SetBlockCommand.register(this.dispatcher, context);
|
||||
+3
-3
@@ -97,10 +97,10 @@ index c485d5b3ba95f2a969bdf0dab9654ac284976f8d..b957585cf7cf7f845e20f59c7b355722
|
||||
this.scheduler.regionFailed(this, false, thr);
|
||||
// regionFailed will schedule a shutdown, so we should avoid letting this region tick further
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index e0e9fcf3224f55f2ef31c8afca3154a5992f761b..a5b59eb79c014ef7a48ff305ed554fc33a184d87 100644
|
||||
index 22d211bee83e3ef34d6ac81dd89c0e73924bee90..1fb359073342a657e9e493403263b56be5b3393f 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -247,7 +247,11 @@ public class Commands {
|
||||
@@ -249,7 +249,11 @@ public class Commands {
|
||||
TeleportCommand.register(this.dispatcher);
|
||||
TellRawCommand.register(this.dispatcher, context);
|
||||
//TestCommand.register(this.dispatcher, context); // Folia - region threading
|
||||
@@ -114,7 +114,7 @@ index e0e9fcf3224f55f2ef31c8afca3154a5992f761b..a5b59eb79c014ef7a48ff305ed554fc3
|
||||
TitleCommand.register(this.dispatcher, context);
|
||||
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index d08a5b553f4e5932d960fbcdeb6a43419730e32a..a0f1db50adf5163a671d3d9e9df7adb7de4250c6 100644
|
||||
index 75027e73859c955a54034640f905cb5d91a6a2f4..2f4970242c754cfba8ff5656a63af07d9d0a723c 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -267,7 +267,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
+2
-2
@@ -5,10 +5,10 @@ Subject: [PATCH] Add config to enable waypoint command & bar
|
||||
|
||||
|
||||
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
|
||||
index a5b59eb79c014ef7a48ff305ed554fc33a184d87..e8c7cc10f10fc013100fa66f3489ac98b3a29227 100644
|
||||
index 1fb359073342a657e9e493403263b56be5b3393f..451a685782da46f5683ea6707289bbaf3193771f 100644
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -255,7 +255,11 @@ public class Commands {
|
||||
@@ -257,7 +257,11 @@ public class Commands {
|
||||
TimeCommand.register(this.dispatcher);
|
||||
TitleCommand.register(this.dispatcher, context);
|
||||
//TriggerCommand.register(this.dispatcher); // Folia - region threading - TODO later
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 2 Jul 2025 23:36:25 +0800
|
||||
Subject: [PATCH] Fix datapack command save function
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 2f4970242c754cfba8ff5656a63af07d9d0a723c..b156b5c635f931a3d4abc0584591f90476d011a6 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2353,6 +2353,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return this.reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.PLUGIN);
|
||||
}
|
||||
|
||||
+ // Lophine start - region thread skip reload // TODO - add reload support
|
||||
+ public void saveDatapacks(Collection<String> selectedIds) {
|
||||
+ this.packRepository.setSelected(selectedIds, false); // Paper - add pendingReload flag to determine required pack loading - false as this is *after* a reload (see above)
|
||||
+ WorldDataConfiguration worldDataConfiguration = new WorldDataConfiguration(
|
||||
+ getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()
|
||||
+ );
|
||||
+ this.worldData.setDataConfiguration(worldDataConfiguration);
|
||||
+ }
|
||||
+ // Lophine end - region thread skip reload // TODO - add reload support
|
||||
+
|
||||
public CompletableFuture<Void> reloadResources(Collection<String> selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause cause) {
|
||||
// Paper end - Add ServerResourcesReloadedEvent
|
||||
CompletableFuture<Void> completableFuture = CompletableFuture.<ImmutableList>supplyAsync(
|
||||
diff --git a/net/minecraft/server/commands/DataPackCommand.java b/net/minecraft/server/commands/DataPackCommand.java
|
||||
index a5032b34752061d61fd9ddb4db828d35e403f5e7..3eaa9c85d06f6ecc8ed639d8befa861439390eb7 100644
|
||||
--- a/net/minecraft/server/commands/DataPackCommand.java
|
||||
+++ b/net/minecraft/server/commands/DataPackCommand.java
|
||||
@@ -98,7 +98,7 @@ public class DataPackCommand {
|
||||
dispatcher.register(
|
||||
Commands.literal("datapack")
|
||||
.requires(Commands.hasPermission(2))
|
||||
- /*.then( // Luminol - Add back read-only datapack command
|
||||
+ .then(
|
||||
Commands.literal("enable")
|
||||
.then(
|
||||
Commands.argument("name", StringArgumentType.string())
|
||||
@@ -160,11 +160,11 @@ public class DataPackCommand {
|
||||
.suggests(SELECTED_PACKS)
|
||||
.executes(commandContext -> disablePack(commandContext.getSource(), getPack(commandContext, "name", false)))
|
||||
)
|
||||
- )*/ // Luminol - Add back read-only datapack command
|
||||
+ )
|
||||
.then(
|
||||
Commands.literal("list")
|
||||
.executes(commandContext -> listPacks(commandContext.getSource()))
|
||||
- // .then(Commands.literal("available").executes(commandContext -> listAvailablePacks(commandContext.getSource()))) // Luminol - Add back read-only datapack command
|
||||
+ .then(Commands.literal("available").executes(commandContext -> listAvailablePacks(commandContext.getSource())))
|
||||
.then(Commands.literal("enabled").executes(commandContext -> listEnabledPacks(commandContext.getSource())))
|
||||
)
|
||||
.then(
|
||||
@@ -252,7 +252,7 @@ public class DataPackCommand {
|
||||
}
|
||||
|
||||
private static int listPacks(CommandSourceStack source) {
|
||||
- return listEnabledPacks(source) ;// + listAvailablePacks(source); // Luminol - Add back read-only datapack command
|
||||
+ return listEnabledPacks(source) + listAvailablePacks(source);
|
||||
}
|
||||
|
||||
private static int listAvailablePacks(CommandSourceStack source) {
|
||||
@@ -280,7 +280,7 @@ public class DataPackCommand {
|
||||
|
||||
private static int listEnabledPacks(CommandSourceStack source) {
|
||||
PackRepository packRepository = source.getServer().getPackRepository();
|
||||
- // packRepository.reload(); // Luminol - Add back read-only datapack command
|
||||
+ packRepository.reload();
|
||||
Collection<? extends Pack> selectedPacks = packRepository.getSelectedPacks();
|
||||
if (selectedPacks.isEmpty()) {
|
||||
source.sendSuccess(() -> Component.translatable("commands.datapack.list.enabled.none"), false);
|
||||
diff --git a/net/minecraft/server/commands/ReloadCommand.java b/net/minecraft/server/commands/ReloadCommand.java
|
||||
index b540a3c3a02f7242578a63477e34b9063e86f1d2..bc999de32931558d0d8dc26264653dd63c1cad19 100644
|
||||
--- a/net/minecraft/server/commands/ReloadCommand.java
|
||||
+++ b/net/minecraft/server/commands/ReloadCommand.java
|
||||
@@ -16,11 +16,17 @@ public class ReloadCommand {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static void reloadPacks(Collection<String> selectedIds, CommandSourceStack source) {
|
||||
+ // Lophine start - region thread skip reload // TODO - add reload support
|
||||
+ source.getServer().saveDatapacks(selectedIds);
|
||||
+ source.getSender().sendMessage("You need to restart server to load datapacks update.");
|
||||
+ if (false) {
|
||||
source.getServer().reloadResources(selectedIds, io.papermc.paper.event.server.ServerResourcesReloadedEvent.Cause.COMMAND).exceptionally(throwable -> { // Paper - Add ServerResourcesReloadedEvent
|
||||
LOGGER.warn("Failed to execute reload", throwable);
|
||||
source.sendFailure(Component.translatable("commands.reload.failure"));
|
||||
return null;
|
||||
});
|
||||
+ }
|
||||
+ // Lophine end - region thread skip reload // TODO - add reload support
|
||||
}
|
||||
|
||||
private static Collection<String> discoverNewPacks(PackRepository packRepository, WorldData worldData, Collection<String> selectedIds) {
|
||||
@@ -8,27 +8,18 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc1
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/io/papermc/paper/threadedregions/RegionizedServer.java b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
index 8405157ec35a443e238fa6866772c839621d73d7..4edb6e6e6287f232f7eef45c747554264ec05319 100644
|
||||
index 8405157ec35a443e238fa6866772c839621d73d7..67f3454e6479abb241a7d94699d4f7bec22da56b 100644
|
||||
--- a/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
+++ b/io/papermc/paper/threadedregions/RegionizedServer.java
|
||||
@@ -334,6 +334,8 @@ public final class RegionizedServer {
|
||||
}
|
||||
// Luminol end - Add a config to enable tick command
|
||||
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleTick(tickCount); // Leaves - protocol
|
||||
+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleTick(); // Leaves - protocol
|
||||
+
|
||||
// tick connections
|
||||
this.tickConnections();
|
||||
|
||||
@@ -443,6 +445,8 @@ public final class RegionizedServer {
|
||||
|
||||
world.updateTickData();
|
||||
|
||||
+ MinecraftServer.getServer().handleTickCount(tickCount); // Lophine - reuse tick count
|
||||
+
|
||||
world.moonrise$getChunkTaskScheduler().chunkHolderManager.processTicketUpdates(); // required to eventually process ticket updates
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java b/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
|
||||
index fb263fa1f30a7dfcb7ec2656abfb38e5fe88eac9..56fd1ed7ccaf96e7eedea60fbdbf7f934939d563 100644
|
||||
--- a/net/minecraft/network/protocol/common/custom/CustomPacketPayload.java
|
||||
@@ -57,36 +48,6 @@ index fb263fa1f30a7dfcb7ec2656abfb38e5fe88eac9..56fd1ed7ccaf96e7eedea60fbdbf7f93
|
||||
}
|
||||
};
|
||||
}
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index b156b5c635f931a3d4abc0584591f90476d011a6..0b7c014114f1f8648824fe7c9b75fde3ea79162a 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -305,6 +305,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
// Folia start - regionised ticking
|
||||
public final io.papermc.paper.threadedregions.RegionizedServer regionizedServer = new io.papermc.paper.threadedregions.RegionizedServer();
|
||||
+ private int tickCount;
|
||||
|
||||
@Override
|
||||
public <V> CompletableFuture<V> submit(java.util.function.Supplier<V> task) {
|
||||
@@ -2227,9 +2228,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return false;
|
||||
}
|
||||
|
||||
+ // Lophine start - reuse tick count
|
||||
public int getTickCount() {
|
||||
- throw new UnsupportedOperationException(); // Folia - region threading
|
||||
+ if (false) throw new UnsupportedOperationException(); // Folia - region threading
|
||||
+ return this.tickCount;
|
||||
+ }
|
||||
+
|
||||
+ public void handleTickCount(int tickCount1) {
|
||||
+ tickCount = tickCount1;
|
||||
}
|
||||
+ // Lophine end - reuse tick count
|
||||
|
||||
public int getSpawnProtectionRadius() {
|
||||
return 16;
|
||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
index 8150b16c196edcb226be9268ea6e0012e44517fa..c54bf0429c0ca3a35a730658c7b1b3ddc776bf9e 100644
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Wed, 29 Oct 2025 00:09:09 +0800
|
||||
Subject: [PATCH] Leaves: Configurable trading with the void
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 985ddea9d74a37f58f32a27375f6f7e6af0f2192..9796c449f924b8fd9c0dd6bb02cf196641e495ed 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2901,7 +2901,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// Spigot start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
|
||||
// Paper start - Fix merchant inventory not closing on entity removal
|
||||
- if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
|
||||
+ if (!fun.bm.lophine.config.modules.function.OldFeatureConfig.villagerVoidTrade && entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { // Leaves - Configurable trading with the void
|
||||
merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
|
||||
}
|
||||
// Paper end - Fix merchant inventory not closing on entity removal
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 593dbcda4b497291eb1ecdc64b947a8d279f8be6..6c1f4f943a5be5f2e43a82cca52ca76a98226915 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -649,7 +649,7 @@ public abstract class PlayerList {
|
||||
player.stopRiding();
|
||||
rootVehicle.getPassengersAndSelf().forEach(entity -> {
|
||||
// Paper start - Fix villager boat exploit
|
||||
- if (entity instanceof net.minecraft.world.entity.npc.AbstractVillager villager) {
|
||||
+ if (!fun.bm.lophine.config.modules.function.OldFeatureConfig.villagerVoidTrade && entity instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { // Leaves - Configurable trading with the void
|
||||
final net.minecraft.world.entity.player.Player human = villager.getTradingPlayer();
|
||||
if (human != null) {
|
||||
villager.setTradingPlayer(null);
|
||||
diff --git a/net/minecraft/world/inventory/MerchantMenu.java b/net/minecraft/world/inventory/MerchantMenu.java
|
||||
index d59f67ffe34201c63e3d9706a4434f33b6732edb..c635c7211bff9d190b7035b284dda162334fd5c2 100644
|
||||
--- a/net/minecraft/world/inventory/MerchantMenu.java
|
||||
+++ b/net/minecraft/world/inventory/MerchantMenu.java
|
||||
@@ -74,6 +74,7 @@ public class MerchantMenu extends AbstractContainerMenu {
|
||||
|
||||
@Override
|
||||
public boolean stillValid(Player player) {
|
||||
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.villagerVoidTrade) return this.trader.getTradingPlayer() == player; // Leaves - Configurable trading with the void
|
||||
if (!checkReachable) return true; // Paper - checkReachable
|
||||
return this.trader.stillValid(player);
|
||||
}
|
||||
+3
-3
@@ -446,10 +446,10 @@ index 10b2cc20bbf3b70e4e09dbbe14b90506e6366158..1535bb8cec8692e8d26eaff090288f1b
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index 4b634dbb45dfb0823e7b21cf2354f89e5a6331e9..ef32bf1351aa28953bfc625d7a7d5175181a7acc 100644
|
||||
index 699bb3cc2b680a4ee438a88c05854e5ab05ea910..d4fe03fd766caca1d7693a5317460ca1a9b9fa4f 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -145,7 +145,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -148,7 +148,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
public void setItem(int index, ItemStack stack) {
|
||||
this.unpackLootTable(null);
|
||||
this.getItems().set(index, stack);
|
||||
@@ -458,7 +458,7 @@ index 4b634dbb45dfb0823e7b21cf2354f89e5a6331e9..ef32bf1351aa28953bfc625d7a7d5175
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -770,9 +770,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
@@ -743,9 +743,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
if (item.isEmpty()) {
|
||||
// Spigot start - SPIGOT-6693, SimpleContainer#setItem
|
||||
ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
|
||||
-19
@@ -7,25 +7,6 @@ Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49060f07e1ab31c827326c9a5/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
|
||||
index 6db566adf2d0df1d26221eda04aa01738df6d3d2..24ebfdf98e343a7892af621d032c35819156deec 100644
|
||||
--- a/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/net/minecraft/world/item/BlockItem.java
|
||||
@@ -56,6 +56,14 @@ public class BlockItem extends Item {
|
||||
if (blockPlaceContext == null) {
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
+ // Leaves start - shears wrench
|
||||
+ if (org.leavesmc.leaves.util.ShearsWrenchUtil.shouldSkipPlace(context)) {
|
||||
+ if (context.getPlayer() != null) {
|
||||
+ context.getPlayer().containerMenu.forceHeldSlot(blockPlaceContext.getHand());
|
||||
+ }
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ // Leaves end - shears wrench
|
||||
BlockState placementState = this.getPlacementState(blockPlaceContext);
|
||||
// CraftBukkit start - special case for handling block placement with water lilies and snow buckets
|
||||
org.bukkit.block.BlockState bukkitState = null;
|
||||
diff --git a/net/minecraft/world/item/ShearsItem.java b/net/minecraft/world/item/ShearsItem.java
|
||||
index 8cf3e51e12f9cf98836657e722edb23943f9e866..5fd5e9fd4e1a79dd1a9d62a5cf0c308805979420 100644
|
||||
--- a/net/minecraft/world/item/ShearsItem.java
|
||||
+1
-1
@@ -6,7 +6,7 @@ Subject: [PATCH] Compatibility fix for Raid Revert and Cross Region Damage
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
|
||||
index 3f4b1c54f9207ba1854a8c8da965cbaca5ea517d..a8348a073682eec31990e9ab963b11ad32cf8bf8 100644
|
||||
index e94687b3aa960f9c630f459fedc17bc01846eaf7..f4f4f886b6558d39d292a45665953f497f84be53 100644
|
||||
--- a/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1216,6 +1216,29 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
||||
+10
-2
@@ -5,10 +5,18 @@ Subject: [PATCH] I18n support
|
||||
|
||||
|
||||
diff --git a/net/minecraft/locale/Language.java b/net/minecraft/locale/Language.java
|
||||
index 7b9e2a1a208b46a69c16e6afd8b502259893574f..db46a31ea8a36562e548eb07f0c4cf9b9e8c3360 100644
|
||||
index 7b9e2a1a208b46a69c16e6afd8b502259893574f..c300ae4363298fecef8fa9bf739f01c0a11e145f 100644
|
||||
--- a/net/minecraft/locale/Language.java
|
||||
+++ b/net/minecraft/locale/Language.java
|
||||
@@ -65,7 +65,7 @@ public abstract class Language {
|
||||
@@ -36,6 +36,7 @@ public abstract class Language {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
BiConsumer<String, String> biConsumer = map::put;
|
||||
parseTranslations(biConsumer, "/assets/minecraft/lang/en_us.json");
|
||||
+ fun.bm.lophine.utils.ServerI18nUtil.loadLophineI18nDefault(biConsumer);
|
||||
deprecatedTranslationsInfo.applyToMap(map);
|
||||
final Map<String, String> map1 = Map.copyOf(map);
|
||||
return new Language() {
|
||||
@@ -65,7 +66,7 @@ public abstract class Language {
|
||||
};
|
||||
}
|
||||
|
||||
+19
-15
@@ -1,7 +1,7 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bacteriawa <A3167717663@hotmail.com>
|
||||
Date: Sat, 30 Aug 2025 17:16:32 +0800
|
||||
Subject: [PATCH] Leaves: Leaves Fakeplayer
|
||||
Subject: [PATCH] Leaves: Fakeplayer
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
@@ -33,10 +33,10 @@ index 66ec0424a46dcd49cf44467357d80b1a2d84d3b2..04ae8de63af0a8abe578f14c8ef85fd4
|
||||
private DisconnectionDetails disconnectionDetails;
|
||||
private boolean encrypted;
|
||||
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
||||
index 0b7c014114f1f8648824fe7c9b75fde3ea79162a..384b121df8bfc72b21b607e8fa4ae90efcc6f3e8 100644
|
||||
index b156b5c635f931a3d4abc0584591f90476d011a6..81726e5782d25ff35a2bea8820a62786e46148b1 100644
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -348,6 +348,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -347,6 +347,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
// Folia end - regionised ticking
|
||||
|
||||
@@ -45,15 +45,19 @@ index 0b7c014114f1f8648824fe7c9b75fde3ea79162a..384b121df8bfc72b21b607e8fa4ae90e
|
||||
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
|
||||
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
|
||||
AtomicReference<S> atomicReference = new AtomicReference<>();
|
||||
@@ -1039,6 +1041,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1038,6 +1040,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Folia end - region threading
|
||||
|
||||
public void stopServer() {
|
||||
+ this.getBotList().removeAll(); // Leaves - save or remove bot
|
||||
+ // Leaves end - save or remove bot
|
||||
+ if (!this.getBotList().forceShutdown && !this.getBotList().removeAll()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - save or remove bot
|
||||
// Folia start - region threading
|
||||
// halt scheduler
|
||||
// don't wait, we may be on a scheduler thread
|
||||
@@ -1589,7 +1592,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1588,7 +1595,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
int i = this.pauseWhileEmptySeconds() * 20;
|
||||
this.removeDisabledPluginsBlockingSleep(); // Paper - API to allow/disallow tick sleeping
|
||||
if (false && i > 0) { // Folia - region threading - this is complicated to implement, and even if done correctly is messy
|
||||
@@ -62,7 +66,7 @@ index 0b7c014114f1f8648824fe7c9b75fde3ea79162a..384b121df8bfc72b21b607e8fa4ae90e
|
||||
this.emptyTicks++;
|
||||
} else {
|
||||
this.emptyTicks = 0;
|
||||
@@ -1913,6 +1916,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1912,6 +1919,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
public void tickConnection() {
|
||||
this.getConnection().tick();
|
||||
@@ -70,7 +74,7 @@ index 0b7c014114f1f8648824fe7c9b75fde3ea79162a..384b121df8bfc72b21b607e8fa4ae90e
|
||||
}
|
||||
|
||||
private void synchronizeTime(ServerLevel level) {
|
||||
@@ -2991,6 +2995,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -2983,6 +2991,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -215,7 +219,7 @@ index f2286b96b8f40b4588f817913c42ae7b4a92340f..e6c7bbb023000b9de90c1256274ff5ab
|
||||
playerList.op(gameProfile);
|
||||
i++;
|
||||
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 79c911003c7b1c3d94e7e9d3974eeadcc16bde3a..328428f0ef8a2305f661c167e6fe1f604b0d6890 100644
|
||||
index 0e278f7b9ed85ce8c3cedd9154f817b30ff1e48a..09d4b1d68c3f046ef304016a1afe7a3038dfae3e 100644
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -162,6 +162,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
@@ -262,7 +266,7 @@ index 70740381c6501c1a518c52b24381edd16792507f..5e31b499a894113b4be1982a1071348f
|
||||
}
|
||||
}
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 576dde41a4b48aac9079cca902f4371a31470af3..952b92c55d7192791a19ecebe80894f6cf992049 100644
|
||||
index 4f1976c47a087bf4f36687124ef29ca7b664f682..96aafe4d63446b3d212f21f14091858f72bb081f 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -207,6 +207,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -294,7 +298,7 @@ index 576dde41a4b48aac9079cca902f4371a31470af3..952b92c55d7192791a19ecebe80894f6
|
||||
@Override
|
||||
public void updatePOIOnBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) {
|
||||
Optional<Holder<PoiType>> optional = PoiTypes.forState(oldState);
|
||||
@@ -2826,6 +2834,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2827,6 +2835,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
// ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.add(serverPlayer);
|
||||
@@ -306,7 +310,7 @@ index 576dde41a4b48aac9079cca902f4371a31470af3..952b92c55d7192791a19ecebe80894f6
|
||||
if (serverPlayer.isReceivingWaypoints()) {
|
||||
ServerLevel.this.getWaypointManager().addPlayer(serverPlayer);
|
||||
}
|
||||
@@ -2913,6 +2926,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
@@ -2914,6 +2927,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
ServerLevel.this.getChunkSource().removeEntity(entity);
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
ServerLevel.this.players.remove(serverPlayer);
|
||||
@@ -430,7 +434,7 @@ index 144a2644c15f276f02bb3be859dc5d05a677ac55..c6a89e8936cffa49b3de153ed3c40e3c
|
||||
boolean stateLocked = true; try { this.stateLock.lock(); // Paper - Fix GameProfileCache concurrency
|
||||
GameProfileCache.GameProfileInfo gameProfileInfo = this.profilesByName.get(string);
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index cb863a36fc67e993956ec3be655e6e4b9764c051..908ec29a6e285122d1a8a43dc547b74af2697442 100644
|
||||
index 8e2775e873c92beed6a0e4e8ce1304ab8ca6e8d1..580f114fd99b017403c61e994d0c947d00e5115d 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -425,6 +425,19 @@ public abstract class PlayerList {
|
||||
@@ -441,7 +445,7 @@ index cb863a36fc67e993956ec3be655e6e4b9764c051..908ec29a6e285122d1a8a43dc547b74a
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable) {
|
||||
+ org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName());
|
||||
+ if (bot != null) {
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false);
|
||||
+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false, true);
|
||||
+ }
|
||||
+ this.server.getBotList().bots.forEach(bot1 -> {
|
||||
+ bot1.sendPlayerInfo(player);
|
||||
@@ -544,7 +548,7 @@ index 52fd730998535ea071bfc99b7cc2c254b9b656d7..0abf6f0265fcb916f2c2c76fb1313bd1
|
||||
|
||||
for (WaypointTransmitter waypointTransmitter : this.waypoints) {
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index bfd29fc6a5af3cd28a462ce97bbc04634402b74c..319789f635b8b6bba2e8843c7fb38ef1fdf51677 100644
|
||||
index 1258591aae1b926ee8085b1984d553b8d3a1df7e..365cb2aed3d0f428ba33d4debdf3c3a3c494882d 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -1225,7 +1225,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
@@ -0,0 +1,20 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Fri, 3 Oct 2025 19:43:36 +0800
|
||||
Subject: [PATCH] Modify merge ItemEntity logic
|
||||
|
||||
Add followTickSequenceMerge to modify merge items, due to Paper's modification of the merge radius, when the merge radius is large and stacks containing many items get stuck in an unexpected position, individual items may never reach their destination. This configuration option is added to fix this behavior.
|
||||
|
||||
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index e5e8c752129a6ebb0dd1315c9b8ec459be11ef07..dfd202a74ec7f2cdb9cdc208a6428090a110f811 100644
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -295,7 +295,7 @@ public class ItemEntity extends Entity implements TraceableEntity, ChangePublish
|
||||
ItemStack item = this.getItem();
|
||||
ItemStack item1 = itemEntity.getItem();
|
||||
if (Objects.equals(this.target, itemEntity.target) && areMergable(item, item1)) {
|
||||
- if (item1.getCount() < item.getCount()) {
|
||||
+ if (fun.bm.lophine.config.modules.misc.ItemEntityConfig.followTickSequenceMerge || item1.getCount() < item.getCount()) { // Lophine - add follow Tick Sequence Merge, see Paper#13073
|
||||
merge(this, item, itemEntity, item1);
|
||||
} else {
|
||||
merge(itemEntity, item1, this, item);
|
||||
@@ -0,0 +1,27 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Mon, 3 Feb 2025 16:51:01 +0800
|
||||
Subject: [PATCH] Leaves: Syncmatica Protocol
|
||||
|
||||
This patch is Powered by Syncmatica(https://github.com/End-Tech/syncmatica)
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index e17f9629369f8653b484b4cc71de4874b5faa4d6..9be4bc9e78c22c12ba594b16dac6901023f0fd47 100644
|
||||
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -330,9 +330,12 @@ public class ServerGamePacketListenerImpl
|
||||
this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(player.getUUID(), server::enforceSecureProfile);
|
||||
this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat
|
||||
this.tickEndEvent = new io.papermc.paper.event.packet.ClientTickEndEvent(player.getBukkitEntity()); // Paper - add client tick end event
|
||||
+ this.exchangeTarget = new org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget(this); // Leaves - Syncmatica Protocol
|
||||
this.playerGameConnection = new io.papermc.paper.connection.PaperPlayerGameConnection(this); // Paper
|
||||
}
|
||||
|
||||
+ public final org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget exchangeTarget; // Leaves - Syncmatica Protocol
|
||||
+
|
||||
// Paper start - configuration phase API
|
||||
@Override
|
||||
public io.papermc.paper.connection.PlayerCommonConnection getApiConnection() {
|
||||
@@ -0,0 +1,25 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Mon, 3 Feb 2025 13:03:42 +0800
|
||||
Subject: [PATCH] Leaves: BBOR Protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 29788fedd54b8411c9c8872b4d83b037874fb5f0..24af6821694768058dc0146220877ab70066b5f9 100644
|
||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -754,6 +754,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
|
||||
|
||||
public void setLoaded(boolean loaded) {
|
||||
this.loaded = loaded;
|
||||
+ // Leaves start - bbor
|
||||
+ if (loaded) {
|
||||
+ org.leavesmc.leaves.protocol.BBORProtocol.onChunkLoaded(this);
|
||||
+ }
|
||||
+ // Leaves end - bbor
|
||||
}
|
||||
|
||||
public Level getLevel() {
|
||||
@@ -0,0 +1,114 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Mon, 3 Feb 2025 13:33:19 +0800
|
||||
Subject: [PATCH] Leaves: Jade Protocol
|
||||
|
||||
This patch is Powered by Jade(https://github.com/Snownee/Jade)
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
index c1798db2972c8f2a343cf6e16fd9354ff212d906..a8d617b16ab2b2c0cdb289a0aa05fa171940cd7e 100644
|
||||
--- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
+++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java
|
||||
@@ -63,7 +63,7 @@ public class Armadillo extends Animal {
|
||||
public final AnimationState rollOutAnimationState = new AnimationState();
|
||||
public final AnimationState rollUpAnimationState = new AnimationState();
|
||||
public final AnimationState peekAnimationState = new AnimationState();
|
||||
- private int scuteTime;
|
||||
+ public int scuteTime; // Leaves - private -> public
|
||||
private boolean peekReceivedClient = false;
|
||||
|
||||
public Armadillo(EntityType<? extends Animal> entityType, Level level) {
|
||||
diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java
|
||||
index 17f58246849ed407821a987b200cc765eb7943f9..ac27df3ba0ce9bbdf2f32ea87171fbb9407008d6 100644
|
||||
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
|
||||
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
|
||||
@@ -254,7 +254,7 @@ public class Tadpole extends AbstractFish {
|
||||
}
|
||||
}
|
||||
|
||||
- private int getTicksLeftUntilAdult() {
|
||||
+ public int getTicksLeftUntilAdult() { // Leaves - private -> public
|
||||
return Math.max(0, ticksToBeFrog - this.age);
|
||||
}
|
||||
|
||||
diff --git a/net/minecraft/world/level/storage/loot/LootPool.java b/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
index 6901e629d941e22e64d83eed4e8cfee3165a96a1..fdc26c8d8c82c20534c57af2a0281b99998cc9f6 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
@@ -37,7 +37,7 @@ public class LootPool {
|
||||
)
|
||||
.apply(instance, LootPool::new)
|
||||
);
|
||||
- private final List<LootPoolEntryContainer> entries;
|
||||
+ public final List<LootPoolEntryContainer> entries; // Leaves - private -> public
|
||||
private final List<LootItemCondition> conditions;
|
||||
private final Predicate<LootContext> compositeCondition;
|
||||
private final List<LootItemFunction> functions;
|
||||
diff --git a/net/minecraft/world/level/storage/loot/LootTable.java b/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
index 8612cdf7161f8ddff60a6478cc901318b8f958ba..07a962d647baa99b0e1bf3898a07cc914e91397e 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
@@ -50,7 +50,7 @@ public class LootTable {
|
||||
public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, Optional.empty(), List.of(), List.of());
|
||||
private final ContextKeySet paramSet;
|
||||
private final Optional<ResourceLocation> randomSequence;
|
||||
- private final List<LootPool> pools;
|
||||
+ public final List<LootPool> pools; // Leaves - private -> public
|
||||
private final List<LootItemFunction> functions;
|
||||
private final BiFunction<ItemStack, LootContext, ItemStack> compositeFunction;
|
||||
public org.bukkit.craftbukkit.CraftLootTable craftLootTable; // CraftBukkit
|
||||
diff --git a/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java b/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
index eeaa49e9f70a18b5d39493aeff73f31b05ac2faa..8cd0403d7873c4c37caef75935b06b056c3d951d 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
@@ -16,7 +16,7 @@ public abstract class CompositeEntryBase extends LootPoolEntryContainer {
|
||||
return "Empty children list";
|
||||
}
|
||||
};
|
||||
- protected final List<LootPoolEntryContainer> children;
|
||||
+ public final List<LootPoolEntryContainer> children; // Leaves - private -> public
|
||||
private final ComposableEntryContainer composedChildren;
|
||||
|
||||
protected CompositeEntryBase(List<LootPoolEntryContainer> children, List<LootItemCondition> conditions) {
|
||||
diff --git a/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java b/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
index 65e27bce9e59ef97bc8b914d646fba924d0f0877..a49bdcdf37b351436e0ba6d7865f10827c4e6ab4 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
@@ -14,7 +14,7 @@ import net.minecraft.world.level.storage.loot.predicates.ConditionUserBuilder;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
public abstract class LootPoolEntryContainer implements ComposableEntryContainer {
|
||||
- protected final List<LootItemCondition> conditions;
|
||||
+ public final List<LootItemCondition> conditions; // Leaves - private -> public
|
||||
private final Predicate<LootContext> compositeCondition;
|
||||
|
||||
protected LootPoolEntryContainer(List<LootItemCondition> conditions) {
|
||||
diff --git a/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java b/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
index 141026601cd9a4561426b85fd1f8e7dc0544fbd7..a5d7ebb93c147bf0f806ac3c9b2dc4b878573944 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
@@ -29,7 +29,7 @@ public class NestedLootTable extends LootPoolSingletonContainer {
|
||||
return "->{inline}";
|
||||
}
|
||||
};
|
||||
- private final Either<ResourceKey<LootTable>, LootTable> contents;
|
||||
+ public final Either<ResourceKey<LootTable>, LootTable> contents; // Leaves - private -> public
|
||||
|
||||
private NestedLootTable(
|
||||
Either<ResourceKey<LootTable>, LootTable> contents, int weight, int quality, List<LootItemCondition> conditions, List<LootItemFunction> functions
|
||||
diff --git a/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java b/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
index bae72197acc929c7ed3e964f156115d728eb2176..8f3094f42f3366a1313d70c0b27fbe5632b2082a 100644
|
||||
--- a/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
+++ b/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
@@ -12,7 +12,7 @@ import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.ValidationContext;
|
||||
|
||||
public abstract class CompositeLootItemCondition implements LootItemCondition {
|
||||
- protected final List<LootItemCondition> terms;
|
||||
+ public final List<LootItemCondition> terms; // Leaves - private -> public
|
||||
private final Predicate<LootContext> composedPredicate;
|
||||
|
||||
protected CompositeLootItemCondition(List<LootItemCondition> terms, Predicate<LootContext> composedPredicate) {
|
||||
@@ -0,0 +1,21 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Fri, 7 Feb 2025 14:23:43 +0800
|
||||
Subject: [PATCH] Leaves: Xaero Map Protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
|
||||
index 908ec29a6e285122d1a8a43dc547b74af2697442..1bf1731e43278b71423fee5d92401c48d6dabaca 100644
|
||||
--- a/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1247,6 +1247,7 @@ public abstract class PlayerList {
|
||||
player.connection.send(new ClientboundInitializeBorderPacket(worldBorder));
|
||||
player.connection.send(new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
|
||||
player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle()));
|
||||
+ org.leavesmc.leaves.protocol.XaeroMapProtocol.onSendWorldInfo(player); // Leaves - xaero map protocol
|
||||
if (level.isRaining()) {
|
||||
// CraftBukkit start - handle player weather
|
||||
// player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F));
|
||||
@@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
Date: Thu, 27 Mar 2025 13:04:35 +0800
|
||||
Subject: [PATCH] Leaves: Support REI protocol
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/net/minecraft/world/item/crafting/SmithingTransformRecipe.java b/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
index 9bc0a9c3577d63a0ad5489bfd4c07d5006245c5f..bb2e891539b7eb49dc7925630695149aa531f672 100644
|
||||
--- a/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
+++ b/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
|
||||
@@ -83,6 +83,12 @@ public class SmithingTransformRecipe implements SmithingRecipe {
|
||||
);
|
||||
}
|
||||
|
||||
+ // Leaves start - REI
|
||||
+ public SlotDisplay getResult() {
|
||||
+ return this.result.display();
|
||||
+ }
|
||||
+ // Leaves end - REI
|
||||
+
|
||||
// CraftBukkit start
|
||||
@Override
|
||||
public org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id) {
|
||||
diff --git a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
index c324896afc2ee28ebb4d426ce4a469ee847ce24d..d5b26ff7be916e07e1162536cb2ddf5674c82f46 100644
|
||||
--- a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
+++ b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
|
||||
@@ -85,6 +85,12 @@ public class SmithingTrimRecipe implements SmithingRecipe {
|
||||
return Optional.of(this.addition);
|
||||
}
|
||||
|
||||
+ // Leaves start
|
||||
+ public Holder<TrimPattern> pattern() {
|
||||
+ return pattern;
|
||||
+ }
|
||||
+ // Leaves end
|
||||
+
|
||||
@Override
|
||||
public RecipeSerializer<SmithingTrimRecipe> getSerializer() {
|
||||
return RecipeSerializer.SMITHING_TRIM;
|
||||
@@ -0,0 +1,95 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
|
||||
Date: Mon, 27 Oct 2025 15:38:29 +0800
|
||||
Subject: [PATCH] Leaves: Wool Hopper Counter
|
||||
|
||||
Co-authored by: violetc <58360096+s-yh-china@users.noreply.github.com>
|
||||
As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: MIT
|
||||
|
||||
This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet)
|
||||
|
||||
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
index d4fe03fd766caca1d7693a5317460ca1a9b9fa4f..a821deaa5c076151336762d17a8da45abb4c43cd 100644
|
||||
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
||||
@@ -232,8 +232,30 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
flag |= validator.getAsBoolean(); // Paper - note: this is not a validator, it's what adds/sucks in items
|
||||
}
|
||||
|
||||
+ // Leaves start - Wool hopper counter
|
||||
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
|
||||
+ net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, blockEntity.getBlockPos().relative(state.getValue(HopperBlock.FACING)));
|
||||
+ if (woolColor != null) {
|
||||
+ for (int i = 0; i < Short.MAX_VALUE; i++) {
|
||||
+ flag |= suckInItems(level, blockEntity);
|
||||
+ if (!flag) {
|
||||
+ break;
|
||||
+ } else {
|
||||
+ woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - Wool hopper counter
|
||||
+
|
||||
if (flag) {
|
||||
blockEntity.setCooldown(level.spigotConfig.hopperTransfer); // Spigot
|
||||
+ // Leaves start - Wool hopper counter
|
||||
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && woolHopperCounter(level, pos, state, HopperBlockEntity.getContainerAt(level, pos))) {
|
||||
+ blockEntity.setCooldown(0);
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Leaves end - Wool hopper counter
|
||||
setChanged(level, pos, state);
|
||||
// Leaves start - Lithium Sleeping Block Entity
|
||||
if (me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled
|
||||
@@ -465,6 +487,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
// Paper end - Perf: Optimize Hoppers
|
||||
|
||||
private static boolean ejectItems(Level level, BlockPos pos, HopperBlockEntity blockEntity) {
|
||||
+ // Leaves start - hopper counter
|
||||
+ if (org.leavesmc.leaves.util.HopperCounter.isEnabled()) {
|
||||
+ if (woolHopperCounter(level, pos, level.getBlockState(pos), HopperBlockEntity.getContainerAt(level, pos))) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - hopper counter
|
||||
Container attachedContainer = me.earthme.luminol.config.modules.optimizations.LeavesSleepingBlockEntityConfig.enabled ? blockEntity.getInsertInventory(level) : getAttachedContainer(level, pos, blockEntity); // Leaves - Lithium Sleeping Block Entity
|
||||
if (attachedContainer == null) {
|
||||
return false;
|
||||
@@ -541,6 +570,26 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
}
|
||||
|
||||
+ // Leaves start - hopper counter
|
||||
+ private static boolean woolHopperCounter(Level level, BlockPos blockPos, BlockState state, @Nullable Container container) {
|
||||
+ if (container == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ net.minecraft.world.item.DyeColor woolColor = org.leavesmc.leaves.util.WoolUtils.getWoolColorAtPosition(level, blockPos.relative(state.getValue(HopperBlock.FACING)));
|
||||
+ if (woolColor != null) {
|
||||
+ for (int i = 0; i < container.getContainerSize(); ++i) {
|
||||
+ if (!container.getItem(i).isEmpty()) {
|
||||
+ ItemStack itemstack = container.getItem(i);
|
||||
+ org.leavesmc.leaves.util.HopperCounter.getCounter(woolColor).add(level, itemstack);
|
||||
+ container.setItem(i, ItemStack.EMPTY);
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Leaves end - hopper counter
|
||||
+
|
||||
private static int[] getSlots(Container container, Direction direction) {
|
||||
if (container instanceof WorldlyContainer worldlyContainer) {
|
||||
return worldlyContainer.getSlotsForFace(direction);
|
||||
@@ -683,6 +732,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
||||
}
|
||||
|
||||
public static boolean addItem(Container container, ItemEntity item) {
|
||||
+ if (fun.bm.lophine.config.modules.function.WoolHopperCounterConfig.unlimitedSpeed && org.leavesmc.leaves.util.HopperCounter.isEnabled() && item.isRemoved()) return false; // Leaves - Wool hopper counter
|
||||
boolean flag = false;
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.event.inventory.InventoryPickupItemEvent.getHandlerList().getRegisteredListeners().length > 0) { // Paper - optimize hoppers
|
||||
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/ea91106ae57fc4cc1
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 5d05a8a843e605b6cb6d16883d17dd73d4c21e06..57ea85aebc72eb002d3dcf04144499feeb82081a 100644
|
||||
index 4dde33c872d463bf17ba03e926de90e6988444b2..de72f36bd22e2c7452b9c3ee40657f6119ca70b3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -497,6 +497,7 @@ public final class CraftServer implements Server {
|
||||
|
||||
@@ -8,19 +8,13 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves)
|
||||
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
index 9180f23529a31b6b0a5b38bb7cda3e32d487f691..cc8686b791f4c559e51bb06b52b02e295b6e0547 100644
|
||||
index 9180f23529a31b6b0a5b38bb7cda3e32d487f691..e1f456b31ffda9370b63e51f343847d6f9f62263 100644
|
||||
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
|
||||
@@ -47,6 +47,23 @@ class PaperEventManager {
|
||||
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
|
||||
}
|
||||
@@ -36,6 +36,15 @@ class PaperEventManager {
|
||||
|
||||
+ // Leaves start - skip bot
|
||||
+ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.bot.Bot) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - skip bot
|
||||
+
|
||||
// SimplePluginManager
|
||||
public void callEvent(@NotNull Event event) {
|
||||
+ // Leaves start - process bot load/save
|
||||
+ if (fun.bm.lophine.config.modules.function.FakeplayerConfig.enable && fun.bm.lophine.config.modules.function.FakeplayerConfig.canResident) {
|
||||
+ if (event instanceof org.bukkit.event.world.WorldLoadEvent worldLoadEvent) {
|
||||
@@ -30,7 +24,18 @@ index 9180f23529a31b6b0a5b38bb7cda3e32d487f691..cc8686b791f4c559e51bb06b52b02e29
|
||||
+ }
|
||||
+ }
|
||||
+ // Leaves end - process bot load/save
|
||||
+
|
||||
// Leaf start - Skip event if no listeners
|
||||
RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners();
|
||||
if (listeners.length == 0) return;
|
||||
@@ -47,6 +56,12 @@ class PaperEventManager {
|
||||
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
|
||||
}
|
||||
|
||||
+ // Leaves start - skip bot
|
||||
+ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.bot.Bot) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Leaves end - skip bot
|
||||
+
|
||||
for (RegisteredListener registration : listeners) {
|
||||
if (!registration.getPlugin().isEnabled()) {
|
||||
@@ -48,7 +53,7 @@ index 0a10f49ee410d93e95ceb90108200a1a9d12b54b..d2eee37d810a6d5cf514bc71dea66a4d
|
||||
if (nmsEntity.level() != this.getHandle().getLevel()) {
|
||||
nmsEntity = nmsEntity.teleport(new TeleportTransition(this.getHandle().getLevel(), nmsEntity, TeleportTransition.DO_NOTHING));
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 57ea85aebc72eb002d3dcf04144499feeb82081a..e03de696e7652b7e211bf61ff6d6cdf44a587146 100644
|
||||
index de72f36bd22e2c7452b9c3ee40657f6119ca70b3..0a96721797b9bbc643f68677bbb1d10c3c89e815 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -316,6 +316,7 @@ public final class CraftServer implements Server {
|
||||
@@ -156,7 +161,7 @@ index 852e1ffef6a022caad7c8eff34091e50112a2290..8eb5d014d9ed688ffebaffb4ce0bb408
|
||||
if (entity instanceof EnderDragonPart complexPart) {
|
||||
if (complexPart.parentMob instanceof EnderDragon) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index ffb10b412d19907e6f63b7e3ca67ef061eec96ba..de14df49b11f1243de9aa6870a3c8e3f429502fd 100644
|
||||
index 317837a2a9b3b511b5cac4df4db248d4652816dc..a8253d1a3129c8258e9ead7c430e1bcf82f735d7 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -897,7 +897,11 @@ public class CraftEventFactory {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package fun.bm.lophine.command.counter;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import fun.bm.lophine.command.counter.sub.DisplayCommand;
|
||||
import fun.bm.lophine.command.counter.sub.ResetCommand;
|
||||
import fun.bm.lophine.command.counter.sub.ToggleCommand;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.command.RootNode;
|
||||
import org.leavesmc.leaves.util.HopperCounter;
|
||||
|
||||
public class CounterCommand extends RootNode {
|
||||
private final String PERM_BASE;
|
||||
|
||||
public CounterCommand() {
|
||||
super("counter", "lophine.commands.counter");
|
||||
this.PERM_BASE = "lophine.commands.counter";
|
||||
children(
|
||||
new ToggleCommand(this),
|
||||
new ResetCommand(this),
|
||||
new DisplayCommand(this)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
context.getSender().sendMessage(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Hopper Counter: ", NamedTextColor.GRAY),
|
||||
Component.text(HopperCounter.isEnabled(), HopperCounter.isEnabled() ? NamedTextColor.AQUA : NamedTextColor.GRAY)
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasPermission(@NotNull CommandSender sender, String... subcommand) {
|
||||
return hasPermission(PERM_BASE, sender, subcommand);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package fun.bm.lophine.command.counter;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.LiteralNode;
|
||||
|
||||
public class CounterSubCommand extends LiteralNode {
|
||||
protected final CounterCommand parent;
|
||||
|
||||
protected CounterSubCommand(String name, CounterCommand parent) {
|
||||
super(name);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requires(@NotNull CommandSourceStack source) {
|
||||
return hasPermission(source.getSender());
|
||||
}
|
||||
|
||||
protected boolean hasPermission(CommandSender sender) {
|
||||
return parent.hasPermission(sender, this.name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package fun.bm.lophine.command.counter.sub;
|
||||
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import fun.bm.lophine.command.counter.CounterCommand;
|
||||
import fun.bm.lophine.command.counter.CounterSubCommand;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.ArgumentNode;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.util.HopperCounter;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class DisplayCommand extends CounterSubCommand {
|
||||
public DisplayCommand(CounterCommand parent) {
|
||||
super("display", parent);
|
||||
children(
|
||||
DyeColorArg::new
|
||||
);
|
||||
}
|
||||
|
||||
public static void displayCounter(CommandContext context, @NotNull HopperCounter counter, boolean realTime) {
|
||||
for (Component component : counter.format(MinecraftServer.getServer(), context.getSource().getLevel(), realTime)) {
|
||||
context.getSender().sendMessage(component);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DyeColorArg extends ArgumentNode<String> {
|
||||
protected DyeColorArg() {
|
||||
super("color", StringArgumentType.string());
|
||||
children(
|
||||
TimeArg::new
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) {
|
||||
String color0 = context.getArgument(DyeColorArg.class);
|
||||
DyeColor color = DyeColor.byName(color0, null);
|
||||
if (color == null) return true;
|
||||
HopperCounter counter = HopperCounter.getCounter(color);
|
||||
displayCounter(context, counter, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Suggestions> getSuggestions(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) {
|
||||
String path = context.getArgumentOrDefault(DyeColorArg.class, "");
|
||||
for (DyeColor value : DyeColor.values()) {
|
||||
String color = value.getName();
|
||||
if (color.startsWith(path)) {
|
||||
builder.suggest(color);
|
||||
}
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
|
||||
private static class TimeArg extends ArgumentNode<String> {
|
||||
protected TimeArg() {
|
||||
super("time", StringArgumentType.string());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) {
|
||||
String color0 = context.getArgument(DyeColorArg.class);
|
||||
DyeColor color = DyeColor.byName(color0, null);
|
||||
if (color == null) return true;
|
||||
HopperCounter counter = HopperCounter.getCounter(color);
|
||||
String timeType = context.getArgument(TimeArg.class);
|
||||
switch (timeType) {
|
||||
case "realtime" -> displayCounter(context, counter, true);
|
||||
case "gametick" -> displayCounter(context, counter, false);
|
||||
default ->
|
||||
context.getSender().sendMessage(Component.text("Invalid time type: " + timeType, NamedTextColor.RED));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected CompletableFuture<Suggestions> getSuggestions(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) {
|
||||
builder.suggest("realtime");
|
||||
builder.suggest("gametick");
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package fun.bm.lophine.command.counter.sub;
|
||||
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import fun.bm.lophine.command.counter.CounterCommand;
|
||||
import fun.bm.lophine.command.counter.CounterSubCommand;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.ArgumentNode;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.util.HopperCounter;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ResetCommand extends CounterSubCommand {
|
||||
public ResetCommand(CounterCommand parent) {
|
||||
super("reset", parent);
|
||||
children(
|
||||
DyeColorArg::new
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
HopperCounter.resetAll(context.getSource().getLevel(), false);
|
||||
context.getSender().sendMessage(Component.text("Restarted all counters."));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class DyeColorArg extends ArgumentNode<String> {
|
||||
protected DyeColorArg() {
|
||||
super("color", StringArgumentType.string());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) {
|
||||
String color0 = context.getArgument(DyeColorArg.class);
|
||||
if (color0.equals("all")) {
|
||||
HopperCounter.resetAll(context.getSource().getLevel(), false);
|
||||
context.getSender().sendMessage(Component.text("Restarted all counters."));
|
||||
return true;
|
||||
}
|
||||
DyeColor color = DyeColor.byName(color0, null);
|
||||
if (color == null) return true;
|
||||
HopperCounter counter = HopperCounter.getCounter(color);
|
||||
counter.reset(context.getSource().getLevel());
|
||||
context.getSender().sendMessage(Component.join(JoinConfiguration.noSeparators(),
|
||||
Component.text("Restarted "),
|
||||
Component.text(color.getName(), TextColor.color(color.getTextColor())),
|
||||
Component.text(" counter.")
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompletableFuture<Suggestions> getSuggestions(@NotNull CommandContext context, @NotNull SuggestionsBuilder builder) {
|
||||
String path = context.getArgumentOrDefault(DyeColorArg.class, "");
|
||||
if ("all".startsWith(path)) {
|
||||
builder.suggest("all");
|
||||
}
|
||||
for (DyeColor value : DyeColor.values()) {
|
||||
String color = value.getName();
|
||||
if (color.startsWith(path)) {
|
||||
builder.suggest(color);
|
||||
}
|
||||
}
|
||||
return builder.buildFuture();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package fun.bm.lophine.command.counter.sub;
|
||||
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import fun.bm.lophine.command.counter.CounterCommand;
|
||||
import fun.bm.lophine.command.counter.CounterSubCommand;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.ArgumentNode;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
import org.leavesmc.leaves.util.HopperCounter;
|
||||
|
||||
public class ToggleCommand extends CounterSubCommand {
|
||||
public ToggleCommand(CounterCommand parent) {
|
||||
super("toggle", parent);
|
||||
children(
|
||||
BooleanArg::new
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
if (!HopperCounter.isEnabled()) {
|
||||
HopperCounter.setEnabled(true);
|
||||
context.getSender().sendMessage(Component.text("Hopper Counter now is enabled.", NamedTextColor.AQUA));
|
||||
} else {
|
||||
HopperCounter.setEnabled(false);
|
||||
context.getSender().sendMessage(Component.text("Hopper Counter now is disabled.", NamedTextColor.RED));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class BooleanArg extends ArgumentNode<Boolean> {
|
||||
protected BooleanArg() {
|
||||
super("enabled", BoolArgumentType.bool());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) {
|
||||
boolean enabled = context.getArgument(BooleanArg.class);
|
||||
if (enabled == HopperCounter.isEnabled()) {
|
||||
context.getSender().sendMessage(Component.text("Hopper Counter is already " + (enabled ? "enabled" : "disabled") + ".", NamedTextColor.GRAY));
|
||||
} else {
|
||||
HopperCounter.setEnabled(enabled);
|
||||
if (enabled) {
|
||||
context.getSender().sendMessage(Component.text("Hopper Counter now is enabled.", NamedTextColor.AQUA));
|
||||
} else {
|
||||
context.getSender().sendMessage(Component.text("Hopper Counter now is disabled.", NamedTextColor.RED));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-14
@@ -6,28 +6,27 @@ import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "command")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.EXPERIMENT, name = "command")
|
||||
public class CommandConfig implements IConfigModule {
|
||||
@ConfigInfo(baseName = "tick_command_enabled", comments =
|
||||
@ConfigInfo(name = "tick_command_enabled", comments =
|
||||
"""
|
||||
Allow to use tick command""")
|
||||
public static boolean tick = false;
|
||||
|
||||
@ConfigInfo(baseName = "datapack_command_enabled", comments =
|
||||
"""
|
||||
Allow to use datapack command
|
||||
--- datapack hot-update unsupported, please restart server""")
|
||||
public static boolean datapack = false;
|
||||
|
||||
@ConfigInfo(baseName = "function_command_enabled", comments =
|
||||
@ConfigInfo(name = "function_command_enabled", comments =
|
||||
"""
|
||||
Allow to use function command""")
|
||||
public static boolean function = false;
|
||||
|
||||
@TransformedConfig(name = "enable-waypoint", category = {"experiment", "waypoint bar"})
|
||||
@TransformedConfig(name = "enable-waypoint", category = {"experiment", "waypoint_bar"})
|
||||
@ConfigInfo(baseName = "waypoint_command_enabled", comments = """
|
||||
Allow to use waypoint command
|
||||
""")
|
||||
@TransformedConfig(name = "enable-waypoint", directory = {"experiment", "waypoint bar"})
|
||||
@TransformedConfig(name = "enable-waypoint", directory = {"experiment", "waypoint_bar"})
|
||||
@ConfigInfo(name = "waypoint_command_enabled", comments =
|
||||
"""
|
||||
Allow to use waypoint command""")
|
||||
public static boolean waypoint = false;
|
||||
|
||||
@ConfigInfo(name = "scoreboard_command_enabled", comments =
|
||||
"""
|
||||
Allow to use scoreboard command""")
|
||||
public static boolean scoreboard = false;
|
||||
}
|
||||
+2
-2
@@ -5,9 +5,9 @@ import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "entity_damage_source_trace")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.EXPERIMENT, name = "entity_damage_source_trace")
|
||||
public class EntityDamageSourceTraceConfig implements IConfigModule {
|
||||
@ConfigInfo(baseName = "enabled", comments =
|
||||
@ConfigInfo(name = "enabled", comments =
|
||||
"""
|
||||
Allow trace damage source cross different Region Scheduler.""")
|
||||
public static boolean enabled = false;
|
||||
|
||||
+6
-6
@@ -5,16 +5,16 @@ import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "ray_tracking_entity_tracker")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.EXPERIMENT, name = "ray_tracking_entity_tracker")
|
||||
public class RayTrackingEntityTrackerConfig implements IConfigModule {
|
||||
@ConfigInfo(baseName = "enabled")
|
||||
@ConfigInfo(name = "enabled")
|
||||
public static boolean enabled = false;
|
||||
@ConfigInfo(baseName = "skip_marker_armor_stands")
|
||||
@ConfigInfo(name = "skip_marker_armor_stands")
|
||||
public static boolean skipMarkerArmorStands = true;
|
||||
@ConfigInfo(baseName = "check_interval_ms")
|
||||
@ConfigInfo(name = "check_interval_ms")
|
||||
public static int checkIntervalMs = 10;
|
||||
@ConfigInfo(baseName = "tracing_distance")
|
||||
@ConfigInfo(name = "tracing_distance")
|
||||
public static int tracingDistance = 48;
|
||||
@ConfigInfo(baseName = "hitbox_limit")
|
||||
@ConfigInfo(name = "hitbox_limit")
|
||||
public static int hitboxLimit = 50;
|
||||
}
|
||||
+3
-3
@@ -6,10 +6,10 @@ import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.FIXES, mainName = "end-void-ring")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FIXES, name = "end-void-ring")
|
||||
public class EndVoidRingsConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "enabled", category = {"gameplay", "end_void_rings"})
|
||||
@ConfigInfo(baseName = "enabled", comments = """
|
||||
@TransformedConfig(name = "enabled", directory = {"gameplay", "end_void_rings"})
|
||||
@ConfigInfo(name = "enabled", comments = """
|
||||
If enabled, it will generate end void rings, like MC-159283.""")
|
||||
public static boolean enabled = false;
|
||||
}
|
||||
|
||||
+15
-9
@@ -1,32 +1,38 @@
|
||||
package fun.bm.lophine.config.modules.function;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.CommandSuggestions;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "container_expansion")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "container_expansion")
|
||||
public class ContainerExpansionConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "barrel_rows", category = {"misc", "container_expansion"})
|
||||
@ConfigInfo(baseName = "barrel_rows", comments =
|
||||
@TransformedConfig(name = "barrel_rows", directory = {"misc", "container_expansion"})
|
||||
@CommandSuggestions(suggest = {"1", "2", "3", "4", "5", "6"})
|
||||
@ConfigInfo(name = "barrel_rows", comments =
|
||||
"""
|
||||
range: 1~6""")
|
||||
public static int barrelRows = 3;
|
||||
|
||||
@TransformedConfig(name = "enderchest_rows", category = {"misc", "container_expansion"})
|
||||
@ConfigInfo(baseName = "enderchest_rows", comments =
|
||||
@TransformedConfig(name = "enderchest_rows", directory = {"misc", "container_expansion"})
|
||||
@CommandSuggestions(suggest = {"1", "2", "3", "4", "5", "6"})
|
||||
@ConfigInfo(name = "enderchest_rows", comments =
|
||||
"""
|
||||
range: 1~6""")
|
||||
public static int enderchestRows = 3;
|
||||
|
||||
@TransformedConfig(name = "shulker_stackable_count", category = {"misc", "container_expansion"})
|
||||
@ConfigInfo(baseName = "shulker_stackable_count", comments =
|
||||
@TransformedConfig(name = "shulker_stackable_count", directory = {"function", "container_expansion"})
|
||||
@TransformedConfig(name = "shulker_stackable_count", directory = {"misc", "container_expansion"})
|
||||
@CommandSuggestions(suggest = {"1", "2", "32", "64"})
|
||||
@ConfigInfo(name = "shulker_stackable_count", directory = {"shulker_box"}, comments =
|
||||
"""
|
||||
range: 1~64""")
|
||||
public static int shulkerCount = 1;
|
||||
|
||||
@TransformedConfig(name = "same_nbt_shulker_stackable", category = {"misc", "container_expansion"})
|
||||
@ConfigInfo(baseName = "same_nbt_shulker_stackable")
|
||||
@TransformedConfig(name = "same_nbt_shulker_stackable", directory = {"function", "container_expansion"})
|
||||
@TransformedConfig(name = "same_nbt_shulker_stackable", directory = {"misc", "container_expansion"})
|
||||
@ConfigInfo(name = "same_nbt_shulker_stackable", directory = {"shulker_box"})
|
||||
public static boolean nbtShulkerStackable = false;
|
||||
}
|
||||
+21
-19
@@ -5,78 +5,80 @@ import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.bot.BotCommand;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "fakeplayer")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "fakeplayer")
|
||||
public class FakeplayerConfig implements IConfigModule {
|
||||
@ConfigInfo(baseName = "enable", comments = """
|
||||
@ConfigInfo(name = "enable", comments = """
|
||||
Enable fakeplayer functionality""")
|
||||
public static boolean enable = true;
|
||||
|
||||
@ConfigInfo(baseName = "unable-fakeplayer-names", comments = """
|
||||
@ConfigInfo(name = "unable-fakeplayer-names", comments = """
|
||||
List of names that cannot be used for fakeplayers""")
|
||||
public static List<String> unableNames = List.of("player-name");
|
||||
|
||||
@ConfigInfo(baseName = "limit", comments = """
|
||||
@ConfigInfo(name = "limit", comments = """
|
||||
Maximum number of fakeplayers allowed""")
|
||||
public static int limit = 10;
|
||||
|
||||
@ConfigInfo(baseName = "prefix", comments = """
|
||||
@ConfigInfo(name = "prefix", comments = """
|
||||
Prefix for fakeplayer names""")
|
||||
public static String prefix = "";
|
||||
|
||||
@ConfigInfo(baseName = "suffix", comments = """
|
||||
@ConfigInfo(name = "suffix", comments = """
|
||||
Suffix for fakeplayer names""")
|
||||
public static String suffix = "";
|
||||
|
||||
@ConfigInfo(baseName = "regen-amount", comments = """
|
||||
@ConfigInfo(name = "regen-amount", comments = """
|
||||
Regeneration amount for fakeplayers""")
|
||||
public static double regenAmount = 0.0;
|
||||
|
||||
@ConfigInfo(baseName = "resident-fakeplayer", comments = """
|
||||
@ConfigInfo(name = "resident-fakeplayer", comments = """
|
||||
Allow fakeplayers to be resident""")
|
||||
public static boolean canResident = false;
|
||||
|
||||
@ConfigInfo(baseName = "open-fakeplayer-inventory", comments = """
|
||||
@ConfigInfo(name = "open-fakeplayer-inventory", comments = """
|
||||
Allow opening fakeplayer inventory""")
|
||||
public static boolean canOpenInventory = false;
|
||||
|
||||
@ConfigInfo(baseName = "use-action", comments = """
|
||||
@ConfigInfo(name = "use-action", comments = """
|
||||
Allow fakeplayers to use actions""")
|
||||
public static boolean canUseAction = true;
|
||||
|
||||
@ConfigInfo(baseName = "modify-config", comments = """
|
||||
@ConfigInfo(name = "modify-config", comments = """
|
||||
Allow modifying fakeplayer config""")
|
||||
public static boolean canModifyConfig = false;
|
||||
|
||||
@ConfigInfo(baseName = "manual-save-and-load", comments = """
|
||||
@ConfigInfo(name = "manual-save-and-load", comments = """
|
||||
Allow manual save and load of fakeplayers""")
|
||||
public static boolean canManualSaveAndLoad = false;
|
||||
|
||||
@ConfigInfo(baseName = "cache-skin", comments = """
|
||||
@ConfigInfo(name = "cache-skin", comments = """
|
||||
Use skin cache for fakeplayers""")
|
||||
public static boolean useSkinCache = false;
|
||||
|
||||
@ConfigInfo(baseName = "always-send-data", comments = """
|
||||
@ConfigInfo(name = "always-send-data", comments = """
|
||||
Always send data for fakeplayers""")
|
||||
public static boolean canSendDataAlways = true;
|
||||
|
||||
@ConfigInfo(baseName = "skip-sleep-check", comments = """
|
||||
@ConfigInfo(name = "skip-sleep-check", comments = """
|
||||
Skip sleep check for fakeplayers""")
|
||||
public static boolean canSkipSleep = false;
|
||||
|
||||
@ConfigInfo(baseName = "spawn-phantom", comments = """
|
||||
@ConfigInfo(name = "spawn-phantom", comments = """
|
||||
Allow phantoms to spawn for fakeplayers""")
|
||||
public static boolean canSpawnPhantom = false;
|
||||
|
||||
@ConfigInfo(baseName = "simulation-distance", comments = """
|
||||
@ConfigInfo(name = "simulation-distance", comments = """
|
||||
Simulation distance for fakeplayers (-1 for default)""")
|
||||
public static int simulationDistance = -1;
|
||||
|
||||
@ConfigInfo(baseName = "enable-locator-bar", comments = """
|
||||
@ConfigInfo(name = "enable-locator-bar", comments = """
|
||||
Enable locator bar for fakeplayers""")
|
||||
public static boolean enableLocatorBar = false;
|
||||
|
||||
@@ -91,7 +93,7 @@ public class FakeplayerConfig implements IConfigModule {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaded(CommentedFileConfig configInstance) {
|
||||
public void onLoaded(CommentedFileConfig configInstance, @Nullable Set<Exception> exs) {
|
||||
if (enable) {
|
||||
command = new BotCommand();
|
||||
command.register();
|
||||
|
||||
+3
-3
@@ -6,10 +6,10 @@ import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "language")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "language")
|
||||
public class LanguageConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "lang", category = {"optimizations", "language"})
|
||||
@ConfigInfo(baseName = "lang", comments = """
|
||||
@TransformedConfig(name = "lang", directory = {"optimizations", "language"})
|
||||
@ConfigInfo(name = "lang", comments = """
|
||||
Please use the key from https://minecraft.wiki/w/Language
|
||||
Sample of format: en_us zh_cn zh_hk zh_tw""")
|
||||
public static String lang = "en_us";
|
||||
|
||||
+18
-10
@@ -6,22 +6,30 @@ import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "old-feature")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "old-feature")
|
||||
public class OldFeatureConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "spawn_invulnerable_time", category = {"misc", "old-feature"})
|
||||
@ConfigInfo(baseName = "spawn_invulnerable_time")
|
||||
@TransformedConfig(name = "spawn_invulnerable_time", directory = {"misc", "old-feature"})
|
||||
@ConfigInfo(name = "spawn_invulnerable_time")
|
||||
public static boolean spawnInvulnerableTime = false;
|
||||
|
||||
@TransformedConfig(name = "old_zombie_reinforcement", category = {"misc", "old-feature"})
|
||||
@ConfigInfo(baseName = "old_zombie_reinforcement")
|
||||
@TransformedConfig(name = "old_zombie_reinforcement", directory = {"misc", "old-feature"})
|
||||
@ConfigInfo(name = "old_zombie_reinforcement")
|
||||
public static boolean oldZombieReinforcement = false;
|
||||
|
||||
@TransformedConfig(name = "old_explosion_damage_calculator", category = {"misc", "old-feature"})
|
||||
@ConfigInfo(baseName = "old_explosion_damage_calculator")
|
||||
@TransformedConfig(name = "old_explosion_damage_calculator", directory = {"misc", "old-feature"})
|
||||
@ConfigInfo(name = "old_explosion_damage_calculator")
|
||||
public static boolean oldExplosionDamageCalculator = false;
|
||||
|
||||
@TransformedConfig(name = "old_raid_behavior", category = {"misc", "old-feature"})
|
||||
@TransformedConfig(name = "give_bad_omen_when_kill_raid_captain", category = {"misc", "revert_raid_changes"}, transformComments = false)
|
||||
@ConfigInfo(baseName = "old_raid_behavior")
|
||||
@TransformedConfig(name = "old_raid_behavior", directory = {"misc", "old-feature"})
|
||||
@TransformedConfig(name = "give_bad_omen_when_kill_raid_captain", directory = {"misc", "revert_raid_changes"}, transformComments = false)
|
||||
@ConfigInfo(name = "old_raid_behavior")
|
||||
public static boolean oldRaidBehavior = false;
|
||||
|
||||
@TransformedConfig(name = "villager-infinite-trade", directory = {"function", "villager"}, transformComments = false)
|
||||
@TransformedConfig(name = "villager-infinite-trade", directory = {"misc", "villager"}, transformComments = false)
|
||||
@TransformedConfig(name = "villager-infinite-trade", directory = {"misc", "villager-config"}, transformComments = false)
|
||||
@ConfigInfo(name = "villager-void-trade", comments =
|
||||
"""
|
||||
Allow villager void trade.""")
|
||||
public static boolean villagerVoidTrade = false;
|
||||
}
|
||||
+4
-4
@@ -6,11 +6,11 @@ import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "redstone")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "redstone")
|
||||
public class RedStoneConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "shears_rotate", category = {"misc", "redstone"})
|
||||
@TransformedConfig(name = "allow_skip_cooldown", category = {"misc", "redstone"})
|
||||
@ConfigInfo(baseName = "shears_rotate", comments =
|
||||
@TransformedConfig(name = "shears_rotate", directory = {"misc", "redstone"})
|
||||
@TransformedConfig(name = "allow_skip_cooldown", directory = {"misc", "redstone"})
|
||||
@ConfigInfo(name = "shears_rotate", comments =
|
||||
"""
|
||||
Allows you to use the Shears to right-click to rotate the block.""")
|
||||
public static boolean shears = false;
|
||||
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
package fun.bm.lophine.config.modules.function;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "survux-protocol")
|
||||
public class SurvuxProtocolConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "entity-protocol", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "entity-protocol")
|
||||
public static boolean entityProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-logger-protocol", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "hud-logger-protocol")
|
||||
public static boolean hudLoggerProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-metadata-protocol", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "hud-metadata-protocol")
|
||||
public static boolean hudMetadataProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-metadata-share-seed", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "hud-metadata-share-seed")
|
||||
public static boolean hudMetadataShareSeed = false;
|
||||
|
||||
@TransformedConfig(name = "structure-protocol", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "structure-protocol")
|
||||
public static boolean structureProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-enabled-loggers", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "hud-enabled-loggers")
|
||||
public static List<String> hudEnabledLoggers = List.of("tps", "mob_caps");
|
||||
|
||||
@TransformedConfig(name = "hud-update-interval", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "hud-update-interval")
|
||||
public static int hudUpdateInterval = 1;
|
||||
|
||||
@TransformedConfig(name = "litematics-enabled", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "litematics-enabled")
|
||||
public static boolean litematicsEnabled = false;
|
||||
|
||||
@TransformedConfig(name = "litematics-max-nbt-size", category = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(baseName = "litematics-max-nbt-size")
|
||||
public static int litematicsMaxNbtSize = 2097152;
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package fun.bm.lophine.config.modules.function;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "villager")
|
||||
public class VillagerConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "villager-infinite-trade", category = {"misc", "villager"})
|
||||
@TransformedConfig(name = "villager-infinite-trade", category = {"misc", "villager-config"})
|
||||
@ConfigInfo(baseName = "villager-infinite-trade", comments =
|
||||
"""
|
||||
Allow villager infinite trade (limit of 524288 times)
|
||||
---- we won't edit saved data, only edit in send data to client.""")
|
||||
public static boolean villagerInfiniteTrade = false;
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package fun.bm.lophine.config.modules.function;
|
||||
|
||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
import fun.bm.lophine.command.counter.CounterCommand;
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "wool-hopper-counter")
|
||||
public class WoolHopperCounterConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enabled")
|
||||
public static boolean enabled = false;
|
||||
|
||||
@ConfigInfo(name = "unlimited-speed")
|
||||
public static boolean unlimitedSpeed = false;
|
||||
|
||||
@Override
|
||||
public void onLoaded(CommentedFileConfig configInstance, @Nullable Set<Exception> exs) {
|
||||
if (enabled) new CounterCommand().register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnloaded(CommentedFileConfig configInstance) {
|
||||
Bukkit.getCommandMap().getKnownCommands().remove("luminol:tpsbar");
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package fun.bm.lophine.config.modules.function.protocol;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "appleskin", directory = {"protocol"})
|
||||
public class AppleSkinProtocolConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enabled", comments = """
|
||||
Enable AppleSkin protocol support""")
|
||||
public static boolean enabled = false;
|
||||
@ConfigInfo(name = "sync-tick-interval", comments = """
|
||||
Set AppleSkin Synchronization Frequency (Unit: Game Ticks)""")
|
||||
public static int syncTickInterval = 20;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package fun.bm.lophine.config.modules.function.protocol;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "bbor", directory = {"protocol"})
|
||||
public class BBORProtocolConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enabled", comments = """
|
||||
Enable BBOR protocol support""")
|
||||
public static boolean enabled = false;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package fun.bm.lophine.config.modules.function.protocol;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "jade", directory = {"protocol"})
|
||||
public class JadeProtocolConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enabled", comments = """
|
||||
Enable Jade protocol support""")
|
||||
public static boolean enabled = false;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package fun.bm.lophine.config.modules.function.protocol;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "rei", directory = {"protocol"})
|
||||
public class REIServerProtocolConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enabled", comments = """
|
||||
Enable Roughly Enough Items protocol support""")
|
||||
public static boolean enabled = false;
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package fun.bm.lophine.config.modules.function.protocol;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.CommandSuggestions;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "servux", directory = {"protocol"})
|
||||
public class ServuxProtocolConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "entity-protocol", directory = {"function", "servux-protocol", "data"})
|
||||
@TransformedConfig(name = "entity-protocol", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "entity-protocol", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "entity-protocol", directory = {"data"})
|
||||
public static boolean entityProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-logger-protocol", directory = {"function", "servux-protocol"})
|
||||
@TransformedConfig(name = "hud-logger-protocol", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "hud-logger-protocol", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "hud-logger-protocol")
|
||||
public static boolean hudLoggerProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-metadata-protocol", directory = {"function", "servux-protocol"})
|
||||
@TransformedConfig(name = "hud-metadata-protocol", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "hud-metadata-protocol", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "hud-metadata-protocol")
|
||||
public static boolean hudMetadataProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-metadata-share-seed", directory = {"function", "servux-protocol"})
|
||||
@TransformedConfig(name = "hud-metadata-share-seed", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "hud-metadata-share-seed", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "hud-metadata-share-seed")
|
||||
public static boolean hudMetadataShareSeed = false;
|
||||
|
||||
@TransformedConfig(name = "structure-protocol", directory = {"function", "servux-protocol"})
|
||||
@TransformedConfig(name = "structure-protocol", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "structure-protocol", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "structure-protocol")
|
||||
public static boolean structureProtocol = false;
|
||||
|
||||
@TransformedConfig(name = "hud-enabled-loggers", directory = {"function", "servux-protocol"})
|
||||
@TransformedConfig(name = "hud-enabled-loggers", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "hud-enabled-loggers", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "hud-enabled-loggers")
|
||||
public static List<String> hudEnabledLoggers = List.of("tps", "mob_caps");
|
||||
|
||||
@TransformedConfig(name = "hud-update-interval", directory = {"function", "servux-protocol"})
|
||||
@TransformedConfig(name = "hud-update-interval", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "hud-update-interval", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "hud-update-interval")
|
||||
public static int hudUpdateInterval = 1;
|
||||
|
||||
@TransformedConfig(name = "litematics-enabled", directory = {"function", "servux-protocol", "litematics"})
|
||||
@TransformedConfig(name = "litematics-enabled", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "litematics-enabled", directory = {"misc", "survux-protocol"})
|
||||
@ConfigInfo(name = "litematics-enabled", directory = {"litematics"})
|
||||
public static boolean litematicsEnabled = false;
|
||||
|
||||
@TransformedConfig(name = "litematics-max-nbt-size", directory = {"function", "servux-protocol", "litematics"})
|
||||
@TransformedConfig(name = "litematics-max-nbt-size", directory = {"function", "survux-protocol"})
|
||||
@TransformedConfig(name = "litematics-max-nbt-size", directory = {"misc", "survux-protocol"})
|
||||
@CommandSuggestions(suggest = {"-1", "2097152"})
|
||||
@ConfigInfo(name = "litematics-max-nbt-size", directory = {"litematics"})
|
||||
public static int litematicsMaxNbtSize = 2097152;
|
||||
|
||||
@TransformedConfig(name = "litematics-print-max-delay-ticks", directory = {"function", "servux-protocol", "litematics"})
|
||||
@TransformedConfig(name = "litematics-print-max-delay-ticks", directory = {"function", "survux-protocol"})
|
||||
@CommandSuggestions(suggest = {"-1", "1200"})
|
||||
@ConfigInfo(name = "litematics-print-max-delay-ticks", directory = {"litematics"}, comments = "The max delay ticks for printing litematics, -1 to disable")
|
||||
public static int maxDelay = 1200;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package fun.bm.lophine.config.modules.function.protocol;
|
||||
|
||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "syncmatica", directory = {"protocol"})
|
||||
public class SyncmaticaProtocolConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enabled", comments = """
|
||||
Enable Syncmatica protocol support""")
|
||||
public static boolean enabled = false;
|
||||
@ConfigInfo(name = "useQuota", comments = """
|
||||
Is there a limit on the size of projection files?""")
|
||||
public static boolean useQuota = false;
|
||||
@ConfigInfo(name = "quota-Limit", comments = """
|
||||
Maximum Projection File Size (in bytes)""")
|
||||
public static int quotaLimit = 40000000;
|
||||
|
||||
public void onLoaded(CommentedFileConfig configInstance, @Nullable Set<Exception> e) {
|
||||
SyncmaticaProtocol.init(enabled);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package fun.bm.lophine.config.modules.function.protocol;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.FUNCTION, name = "xaero-map", directory = {"protocol"})
|
||||
public class XaeroMapProtocolConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "enabled", comments = """
|
||||
Enable Xaero World Map Protocol Support""")
|
||||
public static boolean enabled = false;
|
||||
@ConfigInfo(name = "xaeroMapServerID")
|
||||
public static int xaeroMapServerID = new Random().nextInt();
|
||||
}
|
||||
+3
-3
@@ -5,13 +5,13 @@ import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "disable-check")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.MISC, name = "disable-check")
|
||||
public class DisableCheckConfig implements IConfigModule {
|
||||
@ConfigInfo(baseName = "disable-op-move-check", comments = """
|
||||
@ConfigInfo(name = "disable-op-move-check", comments = """
|
||||
Disable the check for the operator's move check""")
|
||||
public static boolean disableOpMoveCheck = false;
|
||||
|
||||
@ConfigInfo(baseName = "disable-op-fly-check", comments = """
|
||||
@ConfigInfo(name = "disable-op-fly-check", comments = """
|
||||
Disable the check for the operator's fly check""")
|
||||
public static boolean disableOpFlyCheck = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package fun.bm.lophine.config.modules.misc;
|
||||
|
||||
import me.earthme.luminol.config.IConfigModule;
|
||||
import me.earthme.luminol.config.flags.ConfigClassInfo;
|
||||
import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(category = EnumConfigCategory.MISC, name = "item-entity")
|
||||
public class ItemEntityConfig implements IConfigModule {
|
||||
@ConfigInfo(name = "follow-tick-sequence-merge", comments = """
|
||||
Due to Paper's modification of the merge radius,
|
||||
when the merge radius is large and stacks containing many items get stuck in an unexpected position,
|
||||
individual items may never reach their destination.
|
||||
This configuration option is added to fix this behavior.""")
|
||||
public static boolean followTickSequenceMerge = false;
|
||||
}
|
||||
+14
-13
@@ -6,20 +6,21 @@ import me.earthme.luminol.config.flags.ConfigInfo;
|
||||
import me.earthme.luminol.config.flags.TransformedConfig;
|
||||
import me.earthme.luminol.enums.EnumConfigCategory;
|
||||
|
||||
@ConfigClassInfo(configAttribution = EnumConfigCategory.REMOVED, mainName = "removed_config")
|
||||
@ConfigClassInfo(category = EnumConfigCategory.REMOVED, name = "removed_config")
|
||||
public class RemovedConfig implements IConfigModule {
|
||||
@TransformedConfig(name = "disable_end_crystal_check", category = {"fixes", "end_crystal"}, transform = false)
|
||||
@TransformedConfig(name = "disable_end_crystal_check", category = {"misc", "end_crystal"}, transform = false)
|
||||
@TransformedConfig(name = "allow_skip_cooldown", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "bad_omen_infinite", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "skip_height_check", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "skip_self_raid_check", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "use_old_position_find", category = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "vanilla_hopper", category = {"misc", "redstone"}, transform = false)
|
||||
@TransformedConfig(name = "old_replaceable_by_mushrooms", category = {"misc", "old-feature"}, transform = false)
|
||||
@TransformedConfig(name = "old_nether_portal_collision", category = {"misc", "old-feature"}, transform = false)
|
||||
@TransformedConfig(name = "better_shulker_box", category = {"misc", "container_expansion"}, transform = false)
|
||||
@ConfigInfo(baseName = "removed", comments =
|
||||
@TransformedConfig(name = "datapack_command_enabled", directory = {"experiment", "command"}, transform = false)
|
||||
@TransformedConfig(name = "disable_end_crystal_check", directory = {"fixes", "end_crystal"}, transform = false)
|
||||
@TransformedConfig(name = "disable_end_crystal_check", directory = {"misc", "end_crystal"}, transform = false)
|
||||
@TransformedConfig(name = "allow_skip_cooldown", directory = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "bad_omen_infinite", directory = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "skip_height_check", directory = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "skip_self_raid_check", directory = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "use_old_position_find", directory = {"misc", "revert_raid_changes"}, transform = false)
|
||||
@TransformedConfig(name = "vanilla_hopper", directory = {"misc", "redstone"}, transform = false)
|
||||
@TransformedConfig(name = "old_replaceable_by_mushrooms", directory = {"misc", "old-feature"}, transform = false)
|
||||
@TransformedConfig(name = "old_nether_portal_collision", directory = {"misc", "old-feature"}, transform = false)
|
||||
@TransformedConfig(name = "better_shulker_box", directory = {"misc", "container_expansion"}, transform = false)
|
||||
@ConfigInfo(name = "removed", comments =
|
||||
"""
|
||||
RemovedConfig redirect to here, no any function.""")
|
||||
public static boolean enabled = true;
|
||||
|
||||
@@ -6,9 +6,9 @@ import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import fun.bm.lophine.config.modules.function.LanguageConfig;
|
||||
import io.papermc.paper.ServerBuildInfo;
|
||||
import me.earthme.luminol.config.ConfigManager;
|
||||
import me.earthme.luminol.config.ConfigsInstance;
|
||||
import net.minecraft.DetectedVersion;
|
||||
import net.minecraft.locale.DeprecatedTranslationsInfo;
|
||||
import net.minecraft.locale.Language;
|
||||
import net.minecraft.network.chat.FormattedText;
|
||||
@@ -41,7 +41,7 @@ import java.util.function.BiConsumer;
|
||||
*/
|
||||
public class ServerI18nUtil {
|
||||
private static final Logger logger = LogUtils.getClassLogger();
|
||||
private static final String VERSION = DetectedVersion.BUILT_IN.name();
|
||||
private static final String VERSION = ServerBuildInfo.buildInfo().minecraftVersionId();
|
||||
private static final String BASE_PATH = "cache/lophine/" + VERSION + "/";
|
||||
private static final String defaultLophineLangPath = "/assets/lophine/lang/en_us.json";
|
||||
private static final String manifestUrl = "https://launchermeta.mojang.com/mc/game/version_manifest.json";
|
||||
@@ -83,8 +83,8 @@ public class ServerI18nUtil {
|
||||
logger.warn("Unsupported language: {}", LanguageConfig.lang);
|
||||
// Fallback to English
|
||||
final ConfigsInstance configsInstance = ConfigManager.configfiles.get("lophine");
|
||||
configsInstance.setConfig(new String[]{"optimizations", "lang"}, "en_us");
|
||||
configsInstance.reloadAsync();
|
||||
configsInstance.setConfig(new String[]{"function", "language", "lang"}, "en_us");
|
||||
configsInstance.reloadAsync(true);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof MalformedJsonException malformedJson) {
|
||||
malformedJson.clean();
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
|
||||
package org.leavesmc.leaves.bot;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.threadedregions.RegionizedServer;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
@@ -41,6 +43,7 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
@@ -51,6 +54,7 @@ import org.slf4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class BotList {
|
||||
|
||||
@@ -67,6 +71,8 @@ public class BotList {
|
||||
private final Map<String, ServerBot> botsByName = Maps.newHashMap();
|
||||
private final Map<String, Set<String>> botsNameByWorldUuid = Maps.newHashMap();
|
||||
|
||||
public boolean forceShutdown = false;
|
||||
|
||||
public BotList(MinecraftServer server) {
|
||||
this.server = server;
|
||||
this.dataStorage = new BotDataStorage(server.storageSource);
|
||||
@@ -129,7 +135,7 @@ public class BotList {
|
||||
|
||||
ResourceKey<Level> resourcekey = null;
|
||||
if (nbt.getLong("WorldUUIDMost").isPresent() && nbt.getLong("WorldUUIDLeast").isPresent()) {
|
||||
org.bukkit.World bWorld = Bukkit.getServer().getWorld(new UUID(nbt.getLong("WorldUUIDMost").orElseThrow(), nbt.getLong("WorldUUIDLeast").orElseThrow()));
|
||||
World bWorld = Bukkit.getServer().getWorld(new UUID(nbt.getLong("WorldUUIDMost").orElseThrow(), nbt.getLong("WorldUUIDLeast").orElseThrow()));
|
||||
if (bWorld != null) {
|
||||
resourcekey = ((CraftWorld) bWorld).getHandle().dimension();
|
||||
}
|
||||
@@ -167,11 +173,24 @@ public class BotList {
|
||||
this.botsByUUID.put(bot.getUUID(), bot);
|
||||
|
||||
bot.supressTrackerForLogin = true;
|
||||
world.addNewPlayer(bot);
|
||||
|
||||
if (TickThread.isTickThreadFor(world, net.minecraft.util.Mth.floor(location.getX()) >> 4, net.minecraft.util.Mth.floor(location.getZ()) >> 4)) {
|
||||
summonBot(bot, world);
|
||||
} else {
|
||||
RegionizedServer.getInstance().taskQueue.queueTickTaskQueue(
|
||||
world, net.minecraft.util.Mth.floor(location.getX()) >> 4, net.minecraft.util.Mth.floor(location.getZ()) >> 4,
|
||||
() -> summonBot(bot, world),
|
||||
ca.spottedleaf.concurrentutil.util.Priority.HIGHER);
|
||||
}
|
||||
optional.ifPresent(nbt -> {
|
||||
bot.loadAndSpawnEnderPearls(nbt);
|
||||
bot.loadAndSpawnParentVehicle(nbt);
|
||||
});
|
||||
return bot;
|
||||
}
|
||||
|
||||
private ServerBot summonBot(ServerBot bot, ServerLevel world) {
|
||||
world.addNewPlayer(bot);
|
||||
|
||||
BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitEntity(), PaperAdventure.asAdventure(Component.translatable("multiplayer.player.joined", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW)));
|
||||
this.server.server.getPluginManager().callEvent(event1);
|
||||
@@ -194,6 +213,18 @@ public class BotList {
|
||||
return bot;
|
||||
}
|
||||
|
||||
/*
|
||||
* return true if async
|
||||
*/
|
||||
public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean saved, boolean async) {
|
||||
if (async && !TickThread.isTickThreadFor(bot.level(), bot.getX(), bot.getZ())) {
|
||||
bot.getBukkitEntity().taskScheduler.schedule((Entity unused) -> this.removeBot(bot, reason, remover, saved), null, 1L);
|
||||
return true;
|
||||
}
|
||||
this.removeBot(bot, reason, remover, saved);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean saved) {
|
||||
return this.removeBot(bot, reason, remover, saved, this.dataStorage);
|
||||
}
|
||||
@@ -225,7 +256,7 @@ public class BotList {
|
||||
if (entity.hasExactlyOnePlayerPassenger()) {
|
||||
bot.stopRiding();
|
||||
entity.getPassengersAndSelf().forEach((entity1) -> {
|
||||
if (!false && entity1 instanceof AbstractVillager villager) {
|
||||
if (entity1 instanceof AbstractVillager villager) {
|
||||
final Player human = villager.getTradingPlayer();
|
||||
if (human != null) {
|
||||
villager.setTradingPlayer(null);
|
||||
@@ -279,11 +310,40 @@ public class BotList {
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
public boolean removeAll() {
|
||||
boolean finished = true;
|
||||
AtomicInteger check = new AtomicInteger();
|
||||
AtomicInteger received = new AtomicInteger();
|
||||
for (ServerBot bot : this.bots) {
|
||||
bot.resume = FakeplayerConfig.canResident;
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident);
|
||||
if (TickThread.isTickThreadFor(bot.level(), bot.getX(), bot.getZ())) {
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident);
|
||||
} else {
|
||||
finished = false;
|
||||
check.getAndIncrement();
|
||||
this.removeBot(bot, check, received, new AtomicInteger());
|
||||
}
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
private void removeBot(ServerBot bot, AtomicInteger check, AtomicInteger received, AtomicInteger counter) {
|
||||
bot.getBukkitEntity().taskScheduler.schedule((Entity unused) -> {
|
||||
if (counter.get() >= 20) {
|
||||
BotList.LOGGER.info("Try to remove bot {} located in [{}]{},{},{} too many times!", bot.getName().getString(), bot.level().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ());
|
||||
}
|
||||
counter.getAndIncrement();
|
||||
try {
|
||||
this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, FakeplayerConfig.canResident);
|
||||
received.getAndIncrement();
|
||||
} catch (Exception e) {
|
||||
this.removeBot(bot, check, received, counter);
|
||||
}
|
||||
if (received.get() >= check.get()) {
|
||||
this.forceShutdown = true;
|
||||
MinecraftServer.getServer().stopServer();
|
||||
}
|
||||
}, null, 1L);
|
||||
}
|
||||
|
||||
public void loadBotInfo() {
|
||||
|
||||
@@ -154,7 +154,7 @@ public class ServerBot extends ServerPlayer {
|
||||
this.notSleepTicks++;
|
||||
}
|
||||
|
||||
if (FakeplayerConfig.regenAmount > 0.0 && getServer().getTickCount() % 20 == 0) {
|
||||
if (FakeplayerConfig.regenAmount > 0.0 && this.tickCount % 20 == 0) {
|
||||
float regenAmount = (float) (FakeplayerConfig.regenAmount * 20);
|
||||
this.setHealth(Math.min(this.getHealth() + regenAmount, this.getMaxHealth()));
|
||||
}
|
||||
|
||||
+16
-5
@@ -20,9 +20,12 @@ package org.leavesmc.leaves.bot.agent.configs;
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
import fun.bm.lophine.config.modules.experiment.CommandConfig;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import me.earthme.luminol.utils.NullPlugin;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.waypoints.ServerWaypointManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
public class LocatorBarConfig extends AbstractBotConfig<Boolean, Boolean, LocatorBarConfig> {
|
||||
@@ -40,12 +43,20 @@ public class LocatorBarConfig extends AbstractBotConfig<Boolean, Boolean, Locato
|
||||
|
||||
@Override
|
||||
public void setValue(@NotNull Boolean value) throws IllegalArgumentException {
|
||||
this.value = value;
|
||||
ServerWaypointManager manager = this.bot.level().getWaypointManager();
|
||||
if (value) {
|
||||
manager.trackWaypoint(this.bot);
|
||||
if (bot == null) {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task) -> setValue(value), 20);
|
||||
} else {
|
||||
manager.untrackWaypoint(this.bot);
|
||||
setValue(value, this.bot);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(@NotNull Boolean value, ServerBot bot) throws IllegalArgumentException {
|
||||
this.value = value;
|
||||
ServerWaypointManager manager = bot.level().getWaypointManager();
|
||||
if (value) {
|
||||
manager.trackWaypoint(bot);
|
||||
} else {
|
||||
manager.untrackWaypoint(bot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -20,7 +20,9 @@ package org.leavesmc.leaves.bot.agent.configs;
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import me.earthme.luminol.utils.NullPlugin;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
@@ -66,6 +68,10 @@ public class SimulationDistanceConfig extends AbstractBotConfig<Integer, Integer
|
||||
|
||||
@Override
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
this.setValue(nbt.getIntOr(getName(), FakeplayerConfig.getSimulationDistance(this.bot)));
|
||||
if (this.bot == null) {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task) -> load(nbt), 20);
|
||||
} else {
|
||||
this.setValue(nbt.getIntOr(getName(), FakeplayerConfig.getSimulationDistance(this.bot)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -19,8 +19,11 @@ package org.leavesmc.leaves.bot.agent.configs;
|
||||
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import me.earthme.luminol.utils.NullPlugin;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.ServerBot;
|
||||
import org.leavesmc.leaves.command.CommandContext;
|
||||
|
||||
public class SkipSleepConfig extends AbstractBotConfig<Boolean, Boolean, SkipSleepConfig> {
|
||||
@@ -35,7 +38,15 @@ public class SkipSleepConfig extends AbstractBotConfig<Boolean, Boolean, SkipSle
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Boolean value) throws IllegalArgumentException {
|
||||
public void setValue(@NotNull Boolean value) throws IllegalArgumentException {
|
||||
if (bot == null) {
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(new NullPlugin(), (task) -> setValue(value), 20);
|
||||
} else {
|
||||
setValue(value, this.bot);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(@NotNull Boolean value, ServerBot bot) throws IllegalArgumentException {
|
||||
bot.fauxSleeping = value;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ public class TickTypeConfig extends AbstractBotConfig<ServerBot.TickType, String
|
||||
@Override
|
||||
public void load(@NotNull CompoundTag nbt) {
|
||||
String raw = nbt.getStringOr(getName(), FakeplayerConfig.tickType.name());
|
||||
this.setValue(switch (raw) {
|
||||
this.setValue(switch (raw.toLowerCase()) {
|
||||
case "network" -> ServerBot.TickType.NETWORK;
|
||||
case "entity_list" -> ServerBot.TickType.ENTITY_LIST;
|
||||
default -> throw new IllegalStateException("Unexpected bot tick type value: " + raw);
|
||||
|
||||
+14
@@ -20,6 +20,7 @@ package org.leavesmc.leaves.command.bot.subcommands;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -50,6 +51,19 @@ public class RemoveCommand extends BotSubcommand {
|
||||
}
|
||||
|
||||
private static boolean removeBot(@NotNull ServerBot bot, @Nullable CommandSender sender) {
|
||||
return removeBot(bot, sender, true);
|
||||
}
|
||||
|
||||
private static boolean removeBot(@NotNull ServerBot bot, @Nullable CommandSender sender, boolean taskQueue) {
|
||||
if (taskQueue) {
|
||||
bot.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> removeBotOrigin(bot, sender), null, 1L);
|
||||
} else {
|
||||
return removeBotOrigin(bot, sender);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean removeBotOrigin(@NotNull ServerBot bot, @Nullable CommandSender sender) {
|
||||
boolean success = BotList.INSTANCE.removeBot(bot, BotRemoveEvent.RemoveReason.COMMAND, sender, false);
|
||||
if (!success) {
|
||||
sender = sender == null ? Bukkit.getConsoleSender() : sender;
|
||||
|
||||
+19
-2
@@ -21,6 +21,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.bot.BotList;
|
||||
@@ -55,8 +56,24 @@ public class SaveCommand extends BotSubcommand {
|
||||
|
||||
@Override
|
||||
protected boolean execute(@NotNull CommandContext context) throws CommandSyntaxException {
|
||||
ServerBot bot = context.getCustomArgument(BotArgument.class);
|
||||
CommandSender sender = context.getSender();
|
||||
save(context.getCustomArgument(BotArgument.class), context.getSender());
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean save(ServerBot bot, CommandSender sender) {
|
||||
return save(bot, sender, true);
|
||||
}
|
||||
|
||||
private boolean save(ServerBot bot, CommandSender sender, boolean taskQueue) {
|
||||
if (taskQueue) {
|
||||
bot.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> saveOrigin(bot, sender), null, 1L);
|
||||
} else {
|
||||
saveOrigin(bot, sender);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean saveOrigin(ServerBot bot, CommandSender sender) {
|
||||
BotList botList = BotList.INSTANCE;
|
||||
|
||||
boolean success = botList.removeBot(bot, BotRemoveEvent.RemoveReason.COMMAND, sender, true);
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol;
|
||||
|
||||
import fun.bm.lophine.config.modules.function.protocol.AppleSkinProtocolConfig;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.food.FoodData;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.core.Context;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "appleskin")
|
||||
public class AppleSkinProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID = "appleskin";
|
||||
|
||||
private static final ResourceLocation SATURATION_KEY = id("saturation");
|
||||
private static final ResourceLocation EXHAUSTION_KEY = id("exhaustion");
|
||||
private static final ResourceLocation NATURAL_REGENERATION_KEY = id("natural_regeneration");
|
||||
|
||||
private static final float MINIMUM_EXHAUSTION_CHANGE_THRESHOLD = 0.01F;
|
||||
|
||||
private static final Map<ServerPlayer, Float> previousSaturationLevels = new ConcurrentHashMap<>();
|
||||
private static final Map<ServerPlayer, Float> previousExhaustionLevels = new ConcurrentHashMap<>();
|
||||
private static final Map<ServerPlayer, Boolean> previousNaturalRegeneration = new ConcurrentHashMap<>();
|
||||
|
||||
private static final Map<UUID, Set<String>> subscribedChannels = new ConcurrentHashMap<>();
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation id(String path) {
|
||||
return ResourceLocation.tryBuild(PROTOCOL_ID, path);
|
||||
}
|
||||
|
||||
@ProtocolHandler.PlayerJoin
|
||||
public static void onPlayerLoggedIn(@NotNull ServerPlayer player) {
|
||||
resetPlayerData(player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.PlayerLeave
|
||||
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
|
||||
subscribedChannels.remove(player.getUUID());
|
||||
resetPlayerData(player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.MinecraftRegister(onlyNamespace = true)
|
||||
public static void onPlayerSubscribed(@NotNull Context context, ResourceLocation id) {
|
||||
subscribedChannels.computeIfAbsent(context.profile().getId(), k -> new HashSet<>()).add(id.getPath());
|
||||
}
|
||||
|
||||
@ProtocolHandler.Ticker
|
||||
public static void tick() {
|
||||
for (Map.Entry<UUID, Set<String>> entry : subscribedChannels.entrySet()) {
|
||||
ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(entry.getKey());
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FoodData data = player.getFoodData();
|
||||
for (String channel : entry.getValue()) {
|
||||
switch (channel) {
|
||||
case "saturation" -> {
|
||||
float saturation = data.getSaturationLevel();
|
||||
Float previousSaturation = previousSaturationLevels.get(player);
|
||||
if (previousSaturation == null || saturation != previousSaturation) {
|
||||
ProtocolUtils.sendBytebufPacket(player, SATURATION_KEY, buf -> buf.writeFloat(saturation));
|
||||
previousSaturationLevels.put(player, saturation);
|
||||
}
|
||||
}
|
||||
|
||||
case "exhaustion" -> {
|
||||
float exhaustion = data.exhaustionLevel;
|
||||
Float previousExhaustion = previousExhaustionLevels.get(player);
|
||||
if (previousExhaustion == null || Math.abs(exhaustion - previousExhaustion) >= MINIMUM_EXHAUSTION_CHANGE_THRESHOLD) {
|
||||
ProtocolUtils.sendBytebufPacket(player, EXHAUSTION_KEY, buf -> buf.writeFloat(exhaustion));
|
||||
previousExhaustionLevels.put(player, exhaustion);
|
||||
}
|
||||
}
|
||||
|
||||
case "natural_regeneration" -> {
|
||||
boolean regeneration = player.level().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION);
|
||||
Boolean previousRegeneration = previousNaturalRegeneration.get(player);
|
||||
if (previousRegeneration == null || regeneration != previousRegeneration) {
|
||||
ProtocolUtils.sendBytebufPacket(player, NATURAL_REGENERATION_KEY, buf -> buf.writeBoolean(regeneration));
|
||||
previousNaturalRegeneration.put(player, regeneration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.ReloadServer
|
||||
public static void onServerReload() {
|
||||
disableAllPlayer();
|
||||
}
|
||||
|
||||
public static void disableAllPlayer() {
|
||||
for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
|
||||
onPlayerLoggedOut(player);
|
||||
}
|
||||
}
|
||||
|
||||
private static void resetPlayerData(@NotNull ServerPlayer player) {
|
||||
previousExhaustionLevels.remove(player);
|
||||
previousSaturationLevels.remove(player);
|
||||
previousNaturalRegeneration.remove(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int tickerInterval(String tickerID) {
|
||||
return AppleSkinProtocolConfig.syncTickInterval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return AppleSkinProtocolConfig.enabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol;
|
||||
|
||||
import fun.bm.lophine.config.modules.function.protocol.BBORProtocolConfig;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructurePiece;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "bbor")
|
||||
public class BBORProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID = "bbor";
|
||||
|
||||
// send
|
||||
private static final ResourceLocation INITIALIZE_CLIENT = id("initialize");
|
||||
private static final ResourceLocation ADD_BOUNDING_BOX = id("add_bounding_box_v2");
|
||||
private static final ResourceLocation STRUCTURE_LIST_SYNC = id("structure_list_sync_v1");
|
||||
// call
|
||||
private static final Map<Integer, ServerPlayer> players = new ConcurrentHashMap<>();
|
||||
private static final Map<Integer, Set<BBoundingBox>> playerBoundingBoxesCache = new ConcurrentHashMap<>();
|
||||
private static final Map<ResourceLocation, Map<BBoundingBox, Set<BBoundingBox>>> dimensionCache = new ConcurrentHashMap<>();
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation id(String path) {
|
||||
return ResourceLocation.tryBuild(PROTOCOL_ID, path);
|
||||
}
|
||||
|
||||
@ProtocolHandler.Ticker
|
||||
public static void tick() {
|
||||
for (var playerEntry : players.entrySet()) {
|
||||
sendBoundingToPlayer(playerEntry.getKey(), playerEntry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.ReloadServer
|
||||
public static void onServerReload() {
|
||||
if (BBORProtocolConfig.enabled) {
|
||||
initAllPlayer();
|
||||
} else {
|
||||
loggedOutAllPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.PlayerJoin
|
||||
public static void onPlayerLoggedIn(@NotNull ServerPlayer player) {
|
||||
ServerLevel overworld = MinecraftServer.getServer().overworld();
|
||||
ProtocolUtils.sendBytebufPacket(player, INITIALIZE_CLIENT, buf -> {
|
||||
buf.writeLong(overworld.getSeed());
|
||||
buf.writeInt(overworld.levelData.getSpawnPos().getX());
|
||||
buf.writeInt(overworld.levelData.getSpawnPos().getZ());
|
||||
});
|
||||
sendStructureList(player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.PlayerLeave
|
||||
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
|
||||
players.remove(player.getId());
|
||||
playerBoundingBoxesCache.remove(player.getId());
|
||||
}
|
||||
|
||||
@ProtocolHandler.BytebufReceiver(key = "subscribe")
|
||||
public static void onPlayerSubscribed(@NotNull ServerPlayer player, FriendlyByteBuf buf) {
|
||||
players.put(player.getId(), player);
|
||||
sendBoundingToPlayer(player.getId(), player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.ReloadDataPack
|
||||
public static void onDataPackReload() {
|
||||
players.values().forEach(BBORProtocol::sendStructureList);
|
||||
}
|
||||
|
||||
public static void onChunkLoaded(@NotNull LevelChunk chunk) {
|
||||
Map<String, StructureStart> structures = new HashMap<>();
|
||||
final Registry<Structure> structureFeatureRegistry = chunk.getLevel().registryAccess().lookupOrThrow(Registries.STRUCTURE);
|
||||
for (var es : chunk.getAllStarts().entrySet()) {
|
||||
final var optional = structureFeatureRegistry.getResourceKey(es.getKey());
|
||||
optional.ifPresent(key -> structures.put(key.location().toString(), es.getValue()));
|
||||
}
|
||||
if (!structures.isEmpty()) {
|
||||
onStructuresLoaded(chunk.getLevel().dimension().location(), structures);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onStructuresLoaded(@NotNull ResourceLocation dimensionID, @NotNull Map<String, StructureStart> structures) {
|
||||
Map<BBoundingBox, Set<BBoundingBox>> cache = getOrCreateCache(dimensionID);
|
||||
for (var entry : structures.entrySet()) {
|
||||
StructureStart structureStart = entry.getValue();
|
||||
if (structureStart == null || !structureStart.isValid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String type = "structure:" + entry.getKey();
|
||||
BoundingBox bb = structureStart.getBoundingBox();
|
||||
BBoundingBox boundingBox = buildStructure(bb, type);
|
||||
if (cache.containsKey(boundingBox)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<BBoundingBox> structureBoundingBoxes = new HashSet<>();
|
||||
if (!structureStart.getPieces().isEmpty()) {
|
||||
for (StructurePiece structureComponent : structureStart.getPieces()) {
|
||||
structureBoundingBoxes.add(buildStructure(structureComponent.getBoundingBox(), type));
|
||||
}
|
||||
cache.put(boundingBox, structureBoundingBoxes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static @NotNull BBoundingBox buildStructure(@NotNull BoundingBox bb, String type) {
|
||||
BlockPos min = new BlockPos(bb.minX(), bb.minY(), bb.minZ());
|
||||
BlockPos max = new BlockPos(bb.maxX(), bb.maxY(), bb.maxZ());
|
||||
return new BBoundingBox(type, min, max);
|
||||
}
|
||||
|
||||
private static void sendStructureList(@NotNull ServerPlayer player) {
|
||||
final Registry<Structure> structureRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.STRUCTURE);
|
||||
final Set<String> structureIds = structureRegistry.entrySet().stream()
|
||||
.map(e -> e.getKey().location().toString()).collect(Collectors.toSet());
|
||||
ProtocolUtils.sendBytebufPacket(player, STRUCTURE_LIST_SYNC, buf -> {
|
||||
buf.writeVarInt(structureIds.size());
|
||||
structureIds.forEach(buf::writeUtf);
|
||||
});
|
||||
}
|
||||
|
||||
private static void sendBoundingToPlayer(int id, ServerPlayer player) {
|
||||
for (var entry : dimensionCache.entrySet()) {
|
||||
if (entry.getValue() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<BBoundingBox> playerBoundingBoxes = playerBoundingBoxesCache.computeIfAbsent(id, k -> new HashSet<>());
|
||||
Map<BBoundingBox, Set<BBoundingBox>> boundingBoxMap = entry.getValue();
|
||||
for (BBoundingBox key : boundingBoxMap.keySet()) {
|
||||
if (playerBoundingBoxes.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<BBoundingBox> boundingBoxes = boundingBoxMap.get(key);
|
||||
ProtocolUtils.sendBytebufPacket(player, ADD_BOUNDING_BOX, buf -> {
|
||||
buf.writeResourceLocation(entry.getKey());
|
||||
key.serialize(buf);
|
||||
if (boundingBoxes != null && boundingBoxes.size() > 1) {
|
||||
for (BBoundingBox box : boundingBoxes) {
|
||||
box.serialize(buf);
|
||||
}
|
||||
}
|
||||
});
|
||||
playerBoundingBoxes.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void initAllPlayer() {
|
||||
for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
|
||||
onPlayerLoggedIn(player);
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
public static void loggedOutAllPlayer() {
|
||||
players.clear();
|
||||
playerBoundingBoxesCache.clear();
|
||||
for (var cache : dimensionCache.values()) {
|
||||
cache.clear();
|
||||
}
|
||||
dimensionCache.clear();
|
||||
}
|
||||
|
||||
private static Map<BBoundingBox, Set<BBoundingBox>> getOrCreateCache(ResourceLocation dimensionId) {
|
||||
return dimensionCache.computeIfAbsent(dimensionId, dt -> new ConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
boolean active = BBORProtocolConfig.enabled;
|
||||
if (!active && initialized) {
|
||||
initialized = false;
|
||||
loggedOutAllPlayer();
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
private record BBoundingBox(String type, BlockPos min, BlockPos max) {
|
||||
|
||||
private static int combineHashCodes(int @NotNull ... hashCodes) {
|
||||
final int prime = 31;
|
||||
int result = 0;
|
||||
for (int hashCode : hashCodes) {
|
||||
result = prime * result + hashCode;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void serialize(@NotNull FriendlyByteBuf buf) {
|
||||
buf.writeChar('S');
|
||||
buf.writeInt(type.hashCode());
|
||||
buf.writeVarInt(min.getX()).writeVarInt(min.getY()).writeVarInt(min.getZ());
|
||||
buf.writeVarInt(max.getX()).writeVarInt(max.getY()).writeVarInt(max.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return combineHashCodes(min.hashCode(), max.hashCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol;
|
||||
|
||||
import fun.bm.lophine.config.modules.function.protocol.XaeroMapProtocolConfig;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "xaerominimap_or_xaeroworldmap_i_dont_care")
|
||||
public class XaeroMapProtocol implements LeavesProtocol {
|
||||
|
||||
public static final String PROTOCOL_ID_MINI = "xaerominimap";
|
||||
public static final String PROTOCOL_ID_WORLD = "xaeroworldmap";
|
||||
|
||||
private static final ResourceLocation MINIMAP_KEY = idMini("main");
|
||||
private static final ResourceLocation WORLDMAP_KEY = idWorld("main");
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation idMini(String path) {
|
||||
return ResourceLocation.tryBuild(PROTOCOL_ID_MINI, path);
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation idWorld(String path) {
|
||||
return ResourceLocation.tryBuild(PROTOCOL_ID_WORLD, path);
|
||||
}
|
||||
|
||||
public static void onSendWorldInfo(@NotNull ServerPlayer player) {
|
||||
if (XaeroMapProtocolConfig.enabled) {
|
||||
ProtocolUtils.sendBytebufPacket(player, MINIMAP_KEY, buf -> {
|
||||
buf.writeByte(0);
|
||||
buf.writeInt(XaeroMapProtocolConfig.xaeroMapServerID);
|
||||
});
|
||||
ProtocolUtils.sendBytebufPacket(player, WORLDMAP_KEY, buf -> {
|
||||
buf.writeByte(0);
|
||||
buf.writeInt(XaeroMapProtocolConfig.xaeroMapServerID);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return XaeroMapProtocolConfig.enabled;
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -65,6 +65,8 @@ public class LeavesProtocolManager {
|
||||
private static final List<EmptyInvokerHolder<ProtocolHandler.ReloadServer>> RELOAD_SERVER = new ArrayList<>();
|
||||
private static final List<EmptyInvokerHolder<ProtocolHandler.ReloadDataPack>> RELOAD_DATAPACK = new ArrayList<>();
|
||||
|
||||
private static long lastAcceptTime = 0;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void init() {
|
||||
for (Class<?> clazz : getClasses("org.leavesmc.leaves.protocol")) {
|
||||
@@ -251,9 +253,12 @@ public class LeavesProtocolManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void handleTick(long tickCount) {
|
||||
public static void handleTick() {
|
||||
long currentTime = System.currentTimeMillis() / 50;
|
||||
if (currentTime == lastAcceptTime) return;
|
||||
lastAcceptTime = currentTime;
|
||||
for (var tickerInfo : TICKERS) {
|
||||
if (tickCount % tickerInfo.owner().tickerInterval(tickerInfo.handler().tickerId()) == 0) {
|
||||
if (currentTime % tickerInfo.owner().tickerInterval(tickerInfo.handler().tickerId()) == 0) {
|
||||
tickerInfo.invoke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.util.TickThread;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import fun.bm.lophine.config.modules.function.protocol.JadeProtocolConfig;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.AgeableMob;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.animal.Animal;
|
||||
import net.minecraft.world.entity.animal.Chicken;
|
||||
import net.minecraft.world.entity.animal.allay.Allay;
|
||||
import net.minecraft.world.entity.animal.armadillo.Armadillo;
|
||||
import net.minecraft.world.entity.animal.frog.Tadpole;
|
||||
import net.minecraft.world.entity.animal.sniffer.Sniffer;
|
||||
import net.minecraft.world.entity.monster.ZombieVillager;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.CampfireBlock;
|
||||
import net.minecraft.world.level.block.entity.*;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.EntityAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.payload.*;
|
||||
import org.leavesmc.leaves.protocol.jade.provider.*;
|
||||
import org.leavesmc.leaves.protocol.jade.provider.block.*;
|
||||
import org.leavesmc.leaves.protocol.jade.provider.entity.*;
|
||||
import org.leavesmc.leaves.protocol.jade.util.*;
|
||||
import org.leavesmc.leaves.protocol.servux.litematics.utils.NbtUtils;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@LeavesProtocol.Register(namespace = "jade")
|
||||
public class JadeProtocol implements LeavesProtocol {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static final String PROTOCOL_ID = "jade";
|
||||
public static final String PROTOCOL_VERSION = "8";
|
||||
public static final HierarchyLookup<IServerDataProvider<EntityAccessor>> entityDataProviders = new HierarchyLookup<>(Entity.class);
|
||||
public static final PairHierarchyLookup<IServerDataProvider<BlockAccessor>> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class));
|
||||
public static final WrappedHierarchyLookup<IServerExtensionProvider<ItemStack>> itemStorageProviders = WrappedHierarchyLookup.forAccessor();
|
||||
private static final Set<ServerPlayer> enabledPlayers = new HashSet<>();
|
||||
|
||||
public static PriorityStore<ResourceLocation, IJadeProvider> priorities;
|
||||
private static List<Block> shearableBlocks = null;
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static ResourceLocation id(String path) {
|
||||
return ResourceLocation.tryBuild(PROTOCOL_ID, path);
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static @NotNull ResourceLocation mc_id(String path) {
|
||||
return ResourceLocation.withDefaultNamespace(path);
|
||||
}
|
||||
|
||||
@ProtocolHandler.Init
|
||||
public static void init() {
|
||||
priorities = new PriorityStore<>(IJadeProvider::getDefaultPriority, IJadeProvider::getUid);
|
||||
|
||||
// core plugin
|
||||
blockDataProviders.register(BlockEntity.class, BlockNameProvider.INSTANCE);
|
||||
|
||||
// universal plugin
|
||||
entityDataProviders.register(Entity.class, ItemStorageProvider.getEntity());
|
||||
blockDataProviders.register(Block.class, ItemStorageProvider.getBlock());
|
||||
|
||||
itemStorageProviders.register(Object.class, ItemStorageExtensionProvider.INSTANCE);
|
||||
itemStorageProviders.register(Block.class, ItemStorageExtensionProvider.INSTANCE);
|
||||
|
||||
// vanilla plugin
|
||||
entityDataProviders.register(Entity.class, AnimalOwnerProvider.INSTANCE);
|
||||
entityDataProviders.register(LivingEntity.class, StatusEffectsProvider.INSTANCE);
|
||||
entityDataProviders.register(AgeableMob.class, MobGrowthProvider.INSTANCE);
|
||||
entityDataProviders.register(Tadpole.class, MobGrowthProvider.INSTANCE);
|
||||
entityDataProviders.register(Animal.class, MobBreedingProvider.INSTANCE);
|
||||
entityDataProviders.register(Allay.class, MobBreedingProvider.INSTANCE);
|
||||
entityDataProviders.register(Mob.class, PetArmorProvider.INSTANCE);
|
||||
|
||||
entityDataProviders.register(Chicken.class, NextEntityDropProvider.INSTANCE);
|
||||
entityDataProviders.register(Armadillo.class, NextEntityDropProvider.INSTANCE);
|
||||
entityDataProviders.register(Sniffer.class, NextEntityDropProvider.INSTANCE);
|
||||
|
||||
entityDataProviders.register(ZombieVillager.class, ZombieVillagerProvider.INSTANCE);
|
||||
|
||||
blockDataProviders.register(BrewingStandBlockEntity.class, BrewingStandProvider.INSTANCE);
|
||||
blockDataProviders.register(BeehiveBlockEntity.class, BeehiveProvider.INSTANCE);
|
||||
blockDataProviders.register(CommandBlockEntity.class, CommandBlockProvider.INSTANCE);
|
||||
blockDataProviders.register(JukeboxBlockEntity.class, JukeboxProvider.INSTANCE);
|
||||
blockDataProviders.register(LecternBlockEntity.class, LecternProvider.INSTANCE);
|
||||
|
||||
blockDataProviders.register(ComparatorBlockEntity.class, RedstoneProvider.INSTANCE);
|
||||
blockDataProviders.register(HopperBlockEntity.class, HopperLockProvider.INSTANCE);
|
||||
blockDataProviders.register(CalibratedSculkSensorBlockEntity.class, RedstoneProvider.INSTANCE);
|
||||
|
||||
blockDataProviders.register(AbstractFurnaceBlockEntity.class, FurnaceProvider.INSTANCE);
|
||||
blockDataProviders.register(ChiseledBookShelfBlockEntity.class, ChiseledBookshelfProvider.INSTANCE);
|
||||
blockDataProviders.register(TrialSpawnerBlockEntity.class, MobSpawnerCooldownProvider.INSTANCE);
|
||||
|
||||
itemStorageProviders.register(CampfireBlock.class, CampfireProvider.INSTANCE);
|
||||
|
||||
blockDataProviders.idMapped();
|
||||
entityDataProviders.idMapped();
|
||||
|
||||
blockDataProviders.loadComplete(priorities);
|
||||
entityDataProviders.loadComplete(priorities);
|
||||
itemStorageProviders.loadComplete(priorities);
|
||||
|
||||
rebuildShearableBlocks();
|
||||
}
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = ClientHandshakePayload.class)
|
||||
public static void clientHandshake(ServerPlayer player, ClientHandshakePayload payload) {
|
||||
if (!payload.protocolVersion().equals(PROTOCOL_VERSION)) {
|
||||
player.sendSystemMessage(Component.literal("You are using a different version of Jade than the server. Please update Jade or report to the server operator").withColor(0xff0000));
|
||||
return;
|
||||
}
|
||||
ProtocolUtils.sendPayloadPacket(player, new ServerHandshakePayload(Collections.emptyMap(), shearableBlocks, blockDataProviders.mappedIds(), entityDataProviders.mappedIds()));
|
||||
synchronized (enabledPlayers) {
|
||||
enabledPlayers.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.PlayerLeave
|
||||
public static void onPlayerLeave(ServerPlayer player) {
|
||||
synchronized (enabledPlayers) {
|
||||
enabledPlayers.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = RequestEntityPayload.class)
|
||||
public static void requestEntityData(ServerPlayer player, RequestEntityPayload payload) {
|
||||
player.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> {
|
||||
EntityAccessor accessor = payload.data().unpack(player);
|
||||
if (accessor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity = accessor.getEntity();
|
||||
double maxDistance = Mth.square(player.entityInteractionRange() + 21);
|
||||
if (entity == null || player.distanceToSqr(entity) > maxDistance) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<IServerDataProvider<EntityAccessor>> providers = entityDataProviders.get(entity);
|
||||
if (providers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag tag = new CompoundTag();
|
||||
for (IServerDataProvider<EntityAccessor> provider : providers) {
|
||||
if (!payload.dataProviders().contains(provider)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
provider.appendServerData(tag, accessor);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Error while saving data for entity " + entity);
|
||||
}
|
||||
}
|
||||
tag.putInt("EntityId", entity.getId());
|
||||
|
||||
ProtocolUtils.sendPayloadPacket(player, new ReceiveDataPayload(tag));
|
||||
}, null, 1L);
|
||||
}
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = RequestBlockPayload.class)
|
||||
public static void requestBlockData(ServerPlayer player, RequestBlockPayload payload) {
|
||||
ServerLevel level = player.level();
|
||||
player.getBukkitEntity().taskScheduler.schedule((LivingEntity nmsEntity) -> {
|
||||
BlockAccessor accessor = payload.data().unpack(player);
|
||||
if (accessor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
BlockPos pos = accessor.getPosition();
|
||||
Block block = accessor.getBlock();
|
||||
BlockEntity blockEntity = TickThread.isTickThreadFor(level, pos) ? accessor.getBlockEntity() : null;
|
||||
double maxDistance = Mth.square(player.blockInteractionRange() + 21);
|
||||
if (pos.distSqr(player.blockPosition()) > maxDistance || !accessor.getLevel().isLoaded(pos)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<IServerDataProvider<BlockAccessor>> providers;
|
||||
if (blockEntity != null) {
|
||||
providers = blockDataProviders.getMerged(block, blockEntity);
|
||||
} else {
|
||||
providers = blockDataProviders.first.get(block);
|
||||
}
|
||||
|
||||
if (providers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag tag = new CompoundTag();
|
||||
for (IServerDataProvider<BlockAccessor> provider : providers) {
|
||||
if (!payload.dataProviders().contains(provider)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
provider.appendServerData(tag, accessor);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn("Error while saving data for block " + accessor.getBlockState());
|
||||
}
|
||||
}
|
||||
NbtUtils.writeBlockPosToTag(pos, tag);
|
||||
tag.putString("BlockId", BuiltInRegistries.BLOCK.getKey(block).toString());
|
||||
|
||||
ProtocolUtils.sendPayloadPacket(player, new ReceiveDataPayload(tag));
|
||||
}, null, 1L);
|
||||
}
|
||||
|
||||
@ProtocolHandler.ReloadServer
|
||||
public static void onServerReload() {
|
||||
rebuildShearableBlocks();
|
||||
synchronized (enabledPlayers) {
|
||||
for (ServerPlayer player : enabledPlayers) {
|
||||
ProtocolUtils.sendPayloadPacket(player, new ServerHandshakePayload(Collections.emptyMap(), shearableBlocks, blockDataProviders.mappedIds(), entityDataProviders.mappedIds()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void rebuildShearableBlocks() {
|
||||
try {
|
||||
shearableBlocks = Collections.unmodifiableList(LootTableMineableCollector.execute(
|
||||
MinecraftServer.getServer().reloadableRegistries().lookup().lookupOrThrow(Registries.LOOT_TABLE),
|
||||
Items.SHEARS.getDefaultInstance()
|
||||
));
|
||||
} catch (Throwable ignore) {
|
||||
shearableBlocks = List.of();
|
||||
LOGGER.warn("Failed to collect shearable blocks");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return JadeProtocolConfig.enabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamEncoder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Accessor<T extends HitResult> {
|
||||
ServerLevel getLevel();
|
||||
|
||||
Player getPlayer();
|
||||
|
||||
<D> Tag encodeAsNbt(StreamEncoder<RegistryFriendlyByteBuf, D> codec, D value);
|
||||
|
||||
T getHitResult();
|
||||
|
||||
@Nullable
|
||||
Object getTarget();
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.nbt.ByteArrayTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamEncoder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class AccessorImpl<T extends HitResult> implements Accessor<T> {
|
||||
|
||||
private final ServerLevel level;
|
||||
private final Player player;
|
||||
private final Supplier<T> hit;
|
||||
protected boolean verify;
|
||||
private RegistryFriendlyByteBuf buffer;
|
||||
|
||||
public AccessorImpl(ServerLevel level, Player player, Supplier<T> hit) {
|
||||
this.level = level;
|
||||
this.player = player;
|
||||
this.hit = hit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerLevel getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
private RegistryFriendlyByteBuf buffer() {
|
||||
if (buffer == null) {
|
||||
buffer = new RegistryFriendlyByteBuf(Unpooled.buffer(), level.registryAccess());
|
||||
}
|
||||
buffer.clear();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D> Tag encodeAsNbt(StreamEncoder<RegistryFriendlyByteBuf, D> streamCodec, D value) {
|
||||
RegistryFriendlyByteBuf buffer = buffer();
|
||||
streamCodec.encode(buffer, value);
|
||||
ByteArrayTag tag = new ByteArrayTag(ArrayUtils.subarray(buffer.array(), 0, buffer.readableBytes()));
|
||||
buffer.clear();
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getHitResult() {
|
||||
return hit.get();
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface BlockAccessor extends Accessor<BlockHitResult> {
|
||||
|
||||
Block getBlock();
|
||||
|
||||
BlockState getBlockState();
|
||||
|
||||
BlockEntity getBlockEntity();
|
||||
|
||||
BlockPos getPosition();
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder {
|
||||
Builder level(ServerLevel level);
|
||||
|
||||
Builder player(Player player);
|
||||
|
||||
Builder hit(BlockHitResult hit);
|
||||
|
||||
Builder blockState(BlockState state);
|
||||
|
||||
default Builder blockEntity(BlockEntity blockEntity) {
|
||||
return blockEntity(() -> blockEntity);
|
||||
}
|
||||
|
||||
Builder blockEntity(Supplier<BlockEntity> blockEntity);
|
||||
|
||||
Builder from(BlockAccessor accessor);
|
||||
|
||||
BlockAccessor build();
|
||||
}
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Class to get information of block target and context.
|
||||
*/
|
||||
public class BlockAccessorImpl extends AccessorImpl<BlockHitResult> implements BlockAccessor {
|
||||
|
||||
private final BlockState blockState;
|
||||
@Nullable
|
||||
private final Supplier<BlockEntity> blockEntity;
|
||||
|
||||
private BlockAccessorImpl(Builder builder) {
|
||||
super(builder.level, builder.player, Suppliers.ofInstance(builder.hit));
|
||||
blockState = builder.blockState;
|
||||
blockEntity = builder.blockEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlock() {
|
||||
return getBlockState().getBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState() {
|
||||
return blockState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity getBlockEntity() {
|
||||
return blockEntity == null ? null : blockEntity.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPosition() {
|
||||
return getHitResult().getBlockPos();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getTarget() {
|
||||
return getBlockEntity();
|
||||
}
|
||||
|
||||
public static class Builder implements BlockAccessor.Builder {
|
||||
private ServerLevel level;
|
||||
private Player player;
|
||||
private BlockHitResult hit;
|
||||
private BlockState blockState = Blocks.AIR.defaultBlockState();
|
||||
private Supplier<BlockEntity> blockEntity;
|
||||
|
||||
@Override
|
||||
public Builder level(ServerLevel level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder player(Player player) {
|
||||
this.player = player;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder hit(BlockHitResult hit) {
|
||||
this.hit = hit;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder blockState(BlockState blockState) {
|
||||
this.blockState = blockState;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder blockEntity(Supplier<BlockEntity> blockEntity) {
|
||||
this.blockEntity = blockEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder from(BlockAccessor accessor) {
|
||||
level = accessor.getLevel();
|
||||
player = accessor.getPlayer();
|
||||
hit = accessor.getHitResult();
|
||||
blockEntity = accessor::getBlockEntity;
|
||||
blockState = accessor.getBlockState();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockAccessor build() {
|
||||
return new BlockAccessorImpl(this);
|
||||
}
|
||||
}
|
||||
|
||||
public record SyncData(boolean showDetails, BlockHitResult hit, BlockState blockState, ItemStack fakeBlock) {
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, SyncData> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL,
|
||||
SyncData::showDetails,
|
||||
StreamCodec.of(FriendlyByteBuf::writeBlockHitResult, FriendlyByteBuf::readBlockHitResult),
|
||||
SyncData::hit,
|
||||
ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY),
|
||||
SyncData::blockState,
|
||||
ItemStack.OPTIONAL_STREAM_CODEC,
|
||||
SyncData::fakeBlock,
|
||||
SyncData::new
|
||||
);
|
||||
|
||||
public BlockAccessor unpack(ServerPlayer player) {
|
||||
Supplier<BlockEntity> blockEntity = null;
|
||||
if (blockState.hasBlockEntity()) {
|
||||
blockEntity = Suppliers.memoize(() -> player.level().getBlockEntity(hit.getBlockPos()));
|
||||
}
|
||||
return new Builder()
|
||||
.level(player.level())
|
||||
.player(player)
|
||||
.hit(hit)
|
||||
.blockState(blockState)
|
||||
.blockEntity(blockEntity)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface EntityAccessor extends Accessor<EntityHitResult> {
|
||||
|
||||
Entity getEntity();
|
||||
|
||||
/**
|
||||
* For part entity like ender dragon's, getEntity() will return the parent entity.
|
||||
*/
|
||||
Entity getRawEntity();
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
interface Builder {
|
||||
Builder level(ServerLevel level);
|
||||
|
||||
Builder player(Player player);
|
||||
|
||||
default Builder hit(EntityHitResult hit) {
|
||||
return hit(() -> hit);
|
||||
}
|
||||
|
||||
Builder hit(Supplier<EntityHitResult> hit);
|
||||
|
||||
default Builder entity(Entity entity) {
|
||||
return entity(() -> entity);
|
||||
}
|
||||
|
||||
Builder entity(Supplier<Entity> entity);
|
||||
|
||||
Builder from(EntityAccessor accessor);
|
||||
|
||||
EntityAccessor build();
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.accessor;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.jade.util.CommonUtil;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class EntityAccessorImpl extends AccessorImpl<EntityHitResult> implements EntityAccessor {
|
||||
|
||||
private final Supplier<Entity> entity;
|
||||
|
||||
public EntityAccessorImpl(Builder builder) {
|
||||
super(builder.level, builder.player, builder.hit);
|
||||
entity = builder.entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getEntity() {
|
||||
return CommonUtil.wrapPartEntityParent(getRawEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity getRawEntity() {
|
||||
return entity.get();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object getTarget() {
|
||||
return getEntity();
|
||||
}
|
||||
|
||||
public static class Builder implements EntityAccessor.Builder {
|
||||
private ServerLevel level;
|
||||
private Player player;
|
||||
private Supplier<EntityHitResult> hit;
|
||||
private Supplier<Entity> entity;
|
||||
|
||||
@Override
|
||||
public Builder level(ServerLevel level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder player(Player player) {
|
||||
this.player = player;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Builder hit(Supplier<EntityHitResult> hit) {
|
||||
this.hit = hit;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder entity(Supplier<Entity> entity) {
|
||||
this.entity = entity;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder from(EntityAccessor accessor) {
|
||||
level = accessor.getLevel();
|
||||
player = accessor.getPlayer();
|
||||
hit = accessor::getHitResult;
|
||||
entity = accessor::getEntity;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityAccessor build() {
|
||||
return new EntityAccessorImpl(this);
|
||||
}
|
||||
}
|
||||
|
||||
public record SyncData(boolean showDetails, int id, int partIndex, Vec3 hitVec) {
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, SyncData> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL,
|
||||
SyncData::showDetails,
|
||||
ByteBufCodecs.VAR_INT,
|
||||
SyncData::id,
|
||||
ByteBufCodecs.VAR_INT,
|
||||
SyncData::partIndex,
|
||||
ByteBufCodecs.VECTOR3F.map(Vec3::new, Vec3::toVector3f),
|
||||
SyncData::hitVec,
|
||||
SyncData::new
|
||||
);
|
||||
|
||||
public EntityAccessor unpack(ServerPlayer player) {
|
||||
Supplier<Entity> entity = Suppliers.memoize(() -> CommonUtil.getPartEntity(player.level().getEntity(id), partIndex));
|
||||
return new EntityAccessorImpl.Builder()
|
||||
.level(player.level())
|
||||
.player(player)
|
||||
.entity(entity)
|
||||
.hit(Suppliers.memoize(() -> new EntityHitResult(entity.get(), hitVec)))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.payload;
|
||||
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
|
||||
public record ClientHandshakePayload(String protocolVersion) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation PACKET_CLIENT_HANDSHAKE = JadeProtocol.id("client_handshake");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, ClientHandshakePayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.STRING_UTF8, ClientHandshakePayload::protocolVersion, ClientHandshakePayload::new
|
||||
);
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.payload;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
|
||||
public record ReceiveDataPayload(CompoundTag tag) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation PACKET_RECEIVE_DATA = JadeProtocol.id("receive_data");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<FriendlyByteBuf, ReceiveDataPayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.COMPOUND_TAG, ReceiveDataPayload::tag, ReceiveDataPayload::new
|
||||
);
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.payload;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessorImpl;
|
||||
import org.leavesmc.leaves.protocol.jade.provider.IServerDataProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.leavesmc.leaves.protocol.jade.JadeProtocol.blockDataProviders;
|
||||
|
||||
public record RequestBlockPayload(BlockAccessorImpl.SyncData data,
|
||||
List<@Nullable IServerDataProvider<BlockAccessor>> dataProviders) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation PACKET_REQUEST_BLOCK = JadeProtocol.id("request_block");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, RequestBlockPayload> CODEC = StreamCodec.composite(
|
||||
BlockAccessorImpl.SyncData.STREAM_CODEC,
|
||||
RequestBlockPayload::data,
|
||||
ByteBufCodecs.<ByteBuf, IServerDataProvider<BlockAccessor>>list()
|
||||
.apply(ByteBufCodecs.idMapper(
|
||||
$ -> Objects.requireNonNull(blockDataProviders.idMapper()).byId($),
|
||||
$ -> Objects.requireNonNull(blockDataProviders.idMapper()).getIdOrThrow($))),
|
||||
RequestBlockPayload::dataProviders,
|
||||
RequestBlockPayload::new);
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.payload;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.EntityAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.EntityAccessorImpl;
|
||||
import org.leavesmc.leaves.protocol.jade.provider.IServerDataProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.leavesmc.leaves.protocol.jade.JadeProtocol.entityDataProviders;
|
||||
|
||||
public record RequestEntityPayload(EntityAccessorImpl.SyncData data,
|
||||
List<@Nullable IServerDataProvider<EntityAccessor>> dataProviders) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation PACKET_REQUEST_ENTITY = JadeProtocol.id("request_entity");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, RequestEntityPayload> CODEC = StreamCodec.composite(
|
||||
EntityAccessorImpl.SyncData.STREAM_CODEC,
|
||||
RequestEntityPayload::data,
|
||||
ByteBufCodecs.<ByteBuf, IServerDataProvider<EntityAccessor>>list()
|
||||
.apply(ByteBufCodecs.idMapper(
|
||||
$ -> Objects.requireNonNull(entityDataProviders.idMapper()).byId($),
|
||||
$ -> Objects.requireNonNull(entityDataProviders.idMapper()).getIdOrThrow($)
|
||||
)),
|
||||
RequestEntityPayload::dataProviders,
|
||||
RequestEntityPayload::new);
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.payload;
|
||||
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.leavesmc.leaves.protocol.jade.util.JadeCodec.PRIMITIVE_STREAM_CODEC;
|
||||
|
||||
public record ServerHandshakePayload(
|
||||
Map<ResourceLocation, Object> serverConfig,
|
||||
List<Block> shearableBlocks,
|
||||
List<ResourceLocation> blockProviderIds,
|
||||
List<ResourceLocation> entityProviderIds
|
||||
) implements LeavesCustomPayload {
|
||||
|
||||
@ID
|
||||
private static final ResourceLocation PACKET_SERVER_HANDSHAKE = JadeProtocol.id("server_handshake");
|
||||
|
||||
@Codec
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, ServerHandshakePayload> CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.map(Maps::newHashMapWithExpectedSize, ResourceLocation.STREAM_CODEC, PRIMITIVE_STREAM_CODEC),
|
||||
ServerHandshakePayload::serverConfig,
|
||||
ByteBufCodecs.registry(Registries.BLOCK).apply(ByteBufCodecs.list()),
|
||||
ServerHandshakePayload::shearableBlocks,
|
||||
ByteBufCodecs.<ByteBuf, ResourceLocation>list().apply(ResourceLocation.STREAM_CODEC),
|
||||
ServerHandshakePayload::blockProviderIds,
|
||||
ByteBufCodecs.<ByteBuf, ResourceLocation>list().apply(ResourceLocation.STREAM_CODEC),
|
||||
ServerHandshakePayload::entityProviderIds,
|
||||
ServerHandshakePayload::new
|
||||
);
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface IJadeProvider {
|
||||
|
||||
ResourceLocation getUid();
|
||||
|
||||
default int getDefaultPriority() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
|
||||
|
||||
public interface IServerDataProvider<T extends Accessor<?>> extends IJadeProvider {
|
||||
void appendServerData(CompoundTag data, T accessor);
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider;
|
||||
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
|
||||
import org.leavesmc.leaves.protocol.jade.util.ViewGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IServerExtensionProvider<T> extends IJadeProvider {
|
||||
List<ViewGroup<T>> getGroups(Accessor<?> request);
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.LockCode;
|
||||
import net.minecraft.world.RandomizableContainer;
|
||||
import net.minecraft.world.WorldlyContainerHolder;
|
||||
import net.minecraft.world.entity.animal.horse.AbstractHorse;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.vehicle.ContainerEntity;
|
||||
import net.minecraft.world.inventory.PlayerEnderChestContainer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.util.ItemCollector;
|
||||
import org.leavesmc.leaves.protocol.jade.util.ItemIterator;
|
||||
import org.leavesmc.leaves.protocol.jade.util.ViewGroup;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public enum ItemStorageExtensionProvider implements IServerExtensionProvider<ItemStack> {
|
||||
INSTANCE;
|
||||
|
||||
public static final Cache<Object, ItemCollector<?>> targetCache = CacheBuilder.newBuilder().weakKeys().expireAfterAccess(60, TimeUnit.SECONDS).build();
|
||||
|
||||
private static final ResourceLocation UNIVERSAL_ITEM_STORAGE = JadeProtocol.mc_id("item_storage.default");
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public static ItemCollector<?> createItemCollector(Accessor<?> request) {
|
||||
if (request.getTarget() instanceof AbstractHorse) {
|
||||
return new ItemCollector<>(new ItemIterator.ContainerItemIterator(o -> {
|
||||
if (o instanceof AbstractHorse horse) {
|
||||
return horse.inventory;
|
||||
}
|
||||
return null;
|
||||
}, 2));
|
||||
}
|
||||
|
||||
// TODO BlockEntity like fabric's ItemStorage
|
||||
|
||||
final Container container = findContainer(request);
|
||||
if (container != null) {
|
||||
if (container instanceof ChestBlockEntity) {
|
||||
return new ItemCollector<>(new ItemIterator.ContainerItemIterator(o -> {
|
||||
if (o instanceof ChestBlockEntity blockEntity) {
|
||||
if (blockEntity.getBlockState().getBlock() instanceof ChestBlock chestBlock) {
|
||||
Container compound = null;
|
||||
if (blockEntity.getLevel() != null) {
|
||||
compound = ChestBlock.getContainer(
|
||||
chestBlock, blockEntity.getBlockState(),
|
||||
blockEntity.getLevel(), blockEntity.getBlockPos(),
|
||||
true // Bypass lock check
|
||||
);
|
||||
}
|
||||
if (compound != null) {
|
||||
return compound;
|
||||
}
|
||||
}
|
||||
return blockEntity;
|
||||
}
|
||||
return null;
|
||||
}, 0));
|
||||
}
|
||||
return new ItemCollector<>(new ItemIterator.ContainerItemIterator(0));
|
||||
}
|
||||
|
||||
return ItemCollector.EMPTY;
|
||||
}
|
||||
|
||||
public static @Nullable Container findContainer(@NotNull Accessor<?> accessor) {
|
||||
Object target = accessor.getTarget();
|
||||
if (target == null && accessor instanceof BlockAccessor blockAccessor &&
|
||||
blockAccessor.getBlock() instanceof WorldlyContainerHolder holder) {
|
||||
return holder.getContainer(blockAccessor.getBlockState(), accessor.getLevel(), blockAccessor.getPosition());
|
||||
} else if (target instanceof Container container) {
|
||||
return container;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewGroup<ItemStack>> getGroups(Accessor<?> request) {
|
||||
Object target = request.getTarget();
|
||||
|
||||
switch (target) {
|
||||
case null -> {
|
||||
return createItemCollector(request).update(request);
|
||||
}
|
||||
case RandomizableContainer te when te.getLootTable() != null -> {
|
||||
return List.of();
|
||||
}
|
||||
case ContainerEntity containerEntity when containerEntity.getContainerLootTable() != null -> {
|
||||
return List.of();
|
||||
}
|
||||
case EnderChestBlockEntity enderChest when request.getPlayer().getEnderChestInventory().isEmpty() -> {
|
||||
return List.of();
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
|
||||
Player player = request.getPlayer();
|
||||
if (!player.isCreative() && !player.isSpectator() && target instanceof BaseContainerBlockEntity te) {
|
||||
if (te.lockKey != LockCode.NO_LOCK) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
if (target instanceof EnderChestBlockEntity) {
|
||||
PlayerEnderChestContainer inventory = player.getEnderChestInventory();
|
||||
return new ItemCollector<>(new ItemIterator.ContainerItemIterator(x -> inventory, 0)).update(request);
|
||||
}
|
||||
|
||||
ItemCollector<?> itemCollector;
|
||||
try {
|
||||
itemCollector = targetCache.get(target, () -> createItemCollector(request));
|
||||
} catch (ExecutionException e) {
|
||||
LOGGER.warn("Failed to get item collector for " + target);
|
||||
return null;
|
||||
}
|
||||
|
||||
return itemCollector.update(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getUid() {
|
||||
return UNIVERSAL_ITEM_STORAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultPriority() {
|
||||
return 9999;
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.LockCode;
|
||||
import net.minecraft.world.RandomizableContainer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.EntityAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.util.CommonUtil;
|
||||
import org.leavesmc.leaves.protocol.jade.util.ItemCollector;
|
||||
import org.leavesmc.leaves.protocol.jade.util.ViewGroup;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class ItemStorageProvider<T extends Accessor<?>> implements IServerDataProvider<T> {
|
||||
|
||||
private static final StreamCodec<RegistryFriendlyByteBuf, Map.Entry<ResourceLocation, List<ViewGroup<ItemStack>>>> STREAM_CODEC = ViewGroup.listCodec(ItemStack.OPTIONAL_STREAM_CODEC);
|
||||
|
||||
private static final ResourceLocation UNIVERSAL_ITEM_STORAGE = JadeProtocol.mc_id("item_storage");
|
||||
|
||||
public static ForBlock getBlock() {
|
||||
return ForBlock.INSTANCE;
|
||||
}
|
||||
|
||||
public static ForEntity getEntity() {
|
||||
return ForEntity.INSTANCE;
|
||||
}
|
||||
|
||||
public static void putData(CompoundTag tag, @NotNull Accessor<?> accessor) {
|
||||
Object target = accessor.getTarget();
|
||||
Player player = accessor.getPlayer();
|
||||
Map.Entry<ResourceLocation, List<ViewGroup<ItemStack>>> entry = CommonUtil.getServerExtensionData(accessor, JadeProtocol.itemStorageProviders);
|
||||
if (entry != null) {
|
||||
List<ViewGroup<ItemStack>> groups = entry.getValue();
|
||||
for (ViewGroup<ItemStack> group : groups) {
|
||||
if (group.views.size() > ItemCollector.MAX_SIZE) {
|
||||
group.views = group.views.subList(0, ItemCollector.MAX_SIZE);
|
||||
}
|
||||
}
|
||||
tag.put(UNIVERSAL_ITEM_STORAGE.toString(), accessor.encodeAsNbt(STREAM_CODEC, entry));
|
||||
return;
|
||||
}
|
||||
if (target instanceof RandomizableContainer containerEntity && containerEntity.getLootTable() != null) {
|
||||
tag.putBoolean("Loot", true);
|
||||
} else if (!player.isCreative() && !player.isSpectator() && target instanceof BaseContainerBlockEntity te) {
|
||||
if (te.lockKey != LockCode.NO_LOCK) {
|
||||
tag.putBoolean("Locked", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getUid() {
|
||||
return UNIVERSAL_ITEM_STORAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendServerData(CompoundTag tag, @NotNull T accessor) {
|
||||
if (accessor.getTarget() instanceof AbstractFurnaceBlockEntity) {
|
||||
return;
|
||||
}
|
||||
putData(tag, accessor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultPriority() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public static class ForBlock extends ItemStorageProvider<BlockAccessor> {
|
||||
private static final ForBlock INSTANCE = new ForBlock();
|
||||
}
|
||||
|
||||
public static class ForEntity extends ItemStorageProvider<EntityAccessor> {
|
||||
private static final ForEntity INSTANCE = new ForEntity();
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.Accessor;
|
||||
|
||||
public interface StreamServerDataProvider<T extends Accessor<?>, D> extends IServerDataProvider<T> {
|
||||
|
||||
@Override
|
||||
default void appendServerData(CompoundTag data, T accessor) {
|
||||
D value = streamData(accessor);
|
||||
if (value != null) {
|
||||
data.put(getUid().toString(), accessor.encodeAsNbt(streamCodec(), value));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
D streamData(T accessor);
|
||||
|
||||
StreamCodec<RegistryFriendlyByteBuf, D> streamCodec();
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider.block;
|
||||
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.provider.StreamServerDataProvider;
|
||||
|
||||
public enum BeehiveProvider implements StreamServerDataProvider<BlockAccessor, Byte> {
|
||||
INSTANCE;
|
||||
|
||||
private static final ResourceLocation MC_BEEHIVE = JadeProtocol.mc_id("beehive");
|
||||
|
||||
@Override
|
||||
public @NotNull StreamCodec<RegistryFriendlyByteBuf, Byte> streamCodec() {
|
||||
return ByteBufCodecs.BYTE.cast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte streamData(@NotNull BlockAccessor accessor) {
|
||||
BeehiveBlockEntity beehive = (BeehiveBlockEntity) accessor.getBlockEntity();
|
||||
int bees = beehive.getOccupantCount();
|
||||
return (byte) (beehive.isFull() ? bees : -bees);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getUid() {
|
||||
return MC_BEEHIVE;
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of Leaves (https://github.com/LeavesMC/Leaves)
|
||||
*
|
||||
* Leaves is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Leaves is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Leaves. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.leavesmc.leaves.protocol.jade.provider.block;
|
||||
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.ComponentSerialization;
|
||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.Nameable;
|
||||
import net.minecraft.world.level.block.ChestBlock;
|
||||
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||
import net.minecraft.world.level.block.state.properties.ChestType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
import org.leavesmc.leaves.protocol.jade.accessor.BlockAccessor;
|
||||
import org.leavesmc.leaves.protocol.jade.provider.StreamServerDataProvider;
|
||||
|
||||
public enum BlockNameProvider implements StreamServerDataProvider<BlockAccessor, Component> {
|
||||
INSTANCE;
|
||||
|
||||
private static final ResourceLocation CORE_OBJECT_NAME = JadeProtocol.id("object_name");
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Component streamData(@NotNull BlockAccessor accessor) {
|
||||
if (!(accessor.getBlockEntity() instanceof Nameable nameable)) {
|
||||
return null;
|
||||
}
|
||||
if (nameable instanceof ChestBlockEntity && accessor.getBlock() instanceof ChestBlock && accessor.getBlockState().getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
|
||||
MenuProvider menuProvider = accessor.getBlockState().getMenuProvider(accessor.getLevel(), accessor.getPosition());
|
||||
if (menuProvider != null) {
|
||||
Component name = menuProvider.getDisplayName();
|
||||
if (!(name.getContents() instanceof TranslatableContents contents) || !"container.chestDouble".equals(contents.getKey())) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
} else if (nameable.hasCustomName()) {
|
||||
return nameable.getDisplayName();
|
||||
}
|
||||
return accessor.getBlockEntity().components().get(DataComponents.ITEM_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamCodec<RegistryFriendlyByteBuf, Component> streamCodec() {
|
||||
return ComponentSerialization.STREAM_CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getUid() {
|
||||
return CORE_OBJECT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefaultPriority() {
|
||||
return -10100;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user