Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
473 changes: 25 additions & 448 deletions AGENTS.md

Large diffs are not rendered by default.

494 changes: 447 additions & 47 deletions common/src/main/java/com/github/epsilon/modules/impl/render/ESP.java

Large diffs are not rendered by default.

74 changes: 74 additions & 0 deletions docs/AGENTS/commit-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 提交规范

本项目提交 commit 时遵循以下约定。

## 标题格式

使用 Conventional Commits 风格:

```text
type(scope): 中文概括
```

常用 `type`:

- `feat`:新增功能
- `fix`:修复问题
- `refactor`:重构代码,不改变业务行为
- `chore`:工程配置、文档、依赖、脚本等维护工作
- `docs`:仅文档变更
- `test`:测试相关变更

`scope` 优先使用受影响范围,例如:

- `common`
- `fabric`
- `neoforge`
- `render`
- `module`
- `docs`

## 正文格式

所有 commit 都必须包含正文。正文先用中文无序列表说明变更,再添加强制 `Checklist:` 段:

```text
- 说明第一项变更
- 说明第二项变更
- 说明验证或影响范围

Checklist:
- [x] 说明已完成的代码、文档或配置检查
- [x] 说明已完成的验证方式或无需额外验证的原因
```

## Checklist 强制要求

- 每个 commit message 必须包含 `Checklist:` 段
- `Checklist:` 下至少包含一条 `- [x]` 已完成项
- checklist 必须对应本次提交的真实完成状态,不能使用空泛占位内容
- 涉及接口变更时,checklist 必须覆盖后端接口、前端调用和接口文档是否同步
- 涉及跨端或跨模块变更时,checklist 必须说明相关代码、配置、文档或测试已经同步
- 文档、配置、样式等小改动也必须包含 checklist,不能只写标题

## 写法要求

- 标题要覆盖本次提交的主要范围,不要把范围写窄
- 正文优先说明“做了什么”和“为什么做”,不要只罗列文件名
- 一次提交尽量聚焦一个主题
- 验证结果优先写入 `Checklist:`,例如 `- [x] npm run build 已通过`

## 示例

```text
fix(render): 优化 ESP 区块扫描与渲染稳定性

- 将 ESP 的方块扫描从渲染阶段移到按区块缓存的增量更新流程,降低开启模块后的卡顿
- 增加近区块优先补齐与渲染快照,减少高速移动时的漏显示与并发遍历崩溃
- 调整近距离填充盒渲染策略,缓解贴近目标方块时的显示异常

Checklist:
- [x] `common` 层实现未引入 ModLoader API
- [x] 已在 Fabric 开发环境验证 ESP 基本显示与切区块场景
- [x] 相关提交说明已按客户端仓库规范整理
```
106 changes: 106 additions & 0 deletions docs/AGENTS/mixins-and-managers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Mixin 与管理器

## Mixin 开发

Mixin 类位于 `common/src/main/java/com/github/epsilon/mixins/`。

### 配置文件

- `common/src/main/resources/epsilon.mixins.json`:common 层 mixins
- `fabric/src/main/resources/epsilon.fabric.mixins.json`:Fabric 专有 mixins
- `neoforge/src/main/resources/epsilon.neoforge.mixins.json`:NeoForge 专有 mixins

### Access 配置

- `common/src/main/resources/epsilon.accesswidener`:Fabric 访问拓宽
- `common/src/main/resources/META-INF/accesstransformer.cfg`:NeoForge 访问转换

### 编写规则

1. 不要凭空猜测 API,先查官方文档和当前源码
2. Mixin 类命名使用 `Mixin<目标类名>`
3. 优先使用 `@Inject` 与 `@WrapOperation`,少用 `@Overwrite`
4. 事件发布通常在 `@Inject` 回调中通过 `EventBus.INSTANCE.post(...)` 完成
5. 遇到不熟悉的签名必须先确认文档和源码

## 管理器概览

### ModuleManager

- `initModules()`:注册所有内置模块
- `registerAddonModule(addonId, module, translateComponent)`:注册 Addon 模块
- `getModules()`:获取所有已注册模块

### AddonManager

- `registerAddon(addon)`:注册单个 addon
- `registerAddons(Iterable)`:批量注册 addon
- `setupAddons()`:初始化 addon i18n 并调用 `onSetup()`
- `getAddons()`:获取已注册 addon 列表

### 其他管理器

| 管理器 | 职责 |
|--------|------|
| `ConfigManager` | 配置序列化、反序列化、自动保存 |
| `RotationManager` | 旋转角度管理 |
| `HealthManager` | 实体生命值缓存 |
| `TargetManager` | 目标选择 |
| `FriendManager` | 好友管理 |
| `SoundManager` | 音效播放 |
| `ServerboundPacketManager` / `ClientboundPacketManager` | 网络包管理 |

## RotationManager

