做了LuckPerms适配
补充了下指令文档
This commit is contained in:
parent
03ebcee5c6
commit
014e97662a
|
|
@ -13,6 +13,9 @@ We recommend testing on backups or a development server before deploying to prod
|
|||
**Super Lead Rope** is a mod that enhances the vanilla lead, allowing players to manage and leash entities more flexibly.
|
||||
Compared to the original, it is not only more powerful but also supports cross-dimension and even cross-server features.
|
||||
|
||||
|
||||
Super Lead Rope Commands 超级拴绳指令:
|
||||
[Leash Data Command](./doc/LeashDataCommandUsage_EN) | [超级拴绳数据指令](./doc/LeashDataCommandUsage_CN)
|
||||
---
|
||||
|
||||
## ✨ 功能特色 / Features
|
||||
|
|
|
|||
36
build.gradle
36
build.gradle
|
|
@ -76,6 +76,10 @@ repositories {
|
|||
name = "Curios"
|
||||
url = "https://maven.theillusivec4.top/"
|
||||
}
|
||||
maven {
|
||||
name = "Luck perms"
|
||||
url = "https://repo1.maven.org/maven2/net/luckperms/api/"
|
||||
}
|
||||
maven {
|
||||
name = "GeckoLib"
|
||||
url = "https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/"
|
||||
|
|
@ -173,13 +177,12 @@ dependencies {
|
|||
modRuntimeOnly("curse.maven:spark-361579:4738952")
|
||||
compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1"))
|
||||
modImplementation("io.github.llamalad7:mixinextras-forge:0.4.1")
|
||||
compileOnly("net.luckperms:api:5.4")
|
||||
compileOnly ('me.lucko:spark-api:0.1-SNAPSHOT')
|
||||
implementation 'org.ow2.asm:asm:9.6'
|
||||
implementation 'org.ow2.asm:asm-tree:9.6'
|
||||
implementation 'org.ow2.asm:asm-commons:9.6'
|
||||
implementation 'org.ow2.asm:asm-util:9.6'
|
||||
modCompileOnly("top.r3944realms.lib39:lib39:1.20.1-0.0.15:all@jar")
|
||||
|
||||
}
|
||||
|
||||
// ===================== 修复 Javadoc 任务 =====================
|
||||
|
|
@ -445,7 +448,7 @@ publishing {
|
|||
|
||||
// ===================== 构建任务依赖 =====================
|
||||
tasks.named('build') {
|
||||
dependsOn apiJar, apiJavadocJar
|
||||
dependsOn sourceJar, apiSourceJar, apiJar, apiJavadocJar
|
||||
}
|
||||
|
||||
tasks.named('clean') {
|
||||
|
|
@ -486,3 +489,30 @@ idea {
|
|||
downloadJavadoc = true
|
||||
}
|
||||
}
|
||||
tasks.register('showTaskTree') {
|
||||
doLast {
|
||||
def showTaskDeps
|
||||
showTaskDeps = { task, prefix = '', isLast = true ->
|
||||
// 当前任务节点
|
||||
def connector = isLast ? '└── ' : '├── '
|
||||
println "${prefix}${connector}${task.name}"
|
||||
|
||||
// 子任务
|
||||
def dependencies = task.getTaskDependencies().getDependencies(task).toList()
|
||||
def newPrefix = prefix + (isLast ? ' ' : '│ ')
|
||||
|
||||
dependencies.eachWithIndex { dep, index ->
|
||||
def lastChild = index == dependencies.size() - 1
|
||||
showTaskDeps(dep, newPrefix, lastChild)
|
||||
}
|
||||
}
|
||||
|
||||
def targetTask = tasks.findByName('build')
|
||||
if (targetTask) {
|
||||
println "构建任务依赖树:"
|
||||
showTaskDeps(targetTask, '', true)
|
||||
} else {
|
||||
println "未找到 build 任务"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
176
doc/LeashDataCommandUsage_CN.MD
Normal file
176
doc/LeashDataCommandUsage_CN.MD
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
## 基础指令结构
|
||||
|
||||
### 主要指令
|
||||
```
|
||||
/slp leashdata [子命令]
|
||||
```
|
||||
|
||||
### 指令权限
|
||||
需要 OP 权限(权限等级 2)
|
||||
|
||||
## 子命令分类
|
||||
|
||||
### 1. GET 命令 - 获取信息
|
||||
|
||||
**获取实体拴绳数据:**
|
||||
```
|
||||
/slp leashdata get data <targets>
|
||||
```
|
||||
- `<targets>`: 目标实体(选择器)
|
||||
|
||||
**获取单个实体详细信息:**
|
||||
```
|
||||
/slp leashdata get info <target>
|
||||
```
|
||||
- `<target>`: 目标实体(选择器)
|
||||
|
||||
### 2. ADD 命令 - 添加拴绳
|
||||
|
||||
**添加实体拴绳:**
|
||||
```
|
||||
/slp leashdata add <targets> <holder> [maxDistance] [elasticDistanceScale] [keepTicks] [reserved]
|
||||
```
|
||||
- `<targets>`: 被拴绳实体
|
||||
- `<holder>`: 持有者实体
|
||||
- `[maxDistance]`: 最大距离(默认值范围)
|
||||
- `[elasticDistanceScale]`: 弹性距离比例(默认值范围)
|
||||
- `[keepTicks]`: 保持时间(游戏刻,≥0)
|
||||
- `[reserved]`: 保留字段(字符串)
|
||||
|
||||
**添加方块拴绳:**
|
||||
```
|
||||
/slp leashdata add <targets> block <pos> [maxDistance] [elasticDistanceScale] [keepTicks] [reserved]
|
||||
```
|
||||
- `<pos>`: 方块位置
|
||||
- 其他参数同上
|
||||
|
||||
### 3. REMOVE 命令 - 移除拴绳
|
||||
|
||||
**移除特定实体拴绳:**
|
||||
```
|
||||
/slp leashdata remove <targets> <holder>
|
||||
```
|
||||
- `<targets>`: 目标实体
|
||||
- `<holder>`: 持有者实体
|
||||
|
||||
**移除方块拴绳:**
|
||||
```
|
||||
/slp leashdata remove <targets> block <pos>
|
||||
```
|
||||
- `<pos>`: 方块位置
|
||||
|
||||
**批量移除:**
|
||||
```
|
||||
/slp leashdata remove <targets> all # 移除所有拴绳
|
||||
/slp leashdata remove <targets> holders # 移除所有实体拴绳
|
||||
/slp leashdata remove <targets> knots # 移除所有方块拴绳
|
||||
```
|
||||
|
||||
### 4. TRANSFER 命令 - 转移拴绳
|
||||
|
||||
**实体到实体转移:**
|
||||
```
|
||||
/slp leashdata transfer <targets> <from> <to> [reserved]
|
||||
```
|
||||
- `<from>`: 原持有者
|
||||
- `<to>`: 新持有者
|
||||
|
||||
**方块到实体转移:**
|
||||
```
|
||||
/slp leashdata transfer <targets> fromBlock <fromPos> <to> [reserved]
|
||||
```
|
||||
- `<fromPos>`: 原方块位置
|
||||
- `<to>`: 新持有者实体
|
||||
|
||||
**方块到方块转移:**
|
||||
```
|
||||
/slp leashdata transfer <targets> fromBlock <fromPos> toBlock <toPos> [reserved]
|
||||
```
|
||||
- `<fromPos>`: 原方块位置
|
||||
- `<toPos>`: 新方块位置
|
||||
|
||||
### 5. SET 命令 - 设置属性
|
||||
|
||||
**设置静态属性(适用于所有拴绳):**
|
||||
```
|
||||
/slp leashdata set <targets> static maxDistance reset # 重置最大距离
|
||||
/slp leashdata set <targets> static maxDistance <value> # 设置最大距离
|
||||
/slp leashdata set <targets> static elasticDistanceScale reset # 重置弹性比例
|
||||
/slp leashdata set <targets> static elasticDistanceScale <value> # 设置弹性比例
|
||||
```
|
||||
|
||||
**设置实体拴绳属性:**
|
||||
```
|
||||
# 设置最大距离
|
||||
/slp leashdata set <targets> entity maxDistance <holder> [distance] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> entity maxDistance [distance] [keepTicks] [reserved] # 所有持有者
|
||||
|
||||
# 设置弹性距离比例
|
||||
/slp leashdata set <targets> entity elasticDistanceScale <holder> [scale] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> entity elasticDistanceScale [scale] [keepTicks] [reserved] # 所有持有者
|
||||
```
|
||||
|
||||
**设置方块拴绳属性:**
|
||||
```
|
||||
# 设置最大距离
|
||||
/slp leashdata set <targets> block <pos> maxDistance [distance] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> block maxDistance [distance] [keepTicks] [reserved] # 所有节点
|
||||
|
||||
# 设置弹性距离比例
|
||||
/slp leashdata set <targets> block <pos> elasticDistanceScale [scale] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> block elasticDistanceScale [scale] [keepTicks] [reserved] # 所有节点
|
||||
```
|
||||
|
||||
### 6. APPLY FORCES 命令 - 应用物理力
|
||||
|
||||
**对实体应用拴绳力:**
|
||||
```
|
||||
/slp leashdata applyForces <targets>
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
|
||||
### 选择器参数:
|
||||
- `<targets>`: 实体选择器(如 `@e[type=!player]`, `@a`, `@p`)
|
||||
- `<holder>`, `<from>`, `<to>`: 单个实体选择器
|
||||
|
||||
### 数值参数:
|
||||
- `maxDistance`: 最大距离(`Double`,范围:LeashConfigManager.MAX_DISTANCE_MIN_VALUE 到 MAX_DISTANCE_MAX_VALUE)
|
||||
- `elasticDistanceScale`: 弹性距离比例(`Double`,范围:LeashConfigManager.ELASTIC_DISTANCE_MIN_VALUE 到 ELASTIC_DISTANCE_MAX_VALUE)
|
||||
- `keepTicks`: 保持时间(`Integer`,≥0)
|
||||
|
||||
### 其他参数:
|
||||
- `reserved`: 保留字段(`String`)
|
||||
- `<pos>`, `<fromPos>`, `<toPos>`: 方块位置坐标
|
||||
|
||||
## 使用示例
|
||||
|
||||
1. **拴住所有羊到玩家:**
|
||||
```
|
||||
/slp leashdata add @e[type=sheep] @p 10.0 0.8 600 "farm"
|
||||
```
|
||||
|
||||
2. **查看玩家拴绳状态:**
|
||||
```
|
||||
/slp leashdata get info @p
|
||||
```
|
||||
|
||||
3. **将拴绳从木桩转移到玩家:**
|
||||
```
|
||||
/slp leashdata transfer @e[type=sheep] fromBlock 100 64 100 @p
|
||||
```
|
||||
|
||||
4. **设置所有拴绳的最大距离:**
|
||||
```
|
||||
/slp leashdata set @e[type=sheep] static maxDistance 15.0
|
||||
```
|
||||
|
||||
## 配置默认值
|
||||
- 最大距离范围:`LeashConfigManager.MAX_DISTANCE_MIN_VALUE` 到 `MAX_DISTANCE_MAX_VALUE`
|
||||
- 弹性比例范围:`LeashConfigManager.ELASTIC_DISTANCE_MIN_VALUE` 到 `ELASTIC_DISTANCE_MAX_VALUE`
|
||||
|
||||
## 注意事项
|
||||
1. 所有指令需要 OP 权限(权限等级 2)
|
||||
2. 方块拴绳需要在对应位置存在 SuperLeashKnotEntity
|
||||
3. 转移操作不会作用于来源实体自身(避免循环)
|
||||
4. 显示结果会限制最多显示 4 个实体(超过会显示省略号)
|
||||
176
doc/LeashDataCommandUsage_EN.MD
Normal file
176
doc/LeashDataCommandUsage_EN.MD
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
## Basic Command Structure
|
||||
|
||||
### Main Command
|
||||
```
|
||||
/slp leashdata [subcommand]
|
||||
```
|
||||
|
||||
### Command Permissions
|
||||
Requires OP permissions (permission level 2)
|
||||
|
||||
## Subcommand Categories
|
||||
|
||||
### 1. GET Commands - Retrieve Information
|
||||
|
||||
**Get leash data for entities:**
|
||||
```
|
||||
/slp leashdata get data <targets>
|
||||
```
|
||||
- `<targets>`: Target entities (selector)
|
||||
|
||||
**Get detailed info for a single entity:**
|
||||
```
|
||||
/slp leashdata get info <target>
|
||||
```
|
||||
- `<target>`: Target entity (selector)
|
||||
|
||||
### 2. ADD Commands - Add Leashes
|
||||
|
||||
**Add entity leash:**
|
||||
```
|
||||
/slp leashdata add <targets> <holder> [maxDistance] [elasticDistanceScale] [keepTicks] [reserved]
|
||||
```
|
||||
- `<targets>`: Entities to be leashed
|
||||
- `<holder>`: Holder entity
|
||||
- `[maxDistance]`: Maximum distance (default value range)
|
||||
- `[elasticDistanceScale]`: Elastic distance scale (default value range)
|
||||
- `[keepTicks]`: Keep duration (game ticks, ≥0)
|
||||
- `[reserved]`: Reserved field (string)
|
||||
|
||||
**Add block leash:**
|
||||
```
|
||||
/slp leashdata add <targets> block <pos> [maxDistance] [elasticDistanceScale] [keepTicks] [reserved]
|
||||
```
|
||||
- `<pos>`: Block position
|
||||
- Other parameters same as above
|
||||
|
||||
### 3. REMOVE Commands - Remove Leashes
|
||||
|
||||
**Remove specific entity leash:**
|
||||
```
|
||||
/slp leashdata remove <targets> <holder>
|
||||
```
|
||||
- `<targets>`: Target entities
|
||||
- `<holder>`: Holder entity
|
||||
|
||||
**Remove block leash:**
|
||||
```
|
||||
/slp leashdata remove <targets> block <pos>
|
||||
```
|
||||
- `<pos>`: Block position
|
||||
|
||||
**Batch removal:**
|
||||
```
|
||||
/slp leashdata remove <targets> all # Remove all leashes
|
||||
/slp leashdata remove <targets> holders # Remove all entity leashes
|
||||
/slp leashdata remove <targets> knots # Remove all block leashes
|
||||
```
|
||||
|
||||
### 4. TRANSFER Commands - Transfer Leashes
|
||||
|
||||
**Transfer from entity to entity:**
|
||||
```
|
||||
/slp leashdata transfer <targets> <from> <to> [reserved]
|
||||
```
|
||||
- `<from>`: Original holder
|
||||
- `<to>`: New holder
|
||||
|
||||
**Transfer from block to entity:**
|
||||
```
|
||||
/slp leashdata transfer <targets> fromBlock <fromPos> <to> [reserved]
|
||||
```
|
||||
- `<fromPos>`: Original block position
|
||||
- `<to>`: New holder entity
|
||||
|
||||
**Transfer from block to block:**
|
||||
```
|
||||
/slp leashdata transfer <targets> fromBlock <fromPos> toBlock <toPos> [reserved]
|
||||
```
|
||||
- `<fromPos>`: Original block position
|
||||
- `<toPos>`: New block position
|
||||
|
||||
### 5. SET Commands - Set Properties
|
||||
|
||||
**Set static properties (applies to all leashes):**
|
||||
```
|
||||
/slp leashdata set <targets> static maxDistance reset # Reset max distance
|
||||
/slp leashdata set <targets> static maxDistance <value> # Set max distance
|
||||
/slp leashdata set <targets> static elasticDistanceScale reset # Reset elastic scale
|
||||
/slp leashdata set <targets> static elasticDistanceScale <value> # Set elastic scale
|
||||
```
|
||||
|
||||
**Set entity leash properties:**
|
||||
```
|
||||
# Set max distance
|
||||
/slp leashdata set <targets> entity maxDistance <holder> [distance] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> entity maxDistance [distance] [keepTicks] [reserved] # All holders
|
||||
|
||||
# Set elastic distance scale
|
||||
/slp leashdata set <targets> entity elasticDistanceScale <holder> [scale] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> entity elasticDistanceScale [scale] [keepTicks] [reserved] # All holders
|
||||
```
|
||||
|
||||
**Set block leash properties:**
|
||||
```
|
||||
# Set max distance
|
||||
/slp leashdata set <targets> block <pos> maxDistance [distance] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> block maxDistance [distance] [keepTicks] [reserved] # All knots
|
||||
|
||||
# Set elastic distance scale
|
||||
/slp leashdata set <targets> block <pos> elasticDistanceScale [scale] [keepTicks] [reserved]
|
||||
/slp leashdata set <targets> block elasticDistanceScale [scale] [keepTicks] [reserved] # All knots
|
||||
```
|
||||
|
||||
### 6. APPLY FORCES Command - Apply Physics Forces
|
||||
|
||||
**Apply leash forces to entities:**
|
||||
```
|
||||
/slp leashdata applyForces <targets>
|
||||
```
|
||||
|
||||
## Parameter Descriptions
|
||||
|
||||
### Selector Parameters:
|
||||
- `<targets>`: Entity selector (e.g., `@e[type=!player]`, `@a`, `@p`)
|
||||
- `<holder>`, `<from>`, `<to>`: Single entity selector
|
||||
|
||||
### Numerical Parameters:
|
||||
- `maxDistance`: Maximum distance (`Double`, range: LeashConfigManager.MAX_DISTANCE_MIN_VALUE to MAX_DISTANCE_MAX_VALUE)
|
||||
- `elasticDistanceScale`: Elastic distance scale (`Double`, range: LeashConfigManager.ELASTIC_DISTANCE_MIN_VALUE to ELASTIC_DISTANCE_MAX_VALUE)
|
||||
- `keepTicks`: Keep duration (`Integer`, ≥0)
|
||||
|
||||
### Other Parameters:
|
||||
- `reserved`: Reserved field (`String`)
|
||||
- `<pos>`, `<fromPos>`, `<toPos>`: Block position coordinates
|
||||
|
||||
## Usage Examples
|
||||
|
||||
1. **Leash all sheep to player:**
|
||||
```
|
||||
/slp leashdata add @e[type=sheep] @p 10.0 0.8 600 "farm"
|
||||
```
|
||||
|
||||
2. **Check player's leash status:**
|
||||
```
|
||||
/slp leashdata get info @p
|
||||
```
|
||||
|
||||
3. **Transfer leash from fence post to player:**
|
||||
```
|
||||
/slp leashdata transfer @e[type=sheep] fromBlock 100 64 100 @p
|
||||
```
|
||||
|
||||
4. **Set max distance for all leashes:**
|
||||
```
|
||||
/slp leashdata set @e[type=sheep] static maxDistance 15.0
|
||||
```
|
||||
|
||||
## Configuration Defaults
|
||||
- Max distance range: `LeashConfigManager.MAX_DISTANCE_MIN_VALUE` to `MAX_DISTANCE_MAX_VALUE`
|
||||
- Elastic scale range: `LeashConfigManager.ELASTIC_DISTANCE_MIN_VALUE` to `ELASTIC_DISTANCE_MAX_VALUE`
|
||||
|
||||
## Important Notes
|
||||
1. All commands require OP permissions (permission level 2)
|
||||
2. Block leashes require SuperLeashKnotEntity to exist at the target position
|
||||
3. Transfer operations do not affect the source entity itself (to prevent loops)
|
||||
4. Display results are limited to showing up to 4 entities (shows ellipsis for more)
|
||||
|
|
@ -22,10 +22,7 @@ import net.minecraftforge.fml.ModList;
|
|||
/**
|
||||
* The type Curtain compat.
|
||||
*/
|
||||
public class CurtainCompat {
|
||||
/**
|
||||
* The constant isModLoaded.
|
||||
*/
|
||||
public class CurtainCompat{
|
||||
public final static boolean isModLoaded = ModList.get().isLoaded("curtain");
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
package top.r3944realms.superleadrope.compat;
|
||||
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.luckperms.api.context.*;
|
||||
import net.luckperms.api.node.Node;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import top.r3944realms.superleadrope.SuperLeadRope;
|
||||
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class LuckPermsCompat {
|
||||
public final static boolean isModLoaded = ModList.get().isLoaded("luckperms");
|
||||
public static volatile ILPC instance;
|
||||
public interface ILPC {
|
||||
void init();
|
||||
default boolean isLeashedBypass(Entity player) { return false; }
|
||||
}
|
||||
|
||||
@Contract(" -> new")
|
||||
public static @NotNull ILPC getOrCreateLPC() {
|
||||
|
||||
if (instance == null) {
|
||||
synchronized (LuckPermsCompat.class) {
|
||||
if (instance == null) {
|
||||
if (!isModLoaded) {
|
||||
instance = new DummyLPC();
|
||||
} else instance = new RealLPC();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
// 空实现
|
||||
private static class DummyLPC implements ILPC {
|
||||
@Override
|
||||
public void init() {}
|
||||
}
|
||||
|
||||
// 真实实现(只有在模组加载时才被初始化)
|
||||
private static class RealLPC implements ILPC {
|
||||
private boolean isInitialized;
|
||||
private LuckPerms luckPerms ;
|
||||
private final Node LeashBypass = Node.builder(SuperLeadRope.MOD_ID + ".leash.bypass").build();
|
||||
public RealLPC() {
|
||||
isInitialized = false;
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
try {
|
||||
luckPerms = LuckPermsProvider.get();
|
||||
luckPerms.getContextManager().registerCalculator(new LeashCalculator());
|
||||
isInitialized = true;
|
||||
} catch (IllegalStateException e) {
|
||||
SuperLeadRope.logger.error("LuckPermsCompat failed to initialize", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeashedBypass(Entity player) {
|
||||
if (!(player instanceof Player)) return false;
|
||||
return isInitialized && luckPerms.getUserManager().isLoaded(player.getUUID()) &&
|
||||
Objects.requireNonNull(luckPerms.getUserManager().getUser(player.getUUID()))
|
||||
.getNodes()
|
||||
.stream()
|
||||
.filter(i -> i.equals(LeashBypass))
|
||||
.findFirst()
|
||||
.map(Node::getValue)
|
||||
.orElse(false);
|
||||
}
|
||||
|
||||
public static class LeashCalculator implements ContextCalculator<Player> {
|
||||
@Override
|
||||
public void calculate(@NotNull Player target, ContextConsumer contextConsumer) {
|
||||
contextConsumer.accept("isLeashed", String.valueOf(LeashDataInnerAPI.QueryOperations.hasLeash(target)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ContextSet estimatePotentialContexts() {
|
||||
ImmutableContextSet.Builder builder = ImmutableContextSet.builder();
|
||||
builder.add("isLeashed", "false");
|
||||
builder.add("isLeashed", "true");
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent;
|
|||
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
|
||||
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
|
||||
import top.r3944realms.superleadrope.compat.CurtainCompat;
|
||||
import top.r3944realms.superleadrope.compat.LuckPermsCompat;
|
||||
import top.r3944realms.superleadrope.config.LeashConfigManager;
|
||||
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
|
||||
import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
|
||||
|
|
@ -1607,7 +1608,7 @@ public class LeashDataImpl implements ILeashData {
|
|||
}
|
||||
|
||||
public boolean canBeAttachedTo(Entity pEntity) {
|
||||
if (pEntity == entity) {
|
||||
if (pEntity == entity && !LuckPermsCompat.getOrCreateLPC().isLeashedBypass(entity)) {
|
||||
return false;
|
||||
} else {
|
||||
Optional<LeashInfo> leashInfo = getLeashInfo(pEntity);
|
||||
|
|
|
|||
|
|
@ -13,48 +13,54 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
var ASMAPI = Java.type('net.minecraftforge.coremod.api.ASMAPI');
|
||||
var Opcodes = Java.type("org.objectweb.asm.Opcodes");
|
||||
var ASMAPI = Java.type("net.minecraftforge.coremod.api.ASMAPI");
|
||||
var VarInsnNode = Java.type("org.objectweb.asm.tree.VarInsnNode");
|
||||
var MethodInsnNode = Java.type("org.objectweb.asm.tree.MethodInsnNode");
|
||||
var InsnNode = Java.type("org.objectweb.asm.tree.InsnNode");
|
||||
|
||||
function initializeCoreMod() {
|
||||
return {
|
||||
"leash_render_patch": {
|
||||
"target": {
|
||||
"type": "METHOD",
|
||||
"class": "net.minecraft.client.renderer.entity.MobRenderer",
|
||||
"methodName": "m_5523_",
|
||||
"methodDesc": "(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/client/renderer/culling/Frustum;DDD)Z"
|
||||
'leash_render': {
|
||||
'target': {
|
||||
'type': 'METHOD',
|
||||
'class': 'net.minecraft.client.renderer.entity.MobRenderer',
|
||||
'methodName': ASMAPI.mapMethod('m_5523_'), // shouldRender
|
||||
'methodDesc': '(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/client/renderer/culling/Frustum;DDD)Z'
|
||||
},
|
||||
"transformer": function(method) {
|
||||
'transformer': function(method) {
|
||||
var insns = method.instructions;
|
||||
|
||||
// 寻找具体的 ICONST_0 位置
|
||||
for (var i = 0; i < insns.size(); i++) {
|
||||
var insn = insns.get(i);
|
||||
if (insn.getOpcode && insn.getOpcode() === Opcodes.ICONST_0) {
|
||||
var next = insns.get(i + 1);
|
||||
if (next && next.getOpcode() === Opcodes.IRETURN) {
|
||||
// 插入调试日志和方法调用
|
||||
insns.insertBefore(insn, ASMAPI.listOf(
|
||||
new VarInsnNode(Opcodes.ALOAD, 1), // Mob
|
||||
new VarInsnNode(Opcodes.ALOAD, 2), // Frustum
|
||||
ASMAPI.buildMethodCall(
|
||||
|
||||
// 寻找 L4 标签后的 ICONST_0 -> IRETURN 序列
|
||||
if (insn.getOpcode() === Opcodes.ICONST_0) {
|
||||
var nextInsn = insns.get(i + 1);
|
||||
if (nextInsn && nextInsn.getOpcode() === Opcodes.IRETURN) {
|
||||
// 找到目标位置,插入我们的钩子调用
|
||||
var newInstructions = ASMAPI.listOf(
|
||||
new VarInsnNode(Opcodes.ALOAD, 1), // 加载 Mob 参数 (livingEntity)
|
||||
new VarInsnNode(Opcodes.ALOAD, 2), // 加载 Frustum 参数 (camera)
|
||||
new MethodInsnNode(
|
||||
Opcodes.INVOKESTATIC,
|
||||
'top/r3944realms/superleadrope/core/hook/LeashRenderHook',
|
||||
null,
|
||||
ASMAPI.MethodType.STATIC,
|
||||
'shouldRenderExtra',
|
||||
'(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/client/renderer/culling/Frustum;)Z',
|
||||
ASMAPI.MethodCallMode.STATIC
|
||||
false
|
||||
)
|
||||
));
|
||||
// 移除原来的 ICONST_0
|
||||
insns.remove(insn);
|
||||
);
|
||||
|
||||
// 在 ICONST_0 之前插入新指令,然后移除 ICONST_0
|
||||
method.instructions.insertBefore(insn, newInstructions);
|
||||
method.instructions.remove(insn);
|
||||
|
||||
// 只需要修改这一个地方
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user