# 📖 Late Nextgen - 完整学习指南

> **项目类型**: Minecraft Fabric Client Mod  
> **Minecraft 版本**: 1.20.1+  
> **开发语言**: Java 21  
> **文档版本**: 3.0  
> **最后更新**: 2026-04-23

---

## 🗺️ 完整导航目录 (TOC)

### 🎯 快速开始
- [📌 项目简介](#-late-nextgen---完整学习指南)
- [🛠️ 环境准备与开发工具](#-环境准备与开发工具)
- [📚 完整学习路径](#-完整学习路径)

### 📖 Java 基础阶段
- [1. Java 是什么？](#1-java-是什么)
- [2. 第一个 Java 程序](#2-第一个-java-程序)
- [3. 变量与数据类型](#3-变量与数据类型)
  - [3.1 基本数据类型（8种）](#31-基本数据类型8种)
  - [3.2 引用数据类型](#32-引用数据类型)
  - [3.3 变量命名规则](#33-变量命名规则)
- [4. 运算符](#4-运算符)
  - [4.1 算术运算符](#41-算术运算符)
  - [4.2 比较运算符](#42-比较运算符返回-boolean)
  - [4.3 逻辑运算符](#43-逻辑运算符)
  - [4.4 赋值运算符](#44-赋值运算符)
- [5. 流程控制](#5-流程控制)
  - [5.1 if-else 条件判断](#51-if-else-条件判断)
  - [5.2 switch 语句](#52-switch-语句)
  - [5.3 for 循环](#53-for-循环)
  - [5.4 while 循环](#54-while-循环)
  - [5.5 break 和 continue](#55-break-和-continue)
- [6. 方法（函数）](#6-方法函数)
  - [6.1 方法定义](#61-方法定义)
  - [6.2 方法重载](#62-方法重载)
  - [6.3 递归](#63-递归)
- [7. 类与对象](#7-类与对象)
  - [7.1 类的定义](#71-类的定义)
  - [7.2 构造方法](#72-构造方法)
  - [7.3 this 关键字](#73-this-关键字)
  - [7.4 static 关键字](#74-static-关键字)
- [8. 数组](#8-数组)
- [9. 字符串操作](#9-字符串操作)
- [10. 异常处理](#10-异常处理)
- [11. Java 注意事项（必读）](#11-java-注意事项必读)
- [12. 实战练习](#12-实战练习)

### 🚀 Java 进阶阶段
- [Java 进阶详细教程](#java-进阶详细教程)
  - [1. 面向对象编程深入](#1-面向对象编程深入)
    - [1.1 封装（Encapsulation）](#11-封装encapsulation)
    - [1.2 继承（Inheritance）](#12-继承inheritance)
    - [1.3 多态（Polymorphism）](#13-多态polymorphism)
    - [1.4 方法重写（Override）](#14-方法重写override)
  - [2. 接口与抽象类](#2-接口与抽象类)
    - [2.1 抽象类](#21-抽象类)
    - [2.2 接口](#22-接口)
    - [2.3 默认方法（Java 8+）](#23-默认方法java-8)
  - [3. 内部类与匿名类](#3-内部类与匿名类)
  - [4. 泛型编程](#4-泛型编程)
  - [5. 集合框架](#5-集合框架)
  - [6. 异常处理进阶](#6-异常处理进阶)
  - [7. Lambda 表达式与 Stream API](#7-lambda-表达式与-stream-api)
  - [8. 多线程基础](#8-多线程基础)
  - [9. I/O 与文件操作](#9-io-与文件操作)
  - [10. 注解与反射](#10-注解与反射)
  - [11. 设计模式入门](#11-设计模式入门)
  - [12. 实战项目](#12-实战项目)

### 🔧 开发工具
- [IntelliJ IDEA 配置与快捷键指南](#intellij-idea-配置与快捷键指南)
  - [1. IDEA 初始配置](#1-idea-初始配置)
  - [2. 必装插件推荐](#2-必装插件推荐)
  - [3. 核心快捷键](#3-核心快捷键)
  - [4. 高级功能使用](#4-高级功能使用)
  - [5. 调试技巧](#5-调试技巧)
  - [6. Gradle 配置优化](#6-gradle-配置优化)
  - [7. 常见问题解决](#7-常见问题解决)

### 📦 Minecraft 开发核心
- [Java 注解与 Minecraft 包详解](#java-注解与-minecraft-包详解)
  - [1. Java 注解完全指南](#1-java-注解完全指南)
  - [2. Minecraft 核心包结构详解](#2-minecraft-核心包结构详解)
    - [2.1 包结构总览](#21-包结构总览)
    - [2.2 客户端包](#22-客户端包-netminecraftclient)
    - [2.3 世界包](#23-世界包-netminecraftworld)
    - [2.4 实体包](#24-实体包-netminecraftentity)
    - [2.5 物品包](#25-物品包-netminecraftitem)
    - [2.6 方块包](#26-方块包-netminecraftblock)
    - [2.7 网络包](#27-网络包-netminecraftnetwork)
    - [2.8 注册表包](#28-注册表包-netminecraftregistry)
    - [2.9 常用核心类速查](#29-常用核心类速查)
  - [3. Import 导入完整教程](#3-import-导入完整教程)

### 🎮 Minecraft 模组开发实战
- [Minecraft 模组开发基础](#minecraft-模组开发基础)
  - [1.1 项目结构](#11-项目结构)
  - [1.2 核心概念](#12-核心概念)
  - [1.3 常用 API](#13-常用-api)
- [Mixin 注入技术](#mixin-注入技术)
  - [2.1 Mixin 基础](#21-mixin-基础)
  - [2.2 高级注入](#22-高级注入)
  - [2.3 Mixin 配置文件](#23-mixin-配置文件)
- [渲染系统](#渲染系统)
  - [3.1 NanoVG 渲染](#31-nanovg-渲染)
  - [3.2 传统渲染](#32-传统渲染)
- [模块系统](#模块系统)
- [事件系统](#事件系统)
- [配置系统](#配置系统)

### 💪 实战项目
- [实战项目：编写你的第一个模块](#实战项目编写你的第一个模块)
  - [4.1 创建 KillAura 模块](#41-创建-killaura-模块)
  - [4.2 调试技巧](#42-调试技巧)
  - [4.3 最佳实践](#43-最佳实践)
- [常见问题与解决方案](#常见问题与解决方案)
- [总结](#总结)

---

# Java 基础语法教程（小白必看）

> **适合人群**：完全没有Java基础的新手  
> **学习目标**：掌握Java基础语法，能够理解并编写简单的客户端模块代码

---

## 📚 目录

1. [Java 是什么？](#1-java-是什么)
2. [第一个 Java 程序](#2-第一个-java-程序)
3. [变量与数据类型](#3-变量与数据类型)
4. [运算符](#4-运算符)
5. [流程控制](#5-流程控制)
6. [方法（函数）](#6-方法函数)
7. [类与对象](#7-类与对象)
8. [数组](#8-数组)
9. [字符串操作](#9-字符串操作)
10. [异常处理](#10-异常处理)
11. [Java 注意事项（必读）](#11-java-注意事项必读)
12. [实战练习](#12-实战练习)

---

## 1. Java 是什么？

Java 是一种广泛使用的编程语言，特点：
- **跨平台**：一次编写，到处运行（Write Once, Run Anywhere）
- **面向对象**：一切皆对象
- **强类型**：变量必须先声明类型才能使用
- **广泛应用**：Minecraft 就是用 Java 编写的！

---

## 2. 第一个 Java 程序

```java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
```

**代码解释：**
- `public class HelloWorld` - 定义一个公开的类，类名必须与文件名相同
- `public static void main(String[] args)` - 程序的主入口，从这里开始执行
- `System.out.println()` - 打印内容到控制台并换行

---

## 3. 变量与数据类型

### 3.1 基本数据类型（8种）

```java
// 整数类型
byte b = 127;              // 1字节，范围：-128 ~ 127
short s = 32767;           // 2字节，范围：-32768 ~ 32767
int i = 2147483647;        // 4字节，最常用
long l = 9999999999L;      // 8字节，注意加 L 后缀

// 浮点类型
float f = 3.14f;           // 4字节，注意加 f 后缀
double d = 3.1415926;      // 8字节，默认浮点类型

// 字符类型
char c = 'A';              // 2字节，单个字符（用单引号）

// 布尔类型
boolean flag = true;       // 只有 true 或 false
```

### 3.2 引用数据类型

```java
// 字符串（用双引号）
String name = "张三";

// 数组
int[] numbers = {1, 2, 3, 4, 5};
String[] names = new String[3];

// 对象
Player player = new Player();
```

### 3.3 变量命名规则

```java
// ✅ 正确的命名
int age = 18;
String playerName = "Steve";
boolean isAlive = true;
double attackRange = 4.5;

// ❌ 错误的命名
int 1player = 1;           // 不能以数字开头
String player name = "";   // 不能有空格
int class = 10;            // 不能用关键字
```

**命名规范（驼峰命名法）：**
- 变量名：首字母小写，后续单词首字母大写 `playerName`
- 类名：每个单词首字母大写 `PlayerManager`
- 常量：全部大写，用下划线分隔 `MAX_HEALTH`

---

## 4. 运算符

### 4.1 算术运算符

```java
int a = 10, b = 3;

int sum = a + b;           // 13（加法）
int diff = a - b;          // 7（减法）
int product = a * b;       // 30（乘法）
int quotient = a / b;      // 3（整除，不是 3.33）
int remainder = a % b;     // 1（取余数）

// 自增自减
int x = 5;
x++;                       // x = 6（加1）
x--;                       // x = 5（减1）
```

### 4.2 比较运算符（返回 boolean）

```java
int a = 10, b = 5;

boolean eq = (a == b);     // false（等于）
boolean ne = (a != b);     // true（不等于）
boolean gt = (a > b);      // true（大于）
boolean lt = (a < b);      // false（小于）
boolean ge = (a >= b);     // true（大于等于）
boolean le = (a <= b);     // false（小于等于）
```

### 4.3 逻辑运算符

```java
boolean a = true, b = false;

// && 逻辑与（AND）- 两个都为 true 才返回 true
boolean and = (a && b);    // false

// || 逻辑或（OR）- 任意一个为 true 就返回 true
boolean or = (a || b);     // true

// ! 逻辑非（NOT）- 取反
boolean not = !a;          // false

// 实际应用示例
boolean canAttack = (player != null && target != null && distance < 5.0);
boolean shouldRender = (enabled || visible);
```

### 4.4 赋值运算符

```java
int x = 10;
x += 5;     // 等价于 x = x + 5，结果 15
x -= 3;     // 等价于 x = x - 3，结果 12
x *= 2;     // 等价于 x = x * 2，结果 24
x /= 4;     // 等价于 x = x / 4，结果 6
x %= 3;     // 等价于 x = x % 3，结果 0
```

---

## 5. 流程控制

### 5.1 if-else 条件判断

```java
int score = 85;

if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

// 三元运算符（简化的 if-else）
String result = (score >= 60) ? "及格" : "不及格";
```
//developer yy130202 AI
### 5.2 switch 语句

```java
int day = 3;

switch (day) {
    case 1:
        System.out.println("星期一");
        break;
    case 2:
        System.out.println("星期二");
        break;
    case 3:
        System.out.println("星期三");
        break;
    default:
        System.out.println("其他");
}
```

### 5.3 for 循环

```java
// 基本 for 循环
for (int i = 0; i < 5; i++) {
    System.out.println("i = " + i);  // 输出 0 到 4
}

// 增强 for 循环（遍历数组/集合）
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
    System.out.println(num);
}
```

### 5.4 while 循环

```java
// while 循环
int count = 0;
while (count < 5) {
    System.out.println(count);
    count++;
}

// do-while 循环（至少执行一次）
int num = 0;
do {
    System.out.println(num);
    num++;
} while (num < 5);
```

### 5.5 跳出循环

```java
// break - 跳出整个循环
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break;  // 当 i=5 时跳出循环
    }
    System.out.println(i);  // 输出 0 到 4
}

// continue - 跳过本次循环
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue;  // 跳过偶数
    }
    System.out.println(i);  // 只输出奇数：1, 3, 5, 7, 9
}
```

---

## 6. 方法（函数）

### 6.1 方法的定义

```java
public class MathUtil {
    // 无返回值的方法
    public static void printHello() {
        System.out.println("Hello!");
    }
    
    // 有返回值的方法
    public static int add(int a, int b) {
        return a + b;
    }
    
    // 多个参数
    public static double average(double a, double b, double c) {
        return (a + b + c) / 3.0;
    }
    
    // 可变参数
    public static double sum(double... numbers) {
        double total = 0;
        for (double num : numbers) {
            total += num;
        }
        return total;
    }
}
```

### 6.2 方法的调用

```java
// 调用无返回值方法
MathUtil.printHello();

// 调用有返回值方法
int result = MathUtil.add(5, 3);  // result = 8
double avg = MathUtil.average(10.0, 20.0, 30.0);

// 调用可变参数方法
double total = MathUtil.sum(1.0, 2.0, 3.0, 4.0, 5.0);
```

### 6.3 方法重载

```java
// 方法名相同，参数不同
public static int add(int a, int b) {
    return a + b;
}

public static double add(double a, double b) {
    return a + b;
}

public static int add(int a, int b, int c) {
    return a + b + c;
}
```

---

## 7. 类与对象

### 7.1 定义类

```java
public class Player {
    // 成员变量（属性）
    private String name;
    private int health;
    private double attackDamage;
    
    // 构造方法（用于创建对象）
    public Player(String name, int health, double attackDamage) {
        this.name = name;
        this.health = health;
        this.attackDamage = attackDamage;
    }
    
    // getter 方法（获取属性值）
    public String getName() {
        return name;
    }
    
    public int getHealth() {
        return health;
    }
    
    // setter 方法（设置属性值）
    public void setHealth(int health) {
        if (health >= 0) {
            this.health = health;
        }
    }
    
    // 普通方法
    public void attack(Player target) {
        target.setHealth(target.getHealth() - (int)this.attackDamage);
        System.out.println(this.name + " 攻击了 " + target.getName());
    }
    
    public boolean isAlive() {
        return this.health > 0;
    }
}
```

### 7.2 使用对象

```java
// 创建对象
Player player1 = new Player("Steve", 20, 5.0);
Player player2 = new Player("Alex", 20, 4.0);

// 调用方法
player1.attack(player2);

// 获取属性
System.out.println(player1.getName());  // "Steve"
System.out.println(player2.getHealth()); // 15（被攻击后）

// 判断状态
if (player2.isAlive()) {
    System.out.println(player2.getName() + " 还活着");
}
```

### 7.3 继承

```java
// 父类
public class Entity {
    protected String name;
    protected double health;
    
    public void takeDamage(double damage) {
        this.health -= damage;
    }
}

// 子类
public class Monster extends Entity {
    private int level;
    
    public Monster(String name, double health, int level) {
        this.name = name;
        this.health = health;
        this.level = level;
    }
    
    // 重写父类方法
    @Override
    public void takeDamage(double damage) {
        // 高级怪物有减伤
        double actualDamage = damage * (1.0 - level * 0.05);
        super.takeDamage(actualDamage);
    }
}
```

---

## 8. 数组

### 8.1 数组的声明和初始化

```java
// 方法 1：直接初始化
int[] numbers = {1, 2, 3, 4, 5};

// 方法 2：指定大小
int[] arr = new int[5];  // 默认值都是 0

// 方法 3：先声明后初始化
String[] names;
names = new String[]{"Alice", "Bob", "Charlie"};
```

### 8.2 数组的使用

```java
int[] numbers = {10, 20, 30, 40, 50};

// 访问元素（索引从 0 开始）
System.out.println(numbers[0]);  // 10
System.out.println(numbers[2]);  // 30

// 修改元素
numbers[1] = 25;

// 数组长度
int length = numbers.length;  // 5

// 遍历数组
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

// 增强 for 循环
for (int num : numbers) {
    System.out.println(num);
}
```

### 8.3 多维数组

```java
// 二维数组（矩阵）
int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 访问元素
System.out.println(matrix[0][0]);  // 1（第一行第一列）
System.out.println(matrix[1][2]);  // 6（第二行第三列）

// 遍历二维数组
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        System.out.print(matrix[i][j] + " ");
    }
    System.out.println();
}
```

---

## 9. 字符串操作

### 9.1 字符串的基本操作

```java
String str = "Hello World";

// 获取长度
int len = str.length();  // 11

// 转换为大写/小写
String upper = str.toUpperCase();    // "HELLO WORLD"
String lower = str.toLowerCase();    // "hello world"

// 获取字符（索引从 0 开始）
char c = str.charAt(0);  // 'H'

// 子字符串
String sub = str.substring(0, 5);    // "Hello"
String sub2 = str.substring(6);      // "World"

// 包含检查
boolean contains = str.contains("World");  // true

// 查找位置
int index = str.indexOf("World");    // 6
int lastIndex = str.lastIndexOf("o"); // 7
```

### 9.2 字符串分割和替换

```java
String text = "Java,Python,C++,JavaScript";

// 分割字符串
String[] languages = text.split(",");  // ["Java", "Python", "C++", "JavaScript"]

// 替换
String replaced = text.replace("Java", "Ruby");
// "Ruby,Python,C++,RubyScript"

// 去除首尾空格
String trimmed = "  Hello  ".trim();  // "Hello"
```

### 9.3 字符串拼接

```java
String firstName = "张";
String lastName = "三";

// 方法 1：使用 + 号
String fullName = firstName + lastName;  // "张三"

// 方法 2：使用 concat
String fullName2 = firstName.concat(lastName);

// 方法 3：使用 String.format（推荐）
String message = String.format("姓名：%s，年龄：%d", "张三", 18);

// 方法 4：使用 StringBuilder（大量拼接时更高效）
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();
```

### 9.4 字符串比较

```java
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");

// ❌ 错误：使用 == 比较
System.out.println(str1 == str2);  // true（可能）
System.out.println(str1 == str3);  // false（比较的是引用地址）

// ✅ 正确：使用 equals 比较内容
System.out.println(str1.equals(str2));  // true
System.out.println(str1.equals(str3));  // true

// 忽略大小写比较
System.out.println(str1.equalsIgnoreCase("hello"));  // true
```

---

## 10. 异常处理

### 10.1 try-catch 语句

```java
try {
    // 可能出错的代码
    int result = 10 / 0;  // 除数为 0，会抛出异常
} catch (ArithmeticException e) {
    // 处理异常
    System.out.println("错误：除数不能为 0");
    e.printStackTrace();  // 打印错误信息
}
```

### 10.2 多个 catch 块

```java
try {
    int[] numbers = {1, 2, 3};
    System.out.println(numbers[5]);  // 数组越界
} catch (ArithmeticException e) {
    System.out.println("算术异常");
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("数组越界异常");
} catch (Exception e) {
    System.out.println("其他异常");
}
```

### 10.3 finally 块

```java
try {
    // 可能出错的代码
} catch (Exception e) {
    // 处理异常
} finally {
    // 无论是否出错，都会执行
    // 通常用于清理资源（关闭文件、数据库连接等）
    System.out.println("执行完毕");
}
```

### 10.4 抛出异常

```java
public void setAge(int age) {
    if (age < 0 || age > 150) {
        throw new IllegalArgumentException("年龄必须在 0-150 之间");
    }
    this.age = age;
}
```

---

## 11. Java 注意事项（必读）

### 11.1 常见错误及避免方法

#### ❌ 错误 1：空指针异常（NullPointerException）

```java
// 错误示例
String str = null;
System.out.println(str.length());  // NullPointerException

// 正确做法
String str = null;
if (str != null) {
    System.out.println(str.length());
}
//developer yy130202 AI
// 或使用安全调用
if (str != null && !str.isEmpty()) {
    System.out.println(str.length());
}
```

#### ❌ 错误 2：数组越界（ArrayIndexOutOfBoundsException）

```java
// 错误示例
int[] arr = {1, 2, 3};
System.out.println(arr[3]);  // 越界！索引最大是 2

// 正确做法
int[] arr = {1, 2, 3};
if (index >= 0 && index < arr.length) {
    System.out.println(arr[index]);
}
```

#### ❌ 错误 3：类型转换错误

```java
// 错误示例
Object obj = "Hello";
Integer num = (Integer) obj;  // ClassCastException

// 正确做法
Object obj = "Hello";
if (obj instanceof Integer) {
    Integer num = (Integer) obj;
}
```

#### ❌ 错误 4：忘记 break（switch 穿透）

```java
// 错误示例
int day = 1;
switch (day) {
    case 1:
        System.out.println("星期一");
        // 忘记 break，会继续执行 case 2
    case 2:
        System.out.println("星期二");
        break;
}

// 正确做法
switch (day) {
    case 1:
        System.out.println("星期一");
        break;  // 必须加 break
    case 2:
        System.out.println("星期二");
        break;
}
```

### 11.2 代码规范

#### ✅ 推荐做法

```java
// 1. 使用有意义的变量名
int playerHealth = 100;     // 好
int ph = 100;               // 不好

// 2. 添加注释说明复杂逻辑
/**
 * 计算玩家受到的伤害
 * 考虑护甲、药水效果等因素
 */
private double calculateDamage(Player player) {
    // 复杂逻辑...
}

// 3. 使用常量避免魔法数字
private static final double MAX_HEALTH = 100.0;
private static final double ARMOR_REDUCTION = 0.8;

// 4. 方法不要太长（建议不超过 50 行）
// 将长方法拆分成多个小方法

// 5. 提前返回，减少嵌套
public void processPlayer(Player player) {
    if (player == null) return;
    if (!player.isAlive()) return;
    if (player.getHealth() <= 0) return;
    
    // 主要逻辑
}
```

#### ❌ 避免的做法

```java
// 1. 硬编码魔法数字
if (distance > 5.432)  // 不好
if (distance > MAX_ATTACK_RANGE)  // 好

// 2. 过深的嵌套（超过 3 层）
if (a) {
    if (b) {
        if (c) {
            if (d) {  // 避免！
                // ...
            }
        }
    }
}

// 3. 忽略异常
try {
    doSomething();
} catch (Exception e) {
    // 空的 catch 块，错误被吞掉了
}

// 4. 过度使用静态变量
public class Module {
    public static String playerName;  // 不好，应该用实例变量
}
```

### 11.3 性能优化建议

```java
// 1. 避免在循环中创建对象
// 不好
for (int i = 0; i < 1000; i++) {
    String str = new String("test");  // 每轮循环都创建新对象
}

// 好
String str = "test";
for (int i = 0; i < 1000; i++) {
    // 复用对象
}

// 2. 使用 StringBuilder 进行大量字符串拼接
// 不好
String result = "";
for (int i = 0; i < 100; i++) {
    result += i;  // 每次都创建新字符串
}

// 好
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
    sb.append(i);
}
String result = sb.toString();

// 3. 缓存频繁使用的值
private Entity cachedTarget;
private long lastCacheTime;

if (System.currentTimeMillis() - lastCacheTime > 100) {
    cachedTarget = findTarget();
    lastCacheTime = System.currentTimeMillis();
}

// 4. 使用合适的数据结构
// 快速查找用 HashMap
Map<String, Module> moduleMap = new HashMap<>();
// 有序列表用 ArrayList
List<Module> moduleList = new ArrayList<>();
```

### 11.4 客户端开发特定注意事项

```java
// 1. 总是检查 Minecraft 实例是否为 null
if (Minecraft.getInstance().player == null) return;
if (Minecraft.getInstance().level == null) return;

// 2. 不要在渲染循环中做耗时操作
@EventTarget
public void onRender(EventRender2D event) {
    // 不好 - 每帧都查找实体
    for (Entity entity : mc.level.getAllEntities()) {
        // ...
    }
    
    // 好 - 使用缓存
    if (shouldUpdateCache()) {
        updateEntityCache();
    }
}

// 3. 正确处理模块的启用/禁用
@Override
public void onEnable() {
    // 初始化代码
}

@Override
public void onDisable() {
    // 清理代码，恢复原版行为
}

// 4. 使用日志而不是 System.out
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger LOGGER = LoggerFactory.getLogger(MyModule.class);

LOGGER.info("模块已启用");
LOGGER.error("发生错误", exception);

// 5. 配置文件要妥善处理
// 使用 try-catch 处理文件读写
try {
    saveConfig();
} catch (IOException e) {
    LOGGER.error("保存配置失败", e);
}
```

### 11.5 调试技巧

```java
// 1. 使用 System.out.println 调试（简单直接）
System.out.println("当前血量: " + player.getHealth());

// 2. 使用断言
assert player != null : "玩家不能为 null";

// 3. 使用断点调试
// 在 IDE 中点击行号左侧设置断点
// 使用 Debug 模式运行

// 4. 打印调用栈
Thread.dumpStack();

// 5. 性能分析
long startTime = System.currentTimeMillis();
// 执行的代码
long endTime = System.currentTimeMillis();
System.out.println("耗时: " + (endTime - startTime) + "ms");
```

---

## 12. 实战练习

### 练习 1：简易计算器

```java
import java.util.Scanner;

public class Calculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入第一个数字: ");
        double num1 = scanner.nextDouble();
        
        System.out.print("请输入运算符 (+, -, *, /): ");
        char operator = scanner.next().charAt(0);
        
        System.out.print("请输入第二个数字: ");
        double num2 = scanner.nextDouble();
        
        double result = 0;
        
        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 != 0) {
                    result = num1 / num2;
                } else {
                    System.out.println("错误：除数不能为 0");
                    return;
                }
                break;
            default:
                System.out.println("错误：无效的运算符");
                return;
        }
        
        System.out.println("结果: " + num1 + " " + operator + " " + num2 + " = " + result);
    }
}
```

### 练习 2：玩家属性管理

```java
public class PlayerStats {
    private String name;
    private int level;
    private int health;
    private int attack;
    private int defense;
    
    public PlayerStats(String name, int level) {
        this.name = name;
        this.level = level;
        this.health = 100 + level * 10;
        this.attack = 10 + level * 2;
        this.defense = 5 + level;
    }
    
    public void takeDamage(int damage) {
        int actualDamage = Math.max(1, damage - defense);
        this.health = Math.max(0, this.health - actualDamage);
        System.out.println(name + " 受到 " + actualDamage + " 点伤害，剩余血量: " + health);
    }
    
    public void heal(int amount) {
        int maxHealth = 100 + level * 10;
        this.health = Math.min(maxHealth, this.health + amount);
        System.out.println(name + " 恢复了 " + amount + " 点血量，当前血量: " + health);
    }
    
    public void levelUp() {
        this.level++;
        this.health = 100 + level * 10;
        this.attack = 10 + level * 2;
        this.defense = 5 + level;
        System.out.println(name + " 升级了！当前等级: " + level);
    }
    
    public boolean isAlive() {
        return health > 0;
    }
    
    // getter 方法
    public String getName() { return name; }
    public int getLevel() { return level; }
    public int getHealth() { return health; }
    
    public static void main(String[] args) {
        PlayerStats player = new PlayerStats("Steve", 1);
        
        System.out.println("玩家信息:");
        System.out.println("姓名: " + player.getName());
        System.out.println("等级: " + player.getLevel());
        System.out.println("血量: " + player.getHealth());
        System.out.println("攻击: " + player.attack);
        System.out.println("防御: " + player.defense);
        System.out.println();
        
        player.takeDamage(15);
        player.heal(10);
        player.levelUp();
        
        System.out.println("\n升级后信息:");
        System.out.println("等级: " + player.getLevel());
        System.out.println("血量: " + player.getHealth());
        System.out.println("攻击: " + player.attack);
        System.out.println("防御: " + player.defense);
    }
}
```

### 练习 3：数组排序

```java
public class ArraySort {
    // 冒泡排序
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
    
    // 打印数组
    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        int[] numbers = {64, 34, 25, 12, 22, 11, 90};
        
        System.out.println("排序前:");
        printArray(numbers);
        
        bubbleSort(numbers);
        
        System.out.println("排序后:");
        printArray(numbers);
    }
}
```

---

## 📖 学习资源推荐

### 官方文档
- [Java 官方文档](https://docs.oracle.com/javase/)
- [Minecraft Wiki](https://minecraft.wiki/)

### 在线学习平台
- [菜鸟教程 - Java](https://www.runoob.com/java/java-tutorial.html)
- [廖雪峰 Java 教程](https://www.liaoxuefeng.com/wiki/1252599548343744)
- [牛客网 Java 专项练习](https://www.nowcoder.com/)

### 推荐书籍
- 《Java 核心技术 卷I》- 适合入门
- 《Effective Java》- 进阶必读
- 《Head First Java》- 图文并茂，易于理解

### IDE 推荐
- **IntelliJ IDEA**（强烈推荐）- 智能提示强大
- **Eclipse** - 经典选择
- **VS Code** - 轻量级，需要安装扩展

---

## 🎯 下一步学习建议

完成本教程后，建议按以下顺序学习：

1. ✅ **Java 基础语法**（本教程）
2. 📖 **面向对象编程深入**（继承、多态、接口）
3.  **Minecraft 模组开发基础**（阅读 README 后续章节）
4. 🔧 **Mixin 注入技术**（第 6 章）
5. 🎨 **渲染系统**（第 7 章）
6. 💪 **实战项目**（编写自己的模块）

---

**文档版本**: 1.0  
**最后更新**: 2026-04-23  
**适合人群**: Java 零基础学习者




# Java 进阶详细教程

> **前置要求**: 已完成 [Java 基础语法教程](JAVA_TUTORIAL.md)  
> **学习目标**: 掌握Java面向对象编程、集合框架、异常处理、泛型等高级特性

---

## 📚 目录

1. [面向对象编程深入](#1-面向对象编程深入)
2. [接口与抽象类](#2-接口与抽象类)
3. [内部类与匿名类](#3-内部类与匿名类)
4. [泛型编程](#4-泛型编程)
5. [集合框架](#5-集合框架)
6. [异常处理进阶](#6-异常处理进阶)
7. [Lambda 表达式与 Stream API](#7-lambda-表达式与-stream-api)
8. [多线程基础](#8-多线程基础)
9. [I/O 与文件操作](#9-io-与文件操作)
10. [注解与反射](#10-注解与反射)
11. [设计模式入门](#11-设计模式入门)
12. [实战项目](#12-实战项目)

---

## 1. 面向对象编程深入

### 1.1 封装（Encapsulation）

封装是隐藏内部实现细节，只暴露必要的接口。

```java
public class Player {
    // 私有属性（封装）
    private String name;
    private int health;
    private int level;
    
    // 公共访问方法（Getter）
    public String getName() {
        return name;
    }
    
    public int getHealth() {
        return health;
    }
    
    // 公共修改方法（Setter）
    public void setName(String name) {
        if (name != null && !name.isEmpty()) {
            this.name = name;
        }
    }
    
    public void setHealth(int health) {
        if (health >= 0 && health <= 100) {
            this.health = health;
        } else {
            System.out.println("血量必须在 0-100 之间");
        }
    }
    
    // 构造方法
    public Player(String name) {
        this.name = name;
        this.health = 100;
        this.level = 1;
    }
}
```

**封装的好处：**
- 数据安全性：防止外部直接修改
- 灵活性：可以随时修改内部实现
- 可维护性：便于统一管理属性访问

### 1.2 继承（Inheritance）

继承允许创建基于现有类的新类。

```java
// 父类
public class Entity {
    protected String name;
    protected double health;
    protected Vec3 position;
    
    public Entity(String name, double health) {
        this.name = name;
        this.health = health;
    }
    
    public void move(double x, double y, double z) {
        this.position = new Vec3(x, y, z);
    }
    
    public void takeDamage(double damage) {
        this.health -= damage;
        if (this.health < 0) {
            this.health = 0;
        }
    }
    
    public boolean isAlive() {
        return health > 0;
    }
}

// 子类：玩家
public class PlayerEntity extends Entity {
    private int level;
    private int experience;
    
    public PlayerEntity(String name) {
        super(name, 100.0);  // 调用父类构造方法
        this.level = 1;
        this.experience = 0;
    }
    
    // 子类特有方法
    public void gainExperience(int exp) {
        this.experience += exp;
        if (this.experience >= getRequiredExp()) {
            levelUp();
        }
    }
    
    private void levelUp() {
        this.level++;
        this.experience = 0;
        this.health = 100.0;  // 升级回满血
        System.out.println(name + " 升级了！当前等级: " + level);
    }
    
    private int getRequiredExp() {
        return level * 100;
    }
}

// 子类：怪物
public class MonsterEntity extends Entity {
    private int level;
    private double attackDamage;
    
    public MonsterEntity(String name, int level) {
        super(name, 50.0 + level * 10);
        this.level = level;
        this.attackDamage = 5.0 + level * 2;
    }
    
    public void attack(PlayerEntity player) {
        player.takeDamage(this.attackDamage);
        System.out.println(name + " 攻击了 " + player.getName() + 
                          "，造成 " + attackDamage + " 点伤害");
    }
}
```

**继承的特点：**
- 子类继承父类的所有非私有成员
- 子类可以添加自己的成员
- 子类可以重写父类方法
- Java 只支持单继承（一个类只能有一个直接父类）

### 1.3 多态（Polymorphism）

多态允许父类引用指向子类对象。

```java
// 多态示例
public class Game {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        Entity player = new PlayerEntity("Steve");
        Entity monster = new MonsterEntity("僵尸", 2);
        
        // 都可以调用父类方法
        System.out.println(player.isAlive());  // true
        System.out.println(monster.isAlive());  // true
        
        // 多态数组
        Entity[] entities = {
                //developer yy130202 AI
            new PlayerEntity("Steve"),
            new PlayerEntity("Alex"),
            new MonsterEntity("骷髅", 1),
            new MonsterEntity("苦力怕", 3)
        };
        
        // 遍历处理
        for (Entity entity : entities) {
            System.out.println(entity.name + " - 血量: " + entity.health);
            
            // 判断实际类型
            if (entity instanceof PlayerEntity) {
                PlayerEntity playerEntity = (PlayerEntity) entity;
                System.out.println("  -> 这是一个玩家，等级: " + playerEntity.level);
            } else if (entity instanceof MonsterEntity) {
                MonsterEntity monster = (MonsterEntity) entity;
                System.out.println("  -> 这是一个怪物，等级: " + monster.level);
            }
        }
    }
}
```

### 1.4 方法重写（Override）

子类可以重写父类的方法。

```java
public class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
    
    public void move() {
        System.out.println("动物移动");
    }
}

public class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("汪汪汪！");
    }
    
    @Override
    public void move() {
        System.out.println("狗跑动");
    }
    
    // 子类特有方法
    public void fetch() {
        System.out.println("狗捡东西");
    }
}

public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("喵喵喵！");
    }
    
    @Override
    public void move() {
        System.out.println("猫走动");
    }
}

// 使用
Animal dog = new Dog();
dog.makeSound();  // 输出: 汪汪汪！

Animal cat = new Cat();
cat.makeSound();  // 输出: 喵喵喵！
```

**@Override 注解的作用：**
- 标记方法为重写
- 编译器检查是否正确重写
- 提高代码可读性

---

## 2. 接口与抽象类

### 2.1 抽象类

抽象类不能被实例化，用于作为父类模板。

```java
// 抽象类
public abstract class Weapon {
    protected String name;
    protected double damage;
    protected int durability;
    
    public Weapon(String name, double damage, int durability) {
        this.name = name;
        this.damage = damage;
        this.durability = durability;
    }
    
    // 抽象方法（没有方法体）
    public abstract void attack(Entity target);
    public abstract String getDescription();
    
    // 普通方法
    public void takeDamage() {
        this.durability--;
        if (this.durability <= 0) {
            breakWeapon();
        }
    }
    
    private void breakWeapon() {
        System.out.println(name + " 损坏了！");
    }
    
    public boolean isBroken() {
        return durability <= 0;
    }
}

// 具体实现
public class Sword extends Weapon {
    public Sword(String name, double damage) {
        super(name, damage, 100);
    }
    
    @Override
    public void attack(Entity target) {
        if (isBroken()) {
            System.out.println("剑已损坏，无法攻击！");
            return;
        }
        
        target.takeDamage(this.damage);
        System.out.println("用 " + name + " 攻击了 " + target.name);
        takeDamage();
    }
    
    @Override
    public String getDescription() {
        return name + " - 伤害: " + damage + ", 耐久: " + durability;
    }
}

public class Bow extends Weapon {
    private int arrows;
    
    public Bow(String name, double damage, int arrows) {
        super(name, damage, 50);
        this.arrows = arrows;
    }
    
    @Override
    public void attack(Entity target) {
        if (isBroken()) {
            System.out.println("弓已损坏！");
            return;
        }
        
        if (arrows <= 0) {
            System.out.println("没有箭了！");
            return;
        }
        
        target.takeDamage(this.damage);
        this.arrows--;
        System.out.println("用 " + name + " 射中了 " + target.name + 
                          "，剩余箭: " + arrows);
        takeDamage();
    }
    
    @Override
    public String getDescription() {
        return name + " - 伤害: " + damage + ", 箭: " + arrows;
    }
}
```

### 2.2 接口

接口定义行为规范，支持多实现。

```java
// 定义接口
public interface Damageable {
    void takeDamage(double damage);
    double getHealth();
    boolean isAlive();
}

public interface Attackable {
    void attack(Entity target);
    double getAttackDamage();
}

public interface Moveable {
    void move(double x, double y, double z);
    double getSpeed();
}

// 实现多个接口
public class Player implements Damageable, Attackable, Moveable {
    private double health;
    private double attackDamage;
    private double speed;
    private Vec3 position;
    
    // 实现 Damageable 接口
    @Override
    public void takeDamage(double damage) {
        this.health -= damage;
        if (this.health < 0) this.health = 0;
    }
    
    @Override
    public double getHealth() {
        return health;
    }
    
    @Override
    public boolean isAlive() {
        return health > 0;
    }
    
    // 实现 Attackable 接口
    @Override
    public void attack(Entity target) {
        if (target instanceof Damageable) {
            ((Damageable) target).takeDamage(this.attackDamage);
        }
    }
    
    @Override
    public double getAttackDamage() {
        return attackDamage;
    }
    
    // 实现 Moveable 接口
    @Override
    public void move(double x, double y, double z) {
        this.position = new Vec3(x, y, z);
    }
    
    @Override
    public double getSpeed() {
        return speed;
    }
}
```

**接口 vs 抽象类：**

| 特性 | 接口 | 抽象类 |
|------|------|--------|
| 方法类型 | 只有抽象方法（Java 8+ 可有默认方法） | 可以有抽象和普通方法 |
| 成员变量 | 只能是常量（public static final） | 可以有各种类型变量 |
| 继承 | 可以多实现 | 只能单继承 |
| 构造方法 | 没有 | 有 |
| 使用场景 | 定义行为规范 | 提供部分实现的模板 |

### 2.3 默认方法（Java 8+）

```java
public interface Logger {
    void log(String message);
    
    // 默认方法
    default void logError(String message) {
        log("ERROR: " + message);
    }
    
    default void logWarning(String message) {
        log("WARNING: " + message);
    }
    
    // 静态方法
    static Logger createConsoleLogger() {
        return message -> System.out.println(message);
    }
}

public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("[LOG] " + message);
    }
    
    // 可以选择重写默认方法
    @Override
    public void logError(String message) {
        System.err.println("[ERROR] " + message);
    }
}
```

---

## 3. 内部类与匿名类

### 3.1 成员内部类

```java
public class OuterClass {
    private String outerField = "外部类字段";
    
    // 成员内部类
    public class InnerClass {
        private String innerField = "内部类字段";
        
        public void display() {
            // 可以访问外部类成员
            System.out.println(outerField);
            System.out.println(innerField);
        }
    }
    
    public void testInnerClass() {
        InnerClass inner = new InnerClass();
        inner.display();
    }
    
    public static void main(String[] args) {
        // 创建内部类实例
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.display();
    }
}
```

### 3.2 静态内部类

```java
public class Container {
    private String name;
    
    // 静态内部类
    public static class Item {
        private String itemName;
        private int count;
        
        public Item(String itemName, int count) {
            this.itemName = itemName;
            this.count = count;
        }
        
        public String getName() { return itemName; }
        public int getCount() { return count; }
    }
    
    public static void main(String[] args) {
        // 静态内部类可以直接创建
        Item item = new Item("钻石", 64);
        System.out.println(item.getName() + " x" + item.getCount());
    }
}
```

### 3.3 局部内部类

```java
public void processList(List<String> list) {
    // 局部内部类（定义在方法内）
    class ItemProcessor {
        public void process(String item) {
            System.out.println("处理: " + item);
        }
    }
    
    ItemProcessor processor = new ItemProcessor();
    for (String item : list) {
        processor.process(item);
    }
}
```

### 3.4 匿名内部类

```java
// 使用匿名内部类实现接口
public interface OnClickListener {
    void onClick();
}

public class Button {
    private OnClickListener listener;
    
    public void setOnClickListener(OnClickListener listener) {
        this.listener = listener;
    }
    
    public void click() {
        if (listener != null) {
            listener.onClick();
        }
    }
}

// 使用匿名内部类
Button button = new Button();
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick() {
        System.out.println("按钮被点击了！");
    }
});

button.click();  // 输出: 按钮被点击了！
```

---

## 4. 泛型编程

### 4.1 泛型类

```java
// 泛型类
public class Box<T> {
    private T content;
    
    public void set(T content) {
        this.content = content;
    }
    
    public T get() {
        return content;
    }
    
    public boolean isEmpty() {
        return content == null;
    }
}

// 使用
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String str = stringBox.get();

Box<Integer> intBox = new Box<>();
intBox.set(100);
Integer num = intBox.get();

Box<Player> playerBox = new Box<>();
playerBox.set(new Player("Steve"));
Player player = playerBox.get();
```

### 4.2 泛型方法

```java
public class Utils {
    // 泛型方法
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
    
    // 多个泛型参数
    public static <K, V> void printMap(Map<K, V> map) {
        for (Map.Entry<K, V> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
    }
    
    // 泛型方法 - 查找
    public static <T> int findIndex(T[] array, T target) {
        for (int i = 0; i < array.length; i++) {
            if (array[i].equals(target)) {
                return i;
            }
        }
        return -1;
    }
}

// 使用
String[] strings = {"A", "B", "C"};
Utils.printArray(strings);

Integer[] numbers = {1, 2, 3};
Utils.printArray(numbers);

String[] names = {"Alice", "Bob", "Charlie"};
int index = Utils.findIndex(names, "Bob");
System.out.println("索引: " + index);  // 1
```

### 4.3 泛型通配符

```java
public class WildcardExample {
    // ? 表示未知类型
    public static void printList(List<?> list) {
        for (Object item : list) {
            System.out.println(item);
        }
    }
    
    // ? extends T - 上界通配符（可以读，不能写）
    public static double sum(List<? extends Number> list) {
        double sum = 0;
        for (Number num : list) {
            sum += num.doubleValue();
        }
        return sum;
    }
    
    // ? super T - 下界通配符（可以写，读出来是 Object）
    public static void addNumbers(List<? super Integer> list) {
        list.add(1);
        list.add(2);
        list.add(3);
    }
}

// 使用
List<Integer> intList = Arrays.asList(1, 2, 3);
List<Double> doubleList = Arrays.asList(1.5, 2.5, 3.5);

System.out.println(sum(intList));      // 6.0
System.out.println(sum(doubleList));   // 7.5

List<Number> numberList = new ArrayList<>();
addNumbers(numberList);
```

---

## 5. 集合框架

### 5.1 Collection 接口

```java
// List - 有序集合，允许重复
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Apple");  // 允许重复
list.add(1, "Cherry");  // 插入到指定位置

// 遍历
for (String fruit : list) {
    System.out.println(fruit);
}

// Set - 无序集合，不允许重复
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Apple");  // 不会添加，已存在

// Map - 键值对集合
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 5);
map.put("Banana", 3);
map.put("Cherry", 8);

// 遍历 Map
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
```

### 5.2 List 实现类

```java
// ArrayList - 基于数组，查询快，增删慢
List<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
String item = arrayList.get(0);  // 快速查询

// LinkedList - 基于链表，增删快，查询慢
List<String> linkedList = new LinkedList<>();
linkedList.add("A");
linkedList.add("B");
linkedList.remove(0);  // 快速删除

// Vector - 线程安全的 ArrayList（不推荐使用）
List<String> vector = new Vector<>();
```

### 5.3 Set 实现类

```java
// HashSet - 基于哈希表，无序
Set<String> hashSet = new HashSet<>();
hashSet.add("C");
hashSet.add("A");
hashSet.add("B");
// 遍历顺序不确定

// TreeSet - 基于红黑树，有序
Set<String> treeSet = new TreeSet<>();
treeSet.add("C");
treeSet.add("A");
treeSet.add("B");
// 遍历顺序: A, B, C

// LinkedHashSet - 保持插入顺序
Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("C");
linkedHashSet.add("A");
linkedHashSet.add("B");
// 遍历顺序: C, A, B
```

### 5.4 Map 实现类

```java
// HashMap - 基于哈希表，无序
Map<String, Integer> hashMap = new HashMap<>();

// TreeMap - 基于红黑树，按键排序
Map<String, Integer> treeMap = new TreeMap<>();

// LinkedHashMap - 保持插入顺序
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();

// 常用方法
map.put("key", value);
map.get("key");
map.containsKey("key");
map.containsValue(value);
map.remove("key");
map.size();
map.clear();
```

### 5.5 Collections 工具类

```java
List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 9));

// 排序
Collections.sort(numbers);
System.out.println(numbers);  // [1, 3, 5, 8, 9]

// 降序排序
Collections.sort(numbers, Collections.reverseOrder());
System.out.println(numbers);  // [9, 8, 5, 3, 1]

// 查找最大值/最小值
int max = Collections.max(numbers);
int min = Collections.min(numbers);

// 打乱顺序
Collections.shuffle(numbers);

// 填充
Collections.fill(numbers, 0);  // 全部填充为 0

// 不可变集合
List<String> immutableList = Collections.unmodifiableList(list);
// immutableList.add("X");  // 抛出异常
```

---

## 6. 异常处理进阶

### 6.1 异常分类

```
//developer yy130202 AI
Throwable
├── Error（错误，JVM 级别，通常无法恢复）
│   ├── OutOfMemoryError
│   ├── StackOverflowError
│   └── ...
└── Exception（异常，可以处理）
    ├── RuntimeException（运行时异常，unchecked）
    │   ├── NullPointerException
    │   ├── ArrayIndexOutOfBoundsException
    │   ├── IllegalArgumentException
    │   └── ...
    └── 其他异常（checked）
        ├── IOException
        ├── SQLException
        └── ...
```

### 6.2 自定义异常

```java
// 自定义检查异常
public class InsufficientHealthException extends Exception {
    private int currentHealth;
    private int requiredHealth;
    
    public InsufficientHealthException(int currentHealth, int requiredHealth) {
        super("血量不足: 当前 " + currentHealth + ", 需要 " + requiredHealth);
        this.currentHealth = currentHealth;
        this.requiredHealth = requiredHealth;
    }
    
    public int getCurrentHealth() { return currentHealth; }
    public int getRequiredHealth() { return requiredHealth; }
}

// 自定义运行时异常
public class PlayerNotFoundException extends RuntimeException {
    public PlayerNotFoundException(String playerName) {
        super("玩家不存在: " + playerName);
    }
}

// 使用自定义异常
public class Player {
    private int health;
    
    public void attack(int damage) throws InsufficientHealthException {
        if (health < damage) {
            throw new InsufficientHealthException(health, damage);
        }
        health -= damage;
    }
    
    public Player findPlayer(String name) {
        // ...
        throw new PlayerNotFoundException(name);
    }
}
```

### 6.3 try-with-resources（Java 7+）

自动关闭资源，不需要 finally 块。

```java
// 传统方式
BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader("file.txt"));
    String line = reader.readLine();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (reader != null) {
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// try-with-resources（推荐）
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
    String line = reader.readLine();
} catch (IOException e) {
    e.printStackTrace();
}
// 自动关闭 reader，无需手动 close()

// 多个资源
try (
    FileReader fileReader = new FileReader("file.txt");
    BufferedReader bufferedReader = new BufferedReader(fileReader)
) {
    String line = bufferedReader.readLine();
} catch (IOException e) {
    e.printStackTrace();
}
```

---

## 7. Lambda 表达式与 Stream API

### 7.1 Lambda 表达式

```java
// 传统方式
Comparator<String> comparator = new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.compareTo(s2);
    }
};

// Lambda 表达式
Comparator<String> lambdaComparator = (s1, s2) -> s1.compareTo(s2);

// 更简洁的写法
Comparator<String> methodRef = String::compareTo;

// 常用示例
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

// forEach
names.forEach(name -> System.out.println(name));
names.forEach(System.out::println);  // 方法引用

// Runnable
Runnable runnable = () -> System.out.println("Hello!");
new Thread(runnable).start();

// Predicate（断言）
Predicate<String> isEmpty = String::isEmpty;
System.out.println(isEmpty.test(""));  // true

// Function（函数）
Function<String, Integer> length = String::length;
System.out.println(length.apply("Hello"));  // 5
```

### 7.2 Stream API

```java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 过滤
List<Integer> evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());
// [2, 4, 6, 8, 10]

// 映射
List<String> strings = numbers.stream()
    .map(n -> "Number: " + n)
    .collect(Collectors.toList());

// 排序
List<Integer> sorted = numbers.stream()
    .sorted(Comparator.reverseOrder())
    .collect(Collectors.toList());

// 去重
List<Integer> distinct = Arrays.asList(1, 2, 2, 3, 3, 3).stream()
    .distinct()
    .collect(Collectors.toList());

// 限制
List<Integer> limited = numbers.stream()
    .limit(5)
    .collect(Collectors.toList());
// [1, 2, 3, 4, 5]

// 跳过
List<Integer> skipped = numbers.stream()
    .skip(5)
    .collect(Collectors.toList());
// [6, 7, 8, 9, 10]

// 统计
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
double average = numbers.stream().mapToInt(Integer::intValue).average().orElse(0);
int max = numbers.stream().mapToInt(Integer::intValue).max().orElse(0);
int min = numbers.stream().mapToInt(Integer::intValue).min().orElse(0);

// 归约
int product = numbers.stream()
    .reduce(1, (a, b) -> a * b);
// 10! = 3628800

// 分组
List<Player> players = ...;
Map<String, List<Player>> byTeam = players.stream()
    .collect(Collectors.groupingBy(Player::getTeam));

// 分区
Map<Boolean, List<Player>> byLevel = players.stream()
    .collect(Collectors.partitioningBy(p -> p.getLevel() >= 10));
```

### 7.3 Optional（Java 8+）

避免 NullPointerException。

```java
// 创建 Optional
Optional<String> empty = Optional.empty();
Optional<String> value = Optional.of("Hello");
Optional<String> nullable = Optional.ofNullable(null);

// 判断是否存在
if (value.isPresent()) {
    System.out.println(value.get());
}

// 推荐用法
value.ifPresent(System.out::println);

// 默认值
String result = nullable.orElse("Default");
String result2 = nullable.orElseGet(() -> "Generated Default");

// 链式调用
Optional<Player> player = findPlayer("Steve");
String name = player
    .map(Player::getName)
    .orElse("Unknown");

// 实战示例
public String getPlayerName(String id) {
    return findPlayerById(id)
        .map(Player::getName)
        .orElseThrow(() -> new PlayerNotFoundException(id));
}
```

---

## 8. 多线程基础

### 8.1 创建线程

```java
// 方式 1：继承 Thread 类
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程运行中");
    }
}

MyThread thread1 = new MyThread();
thread1.start();

// 方式 2：实现 Runnable 接口（推荐）
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程运行中");
    }
}

Thread thread2 = new Thread(new MyRunnable());
thread2.start();

// 方式 3：Lambda 表达式
Thread thread3 = new Thread(() -> {
    System.out.println("线程运行中");
});
thread3.start();

// 方式 4：使用 ExecutorService（推荐）
ExecutorService executor = Executors.newFixedThreadPool(5);

for (int i = 0; i < 10; i++) {
    executor.submit(() -> {
        System.out.println("任务执行: " + Thread.currentThread().getName());
    });
}

executor.shutdown();
```

### 8.2 线程同步

```java
public class Counter {
    private int count = 0;
    
    // synchronized 方法
    public synchronized void increment() {
        count++;
    }
    
    // synchronized 块
    public void decrement() {
        synchronized(this) {
            count--;
        }
    }
    
    // ReentrantLock（更灵活）
    private final Lock lock = new ReentrantLock();
    
    public void safeIncrement() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
}

// volatile 关键字
public class Flag {
    private volatile boolean running = true;
    
    public void stop() {
        running = false;
    }
    
    public boolean isRunning() {
        return running;
    }
}
```

### 8.3 线程间通信

```java
public class ProducerConsumer {
    private Queue<Integer> queue = new LinkedList<>();
    private int capacity = 10;
    
    public synchronized void produce(int item) throws InterruptedException {
        while (queue.size() == capacity) {
            wait();  // 队列满，等待
        }
        queue.add(item);
        System.out.println("生产: " + item);
        notifyAll();  // 通知消费者
    }
    
    public synchronized int consume() throws InterruptedException {
        while (queue.isEmpty()) {
            wait();  // 队列空，等待
        }
        int item = queue.poll();
        System.out.println("消费: " + item);
        notifyAll();  // 通知生产者
        return item;
    }
}
```

---

## 9. I/O 与文件操作

### 9.1 File 类

```java
File file = new File("example.txt");

// 检查文件
boolean exists = file.exists();
boolean isFile = file.isFile();
boolean isDirectory = file.isDirectory();
long size = file.length();

// 创建/删除
boolean created = file.createNewFile();
boolean deleted = file.delete();

// 目录操作
File dir = new File("mydir");
dir.mkdir();  // 创建单级目录
dir.mkdirs();  // 创建多级目录

// 遍历目录
File directory = new File(".");
String[] files = directory.list();
for (String fileName : files) {
    System.out.println(fileName);
}
```

### 9.2 文件读写

```java
// 传统方式 - FileReader/FileWriter
try (FileReader reader = new FileReader("input.txt");
     FileWriter writer = new FileWriter("output.txt")) {
    
    int character;
    while ((character = reader.read()) != -1) {
        writer.write(character);
    }
}

// 缓冲流 - BufferedReader/BufferedWriter
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
     BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
    
    String line;
    while ((line = reader.readLine()) != null) {
        writer.write(line);
        writer.newLine();
    }
}

// NIO（Java 7+）- 推荐
// 读取所有行
List<String> lines = Files.readAllLines(Paths.get("file.txt"));

// 写入所有行
Files.write(Paths.get("output.txt"), lines);

// 复制文件
Files.copy(Paths.get("source.txt"), Paths.get("dest.txt"));

// 移动文件
Files.move(Paths.get("old.txt"), Paths.get("new.txt"));

// 删除文件
Files.delete(Paths.get("file.txt"));
```

### 9.3 序列化

```java
// 可序列化的类
public class Player implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String name;
    private int level;
    private transient int tempData;  // transient 不序列化
    
    // ... getter/setter
}

// 序列化
Player player = new Player("Steve", 10);

try (ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("player.dat"))) {
    oos.writeObject(player);
}

// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(
        new FileInputStream("player.dat"))) {
    Player loadedPlayer = (Player) ois.readObject();
    System.out.println(loadedPlayer.getName());
}
```

---

## 10. 注解与反射

### 10.1 自定义注解

```java
import java.lang.annotation.*;

// 定义注解
@Retention(RetentionPolicy.RUNTIME)  // 运行时可见
@Target(ElementType.FIELD)           // 只能用于字段
public @interface Config {
    String key();
    String defaultValue() default "";
    boolean required() default false;
}

// 使用注解
public class GameSettings {
    @Config(key = "player.name", required = true)
    private String playerName;
    
    @Config(key = "player.health", defaultValue = "100")
    private int health;
    
    @Config(key = "game.difficulty")
    private String difficulty;
}
```

### 10.2 反射基础

```java
// 获取 Class 对象
Class<?> clazz = Player.class;
Class<?> clazz2 = Class.forName("com.example.Player");
Class<?> clazz3 = player.getClass();

// 获取构造函数
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Player player = (Player) constructor.newInstance("Steve", 100);

// 获取字段
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);  // 访问私有字段
field.set(player, "Alex");
String name = (String) field.get(player);

// 获取方法
Method method = clazz.getDeclaredMethod("attack", Entity.class);
method.setAccessible(true);
method.invoke(player, target);

// 获取所有字段
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
    System.out.println(f.getName() + ": " + f.getType());
}

// 获取所有方法
Method[] methods = clazz.getDeclaredMethods();
for (Method m : methods) {
    System.out.println(m.getName());
}
```

### 10.3 注解处理

```java
// 使用反射读取注解
public class ConfigLoader {
    public static void loadConfig(Object obj) {
        Class<?> clazz = obj.getClass();
        
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Config.class)) {
                Config config = field.getAnnotation(Config.class);
                String key = config.key();
                String defaultValue = config.defaultValue();
                
                // 从配置文件读取值
                String value = readFromConfig(key, defaultValue);
                
                // 设置字段值
                field.setAccessible(true);
                try {
                    Object convertedValue = convert(value, field.getType());
                    field.set(obj, convertedValue);
                } catch (Exception e) {
                    if (config.required()) {
                        throw new RuntimeException("Required config missing: " + key);
                    }
                }
            }
        }
    }
}
```

---

## 11. 设计模式入门

### 11.1 单例模式

```java
// 饿汉式（线程安全）
public class Singleton {
    private static final Singleton instance = new Singleton();
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        return instance;
    }
}

// 懒汉式（双重检查锁）
public class LazySingleton {
    private static volatile LazySingleton instance;
    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

// 静态内部类（推荐）
public class StaticSingleton {
    private StaticSingleton() {}
    
    private static class SingletonHolder {
        private static final StaticSingleton instance = new StaticSingleton();
    }
    
    public static StaticSingleton getInstance() {
        return SingletonHolder.instance;
    }
}
```

### 11.2 工厂模式

```java
// 产品接口
public interface Weapon {
    void attack();
}

// 具体产品
public class Sword implements Weapon {
    @Override
    public void attack() {
        System.out.println("用剑攻击");
    }
}

public class Bow implements Weapon {
    @Override
    public void attack() {
        System.out.println("用弓射击");
    }
}

// 工厂类
public class WeaponFactory {
    public static Weapon createWeapon(String type) {
        switch (type.toLowerCase()) {
            case "sword":
                return new Sword();
            case "bow":
                return new Bow();
            default:
                throw new IllegalArgumentException("Unknown weapon: " + type);
        }
    }
}

// 使用
Weapon sword = WeaponFactory.createWeapon("sword");
sword.attack();
```

### 11.3 观察者模式

```java
// 观察者接口
public interface Observer {
    void update(String event);
}

// 主题接口
public interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers(String event);
}

// 具体主题
public class EventManager implements Subject {
    private List<Observer> observers = new ArrayList<>();
    
    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notifyObservers(String event) {
        for (Observer observer : observers) {
            observer.update(event);
        }
    }
}

// 使用
EventManager eventManager = new EventManager();

Observer player1 = event -> System.out.println("玩家1收到: " + event);
Observer player2 = event -> System.out.println("玩家2收到: " + event);

eventManager.addObserver(player1);
eventManager.addObserver(player2);

eventManager.notifyObservers("Boss出现了！");
```

---

## 12. 实战项目

### 项目 1：简易库存管理系统

```java
public class Inventory {
    private Map<String, Item> items = new HashMap<>();
    private int maxSize;
    
    public Inventory(int maxSize) {
        this.maxSize = maxSize;
    }
    
    public boolean addItem(Item item) {
        if (items.size() >= maxSize) {
            System.out.println("库存已满！");
            return false;
        }
        
        String id = item.getId();
        if (items.containsKey(id)) {
            items.get(id).addCount(item.getCount());
        } else {
            items.put(id, item);
        }
        return true;
    }
    
    public boolean removeItem(String itemId, int count) {
        Item item = items.get(itemId);
        if (item == null || item.getCount() < count) {
            return false;
        }
        
        item.setCount(item.getCount() - count);
        if (item.getCount() <= 0) {
            items.remove(itemId);
        }
        return true;
    }
    
    public Item getItem(String itemId) {
        return items.get(itemId);
    }
    
    public void displayAll() {
        items.forEach((id, item) -> {
            System.out.println(id + ": " + item.getName() + " x" + item.getCount());
        });
    }
    
    public static void main(String[] args) {
        Inventory inventory = new Inventory(100);
        
        inventory.addItem(new Item("diamond", "钻石", 64));
        inventory.addItem(new Item("iron", "铁锭", 32));
        inventory.addItem(new Item("diamond", "钻石", 10));  // 叠加
        
        inventory.displayAll();
        
        inventory.removeItem("diamond", 20);
        inventory.displayAll();
    }
}

class Item {
    private String id;
    private String name;
    private int count;
    
    // ... 构造方法、getter/setter
}
```

### 项目 2：任务系统

```java
public class Quest {
    private String title;
    private String description;
    private List<String> objectives;
    private boolean completed;
    
    public Quest(String title, String description) {
        this.title = title;
        this.description = description;
        this.objectives = new ArrayList<>();
        this.completed = false;
    }
    
    public void addObjective(String objective) {
        objectives.add(objective);
    }
    
    public void completeObjective(String objective) {
        objectives.remove(objective);
        if (objectives.isEmpty()) {
            this.completed = true;
            System.out.println("任务完成: " + title);
        }
    }
    
    public boolean isCompleted() {
        return completed;
    }
    
    public void displayStatus() {
        System.out.println("任务: " + title);
        System.out.println("描述: " + description);
        System.out.println("目标:");
        for (String obj : objectives) {
            System.out.println("  - [ ] " + obj);
        }
        if (completed) {
            System.out.println("状态: ✅ 已完成");
        }
    }
}
```

---

## 📖 学习资源推荐

### 书籍
- 《Java 核心技术 卷I & 卷II》- 深入理解
- 《Effective Java》- 最佳实践
- 《Java 并发编程实战》- 多线程必读
- 《Java 8 实战》- Lambda 和 Stream

### 在线资源
- [Oracle 官方教程](https://docs.oracle.com/javase/tutorial/)
- [菜鸟教程 - Java](https://www.runoob.com/java/java-tutorial.html)
- [廖雪峰 Java 教程](https://www.liaoxuefeng.com/wiki/1252599548343744)

---

**文档版本**: 1.0  
**最后更新**: 2026-04-23  
**适合人群**: 已完成 Java 基础学习的开发者








# Minecraft 客户端开发完整教程

> **本教程基于 Late 客户端项目，适用于 Forge 1.20.1+ 版本**  
> 适合初学者到中级开发者，从基础到高级全面讲解

---

## 📚 目录

0. [环境准备与模板获取](#0-环境准备与模板获取)
0.5 [Java 基础语法教程（小白必看）](#05-java-基础语法教程小白必看)
0.6 [IntelliJ IDEA 配置与快捷键指南](#06-intellij-idea-配置与快捷键指南)
0.7 [Java 进阶详细教程](#07-java-进阶详细教程)
0.8 [Java 注解与 Minecraft 包详解](JAVA_ANNOTATIONS_AND_IMPORTS.md)
1. [项目架构概览](#1-项目架构概览)
2. [核心概念理解](#2-核心概念理解)
3. [模块系统详解](#3-模块系统详解)
4. [变量系统详解](#4-变量系统详解)
5. [事件系统详解](#5-事件系统详解)
6. [Mixin 注入技术](#6-mixin-注入技术)
7. [渲染系统](#7-渲染系统)
8. [实用工具类](#8-实用工具类)
9. [编写第一个模块](#9-编写第一个模块)
10. [最佳实践与注意事项](#10-最佳实践与注意事项)

---

## 0. 环境准备与模板获取

> **新手提示**：
> - 如果你完全没有 Java 基础，请先阅读 [Java 基础语法教程](JAVA_TUTORIAL.md)（小白必看）
> - 掌握基础后，继续学习 [Java 进阶详细教程](JAVA_ADVANCED.md)
> - IDE 使用技巧：[IntelliJ IDEA 配置与快捷键指南](IDEA_GUIDE.md)
> - 注解、包结构和 Import 导入：[Java 注解与 Minecraft 包详解](JAVA_ANNOTATIONS_AND_IMPORTS.md)

### 0.1 必需开发工具

#### A. JDK (Java Development Kit)

**推荐版本：**
- Minecraft 1.16.5 及以下 → JDK 8
- Minecraft 1.17 - 1.17.1 → JDK 16
- Minecraft 1.18+ → **JDK 17**（推荐）
- Minecraft 1.20.5+ → JDK 21

**下载地址：**
- [Eclipse Temurin (推荐)](https://adoptium.net/temurin/releases/)
- [Oracle JDK](https://www.oracle.com/java/technologies/downloads/)
- [Azul Zulu](https://www.azul.com/downloads/)

**安装验证：**
```powershell
# 打开 PowerShell，输入
java -version
javac -version

# 应该看到类似输出：
# openjdk version "17.0.x" 202x-xx-xx
```

#### B. IDE (集成开发环境)

**IntelliJ IDEA (强烈推荐)**
- [社区版（免费）](https://www.jetbrains.com/idea/download/)
- [终极版（付费，学生免费）](https://www.jetbrains.com/idea/)

**优势：**
- 原生支持 Gradle
- 优秀的代码补全和重构
- 内置 Git 支持
- Mixin 插件支持

**VS Code (轻量级选择)**
- [下载链接](https://code.visualstudio.com/)
- 需要安装扩展：Extension Pack for Java, Gradle for Java

#### C. Git (版本控制)

- [Git 官网](https://git-scm.com/downloads)
- 用于代码管理和备份

---

### 0.2 获取客户端模板

#### 方案 A：Forge MDK (官方模板) ⭐ 推荐新手

**步骤 1：访问 Forge 官方网站**
```
https://files.minecraftforge.net/net/minecraftforge/forge/
```

**步骤 2：选择 Minecraft 版本**
- 左侧列表选择你想要的 MC 版本（如 1.20.1）
- 点击 "MDK" 按钮下载

**步骤 3：解压并初始化**
```powershell
# 1. 解压下载的 zip 文件
Expand-Archive -Path "forge-1.20.1-47.x.x-mdk.zip" -DestinationPath "MyClient"

# 2. 进入目录
cd MyClient

# 3. 运行 Gradle 初始化（需要联网）
.\gradlew genIntellijRuns    # 如果使用 IntelliJ IDEA
.\gradlew eclipse            # 如果使用 Eclipse
```

**步骤 4：导入 IDE**
- IntelliJ: File → Open → 选择项目文件夹
- 等待 Gradle 同步完成

---

#### 方案 B：Fabric 模板

**步骤 1：使用 Fabric 模板生成器**
```
https://fabricmc.net/develop/template/
```

**步骤 2：配置参数**
- Minecraft Version: 选择版本
- Yarn Mappings: 选择映射版本
- Loader Version: 最新即可
- Mod ID: 你的模组ID（小写）
- Mod Name: 显示名称

**步骤 3：下载并解压**
```powershell
# 解压后进入目录
cd fabric-template

# 初始化
.\gradlew.bat genSources
.\gradlew.bat idea      # IntelliJ
.\gradlew.bat eclipse   # Eclipse
```

---

#### 方案 C：基于现有客户端修改（最快）⭐ 推荐有经验者

**优势：**
- ✅ 已有完整架构（模块、事件、UI系统）
- ✅ 可直接运行测试
- ✅ 有大量参考代码

**操作步骤：**

```powershell
# 1. 复制整个项目
Copy-Item -Path "C:\Users\admin\Documents\仓库\Late" `
          -Destination "C:\Users\admin\Documents\仓库\NewClient" `
          -Recurse

# 2. 进入新目录
cd "C:\Users\admin\Documents\仓库\NewClient"

# 3. 删除 Git 历史（可选）
Remove-Item -Path ".git" -Recurse -Force -ErrorAction SilentlyContinue

# 4. 清理编译产物
.\gradlew clean
```

**修改项目标识：**

编辑 `gradle.properties`：
```properties
# 修改这些关键配置
mod_id=newclient              # 改成你的客户端ID
mod_name=NewClient            # 显示名称
mod_version=1.0.0             # 版本号
mod_authors=YourName          # 作者名
mod_group_id=com.yourname     # 包名前缀
```

**重命名包结构（可选但推荐）：**

在 IntelliJ 中：
1. 右键 `com.heypixel.heypixelmod` 包
2. Refactor → Rename
3. 改为 `com.yourname.newclient`
4. 勾选 "Search in comments and strings"
5. 点击 Refactor

---

### 0.3 如何切换 Minecraft 版本

#### 方法 1：修改 Forge 版本（推荐）

**步骤 1：查看可用版本**
访问：`https://files.minecraftforge.net/net/minecraftforge/forge/`

**步骤 2：修改 gradle.properties**

以从 1.20.1 切换到 1.20.4 为例：

```properties
# 原配置 (1.20.1)
minecraft_version=1.20.1
minecraft_version_range=[1.20.1,1.21)
forge_version=47.4.6
forge_version_range=[47.4,)
loader_version_range=[47.4,)
mapping_channel=official
mapping_version=1.20.1

# 新配置 (1.20.4)
minecraft_version=1.20.4
minecraft_version_range=[1.20.4,1.21)
forge_version=49.0.50        # 查官网获取对应版本
forge_version_range=[49.0,)
loader_version_range=[49.0,)
mapping_channel=official
mapping_version=1.20.4
```

**步骤 3：清理并重新构建**
```powershell
# 1. 清理旧文件
.\gradlew clean

# 2. 删除缓存（重要！）
Remove-Item -Path ".gradle" -Recurse -Force
Remove-Item -Path "build" -Recurse -Force

# 3. 重新下载依赖
.\gradlew --refresh-dependencies

# 4. 生成运行配置
.\gradlew genIntellijRuns

# 5. 重启 IDE
```

⚠️ **注意事项：**
- 大版本切换（如 1.20 → 1.21）可能需要大量代码修改
- Mixin 映射可能变化，需要检查所有 Mixin 类
- API 可能有破坏性变更

---

#### 方法 2：使用 Parchment 映射（更易读）

Parchment 提供带参数名的映射，代码更易理解。

**步骤 1：修改 gradle.properties**
```properties
# 使用 Parchment 映射
mapping_channel=parchment
mapping_version=2023.09.03-1.20.1  # 格式：日期-MC版本
```

**步骤 2：添加 Parchment 仓库**

在 `build.gradle` 的 `repositories` 块中添加：
```groovy
repositories {
    maven {
        name = 'ParchmentMC'
        url = 'https://maven.parchmentmc.org'
    }
    // ... 其他仓库
}
```

**步骤 3：刷新 Gradle**
```powershell
.\gradlew --refresh-dependencies
```

---

#### 方法 3：完全更换框架（Forge ↔ Fabric）

⚠️ **这是最复杂的情况，不建议新手尝试**

**从 Forge 迁移到 Fabric：**

1. 创建新的 Fabric 项目
2. 手动迁移代码：
    - Mixin 类基本可以复用
    - 事件系统需要重写
    - UI 渲染需要适配
    - 网络包处理不同

3. 替换依赖：
```groovy
// Fabric build.gradle 示例
plugins {
    id 'fabric-loom' version '1.5-SNAPSHOT'
}

dependencies {
    minecraft "com.mojang:minecraft:${project.minecraft_version}"
    mappings loom.officialMojangMappings()
    modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
    modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
}
```

---

### 0.4 Gradle 配置详解

#### A. Gradle 是什么？

Gradle 是一个构建自动化工具，负责：
- 下载和管理依赖库
- 编译代码
- 打包成 JAR 文件
- 运行测试

#### B. 关键配置文件

**1. settings.gradle - 项目设置**

```groovy
pluginManagement {
    repositories {
        gradlePluginPortal()           // Gradle 插件仓库
        maven {
            name = 'MinecraftForge'
            url = 'https://maven.minecraftforge.net/'  // Forge 仓库
        }
        maven {                        // 可选：Fabric 仓库
            name = 'Fabric'
            url = 'https://maven.fabricmc.net/'
        }
    }
}

plugins {
    // 自动解析工具链
    id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
}

rootProject.name = 'MyClient'  // 项目名称
```

**2. gradle.properties - 项目属性**

```properties
# JVM 内存设置（重要！）
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=512m
org.gradle.daemon=true  # 启用守护进程加速构建

# Minecraft 和 Forge 版本
minecraft_version=1.20.1
forge_version=47.4.6

# 映射配置
mapping_channel=official
mapping_version=1.20.1

# 模组元数据
mod_id=myclient
mod_name=MyClient
mod_version=1.0.0
mod_authors=YourName
mod_group_id=com.yourname
```

**3. build.gradle - 构建脚本（最重要）**

```groovy
// ========== 构建脚本配置 ==========
buildscript {
    ext.kotlin_version = '2.2.0'  // Kotlin 版本（如果使用）
    repositories {
        maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
        mavenCentral()
    }
    dependencies {
        classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'  // Mixin 支持
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

// ========== 插件应用 ==========
plugins {
    id 'eclipse'
    id 'idea'
    id 'net.minecraftforge.gradle' version '[6.0.16,6.2)'
}

apply plugin: 'org.spongepowered.mixin'  // 应用 Mixin 插件
apply plugin: 'kotlin'                    // 应用 Kotlin 插件（可选）

// ========== 基本信息 ==========
group = mod_group_id
version = mod_version
base { archivesName = mod_id }

// ========== Java 配置 ==========
java {
    toolchain.languageVersion = JavaLanguageVersion.of(17)  // JDK 17
}

// ========== Minecraft 配置 ==========
minecraft {
    mappings channel: mapping_channel, version: mapping_version
    copyIdeResources = true  // 复制资源到 IDE 输出目录
    
    // 运行配置
    runs {
        configureEach {
            workingDirectory project.file('run')
            property 'forge.logging.markers', 'REGISTRIES'
            property 'forge.logging.console.level', 'debug'
            
            mods {
                "${mod_id}" { source sourceSets.main }
            }
        }
        
        client {
            property 'forge.enabledGameTestNamespaces', mod_id
        }
        
        server {
            args '--nogui'
        }
    }
}

// ========== Mixin 配置 ==========
mixin {
    add sourceSets.main, "${mod_id}.refmap.json"
    config "${mod_id}.mixins.json"
}

// ========== 仓库配置 ==========
repositories {
    mavenCentral()
    flatDir { dir 'libs' }  // 本地 libs 文件夹
    
    // 添加自定义仓库
    maven {
        name = 'JitPack'
        url = 'https://jitpack.io'
    }
}

// ========== 依赖配置 ==========
dependencies {
    // Minecraft 和 Forge
    minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
    
    // Mixin 注解处理器
    annotationProcessor 'org.spongepowered:mixin:0.8.5:processor'
    
    // 示例：添加外部库
    implementation 'com.google.code.gson:gson:2.10.1'
    
    // 示例：本地 JAR
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    
    // 示例：Jar-in-Jar（打包进最终 JAR）
    jarJar(group: 'com.example', name: 'library', version: '[1.0,2.0)')
}

// ========== 资源处理 ==========
tasks.named('processResources', ProcessResources).configure {
    var replaceProperties = [
        minecraft_version: minecraft_version,
        forge_version: forge_version,
        mod_id: mod_id,
        mod_name: mod_name,
        mod_version: mod_version,
        mod_authors: mod_authors,
    ]
    
    inputs.properties replaceProperties
    
    filesMatching(['META-INF/mods.toml', 'pack.mcmeta']) {
        expand replaceProperties + [project: project]
    }
}

// ========== JAR 打包配置 ==========
tasks.named('jar', Jar).configure {
    manifest {
        attributes([
            "Specification-Title": mod_id,
            "Specification-Vendor": mod_authors,
            "Implementation-Title": project.name,
            "Implementation-Version": project.jar.archiveVersion,
            "Implementation-Vendor": mod_authors,
        ])
    }
    finalizedBy 'reobfJar'  // 混淆 JAR
}

// ========== 编译选项 ==========
tasks.withType(JavaCompile).configureEach {
    options.encoding = 'UTF-8'
    options.compilerArgs << '-parameters'
}
```

---

#### C. 常用 Gradle 命令

```powershell
# 基础命令
.\gradlew clean                  # 清理编译产物
.\gradlew build                  # 构建项目
.\gradlew runClient              # 运行客户端
.\gradlew runServer              # 运行服务器

# IDE 集成
.\gradlew genIntellijRuns        # 生成 IntelliJ 运行配置
.\gradlew idea                   # 生成 IntelliJ 项目文件
.\gradlew eclipse                # 生成 Eclipse 项目文件

# 依赖管理
.\gradlew dependencies           # 查看依赖树
.\gradlew --refresh-dependencies # 刷新依赖缓存

# 高级命令
.\gradlew build --no-daemon      # 不使用守护进程构建
.\gradlew build --parallel       # 并行构建（加速）
.\gradlew tasks                  # 查看所有可用任务
```

---

#### D. 添加新依赖库

**场景 1：添加 Maven 中央仓库的库**

```groovy
dependencies {
    // 格式：implementation 'group:name:version'
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation 'org.apache.commons:commons-lang3:3.12.0'
}
```

**场景 2：添加 GitHub 项目的库（通过 JitPack）**

```groovy
repositories {
    maven { url 'https://jitpack.io' }
}

dependencies {
    // 格式：implementation 'com.github.User:Repo:Tag'
    implementation 'com.github.User:Library:v1.0.0'
}
```

**场景 3：添加本地 JAR 文件**

```groovy
// 方法 1：flatDir 仓库
repositories {
    flatDir { dirs 'libs' }
}

dependencies {
    implementation name: 'my-library-1.0'
}

// 方法 2：fileTree
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}
```

**场景 4：添加 Skia 等原生库**

```groovy
dependencies {
    // Skia 图形库
    minecraftLibrary 'io.github.humbleui:skija-shared:0.116.4'
    minecraftLibrary 'io.github.humbleui:skija-windows-x64:0.116.4'
    
    // Jar-in-Jar 打包
    jarJar(group: 'io.github.humbleui', name: 'skija-shared', version: '[0.116,0.117)') {
        jarJar.pin(it, '0.116.4')
    }
}
```

---

#### F. Fabric 专用 Gradle 配置

如果你使用 Fabric 而非 Forge，`build.gradle` 会有所不同：

```groovy
plugins {
    id 'fabric-loom' version '1.5-SNAPSHOT'
    id 'maven-publish'
}

version = project.mod_version
group = project.maven_group

base {
    archivesName = project.archives_base_name
}

repositories {
    mavenCentral()
    maven { url 'https://maven.fabricmc.net/' }
}

dependencies {
    // Minecraft 和 Fabric Loader
    minecraft "com.mojang:minecraft:${project.minecraft_version}"
    mappings loom.officialMojangMappings()
    modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
    
    // Fabric API（必需）
    modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
    
    // Mixin Extras（可选，提供高级 Mixin 功能）
    include implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:0.3.5"))
}

processResources {
    inputs.property "version", project.version
    
    filesMatching("fabric.mod.json") {
        expand "version": project.version
    }
}

tasks.withType(JavaCompile).configureEach {
    it.options.release = 17
}

java {
    withSourcesJar()
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

jar {
    from("LICENSE") {
        rename { "${it}_${project.base.archivesName.get()}" }
    }
}
```

**Fabric 的 gradle.properties：**

```properties
# Gradle 设置
org.gradle.jvmargs=-Xmx2G

# Minecraft 版本
minecraft_version=1.20.1
yarn_mappings=1.20.1+build.10
loader_version=0.15.0

# Mod 属性
mod_version=1.0.0
maven_group=com.yourname
archives_base_name=myclient

# Fabric API 版本
fabric_version=0.92.0+1.20.1
```

**Fabric 与 Forge 的主要区别：**

| 特性 | Forge | Fabric |
|------|-------|--------|
| 构建工具 | ForgeGradle | Fabric Loom |
| API | Forge API | Fabric API |
| 事件系统 | Forge Event Bus | Fabric Events |
| 网络包 | Forge NetworkRegistry | Fabric PacketByteBuf |
| 社区规模 | 大（老牌） | 快速增长 |
| 性能 | 较好 | 略优 |
| 模组兼容性 | 广泛 | 较少 |

---

#### E. 解决常见 Gradle 问题

**问题 1：下载速度慢**

使用国内镜像源，在 `settings.gradle` 或 `build.gradle` 添加：

```groovy
repositories {
    maven { url 'https://maven.aliyun.com/repository/central' }
    maven { url 'https://maven.aliyun.com/repository/public' }
    maven { url 'https://maven.aliyun.com/repository/google' }
}
```

**问题 2：内存不足**

修改 `gradle.properties`：
```properties
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=512m
```

**问题 3：依赖冲突**

```powershell
# 查看依赖树，找出冲突
.\gradlew dependencies --configuration runtimeClasspath

# 排除冲突的依赖
dependencies {
    implementation('some.library:1.0') {
        exclude group: 'conflicting.group', module: 'conflicting-module'
    }
}
```

**问题 4：Gradle 同步失败**

```powershell
# 1. 清理缓存
.\gradlew clean
Remove-Item -Path ".gradle" -Recurse -Force

# 2. 重新下载
.\gradlew --refresh-dependencies

# 3. 重启 IDE
```

---

### 0.5 快速开始检查清单

完成以下步骤后，你应该能成功运行客户端：

- [ ] 安装 JDK 17 并配置环境变量
- [ ] 安装 IntelliJ IDEA
- [ ] 下载并解压模板项目
- [ ] 运行 `gradlew genIntellijRuns`
- [ ] 在 IDE 中打开项目
- [ ] 等待 Gradle 同步完成
- [ ] 点击 Run → Run Client
- [ ] Minecraft 成功启动

✅ **如果游戏成功启动，恭喜！环境配置完成！**

---

## 1. 项目架构概览

### 1.1 目录结构

```
src/main/java/com/heypixel/heypixelmod/obsoverlay/
├── modules/              # 模块系统（功能核心）
│   ├── Module.java       # 模块基类
│   ├── ModuleManager.java # 模块管理器
│   ├── Category.java     # 模块分类
│   └── impl/             # 具体模块实现
│       ├── combat/       # 战斗类模块
│       ├── render/       # 渲染类模块
│       ├── move/         # 移动类模块
│       └── misc/         # 杂项模块
├── events/               # 事件系统
│   ├── api/              # 事件API
│   └── impl/             # 具体事件实现
├── values/               # 变量系统
│   ├── Value.java        # 变量基类
│   ├── ValueBuilder.java # 变量构建器
│   └── impl/             # 具体变量类型
├── utils/                # 工具类
├── ui/                   # UI界面
└── Naven.java            # 客户端主类
```

### 1.2 核心组件关系

```
Naven (主类)
├── ModuleManager (模块管理器)
│   └── 管理所有 Module
├── EventManager (事件管理器)
│   └── 分发事件到订阅者
├── ValueManager (变量管理器)
│   └── 管理所有配置选项
└── FileManager (文件管理器)
    └── 保存/加载配置
```

---

## 2. 核心概念理解

### 2.1 什么是模块 (Module)？

模块是客户端的核心功能单元，每个模块代表一个独立的功能。例如：
- **KillAura** - 自动攻击
- **ESP** - 透视显示
- **Speed** - 加速移动
- **HUD** - 信息显示

### 2.2 模块的生命周期

```java
创建 → 注册 → 启用(onEnable) → 运行中 → 禁用(onDisable) → 销毁
```

### 2.3 三大核心系统

1. **模块系统** - 组织和管理功能
2. **事件系统** - 监听游戏事件
3. **变量系统** - 提供用户配置

---

## 3. 模块系统详解

### 3.1 模块基类结构

查看 `Module.java`：

```java
public abstract class Module extends HasValue {
    public static final Minecraft mc = Minecraft.getInstance();
    
    // 基本信息
    private String name;           // 模块名称
    private String description;    // 描述
    private Category category;     // 分类
    private boolean enabled;       // 是否启用
    private int key;               // 绑定按键
    
    // 生命周期方法
    public void onEnable() {}      // 启用时调用
    public void onDisable() {}     // 禁用时调用
    public void setEnabled(boolean enabled) // 设置启用状态
    public void toggle() {}        // 切换状态
}
```

### 3.2 创建新模块的步骤

#### 步骤 1: 继承 Module 类

```java
package com.heypixel.heypixelmod.obsoverlay.modules.impl.combat;

import com.heypixel.heypixelmod.obsoverlay.modules.Category;
import com.heypixel.heypixelmod.obsoverlay.modules.Module;
import com.heypixel.heypixelmod.obsoverlay.modules.ModuleInfo;

@ModuleInfo(
    name = "MyModule",
    description = "我的第一个模块",
    category = Category.COMBAT
)
public class MyModule extends Module {
    
}
```

#### 步骤 2: 在 ModuleManager 中注册

打开 `ModuleManager.java`，在 `initModules()` 方法中添加：

```java
private void initModules() {
    this.registerModule(
        // ... 其他模块
        new MyModule(),  // 添加这一行
        // ... 其他模块
    );
}
```

#### 步骤 3: 实现功能

重写生命周期方法或监听事件：

```java
@Override
public void onEnable() {
    // 模块启用时的初始化代码
    System.out.println("MyModule 已启用！");
}

@Override
public void onDisable() {
    // 模块禁用时的清理代码
    System.out.println("MyModule 已禁用！");
}
```

### 3.3 模块分类 (Category)

```java
public enum Category {
    COMBAT,    // 战斗类
    MOVEMENT,  // 移动类
    RENDER,    // 渲染类
    PLAYER,    // 玩家类
    MISC,      // 杂项
    FUN        // 娱乐类
}
```

### 3.4 模块常用方法

```java
// 获取 Minecraft 实例
Minecraft mc = Module.mc;

// 获取玩家
mc.player

// 获取世界
mc.level

// 发送聊天消息
ChatUtils.addChatMessage("消息内容");

// 播放音效
mc.player.playSound(SoundEvents.WOODEN_BUTTON_CLICK_ON, 0.5F, 1.3F);

// 获取其他模块
Module otherModule = Naven.getInstance()
    .getModuleManager()
    .getModule(SomeModule.class);
```

---

## 4. 变量系统详解

### 4.1 变量类型

| 类型 | 用途 | 示例 |
|------|------|------|
| BooleanValue | 开关 | 启用/禁用某功能 |
| FloatValue | 数值 | 范围、速度等 |
| ModeValue | 模式选择 | 选择不同的算法 |
| StringValue | 文本输入 | 自定义文本 |
| ColorValue | 颜色选择 | 自定义颜色 |
| DragValue | 拖拽位置 | HUD位置调整 |

### 4.2 创建变量的标准方式

使用 `ValueBuilder` 构建器模式：

```java
public class MyModule extends Module {
    
    // 布尔值 - 开关
    private final BooleanValue mySwitch = ValueBuilder.create(this, "My Switch")
            .setDefaultBooleanValue(true)  // 默认值
            .build()
            .getBooleanValue();
    
    // 浮点值 - 范围
    private final FloatValue myRange = ValueBuilder.create(this, "Range")
            .setDefaultFloatValue(5.0F)    // 默认值
            .setMinFloatValue(1.0F)        // 最小值
            .setMaxFloatValue(10.0F)       // 最大值
            .setFloatStep(0.5F)            // 步进
            .build()
            .getFloatValue();
    
    // 模式值 - 选择
    private final ModeValue myMode = ValueBuilder.create(this, "Mode")
            .setModes("Normal", "Advanced", "Silent")  // 可选模式
            .setDefaultModeIndex(0)        // 默认索引
            .build()
            .getModeValue();
    
    // 带可见性条件的变量
    private final FloatValue advancedSpeed = ValueBuilder.create(this, "Advanced Speed")
            .setDefaultFloatValue(2.0F)
            .setVisibility(() -> myMode.isCurrentMode("Advanced"))  // 仅在Advanced模式可见
            .build()
            .getFloatValue();
}
```

### 4.3 读取变量值

```java
// 布尔值
if (mySwitch.getCurrentValue()) {
    // 执行逻辑
}

// 浮点值
float range = myRange.getCurrentValue();

// 模式值
if (myMode.isCurrentMode("Normal")) {
    // Normal 模式逻辑
} else if (myMode.isCurrentMode("Advanced")) {
    // Advanced 模式逻辑
}

// 字符串值
String text = myString.getCurrentValue();

// 颜色值
Color color = myColor.getCurrentValue();
```

### 4.4 变量更新回调

```java
private final FloatValue speed = ValueBuilder.create(this, "Speed")
        .setDefaultFloatValue(1.0F)
        .setOnUpdate(value -> {
            // 当值改变时执行
            System.out.println("速度已更新为: " + value.getCurrentValue());
        })
        .build()
        .getFloatValue();
```

---

## 5. 事件系统详解

### 5.1 事件系统原理

事件系统允许模块监听游戏中的各种事件（如渲染、移动、攻击等），无需修改原版代码。

### 5.2 常用事件类型

#### 渲染事件

```java
@EventTarget
public void onRender2D(EventRender2D event) {
    // 2D 渲染（HUD、文字等）
    PoseStack stack = event.getStack();
    GuiGraphics guiGraphics = event.getGuiGraphics();
}

@EventTarget
public void onRender3D(EventRender3D event) {
    // 3D 渲染（ESP、轨迹等）
    PoseStack poseStack = event.getPoseStack();
    float partialTicks = event.getPartialTicks();
}
```

#### 运动事件

```java
@EventTarget
public void onMotion(EventRunTicks event) {
    // 每 tick 调用
    if (event.getType() == EventType.PRE) {
        // PRE 阶段 - 处理前
    } else {
        // POST 阶段 - 处理后
    }
}

@EventTarget
public void onMoveInput(EventMoveInput event) {
    // 修改移动输入
    event.setForward(1.0F);  // 向前
    event.setStrafe(0.5F);   // 侧向
    event.setJump(true);     // 跳跃
}
```

#### 网络事件

```java
@EventTarget
public void onPacket(EventPacket event) {
    // 监听数据包
    if (event.getPacket() instanceof ClientboundPlayerPositionPacket) {
        // 处理玩家位置包
    }
}
```

#### 交互事件

```java
@EventTarget
public void onClick(EventClick event) {
    // 鼠标点击
}

@EventTarget
public void onAttack(EventAttack event) {
    // 攻击实体
    Entity target = event.getTarget();
}

@EventTarget
public void onKey(EventKey event) {
    // 键盘按键
    if (event.isState() && event.getKey() == GLFW.GLFW_KEY_SPACE) {
        // 空格键按下
    }
}
```

### 5.3 事件优先级

```java
@EventTarget(value = 0)  // 最高优先级，最先执行
public void onHighPriority(EventRender2D e) {}

@EventTarget(value = 2)  // 默认优先级
public void onNormalPriority(EventRender2D e) {}

@EventTarget(value = 5)  // 最低优先级，最后执行
public void onLowPriority(EventRender2D e) {}
```

### 5.4 取消事件

某些事件可以被取消，阻止原版逻辑执行：

```java
@EventTarget
public void onAttackSlowdown(EventAttackSlowdown event) {
    event.setCancelled(true);  // 取消攻击减速
}
```

### 5.5 事件注册与注销

模块启用时自动注册，禁用时自动注销：

```java
// Module.setEnabled() 内部逻辑
if (enabled) {
    naven.getEventManager().register(this);  // 注册
    this.onEnable();
} else {
    naven.getEventManager().unregister(this); // 注销
    this.onDisable();
}
```

---

## 6. Mixin 注入技术

### 6.1 什么是 Mixin？

Mixin 是一种字节码注入技术，允许在不修改原始类的情况下修改其行为。

### 6.2 Mixin 基本结构

```java
@Mixin(TargetClass.class)
public abstract class MixinTargetClass {
    
    // 注入到方法开头
    @Inject(method = "methodName", at = @At("HEAD"), cancellable = true)
    private void injectAtHead(CallbackInfo ci) {
        // 在方法开始时执行
        if (shouldCancel) {
            ci.cancel();  // 取消原方法执行
        }
    }
    
    // 注入到方法结尾
    @Inject(method = "methodName", at = @At("RETURN"))
    private void injectAtReturn(CallbackInfo ci) {
        // 在方法结束时执行
    }
    
    // 注入到特定指令前
    @Inject(method = "methodName", at = @At(value = "INVOKE", 
        target = "Lnet/minecraft/class;method()V"))
    private void injectBeforeCall(CallbackInfo ci) {
        // 在调用指定方法前执行
    }
    
    // 修改返回值
    @ModifyReturnValue(method = "methodName", at = @At("RETURN"))
    private boolean modifyReturn(boolean original) {
        return modifiedValue;
    }
    
    // 访问私有字段
    @Shadow
    private int privateField;
}
```

### 6.3 实际示例：修改渲染

```java
@Mixin(GameRenderer.class)
public abstract class MixinGameRenderer {
    
    @Inject(method = "renderLevel", at = @At("HEAD"))
    private void onRenderLevelStart(CallbackInfo ci) {
        // 在渲染世界前执行
        EventRender3D event = new EventRender3D(...);
        Naven.getInstance().getEventManager().call(event);
    }
}
```

### 6.4 Mixin 配置文件

在 `resources/late.mixins.json` 中注册：

```json
{
  "package": "com.heypixel.heypixelmod.mixin.O",
  "mixins": [
    "MixinMinecraft",
    "MixinGameRenderer",
    "MixinLivingEntity"
  ],
  "client": [
    "MixinTitleScreen",
    "MixinGui"
  ]
}
```

### 6.5 Mixin 调试技巧

1. **使用 @Unique** - 确保方法名唯一
2. **使用 @Final** - 标记最终字段
3. **检查混淆映射** - 确保方法签名正确
4. **查看日志** - Mixin 会输出注入信息

---

## 7. 渲染系统

### 7.1 2D 渲染

```java
@EventTarget
public void onRender2D(EventRender2D event) {
    PoseStack stack = event.getStack();
    GuiGraphics guiGraphics = event.getGuiGraphics();
    
    // 绘制矩形
    RenderUtils.drawRectBound(stack, x, y, width, height, color);
    
    // 绘制圆角矩形
    RenderUtils.drawRoundedRect(stack, x, y, width, height, radius, color);
    
    // 绘制文字
    Fonts.harmony.render(stack, "Hello", x, y, Color.WHITE, true, 0.4F);
    
    // 绘制图片
    guiGraphics.blit(texture, x, y, u, v, width, height, texWidth, texHeight);
}
```

### 7.2 3D 渲染

```java
@EventTarget
public void onRender3D(EventRender3D event) {
    PoseStack poseStack = event.getPoseStack();
    float partialTicks = event.getPartialTicks();
    
    // 绘制包围盒
    AABB box = entity.getBoundingBox();
    RenderUtils.drawSolidBox(box, poseStack);
    RenderUtils.drawOutlinedBox(box, poseStack);
    
    // 绘制线条
    RenderUtils.drawLine(x1, y1, z1, x2, y2, z2, color, poseStack);
    
    // 坐标转换
    Vec3 worldPos = entity.getPosition(partialTicks);
    Vector2f screenPos = ProjectionUtils.project(worldPos.x, worldPos.y, worldPos.z, partialTicks);
}
```

### 7.3 渲染优化

```java
// 1. 距离剔除
if (entity.distanceTo(mc.player) > 100.0f) return;

// 2. 可见性检查
if (!entity.isInvisible() && mc.player.hasLineOfSight(entity)) {
    // 渲染
}

// 3. 批处理渲染
// 尽量一次性绘制多个对象，减少状态切换

// 4. 使用 Stencil 缓冲
StencilUtils.write(false);
// 绘制遮罩
StencilUtils.erase(true);
// 绘制内容
StencilUtils.dispose();
```

---

## 8. 实用工具类

### 8.1 常用工具

```java
// 旋转计算
Vector2f rotation = RotationUtils.calculate(target, true, range);
Vector2f smoothed = RotationUtils.smooth(rotation, speed);

// 投影
Vector2f screenPos = ProjectionUtils.project(x, y, z, partialTicks);

// 渲染辅助
RenderUtils.drawRoundedRect(...);
RenderUtils.fillBound(...);

// 聊天工具
ChatUtils.addChatMessage("消息");

// 网络工具
NetworkUtils.sendPacket(packet);

// 库存工具
InventoryUtils.findItem(item);

// 朋友管理
FriendManager.isFriend(player);
FriendManager.addFriend(player);
```

### 8.2 数学工具

```java
// 角度归一化
float normalized = MathHelper.wrapDegrees(angle);

// 线性插值
float lerp = Mth.lerp(delta, start, end);

// 距离计算
double distance = pos1.distanceTo(pos2);

// 随机数
float random = RandomUtils.nextFloat(min, max);
```

---

## 9. 编写第一个模块

### 9.1 完整示例：简单的 Sprint 模块

创建一个增强版的 Sprint 模块，演示所有核心概念：

```java
package com.heypixel.heypixelmod.obsoverlay.modules.impl.move;

import com.heypixel.heypixelmod.obsoverlay.events.api.EventTarget;
import com.heypixel.heypixelmod.obsoverlay.events.impl.EventMoveInput;
import com.heypixel.heypixelmod.obsoverlay.modules.Category;
import com.heypixel.heypixelmod.obsoverlay.modules.Module;
import com.heypixel.heypixelmod.obsoverlay.modules.ModuleInfo;
import com.heypixel.heypixelmod.obsoverlay.values.ValueBuilder;
import com.heypixel.heypixelmod.obsoverlay.values.impl.BooleanValue;
import com.heypixel.heypixelmod.obsoverlay.values.impl.FloatValue;
import com.heypixel.heypixelmod.obsoverlay.values.impl.ModeValue;
//developer yy130202 AI
/**
 * EnhancedSprint - 增强冲刺模块
 * 
 * 功能：
 * 1. 自动冲刺
 * 2. 可配置冲刺速度
 * 3. 支持多种模式
 */
@ModuleInfo(
    name = "EnhancedSprint",
    description = "增强版冲刺，可自定义速度和模式",
    category = Category.MOVEMENT
)
public class EnhancedSprint extends Module {
    
    // ==================== 配置选项 ====================
    
    /** 冲刺模式 */
    private final ModeValue mode = ValueBuilder.create(this, "Mode")
            .setModes("Vanilla", "Legit", "Bypass")
            .setDefaultModeIndex(0)
            .build()
            .getModeValue();
    
    /** 冲刺速度倍数 */
    private final FloatValue speedMultiplier = ValueBuilder.create(this, "Speed Multiplier")
            .setDefaultFloatValue(1.3F)
            .setMinFloatValue(1.0F)
            .setMaxFloatValue(2.0F)
            .setFloatStep(0.1F)
            .setVisibility(() -> !mode.isCurrentMode("Vanilla"))
            .build()
            .getFloatValue();
    
    /** 饥饿时禁用 */
    private final BooleanValue disableWhenHungry = ValueBuilder.create(this, "Disable When Hungry")
            .setDefaultBooleanValue(true)
            .build()
            .getBooleanValue();
    
    /** 水中冲刺 */
    private final BooleanValue sprintInWater = ValueBuilder.create(this, "Sprint In Water")
            .setDefaultBooleanValue(false)
            .build()
            .getBooleanValue();
    
    // ==================== 事件处理 ====================
    
    /**
     * 监听移动输入事件
     * 在玩家移动时修改冲刺行为
     */
    @EventTarget
    public void onMoveInput(EventMoveInput event) {
        // 检查是否应该冲刺
        if (!shouldSprint()) {
            return;
        }
        
        // 根据模式应用不同的逻辑
        switch (mode.getCurrentMode()) {
            case "Vanilla":
                // 原版冲刺，不做修改
                break;
                
            case "Legit":
                // 合法模式 - 轻微加速
                applyLegitSprint(event);
                break;
                
            case "Bypass":
                // 绕过模式 - 更强的加速但更隐蔽
                applyBypassSprint(event);
                break;
        }
    }
    
    // ==================== 辅助方法 ====================
    
    /**
     * 检查是否应该冲刺
     */
    private boolean shouldSprint() {
        // 检查玩家是否存在
        if (mc.player == null) return false;
        
        // 检查是否在移动
        if (mc.player.input.forwardImpulse <= 0) return false;
        
        // 检查饥饿度
        if (disableWhenHungry.getCurrentValue() && mc.player.getFoodData().getFoodLevel() <= 6) {
            return false;
        }
        
        // 检查是否在水中
        if (!sprintInWater.getCurrentValue() && mc.player.isInWater()) {
            return false;
        }
        
        // 检查是否在使用物品
        if (mc.player.isUsingItem()) return false;
        
        return true;
    }
    
    /**
     * 应用合法模式的冲刺
     */
    private void applyLegitSprint(EventMoveInput event) {
        // 强制设置冲刺状态
        mc.player.setSprinting(true);
        
        // 轻微增加速度（不易被检测）
        float speed = speedMultiplier.getCurrentValue();
        if (speed > 1.0F) {
            // 通过修改移动向量来实现
            double currentSpeed = Math.sqrt(
                mc.player.getDeltaMovement().x * mc.player.getDeltaMovement().x +
                mc.player.getDeltaMovement().z * mc.player.getDeltaMovement().z
            );
            
            if (currentSpeed > 0) {
                double factor = 1.0 + (speed - 1.0) * 0.3; // 降低影响
                mc.player.setDeltaMovement(
                    mc.player.getDeltaMovement().x * factor,
                    mc.player.getDeltaMovement().y,
                    mc.player.getDeltaMovement().z * factor
                );
            }
        }
    }
    
    /**
     * 应用绕过模式的冲刺
     */
    private void applyBypassSprint(EventMoveInput event) {
        // 强制冲刺
        mc.player.setSprinting(true);
        
        // 更激进的加速
        float speed = speedMultiplier.getCurrentValue();
        
        // 直接修改移动输入
        event.setForward(event.getForward() * speed);
        
        // 添加一些随机化以绕过检测
        if (Math.random() < 0.1) { // 10% 的概率
            event.setForward(event.getForward() * 0.95F); // 偶尔减速
        }
    }
    
    /**
     * 模块启用时的初始化
     */
    @Override
    public void onEnable() {
        // 可以在这里进行初始化
        setSuffix(mode.getCurrentMode()); // 显示当前模式
    }
    
    /**
     * 模块禁用时的清理
     */
    @Override
    public void onDisable() {
        // 恢复原版行为
        if (mc.player != null) {
            mc.player.setSprinting(false);
        }
    }
}
```

### 9.2 注册模块

在 `ModuleManager.java` 的 `initModules()` 中添加：

```java
new EnhancedSprint(),
```

### 9.3 测试模块

1. 编译项目
2. 启动 Minecraft
3. 按右 Shift 打开 ClickGUI
4. 找到 Movement 分类
5. 启用 EnhancedSprint
6. 调整配置并测试

---

## 10. 最佳实践与注意事项

### 10.0 Java 编程注意事项（必读）

#### 常见错误及避免方法

**1. 空指针异常（NullPointerException）**
```java
// ❌ 错误
String str = null;
System.out.println(str.length());  // NullPointerException

// ✅ 正确
if (str != null && !str.isEmpty()) {
    System.out.println(str.length());
}

// 在客户端开发中尤为重要
if (mc.player == null || mc.level == null) return;
```

**2. 数组越界（ArrayIndexOutOfBoundsException）**
```java
// ❌ 错误
int[] arr = {1, 2, 3};
System.out.println(arr[3]);  // 越界！

// ✅ 正确
if (index >= 0 && index < arr.length) {
    System.out.println(arr[index]);
}
```

**3. 类型转换错误**
```java
// ❌ 错误
Object obj = "Hello";
Integer num = (Integer) obj;  // ClassCastException

// ✅ 正确
if (obj instanceof Integer) {
    Integer num = (Integer) obj;
}
```

**4. 忘记 break（switch 穿透）**
```java
// ❌ 错误
switch (day) {
    case 1:
        System.out.println("星期一");
        // 忘记 break，会继续执行 case 2
    case 2:
        System.out.println("星期二");
        break;
}

// ✅ 正确
switch (day) {
    case 1:
        System.out.println("星期一");
        break;  // 必须加 break
    case 2:
        System.out.println("星期二");
        break;
}
```

#### 代码规范

**✅ 推荐做法**
```java
// 1. 使用有意义的变量名
int playerHealth = 100;     // 好
int ph = 100;               // 不好

// 2. 添加注释说明复杂逻辑
/**
 * 计算玩家受到的伤害
 * 考虑护甲、药水效果等因素
 */
private double calculateDamage(Player player) { }

// 3. 使用常量避免魔法数字
private static final double MAX_HEALTH = 100.0;
private static final double ARMOR_REDUCTION = 0.8;

// 4. 提前返回，减少嵌套
public void processPlayer(Player player) {
    if (player == null) return;
    if (!player.isAlive()) return;
    
    // 主要逻辑
}
```

**❌ 避免的做法**
```java
// 1. 硬编码魔法数字
if (distance > 5.432)  // 不好
if (distance > MAX_ATTACK_RANGE)  // 好

// 2. 过深的嵌套（超过 3 层）
if (a) {
    if (b) {
        if (c) {
            if (d) {  // 避免！
                // ...
            }
        }
    }
}

// 3. 忽略异常
try {
    doSomething();
} catch (Exception e) {
    // 空的 catch 块，错误被吞掉了
}
```

#### 客户端开发特定注意事项

```java
// 1. 总是检查 Minecraft 实例
if (Minecraft.getInstance().player == null) return;
if (Minecraft.getInstance().level == null) return;

// 2. 不要在渲染循环中做耗时操作
@EventTarget
public void onRender(EventRender2D event) {
    // 不好 - 每帧都查找实体
    for (Entity entity : mc.level.getAllEntities()) { }
    
    // 好 - 使用缓存
    if (shouldUpdateCache()) {
        updateEntityCache();
    }
}

// 3. 正确处理模块的启用/禁用
@Override
public void onEnable() {
    // 初始化代码
}

@Override
public void onDisable() {
    // 清理代码，恢复原版行为
}

// 4. 使用日志而不是 System.out
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger LOGGER = LoggerFactory.getLogger(MyModule.class);
LOGGER.info("模块已启用");
LOGGER.error("发生错误", exception);
```

---

### 10.1 代码规范

#### ✅ 推荐做法

```java
// 1. 使用清晰的命名
private final FloatValue attackRange = ...;  // 好
private final FloatValue r = ...;            // 不好

// 2. 添加注释说明复杂逻辑
/**
 * 计算最佳攻击角度
 * 考虑因素：距离、FoV、障碍物
 */
private Vector2f calculateBestAngle() { ... }

// 3. 使用常量
private static final float MAX_RANGE = 6.0F;

// 4. 空值检查
if (mc.player == null || mc.level == null) return;

// 5. 异常处理
try {
    // 可能出错的代码
} catch (Exception e) {
    e.printStackTrace();
}
```

#### ❌ 避免的做法

```java
// 1. 硬编码魔法数字
if (distance > 5.432)  // 不好
if (distance > MAX_ATTACK_RANGE)  // 好

// 2. 过长的方法（超过 100 行）
// 拆分成多个小方法

// 3. 嵌套过深
if (...) {
    if (...) {
        if (...) {
            if (...) {  // 避免超过 3 层嵌套
            }
        }
    }
}

// 4. 忽略异常
try {
    doSomething();
} catch (Exception e) {
    // 空的 catch 块
}
```

### 10.2 性能优化

```java
// 1. 缓存频繁使用的值
private Entity cachedTarget;
private long lastCacheTime;

if (System.currentTimeMillis() - lastCacheTime > 100) {
    cachedTarget = findTarget();
    lastCacheTime = System.currentTimeMillis();
}

// 2. 避免在渲染循环中创建对象
// 不好 - 每帧创建新对象
@EventTarget
public void onRender(EventRender2D e) {
    Color color = new Color(255, 0, 0);  // 每帧创建
}

// 好 - 复用对象
private static final Color RED = new Color(255, 0, 0);
@EventTarget
public void onRender(EventRender2D e) {
    // 使用静态常量
}

// 3. 提前返回
public void process() {
    if (!isEnabled()) return;
    if (mc.player == null) return;
    if (target == null) return;
    
    // 主要逻辑
}

// 4. 使用合适的数据结构
// 快速查找 - 使用 HashMap
Map<String, Module> moduleMap = new HashMap<>();

// 有序列表 - 使用 ArrayList
List<Module> moduleList = new ArrayList<>();
```

### 10.3 反作弊绕过技巧

```java
// 1. 随机化
float randomDelay = RandomUtils.nextFloat(45, 55);  // 而不是固定的 50ms

// 2. 模拟人类行为
// 添加微小的误差
rotation.x += RandomUtils.nextFloat(-0.5F, 0.5F);

// 3. 限制频率
if (System.currentTimeMillis() - lastActionTime < minInterval) {
    return;
}

// 4. 条件触发
// 只在必要时启用功能
if (isInCombat() && canSeeTarget()) {
    enableFeature();
}

// 5. 隐藏痕迹
// 不发送可疑的数据包
// 清理日志
```

### 10.4 调试技巧

```java
// 1. 使用聊天消息调试
ChatUtils.addChatMessage("Debug: value = " + value);

// 2. 使用日志
Logger log = LogManager.getLogger(MyModule.class);
log.info("模块已启用");
log.error("发生错误", exception);

// 3. 可视化调试
@EventTarget
public void onRender(EventRender3D e) {
    // 绘制调试信息
    RenderUtils.drawLine(start, end, Color.RED, e.getPoseStack());
}

// 4. 性能分析
long startTime = System.currentTimeMillis();
// 执行的代码
long endTime = System.currentTimeMillis();
System.out.println("耗时: " + (endTime - startTime) + "ms");
```

### 10.5 常见问题及解决方案

#### 问题 1: 模块不生效

**原因：**
- 未正确注册
- 事件未正确监听
- 条件判断阻止了执行

**解决：**
```java
// 1. 确认已在 ModuleManager 中注册
// 2. 检查 @EventTarget 注解
// 3. 添加调试输出
@EventTarget
public void onEvent(SomeEvent e) {
    System.out.println("事件被触发了！");
}
```

#### 问题 2: 游戏崩溃

**原因：**
- 空指针异常
- Mixin 注入失败
- 线程安全问题

**解决：**
```java
// 1. 添加空值检查
if (mc.player == null) return;

// 2. 检查 Mixin 配置
// 查看 logs/latest.log 中的错误信息

// 3. 确保在主线程执行
mc.execute(() -> {
    // GUI 相关操作
});
```

#### 问题 3: 配置不保存

**原因：**
- 未正确序列化
- 文件路径错误

**解决：**
```java
// 确保模块和变量正确注册到管理器
// Naven 会自动处理保存/加载
```

### 10.6 安全注意事项

⚠️ **重要提醒：**

1. **不要用于恶意目的** - 仅用于学习和单人游戏
2. **遵守服务器规则** - 多人服务器使用可能导致封禁
3. **保护个人信息** - 不要在代码中硬编码敏感信息
4. **尊重知识产权** - 不要盗用他人的代码
5. **合法使用** - 了解当地法律法规

### 10.7 学习资源

#### 官方文档
- [Minecraft Wiki](https://minecraft.wiki/)
- [Forge Documentation](https://docs.minecraftforge.net/)
- [Mixin Wiki](https://github.com/SpongePowered/Mixin/wiki)

#### 社区资源
- GitHub 上的开源客户端项目
- Minecraft 模组开发论坛
- Discord 开发者社区

#### 推荐学习路径
1. **Java 基础语法**（[JAVA_TUTORIAL.md](JAVA_TUTORIAL.md)）→ 
2. **IntelliJ IDEA 使用**（[IDEA_GUIDE.md](IDEA_GUIDE.md)）→ 
3. **Java 进阶深入**（[JAVA_ADVANCED.md](JAVA_ADVANCED.md)）→ 
4. **注解与包结构**（[JAVA_ANNOTATIONS_AND_IMPORTS.md](JAVA_ANNOTATIONS_AND_IMPORTS.md)）→ 
5. **Minecraft 模组开发基础**（本文档第 1-5 章）→ 
6. **Mixin 技术**（第 6 章）→ 
7. **渲染系统**（第 7 章）→ 
8. **实战项目**（编写自己的模块）

---

## 附录 A: 快速参考

### A.0 版本切换速查表

**从 1.20.1 切换到其他版本的配置：**

| 目标版本 | Forge 版本 | JDK 版本 | 注意事项 |
|---------|-----------|---------|----------|
| 1.8.9 | 11.15.1.2318 | JDK 8 | 需要旧版 Mixin |
| 1.12.2 | 14.23.5.2860 | JDK 8 | 最稳定版本 |
| 1.16.5 | 36.2.39 | JDK 11/16 | 过渡版本 |
| 1.17.1 | 37.1.1 | JDK 16 | 首次使用 JDK 16 |
| 1.18.2 | 40.2.0 | JDK 17 | 世界高度变化 |
| 1.19.4 | 45.2.0 | JDK 17 | API 大幅改动 |
| 1.20.1 | 47.4.6 | JDK 17 | **推荐（当前）** |
| 1.20.4 | 49.0.50 | JDK 17 | 小幅更新 |
| 1.21 | 51.0.0+ | JDK 21 | 最新特性 |

**切换步骤总结：**

```powershell
# 1. 修改 gradle.properties 中的版本号
# 2. 清理项目
.\gradlew clean
Remove-Item -Path ".gradle","build" -Recurse -Force

# 3. 刷新依赖
.\gradlew --refresh-dependencies

# 4. 重新生成 IDE 配置
.\gradlew genIntellijRuns

# 5. 重启 IDE 并等待同步
```

---

### A.1 常用事件速查表

| 事件 | 用途 | 参数 |
|------|------|------|
| EventRender2D | 2D 渲染 | PoseStack, GuiGraphics |
| EventRender3D | 3D 渲染 | PoseStack, partialTicks |
| EventRunTicks | 每 tick 执行 | EventType (PRE/POST) |
| EventMoveInput | 修改移动 | forward, strafe, jump |
| EventPacket | 数据包 | Packet |
| EventAttack | 攻击 | Entity target |
| EventKey | 按键 | int key, boolean state |

### A.2 常用变量类型速查

```java
// 布尔值
BooleanValue bool = ValueBuilder.create(this, "Name")
    .setDefaultBooleanValue(true)
    .build().getBooleanValue();

// 浮点数
FloatValue num = ValueBuilder.create(this, "Name")
    .setDefaultFloatValue(1.0F)
    .setMinFloatValue(0.0F)
    .setMaxFloatValue(10.0F)
    .setFloatStep(0.1F)
    .build().getFloatValue();

// 模式
ModeValue mode = ValueBuilder.create(this, "Name")
    .setModes("A", "B", "C")
    .setDefaultModeIndex(0)
    .build().getModeValue();
```

### A.3 常用工具方法

```java
// 获取模块
Module mod = Naven.getInstance().getModuleManager().getModule(ModuleClass.class);

// 发送消息
ChatUtils.addChatMessage("Message");

// 旋转计算
RotationUtils.calculate(entity, predict, range);

// 投影
ProjectionUtils.project(x, y, z, partialTicks);

// 渲染
RenderUtils.drawRoundedRect(stack, x, y, w, h, radius, color);
```

---

### A.4 模板下载链接汇总

**Forge 模板：**
- 官方 MDK: https://files.minecraftforge.net/
- 示例项目: https://github.com/MinecraftForge/MinecraftForge/tree/1.20.x/mdk

**Fabric 模板：**
- 模板生成器: https://fabricmc.net/develop/template/
- 示例模组: https://github.com/FabricMC/fabric-example-mod

**开源客户端参考：**
- LiquidBounce: https://github.com/CCBlueX/LiquidBounce
- Meteor Client: https://github.com/MeteorDevelopment/meteor-client
- Aristois: https://github.com/MetaArts/Aristois (旧版)

**学习资源：**
- Mixin Wiki: https://github.com/SpongePowered/Mixin/wiki
- Forge 文档: https://docs.minecraftforge.net/
- Fabric Wiki: https://fabricmc.net/wiki/
- Minecraft Wiki: https://minecraft.wiki/

---

### A.5 Gradle 命令速查

```powershell
# === 基础构建 ===
.\gradlew clean              # 清理
.\gradlew build              # 构建
.\gradlew runClient          # 运行客户端
.\gradlew runServer          # 运行服务器

# === IDE 集成 ===
.\gradlew genIntellijRuns    # IntelliJ 配置
.\gradlew idea               # 生成 IDEA 项目
.\gradlew eclipse            # 生成 Eclipse 项目

# === 依赖管理 ===
.\gradlew dependencies       # 查看依赖
.\gradlew --refresh-dependencies  # 刷新缓存

# === 调试 ===
.\gradlew tasks              # 查看所有任务
.\gradlew help               # 帮助信息
.\gradlew build --info       # 详细日志
.\gradlew build --stacktrace # 错误堆栈
```

---

## 附录 B: 完整模块模板

```java
package com.heypixel.heypixelmod.obsoverlay.modules.impl.[category];

import com.heypixel.heypixelmod.obsoverlay.events.api.EventTarget;
import com.heypixel.heypixelmod.obsoverlay.events.impl.*;
import com.heypixel.heypixelmod.obsoverlay.modules.Category;
import com.heypixel.heypixelmod.obsoverlay.modules.Module;
import com.heypixel.heypixelmod.obsoverlay.modules.ModuleInfo;
import com.heypixel.heypixelmod.obsoverlay.values.ValueBuilder;
import com.heypixel.heypixelmod.obsoverlay.values.impl.*;

/**
 * [模块名称] - [简短描述]
 * 
 * 功能说明：
 * [详细说明模块的功能]
 * 
 * 使用方法：
 * [如何使用该模块]
 */
@ModuleInfo(
    name = "[ModuleName]",
    description = "[Description]",
    category = Category.[CATEGORY]
)
public class [ModuleName] extends Module {
    
    // ==================== 配置选项 ====================
    
    private final BooleanValue option1 = ValueBuilder.create(this, "Option1")
            .setDefaultBooleanValue(true)
            .build()
            .getBooleanValue();
    
    private final FloatValue option2 = ValueBuilder.create(this, "Option2")
            .setDefaultFloatValue(1.0F)
            .setMinFloatValue(0.0F)
            .setMaxFloatValue(10.0F)
            .setFloatStep(0.1F)
            .build()
            .getFloatValue();
    
    private final ModeValue option3 = ValueBuilder.create(this, "Option3")
            .setModes("Mode1", "Mode2")
            .setDefaultModeIndex(0)
            .build()
            .getModeValue();
    
    // ==================== 事件处理 ====================
    
    @EventTarget
    public void onRender2D(EventRender2D event) {
        // 2D 渲染逻辑
    }
    
    @EventTarget
    public void onRender3D(EventRender3D event) {
        // 3D 渲染逻辑
    }
    
    @EventTarget
    public void onMotion(EventRunTicks event) {
        // 运动逻辑
    }
    
    // ==================== 生命周期 ====================
    
    @Override
    public void onEnable() {
        // 启用时的初始化
    }
    
    @Override
    public void onDisable() {
        // 禁用时的清理
    }
    
    // ==================== 辅助方法 ====================
    
    private void helperMethod() {
        // 辅助逻辑
    }
}
```

---

## 结语

恭喜你完成了本教程的学习！现在你已经掌握了：

✅ **Java 基础语法**（[JAVA_TUTORIAL.md](JAVA_TUTORIAL.md)）
✅ **IntelliJ IDEA 使用**（[IDEA_GUIDE.md](IDEA_GUIDE.md)）
✅ **Java 进阶编程**（[JAVA_ADVANCED.md](JAVA_ADVANCED.md)）
✅ **注解与 Minecraft 包结构**（[JAVA_ANNOTATIONS_AND_IMPORTS.md](JAVA_ANNOTATIONS_AND_IMPORTS.md)）
✅ 客户端的基本架构  
✅ 模块系统的创建和使用  
✅ 变量系统的配置管理  
✅ 事件系统的监听和处理  
✅ Mixin 注入技术  
✅ 渲染系统的使用  
✅ 最佳实践和注意事项

**下一步建议：**

1. 如果还是新手，先学习 [Java 基础语法教程](JAVA_TUTORIAL.md)
2. 掌握 [IDEA 快捷键和配置](IDEA_GUIDE.md) 提高开发效率
3. 深入学习 [Java 进阶特性](JAVA_ADVANCED.md)
4. 理解 [注解系统与 Minecraft 包结构](JAVA_ANNOTATIONS_AND_IMPORTS.md)
5. 从简单的模块开始练习
6. 阅读现有模块的源代码
7. 尝试修改和优化现有功能
8. 参与社区讨论和交流
9. 持续学习和改进

记住：**编程是一个不断学习和实践的过程**。不要害怕犯错，每个错误都是学习的机会。

祝你开发愉快！🎮

---

**文档版本**: 2.0  
**最后更新**: 2026-04-23  
**适用项目**: Late Client (Forge 1.20.1+)  
**新增内容**:
- 第 0 章：环境准备与模板获取
- Forge/Fabric 模板下载指南
- 版本切换详细步骤
- Gradle 配置完全解析
- 快速参考附录



# IntelliJ IDEA 配置与快捷键指南

> **适用版本**: IntelliJ IDEA 2023+  
> **目标**: 提高开发效率，掌握IDEA核心功能

---

## 📚 目录

1. [IDEA 初始配置](#1-idea-初始配置)
2. [必装插件推荐](#2-必装插件推荐)
3. [核心快捷键](#3-核心快捷键)
4. [高级功能使用](#4-高级功能使用)
5. [调试技巧](#5-调试技巧)
6. [Gradle 配置优化](#6-gradle-配置优化)
7. [常见问题解决](#7-常见问题解决)

---

## 1. IDEA 初始配置

### 1.1 首次启动配置

#### A. 主题设置
1. `File` → `Settings` → `Appearance & Behavior` → `Appearance`
2. 推荐主题：
    - **Darcula**（深色主题，护眼）
    - **IntelliJ Light**（浅色主题）
    - **Material Theme UI**（插件，更美观）

#### B. 字体设置
1. `Settings` → `Editor` → `Font`
2. 推荐配置：
    - **Font**: JetBrains Mono / Fira Code / Consolas
    - **Size**: 14-16
    - **Line height**: 1.2
    - ✅ 勾选 `Enable ligatures`（连字支持）

#### C. 编码设置
1. `Settings` → `Editor` → `File Encodings`
2. 全部设置为 `UTF-8`
    - Global Encoding: UTF-8
    - Project Encoding: UTF-8
    - Default encoding for properties files: UTF-8

### 1.2 Java 环境配置

#### A. 配置 JDK
1. `File` → `Project Structure` → `Project`
2. SDK: 选择已安装的 JDK 17/21
3. Language level: SDK default

#### B. 配置 Gradle
1. `Settings` → `Build, Execution, Deployment` → `Build Tools` → `Gradle`
2. 推荐配置：
    - ✅ **Use Gradle from**: 'gradle-wrapper.properties' file
    - ✅ **Build and run using**: IntelliJ IDEA
    - ✅ **Run tests using**: IntelliJ IDEA
    - **Gradle JVM**: 选择与项目匹配的 JDK

### 1.3 代码风格设置

#### A. 自动导入
1. `Settings` → `Editor` → `General` → `Auto Import`
2. ✅ 勾选：
    - Add unambiguous imports on the fly
    - Optimize imports on the fly

#### B. 代码格式化
1. `Settings` → `Editor` → `Code Style` → `Java`
2. 推荐配置：
    - **Tab size**: 4
    - **Indent**: 4
    - **Continuation indent**: 8
    - **Braces placement**: End of line

#### C. 实时模板（Live Templates）
1. `Settings` → `Editor` → `Live Templates`
2. 常用模板：
    - `sout` → `System.out.println();`
    - `psvm` → `public static void main(String[] args) {}`
    - `fori` → for 循环
    - `iter` → 增强 for 循环
    - `ifn` → if (x == null)
    - `inn` → if (x != null)

---

## 2. 必装插件推荐

### 2.1 开发效率类

| 插件名称 | 功能 | 安装方式 |
|---------|------|---------|
| **Rainbow Brackets** | 彩虹括号，匹配更清晰 | Settings → Plugins |
| **String Manipulation** | 字符串快速转换 | Settings → Plugins |
| **Tabnine** / **Copilot** | AI 代码补全 | Settings → Plugins |
| **Key Promoter X** | 提示快捷键使用 | Settings → Plugins |
| **Translation** | 划词翻译 | Settings → Plugins |

### 2.2 代码质量类

| 插件名称 | 功能 |
|---------|------|
| **SonarLint** | 代码质量检查 |
| **CheckStyle-IDEA** | 代码风格检查 |
| **Alibaba Java Coding Guidelines** | 阿里巴巴编码规范 |
| **FindBugs-IDEA** | 查找 Bug |

### 2.3 UI 美化类

| 插件名称 | 功能 |
|---------|------|
| **Material Theme UI** | 美观的主题 |
| **Atom Material Icons** | 文件图标美化 |
| **Nyan Progress Bar** | 彩虹进度条 |
| **Background Image Plus** | 背景图片 |

### 2.4 Minecraft 开发专用

| 插件名称 | 功能 |
|---------|------|
| **Minecraft Development** | Minecraft 模组开发辅助 |
| **Mixin** | Mixin 语法高亮和检查 |
| **Mojang Mappings** | Mojang 映射支持 |

### 安装插件步骤
1. `File` → `Settings` → `Plugins`
2. 搜索插件名称
3. 点击 `Install`
4. 重启 IDEA

---

## 3. 核心快捷键

### 3.1 编辑相关 ⭐

| 快捷键 | 功能 | 使用场景 |
|--------|------|---------|
| `Ctrl + Space` | 基本代码补全 | 忘记方法名时 |
| `Ctrl + Shift + Space` | 智能代码补全 | 根据上下文推荐 |
| `Ctrl + Alt + L` | 格式化代码 | 保持代码整洁 |
| `Ctrl + Alt + O` | 优化导入 | 移除无用导入 |
| `Ctrl + D` | 复制当前行 | 快速复制代码 |
| `Ctrl + Y` | 删除当前行 | 快速删除代码 |
| `Ctrl + /` | 注释/取消注释 | 切换单行注释 |
| `Ctrl + Shift + /` | 块注释 | 注释多行代码 |
| `Alt + Enter` | 快速修复/建议 | **最重要！** |
| `Ctrl + Shift + Up/Down` | 移动当前行 | 调整代码顺序 |
| `Shift + Enter` | 新起一行 | 在任意位置换行 |

### 3.2 导航相关

| 快捷键 | 功能 |
|--------|------|
| `Ctrl + N` | 查找类 |
| `Ctrl + Shift + N` | 查找文件 |
| `Ctrl + F12` | 查看类结构 |
| `Ctrl + B` / `Ctrl + 点击` | 跳转到定义 |
| `Ctrl + Alt + B` | 跳转到实现 |
| `Ctrl + Shift + Backspace` | 跳转到上次编辑位置 |
| `Alt + Left/Right` | 前进/后退 |
| `Ctrl + E` | 最近文件 |
| `Ctrl + Shift + E` | 最近编辑的文件 |

### 3.3 搜索与替换

| 快捷键 | 功能 |
|--------|------|
| `Ctrl + F` | 当前文件搜索 |
| `Ctrl + R` | 当前文件替换 |
| `Ctrl + Shift + F` | 全局搜索 |
| `Ctrl + Shift + R` | 全局替换 |
| `Ctrl + Shift + S` | 搜索类/文件/符号 |

### 3.4 重构相关 ⭐

| 快捷键 | 功能 |
|--------|------|
| `Shift + F6` | 重命名 |
| `Ctrl + Alt + V` | 提取变量 |
| `Ctrl + Alt + M` | 提取方法 |
| `Ctrl + Alt + C` | 提取常量 |
| `Ctrl + Alt + P` | 提取参数 |
| `Ctrl + Alt + T` | 包围代码（if/try等） |

### 3.5 运行与调试

| 快捷键 | 功能 |
|--------|------|
| `Shift + F10` | 运行 |
| `Shift + F9` | 调试 |
| `Ctrl + Shift + F10` | 运行当前类 |
| `F8` | 步过（Step Over） |
| `F7` | 步入（Step Into） |
| `Shift + F8` | 步出（Step Out） |
| `F9` | 恢复运行 |
| `Ctrl + F8` | 切换断点 |

### 3.6 窗口管理

| 快捷键 | 功能 |
|--------|------|
| `Alt + 1` | 项目窗口 |
| `Alt + 4` | 运行窗口 |
| `Alt + 6` | 问题窗口 |
| `Esc` | 返回编辑器 |
| `Ctrl + Shift + F12` | 最大化编辑器 |
| `Ctrl + Tab` | 切换标签页 |

### 3.7 实用技巧

#### A. 多重选择
- `Alt + 鼠标拖动` - 列选择
- `Alt + Shift + 点击` - 添加多个光标
- `Ctrl + G` - 跳转到指定行

#### B. 代码模板
```java
// 输入 psvm 然后 Tab
public static void main(String[] args) {
    
}

// 输入 sout 然后 Tab
System.out.println();

// 输入 fori 然后 Tab
for (int i = 0; i < ; i++) {
    
}

// 输入 list.for 然后 Tab
for (Object o : list) {
    
}
```

#### C. 快速生成代码
1. 在类中输入 `main` 然后 `Ctrl + J`（或 `Alt + Insert`）
2. 选择要生成的代码：
    - Getter/Setter
    - Constructor
    - toString()
    - equals() 和 hashCode()
    - Override 方法

---

## 4. 高级功能使用

### 4.1 断点调试

#### A. 设置断点
1. 在代码行号左侧点击
2. 红色圆点表示断点

#### B. 条件断点
1. 右键断点
2. 输入条件表达式，如：`i == 5`
3. 只在条件满足时暂停

#### C. 调试窗口
- **Variables**: 查看变量值
- **Watches**: 监控表达式
- **Console**: 执行代码
- **Frames**: 查看调用栈

### 4.2 版本控制集成

#### A. Git 操作
- `Ctrl + K` - 提交
- `Ctrl + Shift + K` - 推送
- `Alt + 9` - Git 窗口
- `Ctrl + T` - 更新
- `Ctrl + Shift + A` → `Git: Merge` - 合并

#### B. 查看历史
1. 右键文件/目录
2. `Git` → `Show History`
3. 查看提交历史和差异

### 4.3 代码检查与分析

#### A. 运行检查
1. `Code` → `Inspect Code`
2. 选择检查范围
3. 查看问题报告

#### B. 查看问题
- `Alt + 6` 打开问题窗口
- 点击问题跳转到代码位置
- `Alt + Enter` 快速修复

### 4.4 数据库工具

1. `View` → `Tool Windows` → `Database`
2. 添加数据源
3. 执行 SQL 查询
4. 查看表结构

---

## 5. 调试技巧

### 5.1 常用调试方法

#### A. 打印调试
```java
// 快速打印
System.out.println("Value: " + value);

// 使用 IDEA 的表达式求值
// 调试时右键变量 → Evaluate Expression
```

#### B. 条件日志
```java
if (BuildConfig.DEBUG) {
    Log.d("TAG", "Debug message");
}
```

### 5.2 高级调试技巧

#### A. 异常断点
1. `Run` → `View Breakpoints`
2. 点击 `+` → `Java Exception Breakpoints`
3. 选择异常类型（如 NullPointerException）
4. 当异常抛出时自动暂停

#### B. 方法断点
1. 在方法签名行设置断点
2. 方法被调用时暂停
3. 可以查看参数值

#### C. 字段断点
1. 在字段声明行设置断点
2. 字段被访问/修改时暂停

### 5.3 性能分析

#### A. CPU Profiler
1. `Run` → `Profile`
2. 查看方法调用时间和次数
3. 找出性能瓶颈

#### B. Memory Profiler
1. 查看内存使用情况
2. 检测内存泄漏//developer yy130202 AI
3. 分析对象分配

---

## 6. Gradle 配置优化

### 6.1 加速 Gradle 构建

#### A. 修改 gradle.properties
```properties
# 增加内存
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=512m

# 启用守护进程
org.gradle.daemon=true

# 并行构建
org.gradle.parallel=true

# 按需配置
org.gradle.configureondemand=true

# 启用构建缓存
org.gradle.caching=true
```

#### B. IDEA 设置
1. `Settings` → `Build, Execution, Deployment` → `Compiler`
2. ✅ 勾选：
    - Build project automatically
    - Build modules in parallel

### 6.2 常见 Gradle 问题

#### 问题 1：下载慢
```groovy
// build.gradle 添加国内镜像
repositories {
    maven { url 'https://maven.aliyun.com/repository/central' }
    maven { url 'https://maven.aliyun.com/repository/public' }
    mavenCentral()
}
```

#### 问题 2：同步失败
```powershell
# 清理缓存
.\gradlew clean
Remove-Item -Path ".gradle" -Recurse -Force

# 刷新依赖
.\gradlew --refresh-dependencies

# 重新生成配置
.\gradlew genIntellijRuns
```

#### 问题 3：内存不足
```properties
# gradle.properties
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=512m

# IDEA 设置
# Help → Edit Custom VM Options
-Xms512m
-Xmx2048m
```

---

## 7. 常见问题解决

### 7.1 IDEA 卡顿

#### 解决方案：
1. **增加内存**
    - `Help` → `Edit Custom VM Options`
   ```
   -Xms512m
   -Xmx2048m
   ```

2. **禁用不需要的插件**
    - `Settings` → `Plugins` → 禁用不用的插件

3. **清理缓存**
    - `File` → `Invalidate Caches` → `Invalidate and Restart`

4. **排除文件夹**
    - 右键文件夹 → `Mark Directory as` → `Excluded`

### 7.2 代码补全不工作

#### 解决方案：
1. 检查 Power Save Mode
    - `File` → 取消勾选 `Power Save Mode`

2. 重新导入项目
    - 右键 `build.gradle` → `Reload Gradle Project`

3. 清理缓存
    - `File` → `Invalidate Caches`

### 7.3 运行配置丢失

#### 解决方案：
1. 重新生成运行配置
   ```powershell
   .\gradlew genIntellijRuns
   ```

2. 刷新 Gradle
    - 点击 Gradle 窗口中的刷新按钮

### 7.4 中文乱码

#### 解决方案：
1. 设置编码为 UTF-8
    - `Settings` → `Editor` → `File Encodings`
    - 全部设置为 UTF-8

2. 修改 VM Options
    - `Help` → `Edit Custom VM Options`
   ```
   -Dfile.encoding=UTF-8
   ```

---

## 📝 速查表

### 最常用快捷键 TOP 10

| 排名 | 快捷键 | 功能 | 使用频率 |
|------|--------|------|---------|
| 1 | `Alt + Enter` | 快速修复 | ⭐⭐⭐⭐⭐ |
| 2 | `Ctrl + Space` | 代码补全 | ⭐⭐⭐⭐⭐ |
| 3 | `Ctrl + D` | 复制行 | ⭐⭐⭐⭐ |
| 4 | `Ctrl + Y` | 删除行 | ⭐⭐⭐⭐ |
| 5 | `Ctrl + Alt + L` | 格式化 | ⭐⭐⭐⭐ |
| 6 | `Shift + F6` | 重命名 | ⭐⭐⭐⭐ |
| 7 | `Ctrl + B` | 跳转定义 | ⭐⭐⭐⭐ |
| 8 | `Ctrl + F` | 搜索 | ⭐⭐⭐⭐ |
| 9 | `Ctrl + /` | 注释 | ⭐⭐⭐ |
| 10 | `Ctrl + N` | 查找类 | ⭐⭐⭐ |

---

**文档版本**: 1.0  
**最后更新**: 2026-04-23  
**IDEA 版本**: 2023+








# Java 注解与 Minecraft 包详解

> **前置要求**: 已完成 [Java 基础教程](JAVA_TUTORIAL.md) 和 [Java 进阶教程](JAVA_ADVANCED.md)  
> **学习目标**: 掌握 Java 注解系统、Minecraft 核心包结构、正确的 import 导入方法

---

## 📚 目录

1. [Java 注解完全指南](#1-java-注解完全指南)
2. [Minecraft 核心包结构详解](#2-minecraft-核心包结构详解)
3. [Import 导入完整教程](#3-import-导入完整教程)
4. [实战示例](#4-实战示例)
5. [常见问题与最佳实践](#5-常见问题与最佳实践)

---

## 1. Java 注解完全指南

### 1.1 什么是注解？

注解（Annotation）是 Java 提供的一种元数据机制，用于为代码添加额外信息。

```java
// 基本语法：@注解名
@Override
public String toString() {
    return "Player";
}

// 带参数的注解
@SuppressWarnings("unchecked")
public void process() {
    // 抑制未检查警告
}
```

### 1.2 内置注解

Java 提供了 7 个内置注解：

#### A. @Override
标记方法为重写父类方法。

```java
public class Player extends Entity {
    @Override  // 告诉编译器这是重写方法
    public void update() {
        super.update();
        // 额外逻辑
    }
}
```

**作用：**
- 编译器检查是否正确重写
- 提高代码可读性
- 防止拼写错误

#### B. @Deprecated
标记已过时的元素。

```java
@Deprecated
public void oldMethod() {
    // 旧方法
}

// 使用会显示警告
player.oldMethod();  // ⚠️ 已弃用
```

#### C. @SuppressWarnings
抑制编译器警告。

```java
@SuppressWarnings("unchecked")
public List<String> getList() {
    return (List<String>) rawList;  // 不会显示未检查警告
}

// 多个警告
@SuppressWarnings({"unchecked", "deprecation"})
```

**常用警告类型：**
- `unchecked` - 未检查的类型转换
- `deprecation` - 使用了已弃用的 API
- `unused` - 未使用的变量/方法
- `rawtypes` - 使用了原始类型

#### D. @SafeVarargs
标记可变参数方法安全。

```java
@SafeVarargs
public static <T> void printAll(T... items) {
    for (T item : items) {
        System.out.println(item);
    }
}
```

#### E. @FunctionalInterface
标记函数式接口。

```java
@FunctionalInterface
public interface ClickHandler {
    void onClick(int x, int y);  // 只能有一个抽象方法
}
```

#### F. @Retention
指定注解的保留策略。

```java
@Retention(RetentionPolicy.SOURCE)    // 仅在源代码中
@Retention(RetentionPolicy.CLASS)     // 编译时保留（默认）
@Retention(RetentionPolicy.RUNTIME)   // 运行时保留（可反射读取）
```

#### G. @Target
指定注解的使用位置。

```java
@Target(ElementType.TYPE)         // 类、接口、枚举
@Target(ElementType.FIELD)        // 字段
@Target(ElementType.METHOD)       // 方法
@Target(ElementType.PARAMETER)    // 参数
@Target(ElementType.CONSTRUCTOR)  // 构造方法
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE) // 注解类型
@Target(ElementType.PACKAGE)      // 包

// 多个目标
@Target({ElementType.FIELD, ElementType.METHOD})
```

### 1.3 自定义注解

#### A. 基本注解

```java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Config {
    String key();              // 必须提供的值
    String defaultValue() default "";  // 默认值
    boolean required() default false;
    String description() default "";
}

// 使用注解
public class Settings {
    @Config(key = "player.name", required = true, description = "玩家名称")
    private String playerName;
    
    @Config(key = "player.health", defaultValue = "100")
    private int health;
    
    @Config(key = "game.difficulty")
    private String difficulty;
}
```

#### B. 注解处理器

使用反射读取注解：

```java
public class ConfigLoader {
    public static void load(Object obj) throws Exception {
        Class<?> clazz = obj.getClass();
        
        for (Field field : clazz.getDeclaredFields()) {
            // 检查字段是否有 Config 注解
            if (field.isAnnotationPresent(Config.class)) {
                Config config = field.getAnnotation(Config.class);
                
                String key = config.key();
                String defaultValue = config.defaultValue();
                boolean required = config.required();
                
                // 从配置文件读取值
                String value = readFromConfig(key, defaultValue);
                
                // 设置字段值
                field.setAccessible(true);
                Object convertedValue = convert(value, field.getType());
                field.set(obj, convertedValue);
            }
        }
    }
    
    private static Object convert(String value, Class<?> type) {
        if (type == int.class || type == Integer.class) {
            return Integer.parseInt(value);
        } else if (type == boolean.class || type == Boolean.class) {
            return Boolean.parseBoolean(value);
        } else if (type == double.class || type == Double.class) {
            return Double.parseDouble(value);
        }
        return value;
    }
}
```

### 1.4 元注解（注解的注解）

| 元注解 | 用途 | 说明 |
|--------|------|------|
| @Retention | 保留策略 | SOURCE/CLASS/RUNTIME |
| @Target | 使用位置 | TYPE/FIELD/METHOD 等 |
| @Documented | 文档化 | 包含在 Javadoc 中 |
| @Inherited | 继承性 | 子类自动继承父类注解 |
| @Repeatable | 可重复 | 同一元素可使用多次 |

#### @Repeatable 示例

```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Roles {
    Role[] value();
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Roles.class)
public @interface Role {
    String value();
}

// 使用
@Role("admin")
@Role("user")
@Role("moderator")
public class AdminUser {
    // 可以多次使用 @Role
}
```

### 1.5 Minecraft 模组开发常用注解

#### A. @Mixin（Mixin 注入）

```java
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity {
    
    // 注入到方法开头
    @Inject(method = "tick", at = @At("HEAD"))
    private void onTickHead(CallbackInfo ci) {
        // 在 tick 方法开始时执行
    }
    
    // 注入到方法结尾
    @Inject(method = "tick", at = @At("TAIL"))
    private void onTickTail(CallbackInfo ci) {
        // 在 tick 方法结束时执行
    }
    
    // 取消方法执行
    @Inject(method = "attack", at = @At("HEAD"), cancellable = true)
    private void onAttack(CallbackInfo ci) {
        if (shouldCancelAttack()) {
            ci.cancel();  // 取消原方法
        }
    }
    
    // 注入到特定调用前
    @Inject(method = "tick", 
            at = @At(value = "INVOKE", 
                    target = "Lnet/minecraft/entity/player/PlayerEntity;updatePotionsAndAmbient()V"))
    private void beforeUpdatePotions(CallbackInfo ci) {
        // 在调用 updatePotionsAndAmbient 前执行
    }
    
    // 访问私有字段
    @Shadow
    private int fireTicks;
    
    @Shadow
    private abstract boolean isSpectator();
}
```

#### B. @EventTarget（事件监听）

```java
public class MyModule extends Module {
    
    @EventTarget(priority = 0)  // 优先级，0 最高
    public void onRender(EventRender2D event) {
        // 渲染事件
    }
    
    @EventTarget
    public void onMotion(EventMotion event) {
        // 运动事件
    }
    
    @EventTarget
    public void onPacket(EventPacket event) {
        // 数据包事件
    }
}
```

#### C. @ModuleInfo（模块信息）

```java
@ModuleInfo(
    name = "KillAura",
    description = "自动攻击附近的实体",
    category = Category.COMBAT,
    key = GLFW_KEY_K  // 绑定按键
)
public class KillAura extends Module {
    // 模块实现
}
```

---

## 2. Minecraft 核心包结构详解

### 2.1 包结构总览

Minecraft 使用混淆后的类名，通过映射文件（Mappings）转换为可读名称。

```
net.minecraft (主包)
├── client (客户端)
├── server (服务器)
├── world (世界)
├── entity (实体)
├── item (物品)
├── block (方块)
├── network (网络)
├── util (工具)
├── text (文本)
└── registry (注册表)
```

### 2.2 客户端包 (net.minecraft.client)

**核心类详解：**

```java
// 游戏主实例 - 最重要的类
MinecraftClient mc = MinecraftClient.getInstance();

// 常用属性
mc.player          // 客户端玩家实体
mc.world           // 客户端世界
mc.cameraEntity    // 相机实体
mc.crosshairTarget // 准星指向的目标
mc.options         // 游戏选项
mc.gameRenderer    // 游戏渲染器
mc.particleManager // 粒子管理器
mc.soundManager    // 音效管理器
mc.itemRenderer    // 物品渲染器
mc.entityRenderDispatcher // 实体渲染调度器

// 常用方法
mc.isPaused()      // 游戏是否暂停
mc.isInSingleplayer() // 是否单人游戏
mc.getCurrentFps() // 当前 FPS
mc.getWindow()     // 获取窗口对象
mc.execute(() -> { /* 在主线程执行 */ })
```

#### A. 渲染系统 (net.minecraft.client.render)

```java
// 1. RenderLayer - 渲染层
// 定义不同的渲染类型
RenderLayer.getSolid()        // 固体方块
RenderLayer.getCutout()       // 镂空（如玻璃）
RenderLayer.getTranslucent()  // 半透明
RenderLayer.getEntitySolid()  // 实体固体
RenderLayer.getEntityCutout() // 实体镂空

// 2. BufferBuilder - 缓冲区构建器
// 用于构建顶点数据
BufferBuilder buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR);
buffer.vertex(x, y, z).color(r, g, b, a).next();

// 3. Tessellator - 网格生成器
// 管理缓冲区并绘制
Tessellator tessellator = Tessellator.getInstance();
tessellator.draw();

// 4. Camera - 相机系统
Camera camera = mc.gameRenderer.getCamera();
camera.getPos()      // 相机位置
camera.getPitch()    // 相机俯仰角
camera.getYaw()      // 相机偏航角
camera.isThirdPerson() // 是否第三人称

// 5. EntityRenderDispatcher - 实体渲染调度器
EntityRenderDispatcher dispatcher = mc.getEntityRenderDispatcher();
dispatcher.render(entity, x, y, z, yaw, tickDelta, matrices, vertexConsumers, light);
```

**实战示例 - 自定义渲染：**

```java
@EventListener
public void onRender3D(Render3DEvent event) {
    MatrixStack matrices = event.getMatrixStack();
    VertexConsumerProvider.Immediate vertexConsumers = event.getVertexConsumers();
    
    // 渲染一个方框
    Box box = new Box(0, 0, 0, 1, 1, 1);
    
    matrices.push();
    matrices.translate(x, y, z);
    
    // 获取顶点消费者
    VertexConsumer consumer = vertexConsumers.getBuffer(RenderLayer.getLineStrip());
    
    // 绘制边框
    WorldRenderer.drawBox(matrices, consumer, box, 1.0f, 0.0f, 0.0f, 1.0f);
    
    matrices.pop();
    vertexConsumers.draw();
}
```

#### B. GUI 系统 (net.minecraft.client.gui)

```java
// 1. Screen - 界面基类
// 创建自定义界面
public class CustomScreen extends Screen {
    protected CustomScreen() {
        super(Text.literal("Custom Screen"));
    }
    
    @Override
    protected void init() {
        // 初始化控件
        addDrawableChild(ButtonWidget.builder(
            Text.literal("Click Me"),
            button -> System.out.println("Clicked!")
        ).dimensions(100, 100, 200, 20).build());
    }
    
    @Override
    public void render(DrawContext context, int mouseX, int mouseY, float delta) {
        super.render(context, mouseX, mouseY, delta);
        context.drawText(textRenderer, "Hello", 10, 10, 0xFFFFFFFF, false);
    }
}

// 打开界面
mc.setScreen(new CustomScreen());

// 2. DrawContext - 绘图上下文
// 用于 2D 渲染
context.fill(x1, y1, x2, y2, color);           // 填充矩形
context.drawBorder(x, y, w, h, color);          // 绘制边框
context.drawText(renderer, text, x, y, color, shadow); // 绘制文本
context.drawTexture(texture, x, y, u, v, w, h); // 绘制纹理

// 3. Widget - 控件
ButtonWidget button = ButtonWidget.builder(...)
TextFieldWidget textField = new TextFieldWidget(...)
SliderWidget slider = new SliderWidget(...)
CheckboxWidget checkbox = new CheckboxWidget(...)
```

#### C. 输入系统 (net.minecraft.client.option & util)

```java
// 1. KeyBinding - 按键绑定
KeyBinding attackKey = mc.options.attackKey;
KeyBinding useKey = mc.options.useKey;
KeyBinding forwardKey = mc.options.forwardKey;

// 检查按键是否按下
if (attackKey.wasPressed()) {
    // 攻击键被按下
}

// 2. InputUtil - 输入工具
// GLFW 键码
int key = InputUtil.GLFW_KEY_SPACE;  // 空格键
int key = InputUtil.GLFW_KEY_W;      // W 键

// 3. Mouse - 鼠标
mc.mouse.getX()      // 鼠标 X 坐标
mc.mouse.getY()      // 鼠标 Y 坐标
mc.mouse.isCursorLocked() // 鼠标是否锁定

// 4. Keyboard - 键盘
mc.keyboard.hasAltDown()   // Alt 是否按下
mc.keyboard.hasShiftDown() // Shift 是否按下
mc.keyboard.hasControlDown() // Ctrl 是否按下
```

#### D. 其他客户端子系统

```java
// 音效系统
mc.soundManager.play(PositionedSoundInstance.master(
    SoundEvents.ENTITY_PLAYER_LEVELUP, 1.0f
));

// 粒子系统
mc.particleManager.addParticle(
    ParticleTypes.FLAME,
    x, y, z,
    velocityX, velocityY, velocityZ
);

// 选项设置
mc.options.getFov().setValue(90);
mc.options.getGamma().setValue(10.0); // 夜视
mc.options.getViewDistance().setValue(12);

// 保存选项
mc.options.write();
```

### 2.3 世界包 (net.minecraft.world)

**核心类详解：**

```java
// World - 世界基类（客户端和服务端通用）
World world = mc.world;  // 客户端世界

// 常用属性
world.getTime()          // 游戏时间（tick）
world.getTimeOfDay()     // 一天中的时间
world.getMoonPhase()     // 月相
world.isDay()            // 是否白天
world.isNight()          // 是否夜晚
world.getRegistryKey()   // 世界维度（主世界/地狱/末地）

// 获取实体
world.getEntities()      // 所有实体
world.getPlayers()       // 所有玩家
world.getEntitiesByClass(EntityType.class, box, predicate) // 按条件获取

// 获取方块
world.getBlockState(pos) // 获取方块状态
world.getBlockEntity(pos) // 获取方块实体
world.getFluidState(pos) // 获取流体状态

// 设置方块
world.setBlockState(pos, state) // 设置方块
world.breakBlock(pos, drop)     // 破坏方块

// 生成实体
world.spawnEntity(entity) // 生成实体

// 爆炸
world.createExplosion(entity, x, y, z, power, createFire, destructionType)
```

#### A. 区块系统 (net.minecraft.world.chunk)

```java
// WorldChunk - 世界区块（16x16x384）
WorldChunk chunk = world.getChunk(chunkX, chunkZ);

// 常用方法
chunk.getBlockState(pos)        // 获取方块状态
chunk.setBlockState(pos, state) // 设置方块状态
chunk.getHeightmap(Heightmap.Type.MOTION_BLOCKING) // 高度图
chunk.getBiomeForNoiseGen(x, y, z) // 获取生物群系

// ChunkSection - 区块段（16x16x16）
// 每个区块有 24 个段（0-23）
ChunkSection section = chunk.getSectionArray()[sectionIndex];

// ChunkStatus - 区块状态
// 定义区块生成的各个阶段
ChunkStatus.FULL      // 完整生成
ChunkStatus.LIQUID_CARVERS // 液体雕刻
ChunkStatus.FEATURES  // 特征生成
```

**实战示例 - 遍历区块：**

```java
// 获取玩家所在区块
BlockPos playerPos = mc.player.getBlockPos();
int chunkX = playerPos.getX() >> 4;  // 除以 16
int chunkZ = playerPos.getZ() >> 4;

WorldChunk chunk = world.getChunk(chunkX, chunkZ);

// 遍历区块中的所有方块
for (int x = 0; x < 16; x++) {
    for (int y = 0; y < 256; y++) {
        for (int z = 0; z < 16; z++) {
            BlockPos pos = new BlockPos(
                chunkX * 16 + x, y, chunkZ * 16 + z
            );
            BlockState state = chunk.getBlockState(pos);
            
            if (state.getBlock() == Blocks.DIAMOND_ORE) {
                System.out.println("发现钻石矿: " + pos);
            }
        }
    }
}
```

#### B. 生物群系 (net.minecraft.world.biome)

```java
// Biome - 生物群系
Biome biome = world.getBiome(pos).value();

// 获取群系信息
biome.getCategory()           // 群系类别
biome.getPrecipitation()      // 降水类型（雨/雪/无）
biome.getTemperature()        // 温度
biome.getDownfall()           // 降雨量

// 常见群系
BiomeKeys.PLAINS              // 平原
BiomeKeys.DESERT              // 沙漠
BiomeKeys.FOREST              // 森林
BiomeKeys.OCEAN               // 海洋
BiomeKeys.NETHER_WASTES       // 地狱荒地
BiomeKeys.THE_END             // 末地
```

#### C. Tick 系统 (net.minecraft.world.tick)

```java
// TickManager - Tick 管理器
TickManager tickManager = world.getTickManager();

// ScheduledTick - 计划 Tick
// 用于延迟执行的操作（如红石、液体流动）
tickManager.scheduleTick(pos, block, delay);

// 自定义 Tick 逻辑
@EventListener
public void onTick(TickEvent event) {
    if (mc.world == null) return;
    
    long gameTime = mc.world.getTime();
    if (gameTime % 20 == 0) {  // 每秒执行一次
        // 定时任务
    }
}
```

### 2.4 实体包 (net.minecraft.entity)

**核心类详解：**

```java
// Entity - 实体基类
Entity entity = ...;

// 常用属性
entity.getX(), entity.getY(), entity.getZ()  // 位置
entity.getPos()                               // Vec3d 位置
entity.getPitch()                             // 俯仰角
entity.getYaw()                               // 偏航角
entity.getVelocity()                          // 速度向量
entity.isOnGround()                           // 是否在地面
entity.isSneaking()                           // 是否潜行
entity.isSprinting()                          // 是否疾跑
entity.isInvisible()                          // 是否隐身
entity.isGlowing()                            // 是否发光
entity.fireTicks                              // 着火时间
entity.hurtTime                               // 受伤时间

// 常用方法
entity.teleport(x, y, z)                      // 传送
entity.kill()                                 // 杀死
entity.damage(DamageSource, amount)           // 造成伤害
entity.setVelocity(x, y, z)                   // 设置速度
entity.addVelocity(x, y, z)                   // 添加速度
entity.getBoundingBox()                       // 获取边界盒
entity.distanceTo(otherEntity)                // 计算距离
entity.squaredDistanceTo(pos)                 // 平方距离（更快）
```

#### A. 玩家相关 (net.minecraft.entity.player)

```java
// PlayerEntity - 玩家实体
PlayerEntity player = mc.player;

// 常用属性
player.getHealth()           // 当前血量
player.getMaxHealth()        // 最大血量
player.getHungerManager()    // 饥饿管理器
player.getInventory()        // 背包
player.experienceLevel       // 经验等级
player.totalExperience       // 总经验
player.abilities             // 玩家能力

// HungerManager - 饥饿管理器
HungerManager hunger = player.getHungerManager();
hunger.getFoodLevel()        // 饥饿值（0-20）
hunger.getSaturationLevel()  // 饱和度
hunger.setFoodLevel(20)      // 设置饥饿值
hunger.setSaturationLevel(5.0f) // 设置饱和度

// PlayerInventory - 玩家背包
PlayerInventory inventory = player.getInventory();
inventory.main                 // 主背包（36 格）
inventory.armor                // 盔甲栏（4 格）
inventory.offHand              // 副手
inventory.selectedSlot         // 选中槽位

// 操作物品
ItemStack stack = inventory.getStack(slot);
inventory.setStack(slot, newStack);
inventory.removeStack(slot, count);

// PlayerAbilities - 玩家能力
PlayerAbilities abilities = player.getAbilities();
abilities.allowFlying          // 允许飞行
abilities.flying               // 正在飞行
abilities.invulnerable         // 无敌
abilities.creativeMode         // 创造模式
abilities.walkSpeed            // 行走速度
abilities.flySpeed             // 飞行速度

// 设置能力
abilities.allowFlying = true;
abilities.flySpeed = 0.1f;
player.sendAbilitiesUpdate();  // 同步到客户端
```

**实战示例 - 修改玩家能力：**

```java
@EventListener
public void onTick(TickEvent event) {
    if (mc.player == null) return;
    
    PlayerAbilities abilities = mc.player.getAbilities();
    
    // 启用飞行
    if (flyModule.isEnabled()) {
        abilities.allowFlying = true;
        abilities.flySpeed = 0.1f;
    }
    
    // 无限跳跃
    if (jumpModule.isEnabled() && mc.options.jumpKey.wasPressed()) {
        mc.player.setVelocity(mc.player.getVelocity().x, 0.42, mc.player.getVelocity().z);
    }
    
    // 同步能力
    mc.player.sendAbilitiesUpdate();
}
```

#### B. 生物相关 (net.minecraft.entity.mob)

```java
// MobEntity - 生物基类
MobEntity mob = ...;

// 常用方法
mob.getTarget()              // 获取目标
mob.setTarget(target)        // 设置目标
mob.getAttacking()           // 获取攻击目标
mob.isAngryAt(player)        // 是否对玩家愤怒
mob.getMovementSpeed()       // 移动速度
mob.getAttributeValue(EntityAttributes.GENERIC_MOVEMENT_SPEED) // 属性值

// Monster - 怪物
Monster zombie = ...;
zombie.isBurning()           // 是否燃烧
zombie.canSeeSky()           // 能否看到天空

// AnimalEntity - 动物
AnimalEntity cow = ...;
cow.isBaby()                 // 是否幼年
cow.getBreedingAge()         // 繁殖年龄
cow.loveTicks                // 爱心时间
```

**实战示例 - 查找附近的怪物：**

```java
public List<MobEntity> findNearbyMobs(double range) {
    if (mc.world == null || mc.player == null) return List.of();
    
    Box searchBox = mc.player.getBoundingBox().expand(range);
    
    return mc.world.getEntitiesByClass(
        MobEntity.class,
        searchBox,
        mob -> mob != null && !mob.isRemoved()
    );
}

// 使用
List<MobEntity> mobs = findNearbyMobs(10.0);
mobs.forEach(mob -> {
    System.out.println("发现怪物: " + mob.getName().getString());
});
```

#### C. 效果系统 (net.minecraft.entity.effect)

```java
// StatusEffect - 状态效果
StatusEffect speed = StatusEffects.SPEED;
StatusEffect strength = StatusEffects.STRENGTH;
StatusEffect regeneration = StatusEffects.REGENERATION;

// StatusEffectInstance - 效果实例
StatusEffectInstance instance = new StatusEffectInstance(
    effect,         // 效果类型
    duration,       // 持续时间（tick）
    amplifier,      // 放大器（等级-1）
    ambient,        // 是否环境效果
    showParticles,  // 是否显示粒子
    showIcon        // 是否显示图标
);

// 给玩家添加效果
player.addStatusEffect(new StatusEffectInstance(
    StatusEffects.SPEED,
    200,    // 10 秒
    1,      // II 级
    false,  // 非环境效果
    true,   // 显示粒子
    true    // 显示图标
));

// 检查是否有效果
if (player.hasStatusEffect(StatusEffects.SPEED)) {
    StatusEffectInstance effect = player.getStatusEffect(StatusEffects.SPEED);
    int duration = effect.getDuration();
    int amplifier = effect.getAmplifier();
}

// 移除效果
player.removeStatusEffect(StatusEffects.SPEED);
```

#### D. 属性系统 (net.minecraft.entity.attribute)

```java
// EntityAttribute - 实体属性
EntityAttribute maxHealth = EntityAttributes.GENERIC_MAX_HEALTH;
EntityAttribute movementSpeed = EntityAttributes.GENERIC_MOVEMENT_SPEED;
EntityAttribute attackDamage = EntityAttributes.GENERIC_ATTACK_DAMAGE;
EntityAttribute armor = EntityAttributes.GENERIC_ARMOR;
EntityAttribute knockbackResistance = EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE;

// 获取属性值
double health = player.getAttributeValue(EntityAttributes.GENERIC_MAX_HEALTH);
double speed = player.getAttributeValue(EntityAttributes.GENERIC_MOVEMENT_SPEED);

// 修改属性（需要权限）
player.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_SPEED)
    .setBaseValue(0.3);  // 默认 0.1
```

### 2.5 物品包 (net.minecraft.item)

**核心类详解：**

```java
// Item - 物品基类
Item item = Items.DIAMOND;

// ItemStack - 物品堆栈（最重要）
ItemStack stack = new ItemStack(Items.DIAMOND, 64);

// 常用属性
stack.getItem()            // 获取物品
stack.getCount()           // 数量
stack.getMaxCount()        // 最大堆叠数
stack.getDamage()          // 耐久度损坏值
stack.isDamaged()          // 是否损坏
stack.isEmpty()            // 是否为空
stack.getName()            // 物品名称

// 常用方法
stack.copy()               // 复制物品堆
stack.setCount(count)      // 设置数量
stack.damage(amount, player, callback) // 损坏物品
stack.enchant(enchantment, level) // 附魔
stack.hasEnchantments()    // 是否有附魔
stack.getRarity()          // 稀有度

// 物品标签（NBT）
NbtCompound nbt = stack.getNbt();
stack.setNbt(nbt);
```

#### A. 物品操作实战

```java
// 1. 创建物品堆
ItemStack diamondStack = new ItemStack(Items.DIAMOND, 64);
ItemStack swordStack = new ItemStack(Items.DIAMOND_SWORD);

// 2. 给玩家物品
player.getInventory().insertStack(diamondStack);

// 3. 检查背包中是否有物品
public boolean hasItem(Item item, int count) {
    int total = 0;
    for (int i = 0; i < player.getInventory().size(); i++) {
        ItemStack stack = player.getInventory().getStack(i);
        if (stack.getItem() == item) {
            total += stack.getCount();
        }
    }
    return total >= count;
}

// 4. 移除物品
public void removeItem(Item item, int count) {
    int remaining = count;
    for (int i = 0; i < player.getInventory().size() && remaining > 0; i++) {
        ItemStack stack = player.getInventory().getStack(i);
        if (stack.getItem() == item) {
            int removeAmount = Math.min(stack.getCount(), remaining);
            stack.decrement(removeAmount);
            remaining -= removeAmount;
        }
    }
}

// 5. 查找最佳工具
public ItemStack findBestTool(Block block) {
    ItemStack bestTool = null;
    float bestSpeed = 1.0f;
    
    for (int i = 0; i < player.getInventory().main.size(); i++) {
        ItemStack stack = player.getInventory().getStack(i);
        if (!stack.isEmpty()) {
            float speed = stack.getMiningSpeedMultiplier(block.getDefaultState());
            if (speed > bestSpeed) {
                bestSpeed = speed;
                bestTool = stack;
            }
        }
    }
    
    return bestTool;
}
```

#### B. 附魔系统

```java
// Enchantment - 附魔
Enchantment sharpness = Enchantments.SHARPNESS;
Enchantment protection = Enchantments.PROTECTION;
Enchantment unbreaking = Enchantments.UNBREAKING;

// 添加附魔
ItemStack sword = new ItemStack(Items.DIAMOND_SWORD);
sword.addEnchantment(Enchantments.SHARPNESS, 5);  // 锋利 V
sword.addEnchantment(Enchantments.UNBREAKING, 3); // 耐久 III

// 检查附魔
if (EnchantmentHelper.getLevel(Enchantments.SHARPNESS, sword) > 0) {
    System.out.println("剑有锋利附魔");
}

// 获取所有附魔
Map<Enchantment, Integer> enchants = EnchantmentHelper.get(sword);
enchants.forEach((enchant, level) -> {
    System.out.println(enchant.getName(level).getString() + " " + 
                      RomanNumeral.toRoman(level));
});

// 附魔台可用附魔
List<EnchantmentLevelEntry> possibleEnchants = 
    EnchantmentHelper.getPossibleResultsForUseableItems(
        world, pos, enchantmentTable
    );
```

#### C. 物品提示（Tooltip）

```java
// 自定义物品提示
@Mixin(ItemStack.class)
public class MixinItemStack {
    @Inject(method = "getTooltip", at = @At("RETURN"))
    private void onGetTooltip(CallbackInfoReturnable<List<Text>> cir) {
        List<Text> tooltip = cir.getReturnValue();
        
        // 添加自定义提示
        tooltip.add(Text.literal("§6自定义信息").formatted(Formatting.GOLD));
        tooltip.add(Text.literal("§7更多信息...").formatted(Formatting.GRAY));
    }
}

// 格式化文本
Text colored = Text.literal("彩色文本")
    .formatted(Formatting.RED)
    .styled(style -> style.withClickEvent(
        new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/say hello")
    ));
```

### 2.6 方块包 (net.minecraft.block)

**核心类详解：**

```java
// Block - 方块基类
Block block = Blocks.DIAMOND_BLOCK;

// BlockState - 方块状态（包含属性）
BlockState state = Blocks.STONE.getDefaultState();
state.get(BlockStateProperties.FACING)  // 获取朝向
state.with(Properties.FACING, Direction.NORTH) // 设置属性

// Blocks - 所有方块实例
Blocks.STONE       // 石头
Blocks.DIRT        // 泥土
Blocks.DIAMOND_ORE // 钻石矿
Blocks.AIR         // 空气
Blocks.WATER       // 水
Blocks.LAVA        // 岩浆
```

#### A. 方块操作实战

```java
// 1. 获取方块信息
BlockPos pos = new BlockPos(100, 64, 100);
BlockState state = world.getBlockState(pos);
Block block = state.getBlock();

// 检查方块类型
if (block == Blocks.DIAMOND_ORE) {
    System.out.println("发现钻石矿！");
}

// 检查方块属性
if (state.contains(Properties.FACING)) {
    Direction facing = state.get(Properties.FACING);
    System.out.println("朝向: " + facing);
}

// 2. 放置方块
world.setBlockState(pos, Blocks.STONE.getDefaultState());

// 3. 破坏方块
world.breakBlock(pos, true);  // true = 掉落物品

// 4. 替换方块
world.setBlockState(pos, Blocks.AIR.getDefaultState());

// 5. 查找附近特定方块
public List<BlockPos> findNearbyBlocks(Block targetBlock, int range) {
    List<BlockPos> positions = new ArrayList<>();
    
    BlockPos playerPos = mc.player.getBlockPos();
    
    for (int x = -range; x <= range; x++) {
        for (int y = -range; y <= range; y++) {
            for (int z = -range; z <= range; z++) {
                BlockPos pos = playerPos.add(x, y, z);
                if (world.getBlockState(pos).getBlock() == targetBlock) {
                    positions.add(pos);
                }
            }
        }
    }
    
    return positions;
}
```

#### B. 方块实体 (BlockEntity)

```java
// BlockEntity - 方块实体（有额外数据的方块）
// 常见方块实体：箱子、熔炉、告示牌等

BlockPos chestPos = new BlockPos(100, 64, 100);
BlockEntity blockEntity = world.getBlockEntity(chestPos);

// 检查是否为箱子
if (blockEntity instanceof ChestBlockEntity chest) {
    // 访问箱子内容
    DefaultedList<ItemStack> items = chest.getItems();
    
    // 遍历物品
    for (int i = 0; i < items.size(); i++) {
        ItemStack stack = items.get(i);
        if (!stack.isEmpty()) {
            System.out.println("槽位 " + i + ": " + stack.getName().getString());
        }
    }
    
    // 放入物品
    chest.setStack(0, new ItemStack(Items.DIAMOND, 64));
}

// 熔炉
if (blockEntity instanceof AbstractFurnaceBlockEntity furnace) {
    // 获取燃料时间
    int fuelTime = furnace.fuelTime;
    
    // 获取烧炼进度
    int cookTime = furnace.cookTime;
    int cookTimeTotal = furnace.cookTimeTotal;
    
    // 放入物品
    furnace.setStack(0, new ItemStack(Items.IRON_ORE)); // 输入
    furnace.setStack(1, new ItemStack(Items.COAL));     // 燃料
}

// 告示牌
if (blockEntity instanceof SignBlockEntity sign) {
    // 读取文本
    Text line1 = sign.getTextOnRow(0, false);
    Text line2 = sign.getTextOnRow(1, false);
    
    // 设置文本（需要权限）
    sign.setTextOnRow(0, Text.literal("第一行"));
}
```

#### C. 方块枚举和属性

```java
// Direction - 方向枚举
Direction.UP
Direction.DOWN
Direction.NORTH
Direction.SOUTH
Direction.EAST
Direction.WEST

// 获取相对方向
Direction opposite = direction.getOpposite();
Direction rotated = direction.rotateYClockwise();

// 从向量获取方向
Direction dir = Direction.fromVector(dx, dy, dz);

// Properties - 方块属性
Properties.FACING           // 朝向
Properties.HORIZONTAL_FACING // 水平朝向
Properties.AXIS             // 轴
Properties.OPEN             // 是否打开
Properties.POWERED          // 是否充能
Properties.WATERLOGGED      // 是否含水

// 使用示例
BlockState state = Blocks.OAK_DOOR.getDefaultState();
state = state.with(Properties.OPEN, true);    // 打开门
state = state.with(Properties.POWERED, true); // 充能
```

### 2.7 网络包 (net.minecraft.network)

**核心概念：**

Minecraft 使用客户端-服务器架构，通过网络数据包进行通信。

```
客户端 (Client) ←→ 服务器 (Server)
     ↓                    ↓
  C2S Packets         S2C Packets
(客户端→服务器)      (服务器→客户端)
```

#### A. 数据包类型

```java
// C2S - 客户端到服务器（Client To Server）
// 玩家发送给服务器的操作

// 1. 玩家移动
PlayerMoveC2SPacket.PositionAndOnGround
PlayerMoveC2SPacket.LookAndOnGround
PlayerMoveC2SPacket.Full

// 2. 玩家操作
PlayerActionC2SPacket          // 挖掘、放置
PlayerInteractEntityC2SPacket  // 与实体交互
PlayerInteractBlockC2SPacket   // 与方块交互
PlayerInteractItemC2SPacket    // 使用物品

// 3. 聊天消息
ChatMessageC2SPacket           // 发送聊天
CommandExecutionC2SPacket      // 执行命令

// 4. 背包操作
ClickSlotC2SPacket             // 点击槽位
CreativeInventoryActionC2SPacket // 创造模式物品操作

// 5. 其他
ClientStatusC2SPacket          // 客户端状态
ConfirmScreenActionC2SPacket   // 确认屏幕操作


// S2C - 服务器到客户端（Server To Client）
// 服务器发送给客户端的信息

// 1. 世界信息
ChunkDataS2CPacket             // 区块数据
WorldTimeUpdateS2CPacket       // 世界时间
DifficultyS2CPacket            // 难度

// 2. 实体信息
EntitySpawnS2CPacket           // 实体生成
EntityPositionS2CPacket        // 实体位置
EntityVelocityUpdateS2CPacket  // 实体速度
EntityEquipmentUpdateS2CPacket // 实体装备

// 3. 玩家信息
PlayerListS2CPacket            // 玩家列表
PlayerRespawnS2CPacket         // 玩家重生
GameStateChangeS2CPacket       // 游戏状态变化

// 4. 背包信息
ScreenHandlerSlotUpdateS2CPacket // 槽位更新
OpenScreenS2CPacket            // 打开界面
CloseScreenS2CPacket           // 关闭界面

// 5. 聊天和标题
GameMessageS2CPacket           // 游戏消息
TitleS2CPacket                 // 标题
SubtitleS2CPacket              // 副标题

// 6. 其他
ExplosionS2CPacket             // 爆炸
ParticleS2CPacket              // 粒子
SoundS2CPacket                 // 音效
```

#### B. 拦截和修改数据包

```java
@Mixin(ClientConnection.class)
public class MixinClientConnection {
    
    @Inject(method = "send(Lnet/minecraft/network/packet/Packet;)V", 
            at = @At("HEAD"), cancellable = true)
    private void onSendPacket(Packet<?> packet, CallbackInfo ci) {
        // 拦截 C2S 数据包
        
        // 示例：取消所有移动数据包
        if (packet instanceof PlayerMoveC2SPacket) {
            if (noSlowModule.isEnabled()) {
                ci.cancel();  // 取消发送
            }
        }
    }
}

@Mixin(ClientPlayNetworkHandler.class)
public class MixinClientPlayNetworkHandler {
    
    @Inject(method = "onEntityVelocityUpdate", at = @At("HEAD"), cancellable = true)
    private void onEntityVelocity(EntityVelocityUpdateS2CPacket packet, CallbackInfo ci) {
        // 拦截 S2C 数据包
        
        // 示例：取消击退
        if (packet.getEntityId() == mc.player.getId()) {
            if (antiKnockbackModule.isEnabled()) {
                ci.cancel();  // 取消处理
            }
        }
    }
}
```

#### C. 发送自定义数据包

```java
// 1. 定义数据包 ID
public class MyPackets {
    public static final Identifier MY_PACKET_ID = 
        new Identifier("mymod", "my_packet");
}

// 2. 注册数据包
public class PacketRegistry {
    public static void register() {
        // 注册 C2S
        ServerPlayNetworking.registerGlobalReceiver(
            MyPackets.MY_PACKET_ID,
            (server, player, handler, buf, responseSender) -> {
                // 处理接收到的数据包
                String message = buf.readString();
                server.execute(() -> {
                    System.out.println("收到消息: " + message);
                });
            }
        );
    }
}

// 3. 发送数据包
// 客户端发送
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
buf.writeString("Hello Server!");
ClientPlayNetworking.send(MyPackets.MY_PACKET_ID, buf);

// 服务器发送
ServerPlayNetworking.send(player, MyPackets.MY_PACKET_ID, buf);
```

#### D. 网络监听器

```java
// ClientPlayNetworkHandler - 客户端游戏阶段网络处理器
ClientPlayNetworkHandler networkHandler = mc.getNetworkHandler();

// 常用方法
networkHandler.sendPacket(packet)           // 发送数据包
networkHandler.getConnection().isConnected() // 是否连接
networkHandler.getPlayerList()              // 玩家列表
networkHandler.getWorld()                   // 世界

// 检查连接状态
if (mc.getNetworkHandler() != null && 
    mc.getNetworkHandler().getConnection().isOpen()) {
    // 已连接到服务器
}
```

### 2.8 注册表包 (net.minecraft.registry)

**核心概念：**

注册表是 Minecraft 管理游戏内容（方块、物品、生物等）的系统。

```java
// Registry - 注册表基类
// Registries - 所有注册表的集合

// 1. 方块注册表
Registry<Block> blockRegistry = Registries.BLOCK;
Block block = blockRegistry.get(new Identifier("minecraft", "stone"));

// 2. 物品注册表
Registry<Item> itemRegistry = Registries.ITEM;
Item item = itemRegistry.get(new Identifier("minecraft", "diamond"));

// 3. 实体类型注册表
Registry<EntityType<?>> entityRegistry = Registries.ENTITY_TYPE;
EntityType<?> entityType = entityRegistry.get(new Identifier("minecraft", "zombie"));

// 4. 生物群系注册表
Registry<Biome> biomeRegistry = Registries.BIOME;

// 5. 音效注册表
Registry<SoundEvent> soundRegistry = Registries.SOUND_EVENT;

// 6. 附魔注册表
Registry<Enchantment> enchantmentRegistry = Registries.ENCHANTMENT;

// 7. 状态效果注册表
Registry<StatusEffect> effectRegistry = Registries.STATUS_EFFECT;

// 8. 粒子类型注册表
Registry<ParticleType<?>> particleRegistry = Registries.PARTICLE_TYPE;
```

#### A. 标签系统 (Tag)

```java
// Tag - 标签（一组相关的项目）
// 常见标签

// 方块标签
BlockTags.LOGS              // 所有原木
BlockTags.PLANKS            // 所有木板
BlockTags.WOOL              // 所有羊毛
BlockTags.ORES              // 所有矿石
BlockTags.NEEDS_DIAMOND_TOOL // 需要钻石工具

// 物品标签
ItemTags.LOGS               // 所有原木
ItemTags.PLANKS             // 所有木板
ItemTags.ARMORS             // 所有盔甲
ItemTags.SWORDS             // 所有剑

// 实体类型标签
EntityTypeTags.UNDEAD       // 亡灵生物
EntityTypeTags.ARROWS       // 箭

// 使用标签
if (state.isIn(BlockTags.LOGS)) {
    System.out.println("这是原木");
}

if (stack.isIn(ItemTags.SWORDS)) {
    System.out.println("这是剑");
}
```

#### B. 自定义注册

```java
// Fabric 提供的注册 API
public class MyMod implements ModInitializer {
    
    // 注册自定义方块
    public static final Block MY_BLOCK = new Block(
        AbstractBlock.Settings.create()
            .strength(2.0f)
            .sounds(BlockSoundGroup.STONE)
    );
    
    public static final Item MY_ITEM = new Item(
        new Item.Settings().group(ItemGroup.MISC)
    );
    
    @Override
    public void onInitialize() {
        // 注册方块
        Registry.register(
            Registries.BLOCK,
            new Identifier("mymod", "my_block"),
            MY_BLOCK
        );
        
        // 注册物品
        Registry.register(
            Registries.ITEM,
            new Identifier("mymod", "my_item"),
            MY_ITEM
        );
    }
}
```

### 2.9 常用核心类速查

#### A. 基础类

| 类名 | 用途 | 包路径 | 常用方法/属性 |
|------|------|--------|-------------|
| MinecraftClient | 游戏主实例 | net.minecraft.client | getInstance(), player, world |
| ClientPlayerEntity | 客户端玩家 | net.minecraft.client.network | getPos(), getPitch(), getYaw() |
| ClientWorld | 客户端世界 | net.minecraft.client.world | getBlockState(), getEntities() |
| Camera | 相机 | net.minecraft.client.render.camera | getPos(), getPitch(), getYaw() |

#### B. 实体类

| 类名 | 用途 | 包路径 | 常用方法/属性 |
|------|------|--------|-------------|
| Entity | 实体基类 | net.minecraft.entity | getX(), getPos(), teleport() |
| PlayerEntity | 玩家实体 | net.minecraft.entity.player | getHealth(), getInventory() |
| LivingEntity | 活体实体 | net.minecraft.entity | damage(), heal(), addStatusEffect() |
| MobEntity | 生物实体 | net.minecraft.entity.mob | getTarget(), setTarget() |
| ItemStack | 物品堆栈 | net.minecraft.item | getCount(), getItem(), copy() |

#### C. 世界和方块

| 类名 | 用途 | 包路径 | 常用方法/属性 |
|------|------|--------|-------------|
| World | 世界基类 | net.minecraft.world | getBlockState(), setBlockState() |
| Block | 方块基类 | net.minecraft.block | getDefaultState() |
| BlockState | 方块状态 | net.minecraft.block | get(), with(), contains() |
| BlockPos | 方块位置 | net.minecraft.util.math | getX(), getY(), getZ(), add() |
| Direction | 方向枚举 | net.minecraft.util.math | UP, DOWN, NORTH, SOUTH, EAST, WEST |

#### D. 数学工具

| 类名 | 用途 | 包路径 | 常用方法/属性 |
|------|------|--------|-------------|
| Vec3d | 3D 向量 | net.minecraft.util.math | x, y, z, distanceTo() |
| Vec2f | 2D 向量 | net.minecraft.util.math | x, y |
| Box | 边界盒 | net.minecraft.util.math | minX, minY, minZ, maxX, maxY, maxZ |
| MathHelper | 数学辅助 | net.minecraft.util.math | clamp(), lerp(), sqrt() |
| MatrixStack | 矩阵堆栈 | net.minecraft.client.util.math | push(), pop(), translate(), scale() |

#### E. 文本和 UI

| 类名 | 用途 | 包路径 | 常用方法/属性 |
|------|------|--------|-------------|
| Text | 文本组件 | net.minecraft.text | literal(), getString() |
| MutableText | 可变文本 | net.minecraft.text | formatted(), styled() |
| Style | 文本样式 | net.minecraft.text | withColor(), withBold() |
| Formatting | 格式化 | net.minecraft.util | RED, GREEN, BLUE, BOLD |
| DrawContext | 绘图上下文 | net.minecraft.client.gui | fill(), drawText(), drawTexture() |

#### F. 网络和注册表

| 类名 | 用途 | 包路径 | 常用方法/属性 |
|------|------|--------|-------------|
| Identifier | 资源标识符 | net.minecraft.util | new Identifier("mod:id") |
| Registry | 注册表 | net.minecraft.registry | get(), register() |
| Registries | 所有注册表 | net.minecraft.registry | BLOCK, ITEM, ENTITY_TYPE |
| Packet | 数据包 | net.minecraft.network | - |

#### G. 其他重要类

| 类名 | 用途 | 包路径 | 说明 |
|------|------|--------|------|
| Hand | 手枚举 | net.minecraft.util | MAIN_HAND, OFF_HAND |
| ActionResult | 操作结果 | net.minecraft.util | SUCCESS, FAIL, PASS |
| HitResult | 命中结果 | net.minecraft.util.hit | getType(), getPos() |
| DamageSource | 伤害来源 | net.minecraft.entity.damage | player(), generic() |
| SoundEvent | 音效事件 | net.minecraft.sound | of() |
| ParticleType | 粒子类型 | net.minecraft.particle | FLAME, HEART, CRIT |

---

## 3. Import 导入完整教程

### 3.1 Import 基本语法

```java
// 导入单个类
import net.minecraft.client.MinecraftClient;

// 导入整个包（不推荐）
import net.minecraft.client.*;

// 静态导入（导入静态成员）
import static net.minecraft.util.math.MathHelper.*;

// 导入静态常量
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
```

### 3.2 如何确定需要导入哪些类？

#### 方法 1：IDE 自动导入（推荐）

```java
// 1. 编写代码时直接使用类名
MinecraftClient client = MinecraftClient.getInstance();

// 2. IDEA 会显示红色波浪线

// 3. 按 Alt + Enter，选择 "Import class"

// 4. IDE 自动添加 import
import net.minecraft.client.MinecraftClient;
```

#### 方法 2：查看 Minecraft Wiki

访问：https://minecraft.wiki/w/Java_Edition_version_history

搜索类名，查看完整包路径。

#### 方法 3：使用 IDE 搜索

1. `Ctrl + Shift + N` 打开搜索
2. 输入类名，如 `PlayerEntity`
3. 选择正确的类
4. 查看包路径

### 3.3 常用 Import 清单

#### A. 客户端开发必备

```java
// 客户端核心
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.client.gui.screen.Screen;

// 渲染
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.gui.DrawContext;

// 输入
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import org.lwjgl.glfw.GLFW;

// 文本
import net.minecraft.text.Text;
import net.minecraft.text.MutableText;
import net.minecraft.text.Style;
import net.minecraft.util.Formatting;
```

#### B. 实体与玩家

```java
// 实体
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.entity.projectile.ProjectileEntity;

// 生物
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.mob.Monster;
import net.minecraft.entity.animal.AnimalEntity;
```

#### C. 世界与方块

```java
// 世界
import net.minecraft.world.World;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.explosion.Explosion;

// 方块
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;

// 位置
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Box;
```

#### D. 物品

```java
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemUsageContext;
```

#### E. 网络

```java
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.*;
import net.minecraft.network.packet.s2c.play.*;
import net.minecraft.network.MessageType;
```

#### F. 工具类

```java
import net.minecraft.util.Identifier;
import net.minecraft.util.Hand;
import net.minecraft.util.ActionResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec2f;
import net.minecraft.util.registry.Registry;
```

### 3.4 静态导入使用场景

```java
// 不使用静态导入
double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));

// 使用静态导入
import static java.lang.Math.sqrt;
import static java.lang.Math.pow;

double result = sqrt(pow(x, 2) + pow(y, 2));  // 更简洁
```

**Minecraft 中的静态导入：**

```java
import static net.minecraft.util.math.MathHelper.clamp;
import static net.minecraft.util.math.MathHelper.lerp;

double clamped = clamp(value, min, max);
double interpolated = lerp(delta, start, end);
```

### 3.5 处理包冲突

当两个包有同名类时：

```java
// 错误：两个 List 类冲突
import java.util.List;
import net.minecraft.util.collection.List;  // 假设有这个类

// 解决方案 1：使用完整类名
java.util.List<String> list1 = new java.util.ArrayList<>();
net.minecraft.util.collection.List<String> list2 = new net.minecraft.util.collection.List<>();

// 解决方案 2：只导入一个，另一个用完整类名
import java.util.List;

List<String> list1 = new ArrayList<>();
net.minecraft.util.collection.List<String> list2 = ...;
```

---

## 4. 实战示例

### 示例 1：创建带注解的模块

```java
package com.example.client.modules.combat;

// 导入注解
import com.example.client.annotations.ModuleInfo;
import com.example.client.annotations.EventTarget;
import com.example.client.annotations.Config;

// 导入模块基类
import com.example.client.modules.Module;
import com.example.client.modules.Category;

// 导入事件
import com.example.client.events.EventRender3D;
import com.example.client.events.EventAttack;

// 导入 Minecraft 类
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.Vec3d;

// 导入工具类
import net.minecraft.util.math.MathHelper;
import net.minecraft.text.Text;

// 导入键码
import org.lwjgl.glfw.GLFW;

// 导入其他工具
import java.util.List;
import java.util.stream.Collectors;

@ModuleInfo(
    name = "AutoAttack",
    description = "自动攻击附近的敌对生物",
    category = Category.COMBAT,
    key = GLFW.GLFW_KEY_R
)
public class AutoAttack extends Module {
    
    @Config(key = "attack.range", defaultValue = "4.5")
    private double attackRange = 4.5;
    
    @Config(key = "attack.players", defaultValue = "true")
    private boolean attackPlayers = true;
    
    @Config(key = "attack.mobs", defaultValue = "false")
    private boolean attackMobs = false;
    
    @Config(key = "attack.priority", defaultValue = "distance")
    private String priority = "distance";
    
    @Override
    public void onEnable() {
        // 模块启用时的初始化
    }
    
    @EventTarget
    public void onRender3D(EventRender3D event) {
        // 渲染附近的实体
        List<LivingEntity> targets = findTargets();
        targets.forEach(this::renderTarget);
    }
    
    @EventTarget
    public void onAttack(EventAttack event) {
        // 处理攻击事件
        LivingEntity target = findBestTarget();
        if (target != null) {
            attackEntity(target);
        }
    }
    
    private List<LivingEntity> findTargets() {
        return mc.world.getEntities().stream()
            .filter(e -> e instanceof LivingEntity)
            .filter(this::isValidTarget)
            .collect(Collectors.toList());
    }
    
    private boolean isValidTarget(Entity entity) {
        if (!(entity instanceof LivingEntity)) return false;
        if (entity == mc.player) return false;
        if (entity.distanceTo(mc.player) > attackRange) return false;
        
        if (entity instanceof PlayerEntity) {
            return attackPlayers;
        } else if (entity instanceof MobEntity) {
            return attackMobs;
        }
        return false;
    }
}
```

### 示例 2：自定义注解处理器

```java
package com.example.client.config;

import com.example.client.annotations.Config;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class AnnotationConfigProcessor {
    
    private Map<String, Object> configMap = new HashMap<>();
    
    public void load(Object obj) {
        Class<?> clazz = obj.getClass();
        
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Config.class)) {
                Config config = field.getAnnotation(Config.class);
                
                String key = config.key();
                String defaultValue = config.defaultValue();
                boolean required = config.required();
                
                // 从配置文件读取
                Object value = readConfig(key);
                
                // 如果没有值，使用默认值
                if (value == null) {
                    if (required) {
                        throw new RuntimeException("缺少必需配置: " + key);
                    }
                    value = parseValue(defaultValue, field.getType());
                }
                
                // 设置字段值
                field.setAccessible(true);
                try {
                    field.set(obj, value);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    private Object parseValue(String value, Class<?> type) {
        if (type == int.class || type == Integer.class) {
            return Integer.parseInt(value);
        } else if (type == double.class || type == Double.class) {
            return Double.parseDouble(value);
        } else if (type == boolean.class || type == Boolean.class) {
            return Boolean.parseBoolean(value);
        } else if (type == float.class || type == Float.class) {
            return Float.parseFloat(value);
        }
        return value;
    }
}
```

---

## 5. 常见问题与最佳实践

### 5.1 Import 相关问题

#### Q1: 为什么我的类找不到？

**A:** 检查以下几点：
1. 包名是否正确
2. 是否在 build.gradle 中添加了依赖
3. 是否刷新了 Gradle
4. IDE 是否重新索引

```powershell
# 刷新 Gradle
.\gradlew --refresh-dependencies

# 重建项目
.\gradlew clean build
```

#### Q2: 如何避免导入冲突？

**A:**
1. 优先使用完整类名
2. 避免使用 `import package.*`
3. 使用 IDE 的优化导入功能（`Ctrl + Alt + O`）

#### Q3: 静态导入过多会导致混乱吗？

**A:** 是的，建议：
1. 只在频繁使用时才静态导入
2. 静态导入的方法名应该清晰
3. 不要过度使用

### 5.2 注解最佳实践

#### A. 注解命名规范

```java
// ✅ 好的命名
@ModuleInfo
@EventTarget
@Config

// ❌ 不好的命名
@Info
@Target
@Cfg
```

#### B. 注解参数设计

```java
// ✅ 好的设计
@Config(
    key = "module.speed",
    defaultValue = "1.0",
    min = "0.1",
    max = "5.0"
)

// ❌ 不好的设计（参数太多）
@Config("speed", 1.0, 0.1, 5.0, "速度", true, false, 0)
```

#### C. 注解处理器性能

```java
// ✅ 缓存注解信息
private static final Map<Class<?>, List<Field>> ANNOTATION_CACHE = new HashMap<>();

public void process(Object obj) {
    Class<?> clazz = obj.getClass();
    
    // 先从缓存获取
    List<Field> fields = ANNOTATION_CACHE.computeIfAbsent(clazz, k -> {
        List<Field> result = new ArrayList<>();
        for (Field field : k.getDeclaredFields()) {
            if (field.isAnnotationPresent(Config.class)) {
                result.add(field);
            }
        }
        return result;
    });
    
    // 处理字段
    for (Field field : fields) {
        // ...
    }
}
```

### 5.3 Minecraft 开发注意事项

#### A. 客户端与服务端区分

```java
// ❌ 错误：在客户端调用服务端代码
World world = MinecraftClient.getInstance().world;  // 客户端世界

// ✅ 正确：根据环境选择
if (mc.isIntegratedServerRunning()) {
    // 单人游戏，可以访问服务端
} else {
    // 多人游戏，只能访问客户端
}
```

#### B. 线程安全

```java
// ❌ 错误：在非主线程访问游戏对象
new Thread(() -> {
    mc.player.jump();  // 可能导致崩溃
}).start();

// ✅ 正确：在主线程执行
mc.execute(() -> {
    mc.player.jump();  // 安全
});
```

#### C. 空值检查

```java
// ✅ 总是检查空值
if (mc.player != null && mc.world != null) {
    // 安全地访问
    Vec3d pos = mc.player.getPos();
}

// ✅ 使用 Optional
Optional<PlayerEntity> player = Optional.ofNullable(mc.player);
player.ifPresent(p -> {
    // 安全地操作
});
```

### 5.4 速查表

#### 常用注解速查

| 注解 | 用途 | 示例 |
|------|------|------|
| @Override | 标记重写方法 | `@Override public void tick()` |
| @Deprecated | 标记过时方法 | `@Deprecated public void old()` |
| @SuppressWarnings | 抑制警告 | `@SuppressWarnings("unchecked")` |
| @Mixin | Mixin 注入 | `@Mixin(PlayerEntity.class)` |
| @Inject | 方法注入 | `@Inject(method = "tick", at = @At("HEAD"))` |
| @EventTarget | 事件监听 | `@EventTarget public void onRender()` |

#### 常用包速查

| 包名 | 用途 | 常用类 |
|------|------|--------|
| net.minecraft.client | 客户端 | MinecraftClient |
| net.minecraft.entity | 实体 | Entity, PlayerEntity |
| net.minecraft.world | 世界 | World, Chunk |
| net.minecraft.item | 物品 | ItemStack, Items |
| net.minecraft.block | 方块 | Block, Blocks |
| net.minecraft.util.math | 数学工具 | BlockPos, Vec3d |
| net.minecraft.text | 文本 | Text, MutableText |

---

## 📖 相关资源

- [Minecraft Wiki - 类列表](https://minecraft.wiki/w/Java_Edition_version_history)
- [Mixin Wiki - 注解详解](https://github.com/SpongePowered/Mixin/wiki)
- [Java 官方文档 - 注解](https://docs.oracle.com/javase/tutorial/java/annotations/)
- [Fabric Wiki - 包结构](https://fabricmc.net/wiki/)

---

**文档版本**: 1.0  
**最后更新**: 2026-04-23  
**适用版本**: Minecraft 1.20.1+ (Fabric/Forge)

---

# Minecraft 模组开发实战指南

> **前置要求**: 已完成 Java 基础和进阶教程  
> **学习目标**: 掌握 Minecraft Fabric 模组开发核心技术

---

## 📚 目录

1. [面向对象编程深入（继承、多态、接口）](#mixin-注入技术)
2. [Minecraft 模组开发基础](#minecraft-模组开发基础)
3. [Mixin 注入技术](#mixin-注入技术-1)
4. [渲染系统](#渲染系统-1)
5. [实战项目：编写你的第一个模块](#实战项目编写你的第一个模块)

---

## 面向对象编程深入（继承、多态、接口）

> **说明**: 这部分内容已在 [Java 进阶详细教程](#1-面向对象编程深入) 中详细讲解，包括：
> - 封装、继承、多态三大特性
> - 接口与抽象类的使用
> - 方法重写与重载
> - 实际代码示例

**快速回顾：**

```java
// 继承示例
public class PlayerEntity extends Entity {
    @Override
    public void tick() {
        super.tick();  // 调用父类方法
        // 额外逻辑
    }
}

// 接口示例
public interface Damageable {
    void takeDamage(double damage);
    boolean isAlive();
}

// 多态示例
Entity entity = new PlayerEntity("Steve");
entity.tick();  // 实际调用 PlayerEntity 的 tick 方法
```

---

## Minecraft 模组开发基础

### 1.1 项目结构

```
Late nextgen/
├── src/
│   ├── client/          # 客户端代码
│   │   ├── java/
│   │   │   └── yy/yy130202/client/
│   │   │       ├── LateNextgenClient.java    # 客户端入口
│   │   │       ├── mixin/                     # 客户端 Mixin
│   │   │       ├── gui/                       # GUI 界面
│   │   │       └── render/                    # 渲染相关
│   │   └── resources/
│   │       └── late-nextgen.client.mixins.json
│   └── main/            # 通用代码
│       ├── java/
│       │   └── yy/yy130202/
│       │       ├── LateNextgen.java           # 主入口
│       │       └── mixin/                     # 通用 Mixin
│       └── resources/
│           ├── fabric.mod.json                # 模组元数据
│           └── late-nextgen.mixins.json
├── build.gradle         # Gradle 构建配置
└── gradle.properties    # Gradle 属性
```

### 1.2 核心概念

#### A. Fabric Mod 生命周期

```java
public class LateNextgen implements ModInitializer {
    @Override
    public void onInitialize() {
        // 模组初始化时调用
        System.out.println("Late Nextgen 已加载！");
    }
}

public class LateNextgenClient implements ClientModInitializer {
    @Override
    public void onInitializeClient() {
        // 客户端初始化时调用
        System.out.println("客户端已初始化！");
    }
}
```

#### B. Mixin 注入原理

Mixin 允许你在不修改原始类的情况下，向 Minecraft 的类中注入代码。

```java
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity {
    
    @Inject(method = "tick", at = @At("HEAD"))
    private void onTick(CallbackInfo ci) {
        // 在玩家 tick 方法开始时执行
    }
}
```

#### C. 事件驱动架构

```java
// 注册事件监听器
EventManager.register(new Object() {
    @EventListener
    public void onRender(Render2DEvent event) {
        // 渲染事件处理
    }
    
    @EventListener
    public void onKey(KeyEvent event) {
        // 键盘事件处理
    }
});
```

### 1.3 常用 API

#### A. 获取游戏对象

```java
// 获取 Minecraft 实例
MinecraftClient mc = MinecraftClient.getInstance();

// 获取玩家
PlayerEntity player = mc.player;

// 获取世界
ClientWorld world = mc.world;

// 获取相机
Camera camera = mc.gameRenderer.getCamera();
```

#### B. 发送消息

```java
// 聊天消息
player.sendMessage(Text.literal("Hello!"), false);

// 动作栏消息
player.sendMessage(Text.literal("Action!").formatted(Formatting.GREEN), true);
```

#### C. 数学工具

```java
// 距离计算
double distance = player.squaredDistanceTo(target);

// 角度转换
float yaw = (float) Math.toDegrees(Math.atan2(dx, dz));

// 插值
double value = MathHelper.lerp(delta, start, end);
```

---

## Mixin 注入技术

### 2.1 Mixin 基础

#### A. 基本注入

```java
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity {
    
    // 注入到方法开头
    @Inject(method = "tick", at = @At("HEAD"))
    private void onTickHead(CallbackInfo ci) {
        System.out.println("Tick 开始");
    }
    
    // 注入到方法结尾
    @Inject(method = "tick", at = @At("TAIL"))
    private void onTickTail(CallbackInfo ci) {
        System.out.println("Tick 结束");
    }
}
```

#### B. 取消原方法

```java
@Inject(method = "attack", at = @At("HEAD"), cancellable = true)
private void onAttack(Entity target, CallbackInfo ci) {
    if (shouldCancel()) {
        ci.cancel();  // 取消攻击
    }
}
```

#### C. 访问私有成员

```java
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity {
    
    // 访问私有字段
    @Shadow
    private int fireTicks;
    
    // 访问私有方法
    @Shadow
    private abstract boolean isSpectator();
    
    @Inject(method = "tick", at = @At("HEAD"))
    private void onTick(CallbackInfo ci) {
        if (fireTicks > 0) {
            System.out.println("正在燃烧！");
        }
    }
}
```

### 2.2 高级注入

#### A. 注入到特定调用

```java
@Inject(
    method = "tick",
    at = @At(
        value = "INVOKE",
        target = "Lnet/minecraft/entity/player/PlayerEntity;updatePotionsAndAmbient()V"
    )
)
private void beforeUpdatePotions(CallbackInfo ci) {
    // 在调用 updatePotionsAndAmbient 之前执行
}
```

#### B. 修改返回值

```java
@Inject(method = "getMovementSpeed", at = @At("RETURN"), cancellable = true)
private void onGetSpeed(CallbackInfoReturnable<Float> cir) {
    float originalSpeed = cir.getReturnValueF();
    cir.setReturnValue(originalSpeed * 2.0f);  // 双倍速度
}
```

#### C. 局部变量捕获

```java
@Inject(
    method = "tick",
    at = @At(
        value = "INVOKE",
        target = "Lnet/minecraft/entity/LivingEntity;tick()V"
    )
)
private void onTick(CallbackInfo ci, @Local float prevYaw) {
    // 可以访问局部变量 prevYaw
    System.out.println("之前的朝向: " + prevYaw);
}
```

### 2.3 Mixin 配置文件

`late-nextgen.mixins.json`:

```json
{
  "required": true,
  "minVersion": "0.8",
  "package": "yy.yy130202.mixin",
  "compatibilityLevel": "JAVA_17",
  "mixins": [
    "PlayerJumpMixin",
    "ServerTickMixin",
    "DamageModifierMixin"
  ],
  "client": [
    "ExampleClientMixin"
  ],
  "injectors": {
    "defaultRequire": 1
  }
}
```

---

## 渲染系统

### 3.1 NanoVG 渲染

#### A. 基础渲染

```java
public class ClickGUI {
    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
        long vg = getNVGContext();
        
        // 绘制圆角矩形
        drawRoundedRect(vg, x, y, width, height, radius, color);
        
        // 绘制文本
        drawTextWithShadow(textRenderer, text, xPos, yPos, r, g, b, a);
    }
    
    private void drawRoundedRect(long vg, float x, float y, float w, float h, 
                                 float radius, float[] color) {
        try (NVGColor nvgColor = NVGColor.create()) {
            NanoVG.nvgBeginPath(vg);
            NanoVG.nvgRoundedRect(vg, x, y, w, h, radius);
            nvgColor.set(color[0], color[1], color[2], color[3]);
            NanoVG.nvgFillColor(vg, nvgColor);
            NanoVG.nvgFill(vg);
        }
    }
}
```

#### B. 配色方案

```java
// 现代配色方案
private static final float[] COLOR_BG_PRIMARY = {0.08f, 0.08f, 0.1f, 0.95f};
private static final float[] COLOR_BG_SECONDARY = {0.12f, 0.12f, 0.15f, 0.95f};
private static final float[] COLOR_ACCENT = {0.2f, 0.6f, 1.0f, 1.0f};
private static final float[] COLOR_ENABLED = {0.2f, 0.8f, 0.4f, 1.0f};
private static final float[] COLOR_DISABLED = {0.5f, 0.5f, 0.5f, 1.0f};
private static final float[] COLOR_TEXT = {0.95f, 0.95f, 0.95f, 1.0f};
```

#### C. NVG 帧控制

```java
// 在渲染事件中
EventManager.register(new Object() {
    @EventListener
    public void onRender(Render2DEvent event) {
        if (clickGUI != null && clickGUI.isEnabled()) {
            // 开始 NVG 帧
            NVGRenderer.beginFrame(mc.getWindow());
            
            // 渲染 GUI
            clickGUI.render(event.getMatrices(), mouseX, mouseY, delta);
            
            // 结束 NVG 帧
            NVGRenderer.endFrame();
        }
    }
});
```

### 3.2 传统渲染

#### A. DrawContext 渲染

```java
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
    // 绘制矩形
    context.fill(x1, y1, x2, y2, color);
    
    // 绘制边框
    context.drawBorder(x, y, width, height, color);
    
    // 绘制文本
    context.drawText(textRenderer, text, x, y, color, shadow);
}
```

#### B. 矩阵变换

```java
MatrixStack matrices = event.getMatrices();
matrices.push();
matrices.translate(x, y, 0);
matrices.scale(scale, scale, 1.0f);

// 渲染内容
renderContent(matrices);

matrices.pop();
```

---

## 实战项目：编写你的第一个模块

### 4.1 创建 KillAura 模块

#### 步骤 1: 创建模块类

```java
package yy.yy130202.client.modules.combat;

import yy.yy130202.client.events.EventListener;
import yy.yy130202.client.events.Render2DEvent;
import yy.yy130202.client.modules.Category;
import yy.yy130202.client.modules.Module;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Hand;

public class KillAura extends Module {
    
    public KillAura() {
        super("KillAura", "自动攻击附近的实体", Category.COMBAT);
    }
    
    @Override
    public void onEnable() {
        // 启用时的初始化
    }
    
    @Override
    public void onDisable() {
        // 禁用时的清理
    }
    
    @EventListener
    public void onTick(TickEvent event) {
        if (mc.player == null || mc.world == null) return;
        
        // 查找最近的敌人
        LivingEntity target = findNearestEnemy();
        
        if (target != null) {
            // 攻击目标
            attackEntity(target);
        }
    }
    
    private LivingEntity findNearestEnemy() {
        return mc.world.getEntities().stream()
            .filter(e -> e instanceof LivingEntity)
            .filter(e -> e != mc.player)
            .filter(e -> e.distanceTo(mc.player) <= 4.5)
            .min((e1, e2) -> Double.compare(
                e1.distanceTo(mc.player),
                e2.distanceTo(mc.player)
            ))
            .orElse(null);
    }
    
    private void attackEntity(LivingEntity target) {
        mc.interactionManager.attackEntity(mc.player, target);
        mc.player.swingHand(Hand.MAIN_HAND);
    }
}
```

#### 步骤 2: 注册模块

```java
// 在 ModuleManager.java 中
public class ModuleManager {
    private static final List<Module> modules = new ArrayList<>();
    
    public static void init() {
        // 战斗类
        registerModule(new KillAura());
        registerModule(new AutoClicker());
        
        // 移动类
        registerModule(new Fly());
        registerModule(new Speed());
        
        // 渲染类
        registerModule(new ESP());
        registerModule(new Nametags());
    }
    
    private static void registerModule(Module module) {
        modules.add(module);
    }
}
```

#### 步骤 3: 添加配置

```java
public class KillAura extends Module {
    
    private final BooleanSetting attackPlayers = new BooleanSetting(
        "Attack Players", true
    );
    
    private final BooleanSetting attackMobs = new BooleanSetting(
        "Attack Mobs", false
    );
    
    private final NumberSetting range = new NumberSetting(
        "Range", 4.5, 1.0, 6.0, 0.5
    );
    
    private final ModeSetting priority = new ModeSetting(
        "Priority", "Distance", "Distance", "Health", "Armor"
    );
    
    public KillAura() {
        super("KillAura", "自动攻击附近的实体", Category.COMBAT);
        addSettings(attackPlayers, attackMobs, range, priority);
    }
    
    private LivingEntity findNearestEnemy() {
        return mc.world.getEntities().stream()
            .filter(this::isValidTarget)
            .min((e1, e2) -> compareByPriority(e1, e2))
            .orElse(null);
    }
    
    private boolean isValidTarget(Entity entity) {
        if (!(entity instanceof LivingEntity)) return false;
        if (entity == mc.player) return false;
        if (entity.distanceTo(mc.player) > range.getValue()) return false;
        
        if (entity instanceof PlayerEntity) {
            return attackPlayers.getValue();
        } else if (entity instanceof MobEntity) {
            return attackMobs.getValue();
        }
        return false;
    }
}
```

### 4.2 调试技巧

#### A. 日志输出

```java
// 控制台输出
System.out.println("KillAura 已启用");

// 聊天消息
ChatUtils.sendModuleMessage("KillAura", "Enabled");

// 警告消息
ChatUtils.sendWarning("找不到目标！");
```

#### B. 断点调试

1. 在 IDEA 中设置断点
2. 使用 `Run → Debug` 启动游戏
3. 触发断点时检查变量值

#### C. 性能分析

```java
long startTime = System.currentTimeMillis();

// 执行的代码
findNearestEnemy();

long endTime = System.currentTimeMillis();
System.out.println("耗时: " + (endTime - startTime) + "ms");
```

### 4.3 最佳实践

#### ✅ 推荐做法

```java
// 1. 空值检查
if (mc.player == null || mc.world == null) return;

// 2. 启用状态检查
@EventListener
public void onTick(TickEvent event) {
    if (!isEnabled()) return;
    // 模块逻辑
}

// 3. 异常处理
try {
    attackEntity(target);
} catch (Exception e) {
    ChatUtils.sendError("攻击失败: " + e.getMessage());
}

// 4. 资源清理
@Override
public void onDisable() {
    // 清理资源
    target = null;
}
```

#### ❌ 避免的做法

```java
// 1. 不要硬编码数值
private static final double RANGE = 4.5;  // ❌
private final NumberSetting range = ...;  // ✅

// 2. 不要在非主线程访问游戏对象
new Thread(() -> {
    mc.player.jump();  // ❌ 危险！
}).start();

// 3. 不要忘记取消事件
@EventListener
public void onPacket(PacketEvent event) {
    if (shouldCancel(event)) {
        event.setCancelled(true);  // ✅ 记得取消
    }
}
```

---

## 常见问题与解决方案

### Q1: Mixin 注入不生效？

**A:** 检查以下几点：
1. Mixin 类是否在配置文件中注册
2. 包名是否正确
3. 方法签名是否匹配
4. 查看日志中的错误信息

```powershell
# 清理并重新构建
.\gradlew clean build
```

### Q2: 渲染闪烁或消失？

**A:** 确保正确使用 NVG 帧控制：

```java
NVGRenderer.beginFrame(mc.getWindow());
// 渲染代码
NVGRenderer.endFrame();
```

### Q3: 模块配置不保存？

**A:** 实现配置持久化：

```java
// 保存配置
public void saveConfig() {
    JsonObject json = new JsonObject();
    for (Module module : modules) {
        json.add(module.getName(), module.serialize());
    }
    FileUtils.writeJson(configFile, json);
}

// 加载配置
public void loadConfig() {
    JsonObject json = FileUtils.readJson(configFile);
    for (Module module : modules) {
        if (json.has(module.getName())) {
            module.deserialize(json.getAsJsonObject(module.getName()));
        }
    }
}
```

---

## 总结

恭喜你完成了整个学习路径！现在你已经掌握了：

✅ **Java 基础语法**
✅ **Java 进阶特性**（面向对象、泛型、集合等）
✅ **IntelliJ IDEA 使用技巧**
✅ **Java 注解与 Minecraft 包结构**
✅ **Mixin 注入技术**
✅ **NanoVG 渲染系统**
✅ **模块系统开发**
✅ **实战项目开发**

**下一步建议：**

1. 从简单模块开始练习
2. 阅读现有开源模组的代码
3. 参与社区讨论和交流
4. 持续学习和改进

记住：**编程是一个不断学习和实践的过程**。不要害怕犯错，每个错误都是学习的机会。

祝你开发愉快！🎮

---

**文档版本**: 2.0  
**最后更新**: 2026-04-23  
**适用项目**: Late Nextgen (Fabric 1.20.1+)  
**总字数**: 约 6600+ 行
//developer yy130202 AI