RotationManager 管理玩家视角旋转,支持优先级队列、平滑插值和射线追踪偏移。

### 核心概念

- `setRotations()` 设置目标旋转后,RotationManager 每 tick 自动平滑旋转
- 旋转角度会在 `SendPositionEvent` 中写入发包
- 旋转完成后会自动 `active = false`
- 多个模块同时设置时,高优先级覆盖低优先级
- 旋转过程中每 tick 会发布 `AfterRotationEvent`

### 常用 API

```java
float yaw = RotationManager.INSTANCE.getYRot();
float pitch = RotationManager.INSTANCE.getXRot();
Vector2f current = RotationManager.INSTANCE.getRotation();

RotationManager.INSTANCE.setRotations(new Vector2f(yaw, pitch), rotationSpeed);
RotationManager.INSTANCE.setRotations(new Vector2f(yaw, pitch), rotationSpeed, Priority.High);

RotationManager.INSTANCE.setRotations(rotations, rotationSpeed, null, Priority.High, () -> {
if (RaytraceUtils.overBlock(
new Vector2f(RotationManager.INSTANCE.getYRot(), RotationManager.INSTANCE.getXRot()),
side, blockPos, true)) {
mc.gameMode.useItemOn(mc.player, hand, hitResult);
}
});

boolean active = RotationManager.INSTANCE.isActive();
boolean done = RotationManager.INSTANCE.isDone();
```

### 优先级

| 优先级 | 值 | 用途 |
|--------|----|------|
| `Lowest` | -200 | 预旋转 |
| `Low` | -100 | 低优先级旋转 |
| `Medium` | 0 | 默认优先级 |
| `High` | 100 | 攻击、放置等即时操作 |
| `Highest` | 200 | 最高优先级 |

### 回调使用模式

推荐通过 `setRotations(..., callback)` 实现“旋转 -> 瞄准 -> 操作”的解耦流程,无需手动订阅 `AfterRotationEvent`。

### 设计要点

- callback 在 `RotationManager.onTick()` 中每 tick 执行一次
- callback 内应使用 `getYRot()` / `getXRot()` 获取当前平滑后的旋转角度
- callback 需要自行防止重复执行
- 模块禁用时应清理 pending 状态,并在需要时 `InvUtils.swapBack()`
138 changes: 138 additions & 0 deletions docs/AGENTS/module-and-events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Module 与事件系统

## 核心包结构

所有平台无关代码位于 `common/src/main/java/com/github/epsilon/`:

| 包名 | 用途 |
|------|------|
| `addon/` | Addon 基类、注册事件、Bootstrap 工具 |
| `assets/` | i18n 翻译、配置文件迁移、资源持有者 |
| `events/` | 自定义事件总线、27 种事件类型 |
| `graphics/` | Lumin Graphics 渲染框架 |
| `gui/` | 点击 GUI(Panel、Dropdown、HUD 编辑器) |
| `managers/` | 各种管理器(Addon、Config、Module、Rotation 等) |
| `mixins/` | 37 个 Mixin 注入类 |
| `modules/` | Module 基类、Category 枚举、HudModule |
| `settings/` | Setting 基类与 8 种设置类型 |
| `utils/` | 工具类(client、combat、math、network、player、render、timer、rotation、world) |

## Module 基本模板

所有功能模块继承 `Module`,参考现有模块,如 `common/.../modules/impl/combat/KillAura.java`。

```java
public class MyModule extends Module {

public static final MyModule INSTANCE = new MyModule();

private MyModule() {
super("My Module", Category.COMBAT);
}

private final BoolSetting enabled = boolSetting("Enabled", true);
private final IntSetting range = intSetting("Range", 4, 1, 64, 1);
private final DoubleSetting reach = doubleSetting("Reach", 3.0, 1.0, 6.0, 0.1);

@Override
protected void onEnable() {
}

@Override
protected void onDisable() {
}

@EventHandler
private void onTick(TickEvent.Pre event) {
if (nullCheck()) return;
}

@EventHandler
private void onRender3D(Render3DEvent event) {
}
}
```

## Module 开发约定

1. 每个 Module 使用 `public static final MyModule INSTANCE = new MyModule()` 单例模式
2. 构造函数必须私有
3. 事件处理方法中先调用 `nullCheck()` 检查世界和玩家
4. Setting 必须声明为类的实例字段,并在构造阶段初始化
5. 事件监听方法必须使用 `@EventHandler`,且必须是实例方法
6. 事件方法必须 `void` 返回,只接收一个事件参数
7. 内置模块在 `ModuleManager.initModules()` 中注册
8. 模块名称和设置名称需要补 i18n 翻译

## Setting 说明

### 可见性依赖

Setting 的依赖是一个 `() -> boolean`,返回 `false` 时该设置在 GUI 中隐藏。

