A Minecraft mod for getting game information, This mod using network(UDP) that you can get information. 懒得翻译了.....
InfoGod 是一个 Minecraft Forge Mod,提供 UDP 服务器接口(端口 41919),允许外部程序通过简单的文本协议获取游戏数据。支持实时监听游戏状态变化和事件推送。
import socket
import time
class InfoGodClient:
def __init__(self, host='127.0.0.1', port=41919):
self.host = host
self.port = port
self.socket = None
def connect(self):
"""初始化UDP套接字"""
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.settimeout(5.0)
print(f"已初始化UDP套接字,准备发送到 {self.host}:{self.port}")
def send_request(self, request_dict):
"""
发送UDP请求并获取响应
参数:
request_dict: 字典类型,包含请求参数
必须包含 'type' 字段指定请求类型
返回:
字典类型的响应数据
"""
# 构建协议字符串
parts = []
for key, value in request_dict.items():
# 使用不可见字符作为分隔符
parts.append(f"{key}\u001F{value}")
message = "\u001D".join(parts) + "\n"
# 发送UDP请求
self.socket.sendto(message.encode('utf-8'), (self.host, self.port))
# 接收响应
try:
response_data, addr = self.socket.recvfrom(8192)
response_str = response_data.decode('utf-8')
# 解析响应
response = self._parse_response(response_str)
return response
except socket.timeout:
return {"error": "请求超时"}
def _parse_response(self, response_str):
"""解析服务器响应"""
response = {}
lines = response_str.strip().split('\n')
for line in lines:
if not line:
continue
fields = line.split('\u001D')
for field in fields:
if field:
key_value = field.split('\u001F', 1)
if len(key_value) == 2:
response[key_value[0]] = key_value[1]
return response
def close(self):
"""关闭套接字"""
if self.socket:
self.socket.close()
print("套接字已关闭")
def __enter__(self):
self.connect()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
# 使用示例
if __name__ == "__main__":
# 创建客户端实例
client = InfoGodClient()
try:
client.connect()
# 示例1: 获取当前玩家ID
response = client.send_request({
'type': 'get_current_player_id',
'id': '1' # 可选请求ID
})
print("当前玩家ID:", response.get('data_id'))
# 示例2: 获取玩家位置信息
player_id = response.get('data_id')
if player_id:
response = client.send_request({
'type': 'get_entity_move_status',
'entity_id': player_id,
'id': '2'
})
print(f"玩家位置: X={response.get('data_position_x')}, "
f"Y={response.get('data_position_y')}, "
f"Z={response.get('data_position_z')}")
# 示例3: 创建监听器(监听玩家移动)
response = client.send_request({
'type': 'add_listener',
'listener_type': 'get_entity_move_status',
'condition_entity_id': player_id,
'condition_data_position_x': 'greater_than:100', # 当X坐标大于100时触发
'min_interval': '1000', # 最小触发间隔1秒
'id': '3'
})
if 'data_listener_id' in response:
print(f"监听器创建成功,ID: {response['data_listener_id']}")
print("注意: UDP模式下,监听器事件将通过单独的UDP数据包发送")
except Exception as e:
print(f"发生错误: {e}")
finally:
client.close()键1\u001F值1\u001D键2\u001F值2\u001D键3\u001F值3\n
特殊字符:
\u001D(0x1D): 字段分隔符\u001F(0x1F): 键值分隔符(替代等号)\n: 消息结束符
必需字段:
type: 请求类型(字符串)id: 请求ID(可选,数字或字符串)
id\u001F请求ID\u001Ddata_key1\u001F值1\u001Ddata_key2\u001F值2\n
错误响应:
id\u001F请求ID\u001Derror\u001F错误描述\n
事件推送格式:
event_type\u001Flistener_triggered\u001Dlistener_id\u001F监听器ID\u001Dlistener_type\u001F监听类型\u001Devent_data_字段名\u001F值\n
类型: get_entity_move_status
描述: 获取指定实体的位置、视角和速度信息
请求参数:
entity_id: 实体ID(整数)
响应字段:
data_id: 实体IDdata_position_x/y/z: 坐标位置data_look_x/y/z: 视角方向data_velocity_x/y/z: 移动速度
示例请求:
{
'type': 'get_entity_move_status',
'entity_id': '123'
}类型: get_current_player_id
描述: 获取当前客户端玩家的实体ID
请求参数: 无
响应字段:
data_id: 当前玩家实体ID
类型: get_block_at
描述: 获取指定坐标的方块信息
请求参数:
x: X坐标(整数)y: Y坐标(整数)z: Z坐标(整数)
响应字段:
data_x/y/z: 坐标data_block_id: 方块注册IDdata_block_name: 方块显示名称
示例请求:
{
'type': 'get_block_at',
'x': '100',
'y': '64',
'z': '200'
}类型: get_entity_ids_by_type
描述: 根据实体类型筛选并返回实体ID列表
请求参数:
entity_type: 实体类型(字符串)-1: 所有实体player: 玩家animal: 动物monster: 怪物living: 所有生物实体
响应字段:
data_entity_ids: 实体ID列表(逗号分隔)data_count: 数量
类型: get_entity_name_by_id
描述: 根据实体ID获取实体名称和类型
请求参数:
entity_id: 实体ID(整数)
响应字段:
data_id: 实体IDdata_name: 实体名称data_type: 实体类型描述
类型: find_blocks_by_type
描述: 在玩家周围半径内查找指定类型的方块
请求参数:
block_type: 方块类型(完整ID或部分名称)radius: 搜索半径(可选,默认50)
响应字段:
data_blocks: 方块列表(格式: X,Y,Z:ID:名称; ...)data_count: 找到的数量
示例请求:
{
'type': 'find_blocks_by_type',
'block_type': 'minecraft:diamond_ore',
'radius': '100'
}类型: get_entity_item
描述: 获取实体指定位置的物品信息
请求参数:
entity_id: 实体ID(整数)index: 索引位置(整数)location: 位置类型hotbar: 快捷栏(0-8)inventory: 背包(0-26)equipment: 装备栏(0-5)offhand: 副手
响应字段:
data_entity_id: 实体IDdata_location: 位置类型data_index: 索引data_item_id: 物品IDdata_item_name: 物品名称data_count: 数量data_durability: 当前耐久data_max_durability: 最大耐久data_enchantments: 附魔信息
示例请求:
{
'type': 'get_entity_item',
'entity_id': '123',
'index': '0',
'location': 'hotbar'
}类型: get_entity_item_batch
描述: 批量获取多个实体物品信息
请求参数:
batch_0_entity_id: 第0批实体IDbatch_0_index: 第0批索引batch_0_location: 第0批位置batch_1_entity_id: 第1批实体ID- ...(以此类推)
响应字段:
data_batch_total: 总批次数data_batch_success: 成功批次数data_batch_results: 批量结果(特殊格式)data_batch_summary: 结果摘要
类型: get_entity_info
描述: 获取生物的详细属性信息
请求参数:
entity_id: 实体ID(整数)
响应字段:
data_id: 实体IDdata_health: 当前生命值data_max_health: 最大生命值data_food_level: 饥饿值(仅玩家)data_saturation: 饱和值(仅玩家)data_effects: 药水效果列表data_attributes: 属性列表
类型: get_entity_status
描述: 获取实体的各种状态标志
请求参数:
entity_id: 实体ID(整数)
响应字段:
data_id: 实体IDdata_is_hurt: 是否受伤data_is_swinging: 是否在挥动data_is_using_item: 是否在使用物品data_is_sneaking: 是否潜行data_is_burning: 是否着火data_is_in_water: 是否在水中data_is_no_gravity: 是否无重力data_is_spectator: 是否为观察者
类型: get_world_status
描述: 获取当前世界的状态信息
请求参数: 无
响应字段:
data_world_name: 世界名称data_time: 游戏时间data_is_raining: 是否下雨data_is_thundering: 是否雷暴data_rain_level: 雨量级别data_thunder_level: 雷暴级别
类型: get_curr_player_item_bar
描述: 获取当前玩家选中的快捷栏位置
请求参数: 无
响应字段:
data_selected_slot: 选中槽位(1-9)
类型: check_attack
描述: 攻击事件现在只能通过监听器获取,不再提供直接查询功能。请使用监听器功能来监控攻击事件。
请求参数: 无(此功能已废弃,使用监听器替代)
响应字段:
error: 错误信息("攻击事件只能通过监听器获取,请使用监听器功能")
类型: get_biome_at
描述: 获取指定坐标的生物群系
请求参数:
x,y,z: 坐标(可选,默认玩家位置)
响应字段:
data_x/y/z: 坐标data_biome_id: 生物群系IDdata_biome_name: 生物群系名称
类型: search_entity
描述: 在指定实体周围搜索符合条件的实体
请求参数:
entity_id: 中心实体ID(必需)s_entity_type: 实体类型(可选,默认-1)-1: 所有实体player: 玩家animal: 动物monster: 怪物living: 生物实体
s_radius: 搜索半径(可选,默认50)s_filter: 筛选器(可选,默认all)all: 全部实体mind: 最近的玩家(不包括自己)maxd: 最远的玩家
响应字段:
data_entity_ids: 实体ID列表(逗号分隔)data_entity_names: 实体名称列表(逗号分隔)data_entity_distances: 距离列表(逗号分隔)data_count: 找到的实体数量
类型: get_target_block
描述: 获取玩家视线选中的方块
请求参数:
entity_id: 玩家实体ID
响应字段:
data_x/y/z: 方块坐标data_block_id: 方块IDdata_block_name: 方块名称data_distance: 距离
类型: get_entity_nbt
描述: 获取实体的NBT数据
请求参数:
entity_id: 实体ID
响应字段:
data_entity_id: 实体IDdata_nbt: NBT字符串
类型: get_entity_dist_to_ground
描述: 计算实体到地面的垂直距离
请求参数:
entity_id: 实体ID
响应字段:
data_distance: 距离(负数表示失败)
类型: get_config_path
描述: 获取游戏目录和配置文件路径
请求参数: 无
响应字段:
data_game_dir: 游戏目录路径data_config_dir: 配置文件路径
类型: get_light_level
描述: 获取指定坐标的光照等级信息
请求参数:
x: X坐标(必需)y: Y坐标(必需)z: Z坐标(必需)
响应字段:
data_light_level: 光照等级(0-15)
类型: get_fluid_status
描述: 获取指定坐标的流体状态信息
请求参数:
x: X坐标(必需)y: Y坐标(必需)z: Z坐标(必需)
响应字段:
data_fluid_id: 流体注册IDdata_fluid_name: 流体名称data_fluid_type: 流体类型data_fluid_level: 流体等级
类型: show_title
描述: 在游戏中显示标题、副标题或清除标题
请求参数:
title_type: 标题类型title: 主标题subtitle: 副标题actionbar: 物品栏上方标题clear: 清除标题
text: 显示文本fade_in: 淡入时间(可选,默认10)stay: 停留时间(可选,默认70)fade_out: 淡出时间(可选,默认20)
响应字段:
data_message: 操作结果消息
示例请求:
{
'type': 'show_title',
'title_type': 'title',
'text': 'Hello World!',
'fade_in': '10',
'stay': '70',
'fade_out': '20'
}类型: add_listener
描述: 创建条件监听器,当条件满足时自动推送事件
请求参数:
listener_type: 监听的请求类型condition_字段名: 条件(可多个)min_interval: 最小触发间隔(毫秒,可选,默认1000)
条件格式:
not_null: 值不为空greater_than:数值: 大于指定值less_than:数值: 小于指定值equals:值: 等于指定值- 直接值: 完全相等
响应字段:
data_listener_id: 监听器IDdata_message: 创建结果消息
示例请求:
{
'type': 'add_listener',
'listener_type': 'get_entity_move_status',
'condition_entity_id': '123',
'condition_data_position_x': 'greater_than:100',
'condition_data_position_y': 'less_than:80',
'min_interval': '500'
}类型: remove_listener
描述: 删除指定的监听器
请求参数:
listener_id: 监听器ID
响应字段:
data_message: 删除结果消息
当监听器条件满足时,服务器会主动推送事件:
事件格式:
event_type\u001Flistener_triggered\u001D
listener_id\u001F监听器ID\u001D
listener_type\u001F监听类型\u001D
timestamp\u001F时间戳\u001D
event_data_字段名\u001F值\u001D...
示例事件:
event_type\u001Flistener_triggered\u001D
listener_id\u001F1\u001D
listener_type\u001Fget_entity_move_status\u001D
timestamp\u001F1700000000000\u001D
event_data_data_position_x\u001F120.5\u001D
event_data_data_position_y\u001F65.3\u001D
- 无连接: UDP是无连接协议,不需要维护连接状态
- 重连策略: UDP不需要重连,直接发送请求即可
- 线程安全: Python客户端需要处理异步事件推送
- 格式错误: 请求格式不正确会返回错误响应
- 无效参数: 参数无效会返回错误描述
- 网络异常: 网络异常时需要重新发送请求
- 请求频率: 避免高频请求,建议使用监听器
- 批量操作: 大量数据获取使用批量接口
- 数据缓存: 客户端可适当缓存不变的数据
- UDP特性: 注意UDP可能存在数据包丢失的情况,重要请求建议实现重试机制
在发送数据前,确保值中不包含分隔符:
\u001D(字段分隔符)\u001F(键值分隔符)\n(消息结束符)
如果值中包含这些字符,客户端应先进行转义。
- 使用网络调试工具(如Wireshark)查看原始通信
- 先测试简单请求(如
get_current_player_id) - 逐步增加功能复杂性