```java
private final BoolSetting enableEsp = boolSetting("Enable ESP", true);
private final ColorSetting espColor = colorSetting("ESP Color", Color.WHITE, () -> enableEsp.getValue());
```

也可以使用 lambda 解决声明顺序问题:

```java
private final BoolSetting advanced = boolSetting("Advanced", false);
private final IntSetting threshold = intSetting("Threshold", 50, 0, 100, 1, () -> advanced.getValue());
```

### 分组

```java
private final SettingGroup sgCombat = settingGroup("Combat");
private final BoolSetting autoAttack = boolSetting("Auto Attack", true).group(sgCombat);
```

### 模块键位

- `getKeyBind()` / `setKeyBind(int)`:键位代码(GLFW key code)
- `BindMode.Toggle`:按下切换开关
- `BindMode.Hold`:按住启用,松开禁用

## 事件系统

### EventBus

Epsilon 使用自定义事件总线,与 Minecraft 原生事件系统独立。

- 订阅:`EventBus.INSTANCE.subscribe(object)` / `EventBus.INSTANCE.subscribe(Class)`
- 取消订阅:`EventBus.INSTANCE.unsubscribe(object)` / `EventBus.INSTANCE.unsubscribe(Class)`
- 发布:`EventBus.INSTANCE.post(event)`
- Lambda 工厂注册:`EventBus.INSTANCE.registerLambdaFactory("com.github.epsilon", factory)`,已由 `EpsilonCommon.init()` 自动注册

Module 启用时自动 `subscribe(this)`,禁用时自动 `unsubscribe(this)`。

### 常用事件类型

| 事件类 | 描述 |
|--------|------|
| `TickEvent.Pre` / `TickEvent.Post` | 每 tick 前后 |
| `Render2DEvent.Level` / `Render2DEvent.HUD` | 2D 渲染 |
| `Render3DEvent` | 3D 渲染 |
| `PacketEvent.Send` / `PacketEvent.Receive` | 网络包收发 |
| `KeyPressEvent` | 按键按下/释放 |
| `MousePressEvent` | 鼠标按键 |
| `AttackEntityEvent` | 攻击实体 |
| `JumpEvent` | 跳跃 |
| `CollisionEvent` | 碰撞检测 |
| `TravelEvent` | 移动 |
| `VelocityEvent` | 击退 |
| `RaytraceEvent` | 射线追踪 |
| `KeyboardInputEvent` | 键盘输入 |
| ... | 等 27 个事件 |

### 事件优先级

`@EventHandler(priority = EventPriority.HIGH)` 对应优先级顺序:`HIGHEST` > `HIGH` > `MEDIUM` > `LOW` > `LOWEST`。

也支持直接传入整数,数值越大越先执行,数值越小越晚执行。

### 可取消事件

实现 `Cancellable` 接口的事件可以通过 `event.setCancelled(true)` 取消,取消后低优先级监听器不再执行。
55 changes: 55 additions & 0 deletions docs/AGENTS/project-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 项目架构与构建

## 三层架构

```text
Epsilon/
├── common/ ← 平台无关核心代码(模块、事件、图形、工具类)
├── fabric/ ← Fabric 加载器适配层
├── neoforge/ ← NeoForge 加载器适配层
├── buildSrc/ ← Gradle 自定义插件(multiloader-common、multiloader-loader)
└── docs/ ← 文档
```

## 目录职责

- `common/`:平台无关核心逻辑
- `fabric/`:Fabric 入口与加载器适配
- `neoforge/`:NeoForge 入口与加载器适配
- `buildSrc/`:Gradle 约定插件
- `docs/`:开发文档

## 关键原则

- `common/` 中的代码不能调用任何 ModLoader API
- 需要加载器 API 时,在 `fabric/` 或 `neoforge/` 中实现,再通过 compat 接口传入 common
- `common/` 中的 Java 源码会被 Gradle 自动共享到 `fabric` 和 `neoforge` 的编译路径
- 编写前必须查阅当前版本 Minecraft 源码

## 构建系统

### 版本信息

当前 Minecraft 版本、Fabric API、NeoForge 版本等信息均在 `gradle.properties` 中定义,编写代码时优先参考该文件。

### buildSrc 约定插件

- `multiloader-common.gradle.kts`:common 子项目共享配置,包括 JDK 工具链、Maven 仓库、资源处理、发布配置
- `multiloader-loader.gradle.kts`:fabric 与 neoforge 共享配置,自动关联 `:common` 源码与资源

## Minecraft 源码查阅

源代码位于:`common/build/moddev/artifacts/vanilla-<游戏版本>-sources.jar`

如果不存在,执行:

```bash
./gradlew :common:downloadAssets
./gradlew :common:createMinecraftArtifacts
```

查阅后解压:

```bash
mkdir -p reference && unzip common/build/moddev/artifacts/vanilla-*-sources.jar -d reference/vanilla/
```
Loading
Loading