From 288994aeec7b18093d204aafad699bbc0cdf7b88 Mon Sep 17 00:00:00 2001 From: LesterLian <32392052+LesterLian@users.noreply.github.com> Date: Sun, 6 Mar 2022 10:22:37 -0500 Subject: [PATCH 01/18] Chinese Translation Improvement (#1959) --- MinecraftClient/Resources/lang/zh-CHS.ini | 552 +++++++++++----------- 1 file changed, 279 insertions(+), 273 deletions(-) diff --git a/MinecraftClient/Resources/lang/zh-CHS.ini b/MinecraftClient/Resources/lang/zh-CHS.ini index 3f022b65..b9ab65f6 100644 --- a/MinecraftClient/Resources/lang/zh-CHS.ini +++ b/MinecraftClient/Resources/lang/zh-CHS.ini @@ -1,76 +1,76 @@ [mcc] # Messages from MCC itself mcc.login=登录: -mcc.login_basic_io=请输入用户名或邮箱 +mcc.login_basic_io=请输入用户名或邮箱。 mcc.password=密码: -mcc.password_basic_io=请输入 {0} 的密码. -mcc.password_hidden=密码: {0} -mcc.offline=§8您正在使用离线模式 -mcc.session_invalid=§8缓存无效或已过期 -mcc.session_valid=§8{0} 的缓存仍然有效. -mcc.connecting=正在连接至 {0}... +mcc.password_basic_io=请输入{0}的密码。 +mcc.password_hidden=密码:{0} +mcc.offline=§8您正在使用离线模式。 +mcc.session_invalid=§8缓存无效或已过期。 +mcc.session_valid=§8{0}的缓存仍然有效。 +mcc.connecting=正在连接至{0}... mcc.ip=服务器IP: -mcc.use_version=§8正在运行Minecraft版本 {0} (v{1}协议) -mcc.unknown_version=§8未知或不受支持的Minecraft版本 {0}.\n正在切换至自动检测模式 +mcc.use_version=§8正在运行Minecraft版本{0} (v{1}协议) +mcc.unknown_version=§8未知或不受支持的Minecraft版本{0}。\n正在切换至自动检测模式。 mcc.forge=检查服务器是否正在运行Forge... -mcc.forgeforce=正在强制启动Forge支持 -mcc.resolve=正在解析 {0}... -mcc.found=§8已找到服务器 {0}:{1} ,域名: {2} -mcc.not_found=§8无法执行 {0} 的SRV解析\n{1}: {2} +mcc.forgeforce=正在强制启动Forge支持。 +mcc.resolve=正在解析{0}... +mcc.found=§8已找到服务器{0}:{1},域名:{2} +mcc.not_found=§8无法执行{0}的SRV解析\n{1}:{2} mcc.retrieve=正在获取服务器信息... -mcc.restart=正在重启Minecraft控制台客户端... -mcc.restart_delay=等待 {0} 秒后重启... +mcc.restart=正在重启Minecraft Console Client... +mcc.restart_delay=等待{0}秒后重启... mcc.server_version=服务器版本: -mcc.disconnected=未连接至任何服务器。输入 '{0}help' 获得帮助 -mcc.press_exit=或者敲击回车退出Minecraft控制台客户端 +mcc.disconnected=未连接至任何服务器。输入 '{0}help' 获得帮助。 +mcc.press_exit=或者敲击回车退出Minecraft Console Client。 mcc.version_supported=该版本受到支持\n正在登录... -mcc.single_cmd=§7已发送命令 §8 {0} -mcc.joined=已成功加入服务器\n输入 '{0}quit' 离开服务器 +mcc.single_cmd=§7已发送命令§8 {0} +mcc.joined=已成功加入服务器。\n输入 '{0}quit' 离开服务器。 mcc.reconnect=等待5秒 (剩余{0}次尝试)... -mcc.disconnect.lost=失去连接 +mcc.disconnect.lost=失去连接。 mcc.disconnect.server=从服务器断开: mcc.disconnect.login=连接失败: mcc.link=链接:{0} -mcc.player_dead_respawn=你死了!1秒后自动重生 -mcc.player_dead=你死了!输入/respawn重生 -mcc.server_offline=§8服务器正处于离线模式 +mcc.player_dead_respawn=你死了!1秒后自动重生。 +mcc.player_dead=你死了!输入/respawn重生。 +mcc.server_offline=§8服务器正处于离线模式。 mcc.session=检查会话... mcc.session_fail=检查会话失败 -mcc.server_protocol=§8服务器版本: {0} (v{1}协议) +mcc.server_protocol=§8服务器版本:{0} (v{1}协议) mcc.with_forge=, 带有Forge -mcc.handshake=§8握手成功 (服务器ID: {0}) -mcc.realms_available==您拥有以下Realms地图的访问权 -mcc.realms_join=加入realms:使用服务器IP连接Realms地图 +mcc.handshake=§8握手成功。 (服务器ID:{0}) +mcc.realms_available==您可以访问以下Realms世界 +mcc.realms_join=请使用realms:<序号>作为服务器IP加入Realms世界 [debug] # Messages from MCC Debug Mode -debug.color_test=颜色测试:终端应该显示的颜色是: {0} -debug.session_cache_ok=§8已成功从磁盘中加载会话数据. +debug.color_test=颜色测试:终端应该显示的颜色是:{0} +debug.session_cache_ok=§8已成功从磁盘中加载会话数据。 debug.session_cache_fail=§8无法从磁盘加载会话 -debug.session_id=成功!(会话ID: {0}) -debug.crypto=§8密钥已生成: -debug.request=§8正在执行请求对 {0} +debug.session_id=成功!(会话ID:{0}) +debug.crypto=§8密钥和哈希值已生成: +debug.request=§8正在请求{0} [error] # Error messages from MCC error.ping=ping此IP失败。 error.unsupported=无法连接到服务器:不支持此版本! error.determine=无法确定服务器版本。 -error.forgeforce=Forge无法强制支持此Minecraft版本! -error.login=Minecraft登录失败: -error.login.migrated=帐户已迁移,使用电子邮件作为用户名. -error.login.server=登录服务器不可用。请稍后再试. -error.login.blocked=密码错误、黑名单IP或登录次数过多 +error.forgeforce=无法为此Minecraft版本强制启动Forge支持! +error.login=登录失败: +error.login.migrated=帐户已迁移,使用电子邮件作为用户名。 +error.login.server=登录服务器不可用。请稍后再试。 +error.login.blocked=密码错误、IP被禁用或登录次数过多。 error.login.response=服务器响应无效。 -error.login.premium=不是白名单内用户 +error.login.premium=不是Premium用户。 error.login.network=网络错误。 -error.login.ssl=SSL错误 -error.login.unknown=未知错误 -error.login.ssl_help=§8似乎您正在使用Mono运行此程序.\n第一次,您必须使用以下命令导入HTTPS证书:\mozroots --import --ask-remove -error.login.cancel=用户取消 +error.login.ssl=SSL错误。 +error.login.unknown=未知错误。 +error.login.ssl_help=§8您似乎正在使用Mono运行此程序.\n当第一次运行,您必须使用以下命令导入HTTPS证书:\nmozroots --import --ask-remove +error.login.cancel=用户取消。 error.login_failed=无法登录到此服务器。 -error.join=无法加入此服务器。 +error.join=加入服务器时发生错误。 error.connect=无法连接到此IP。 error.timeout=连接超时 error.unexpect_response=§8来自服务器的意外响应(这是Minecraft服务器吗?) @@ -78,39 +78,39 @@ error.invalid_response=§8对握手包的响应无效 error.invalid_encrypt=§8对StartEncryption数据包的响应无效 error.version_different=§8服务器报告的版本与手动设置的版本不同。登录可能无法工作。 error.no_version_report=§8服务器未报告其协议版本,自动检测将不起作用。 -error.connection_timeout=§8A 尝试连接到此IP时超时。 +error.connection_timeout=§8尝试连接到此IP时超时。 error.forge=§8Forge登录握手未成功完成 error.forge_encrypt=§8Forge StartEncryption握手未成功完成 -error.setting.str2int=无法将'{0}'转换为int。请检查设置。 -error.setting.argument_syntax={0}: 无效语法,应为--argname=value或--section.argname=value -error.setting.unknown_section={0}: 未知设置部分 '{1}' -error.setting.unknown_or_invalid={0}: 未知设置或无效值 -error.http_code=§8接收到服务器错误: {0} -error.auth=§8在刷新身份验证时接收到服务器错误: {0} -error.realms.ip_error=无法检索您所在领域的服务器IP -error.realms.access_denied=此领域世界不存在或访问被拒绝 -error.realms.server_unavailable=领域服务器可能需要一些时间来启动,请稍后再试。 -error.realms.server_id=领域服务器ID无效或未知。 -error.realms.disabled=正在尝试加入领域世界,但配置中禁用了领域支持 +error.setting.str2int=无法将'{0}'转换为整数。请检查设置。 +error.setting.argument_syntax={0}:无效语法,应为 --argname=value 或 --section.argname=value +error.setting.unknown_section={0}:未知设置部分'{1}' +error.setting.unknown_or_invalid={0}:未知设置或无效值 +error.http_code=§8接收到服务器错误:{0} +error.auth=§8在刷新身份验证时接收到服务器错误:{0} +error.realms.ip_error=无法获取您Realms世界的服务器IP +error.realms.access_denied=此Realms世界不存在或访问被拒绝 +error.realms.server_unavailable=Realms服务器可能需要一些时间来启动。请稍后再试。 +error.realms.server_id=Realms服务器ID无效或未知。 +error.realms.disabled=正在尝试加入Realms世界,但配置中禁用了Realms支持 [internal command] # MCC internal help command -icmd.help=help : 显示有关命令的简要帮助. -icmd.unknown=未知命令 '{0}',请使用 'help' 命令来获取命令列表. -icmd.list=帮助 . 可用命令: {0}. 对于服务器帮助,请改用 '{1}send /help'. -icmd.error=内部命令: 来自{0}的错误{1} +icmd.help=help <命令名称> :显示有关命令的简要帮助。 +icmd.unknown=未知命令 '{0}'。请使用 'help' 命令来获取命令列表。 +icmd.list=help <命令名称>。可用命令:{0}。在服务器上获取帮助,请改用 '{1}send /help'。 +icmd.error=OnInternalCommand: 来自{0}的错误{1} [exception] # Exception messages threw by MCC -exception.user_logout=用户发起的注销应该通过调用Disconnect来完成() +exception.user_logout=用户发起的注销应该通过调用Disconnect()来完成 exception.unknown_direction=未知方向 -exception.palette.block=请更新此minecraft版本的块类型处理. 详细请参考 Material.cs -exception.palette.entity=请更新此Minecraft版本的实体类型处理. 详细请参考 EntityType.cs -exception.palette.item=请更新此Minecraft版本的物品类型处理. 详细请参考 ItemType.cs -exception.palette.packet=请更新此Minecraft版本的数据包类型调色板. 详细请参考 PacketTypePalette.cs -exception.packet_process=无法处理传入的{0}类型的数据包. (数据包ID: {1}, 协议: {2}, 登陆阶段: {3}, 内部异常: {4}). -exception.version_unsupport=版本{0}的协议未被支持. -exception.chatbot.init=不应调用ChatBot方法,因为在构造函数中作为API处理程序的模块尚未初始化,请使用 Override Initialize() or AfterGameJoined() 来执行初始化任务. +exception.palette.block=请为此Minecraft版本更新方块类型处理。详细请参考 Material.cs +exception.palette.entity=请为此Minecraft版本更新实体类型处理。详细请参考 EntityType.cs +exception.palette.item=请为此Minecraft版本更新物品类型处理。详细请参考 ItemType.cs +exception.palette.packet=请为此Minecraft版本更新数据包类型调色板。详细请参考 PacketTypePalette.cs +exception.packet_process=无法处理传入的{0}类型的数据包。(数据包ID:{1},协议:{2},登陆阶段:{3},内部异常:{4})。 +exception.version_unsupport=版本{0}的协议未被支持。 +exception.chatbot.init=不应在构造函数中调用ChatBot的方法,因为作为API处理程序的模块尚未初始化。请重写 Initialize() 或 AfterGameJoined() 来执行初始化任务。 exception.csrunner.invalid_head=提供的脚本没有有效的MCCScript头 [chatbot] @@ -119,114 +119,114 @@ chatbot.reconnect=[{0}] 断开并重新连接到服务器 [filemonitor] # FileMonitor -filemonitor.init=§8[{0}] 正在为文件{1}初始化... -filemonitor.fail=§8[{0}] 无法初始化文件系统监视程序,正在使用轮询重试 +filemonitor.init=§8[{0}] 正在为文件{1}初始化FileSystemWatcher +filemonitor.fail=§8[{0}] 无法初始化FileSystemWatcher,正在使用轮询重试 [extra] # Inventory, Terrain & Movements, Entity related messages # Terrain & Movements extra.terrainandmovement_enabled=地形和移动现在已启用。 -extra.terrainandmovement_disabled=§c该MC版本目前未支持处理地形和移动. -extra.terrainandmovement_required=请先在配置文件中启用地形和移动. +extra.terrainandmovement_disabled=§c该MC版本目前未支持处理地形和移动。 +extra.terrainandmovement_required=请先在配置文件中启用地形和移动。 # Inventory -extra.inventory_enabled=物品栏处理现在已启用. -extra.inventory_disabled=§c该MC版本目前未支持处理物品栏. -extra.inventory_required=请先在配置文件中启用物品栏处理. -extra.inventory_interact=使用 /inventory 来与其交互. -extra.inventory_open=物品栏 # {0} 已开启: {1} -extra.inventory_close=物品栏 # {0} 已关闭. +extra.inventory_enabled=物品栏处理现在已启用。 +extra.inventory_disabled=§c该MC版本目前未支持处理物品栏。 +extra.inventory_required=请先在配置文件中启用InventoryHandling。 +extra.inventory_interact=请使用 /inventory 来与其交互。 +extra.inventory_open=物品栏# {0}已开启:{1} +extra.inventory_close=物品栏# {0}已关闭。 # Entity extra.entity_disabled=§c该MC版本当前未支持处理实体。 -extra.entity_required=请先在配置文件中启用实体处理(Entity Handling). +extra.entity_required=请先在配置文件中启用EntityHandling。 [forge] # Messages from Forge handler -forge.version=§8forge协议版本 : {0} -forge.send_mod=§8向服务器发送forge的mod列表... -forge.accept=§8接受来自的服务器mod列表... -forge.registry=§8收到的注册表有 {0} 个条目 -forge.registry_2=§8已接收注册表 {0} 来自 {1} 条目 -forge.accept_registry=§8接受服务器注册... +forge.version=§8Forge协议版本:{0} +forge.send_mod=§8向服务器发送伪造的forge模组列表... +forge.accept=§8接受来自的服务器模组列表... +forge.registry=§8已接收的注册表包含{0}个条目 +forge.registry_2=§8已接收注册表{0},包含{1}个条目 +forge.accept_registry=§8接受服务器注册表... forge.complete=Forge服务器连接完成! -forge.with_mod=§8服务器正在运行Forge,有 {0} mods. -forge.no_mod=§8正在运行的服务器没有Forgemods. +forge.with_mod=§8服务器正在运行Forge,有{0}个模组。 +forge.no_mod=§8正在运行的服务器没有Forge模组。 forge.mod_list=§8模组列表: # FML2 -forge.fml2.mod=§8收到FM2服务器Mod列表 -forge.fml2.mod_send=§8发回FML2客户端的mod列表 -forge.fml2.registry=§8确认FML2服务器注册表: {0} -forge.fml2.config=§8确认FML2服务器配置: {0} -forge.fml2.unknown=§8收到未知的FML2握手信息. {0} -forge.fml2.unknown_channel=§8忽略未知的FML2登录消息通道: {0} +forge.fml2.mod=§8收到FM2服务器模组列表 +forge.fml2.mod_send=§8发回FML2客户端的模组列表 +forge.fml2.registry=§8确认FML2服务器注册表:{0} +forge.fml2.config=§8确认FML2服务器配置:{0} +forge.fml2.unknown=§8收到未知的FML2握手信息,编号:{0} +forge.fml2.unknown_channel=§8忽略未知的FML2登录消息通道:{0} [cache] # Session Cache -cache.loading=§8加载Minecraft配置文件: {0} -cache.loaded=§8已加载会话: {0}:{1} -cache.converting=§8从磁盘转换的会话缓存: {0} -cache.read_fail=§8无法从磁盘读取序列化会话缓存: {0} -cache.malformed=§8从磁盘读取序列化会话缓存时,获取的数据格式错误,格式错误的数据: {0} -cache.loading_session=§8从磁盘加载会话缓存: {0} -cache.ignore_string=§8忽略会话令牌字符串 '{0}': {1} -cache.ignore_line=§8忽略会话令牌行无效: {0} -cache.read_fail_plain=§8无法从磁盘读取会话缓存: {0} -cache.saving=§8将会话缓存保存到磁盘... -cache.save_fail=§8无法将会话缓存写入磁盘: {0} +cache.loading=§8加载Minecraft配置文件:{0} +cache.loaded=§8已加载会话:{0}:{1} +cache.converting=§8从磁盘转换会话缓存:{0} +cache.read_fail=§8无法从磁盘读取序列化会话缓存:{0} +cache.malformed=§8从磁盘读取序列化会话缓存时,获取到格式错误的数据:{0} +cache.loading_session=§8从磁盘加载会话缓存:{0} +cache.ignore_string=§8忽略会话令牌字符串'{0}':{1} +cache.ignore_line=§8忽略无效的会话令牌行:{0} +cache.read_fail_plain=§8无法从磁盘读取会话缓存:{0} +cache.saving=§8将会话缓存保存到磁盘 +cache.save_fail=§8无法将会话缓存写入磁盘:{0} [proxy] -proxy.connected=§8已连接到代理 {0}:{1} +proxy.connected=§8已连接到代理{0}:{1} [chat] # Chat Parser -chat.download=§8从Mojang服务器下载...'{0}.lang' -chat.request=§8正在执行请求对 {0}... +chat.download=§8从Mojang服务器下载 '{0}.lang'... +chat.request=§8正在请求{0}... chat.done=§8完成。文件另存为 '{0}' -chat.fail=§8下载文件失败. +chat.fail=§8下载文件失败。 chat.from_dir=§8默认为你的Minecraft目录中的en_GB.lang -chat.loaded=§8已加载翻译文件. -chat.not_found=§8找不到翻译文件: '{0}'\n如果没有此文件,某些信息将无法正确打印. +chat.loaded=§8已加载翻译文件。 +chat.not_found=§8找不到翻译文件:'{0}'\n如果没有此文件,某些信息将无法正确打印。 [general] # General message/information (i.e. Done) general.done=完成 general.fail=失败 -general.bot_unload=这将卸载此bot。. -general.available_cmd=可用命令: {0} +general.bot_unload=将会卸载此bot。 +general.available_cmd=可用命令:{0} [cmd] # Commands. Naming style: cmd.. # Animation -cmd.animation.desc=挥动你的手臂. +cmd.animation.desc=挥动你的手臂。 # ChangeSlot -cmd.changeSlot.desc=更改物品栏 -cmd.changeSlot.nan=无法更改插槽:不是数字 -cmd.changeSlot.changed=已更改为插槽 {0} -cmd.changeSlot.fail=无法更改插槽 +cmd.changeSlot.desc=变更快捷栏栏位 +cmd.changeSlot.nan=无法变更栏位:不是数字 +cmd.changeSlot.changed=已变更为栏位{0} +cmd.changeSlot.fail=无法变更栏位 # Connect -cmd.connect.desc=连接到指定的服务器. -cmd.connect.unknown=未知帐户 '{0}'. -cmd.connect.invalid_ip=无效的服务器IP '{0}'. +cmd.connect.desc=连接到指定的服务器。 +cmd.connect.unknown=未知帐户 '{0}'。 +cmd.connect.invalid_ip=无效的服务器IP '{0}'。 # Debug -cmd.debug.desc=切换调试消息. +cmd.debug.desc=切换调试消息。 cmd.debug.state_on=调试消息现在已打开 cmd.debug.state_off=调试消息现在已关闭 # Dig -cmd.dig.desc=试图打破一个方块 -cmd.dig.too_far=你离这个方块太远了. +cmd.dig.desc=试图破坏一个方块 +cmd.dig.too_far=你离这个方块太远了。 cmd.dig.no_block=这个地方没有方块 (空气) cmd.dig.dig=尝试挖掘位于{0} {1} {2}的方块 -cmd.dig.fail=无法开始挖掘方块. +cmd.dig.fail=无法开始挖掘方块。 # Entitycmd -cmd.entityCmd.attacked=被攻击的实体 -cmd.entityCmd.used=使用的实体 +cmd.entityCmd.attacked=已攻击实体 +cmd.entityCmd.used=已使用实体 cmd.entityCmd.not_found=找不到实体 cmd.entityCmd.entity=实体 @@ -235,13 +235,13 @@ cmd.entityCmd.nickname=昵称 cmd.entityCmd.customname=自定义名称 cmd.entityCmd.latency=延迟 cmd.entityCmd.item=物品 -cmd.entityCmd.equipment=设备 -cmd.entityCmd.mainhand=主手臂 -cmd.entityCmd.offhane=副手臂 +cmd.entityCmd.equipment=装备 +cmd.entityCmd.mainhand=主手 +cmd.entityCmd.offhane=副手 cmd.entityCmd.helmet=头盔 cmd.entityCmd.chestplate=胸甲 -cmd.entityCmd.leggings=裤甲 -cmd.entityCmd.boots=护靴 +cmd.entityCmd.leggings=护腿 +cmd.entityCmd.boots=靴子 cmd.entityCmd.pose=姿势 cmd.entityCmd.health=生命值 cmd.entityCmd.distance=距离 @@ -249,84 +249,90 @@ cmd.entityCmd.location=位置 cmd.entityCmd.type=类型 # Exit -cmd.exit.desc=断开与服务器的连接. +cmd.exit.desc=断开与服务器的连接。 # Health -cmd.health.desc=显示生命值和饱食度. -cmd.health.response=健康值: {0}, 饱食度: {1}, 等级: {2}, 经验值: {3} +cmd.health.desc=显示生命值和饱食度。 +cmd.health.response=生命值:{0},饱食度:{1},等级:{2},总经验值:{3} # Inventory -cmd.inventory.desc=存储类型命令 -cmd.inventory.creative_done=请求 {0} x{1} 在存储槽 #{2} -cmd.inventory.creative_delete=请求清除存储槽 #{0} -cmd.inventory.creative_fail=请求创造性操作失败 +cmd.inventory.desc=物品栏相关命令 +cmd.inventory.creative_done=向栏位#{2}请求{0} x{1} +cmd.inventory.creative_delete=请求清除栏位 #{0} +cmd.inventory.creative_fail=请求创造模式操作失败 cmd.inventory.need_creative=你必须在创造模式 cmd.inventory.container_not_found=找不到容器,请使用显式ID重试 cmd.inventory.close=关闭物品栏 #{0} cmd.inventory.close_fail=关闭物品栏失败 #{0} -cmd.inventory.not_exist=物品栏 #{0} 不存在 +cmd.inventory.not_exist=物品栏#{0}不存在 cmd.inventory.inventory=物品栏 -cmd.inventory.inventories=存货 -cmd.inventory.hotbar=您选择的物品栏是 {0} +cmd.inventory.inventories=物品栏集 +cmd.inventory.hotbar=您选择的快捷栏是{0} cmd.inventory.damage=武器伤害值 cmd.inventory.left=左 cmd.inventory.right=右 cmd.inventory.middle=中间 -cmd.inventory.clicking={0} 单机存储槽 {1} 在窗口中 #{2} -cmd.inventory.no_item=存储槽中没有物品 #{0} -cmd.inventory.drop=从存储槽中删除了1个项目 #{0} -cmd.inventory.drop_stack=从存储槽中删除了所有堆叠的物品 #{0} +cmd.inventory.clicking={0}正在点击窗口#{2}中的栏位{1} +cmd.inventory.no_item=栏位#{0}中没有物品 +cmd.inventory.drop=从栏位#{0}中丢弃了1个物品 +cmd.inventory.drop_stack=从栏位#{0}中丢弃了所有堆叠的物品 # Inventory Help cmd.inventory.help.basic=基本用法 cmd.inventory.help.available=可用操作 -cmd.inventory.help.help={0}\n使用 '/inventory help ' 获取帮助.\n'player' 和 'container' 可以简化为 'p' 和 'c'.\n请注意,这些中的参数 '[]' 是可选的. +cmd.inventory.help.help={0}\n使用 '/inventory help ' 获取帮助。\n'player' 和 'container' 可以简化为 'p' 和 'c'。\n请注意,'[]' 中的参数是可选的。 cmd.inventory.help.usage=用法 -cmd.inventory.help.list=列出你的列表. -cmd.inventory.help.close=关闭打开的容器. -cmd.inventory.help.click=单击项目. -cmd.inventory.help.drop=从物品栏中删除项目。 -cmd.inventory.help.creativegive=在创造模式给予物品. -cmd.inventory.help.creativedelete=在创造性模式中清除物品栏. -cmd.inventory.help.unknown=未知操作. +cmd.inventory.help.list=列出你的物品栏。 +cmd.inventory.help.close=关闭打开的容器。 +cmd.inventory.help.click=单击物品。 +cmd.inventory.help.drop=从物品栏中丢弃物品。 +cmd.inventory.help.creativegive=在创造模式中给予物品。 +cmd.inventory.help.creativedelete=在创造性模式中清除栏位。 +cmd.inventory.help.unknown=未知操作。 # List 列表设置 -cmd.list.desc=获取玩家列表.... -cmd.list.players=玩家列表: {0} +cmd.list.desc=获取玩家列表。 +cmd.list.players=玩家列表:{0} # Log -cmd.log.desc=将文本记录到控制台. +cmd.log.desc=将文本记录到控制台。 # Look -cmd.look.desc=查看方向或坐标. +cmd.look.desc=查看方向或坐标。 cmd.look.unknown=未知方向 '{0}' -cmd.look.at=查看相对偏差: {0} 间距: {1} -cmd.look.block=正在看向 {0} +cmd.look.at=正在看向偏航角:{0} 俯仰角:{1} +cmd.look.block=正在看向{0} # Move -cmd.move.desc=移动或开始移动. -cmd.move.enable=在下次服务器登录、重生或世界改变时启用地形和移动。 -cmd.move.disable=禁用地形和移动. -cmd.move.moving=移动 {0} -cmd.move.dir_fail=不能朝此方向移动. -cmd.move.walk=移动到 {0} -cmd.move.fail=无法计算到的路径 {0} +cmd.move.desc=移动或开始移动。 +cmd.move.enable=在下次服务器登录、重生或更换世界时启用地形和移动。 +cmd.move.disable=禁用地形和移动。 +cmd.move.moving=移动{0} +cmd.move.dir_fail=不能朝此方向移动。 +cmd.move.walk=移动到{0} +cmd.move.fail=无法计算到达{0}的路径 +cmd.move.suggestforce=无法计算安全到达{0}的路径. 请使用 -f 参数允许不安全移动。 # Reco -cmd.reco.desc=重新启动并重新连接到服务器. +cmd.reco.desc=重新启动并重新连接到服务器。 # Respawn -cmd.respawn.desc=如果你死亡了,请用这个来重生. -cmd.respawn.done=你重生了. +cmd.respawn.desc=如果你死亡了,请用这个来重生。 +cmd.respawn.done=你重生了。 # Script -cmd.script.desc=运行脚本文件. +cmd.script.desc=运行脚本文件。 # Send -cmd.send.desc=发送聊天信息或命令. +cmd.send.desc=发送聊天信息或命令。 # Set -cmd.set.desc=设置自定义 %variable%. -cmd.set.format=变量名范围必须为 A-Za-z0-9. +cmd.set.desc=设置自定义 %variable%。 +cmd.set.format=变量名范围必须为 A-Za-z0-9。 + +# SetRnd +cmd.setrnd.desc=随机为自定义 %变量名% 赋值。 +cmd.setrndnum.format=setrnd 变量名 -7to17 +cmd.setrndstr.format=setrnd 变量名 字符串1 "\"字符串2\" 字符串3" # Sneak cmd.sneak.desc=切换到潜行 @@ -334,12 +340,12 @@ cmd.sneak.on=现在你在潜行状态 cmd.sneak.off=你不在潜行状态了 # DropItem -cmd.dropItem.desc=删除指定类型的玩家背包或打开的容器中的物品 -cmd.dropItem.dropped=已从清单中删除所有物品{0} #{1} -cmd.dropItem.unknown_item=未知项 {0} +cmd.dropItem.desc=丢弃玩家物品栏中的指定类型物品或打开的容器 +cmd.dropItem.dropped=已从物品栏#{1}中丢弃所有{0} +cmd.dropItem.unknown_item=未知物品:{0} # Tps -cmd.tps.desc=显示服务器当前tps,可能不准确 +cmd.tps.desc=显示服务器当前tps (tick per second)。可能不精确 cmd.tps.current=当前TPS # Useblock @@ -355,147 +361,147 @@ cmd.useitem.use=使用了一个物品 # AutoAttack bot.autoAttack.mode=未知的攻击模式:{0},使用单一模式作为默认值。 -bot.autoAttack.priority=未知优先级:{0},使用距离优先级作为默认值。 +bot.autoAttack.priority=未知优先模式:{0},使用距离优先作为默认值。 bot.autoAttack.invalidcooldown=攻击冷却时间值不能小于0,已使用自动作为默认值 # AutoCraft -bot.autoCraft.cmd=自动创建ChatBot命令 -bot.autoCraft.alias=自动创建ChatBot命令别名 +bot.autoCraft.cmd=自动制作ChatBot命令 +bot.autoCraft.alias=自动制作ChatBot命令的别名 bot.autoCraft.cmd.list=已加载{0}个配方:{1} bot.autoCraft.cmd.resetcfg=将配置重置为默认值 -bot.autoCraft.recipe_not_exist=指定的配方名称不存在。检查配置文件。 +bot.autoCraft.recipe_not_exist=指定的配方名称不存在。请检查配置文件。 bot.autoCraft.no_recipe_name=请指定要制作的配方名称。 -bot.autoCraft.stop=自动合成已停止 -bot.autoCraft.available_cmd=可用命令: {0}. 可使用 /autocraft help 了解更多信息. 您可以使用 /ac 作为命令别名. -bot.autoCraft.help.load=加载配置文件. -bot.autoCraft.help.list=列出加载的配方名称. -bot.autoCraft.help.reload=重新加载配置文件. +bot.autoCraft.stop=AutoCraft已停止 +bot.autoCraft.available_cmd=可用命令:{0}。可使用 /autocraft help <命令名> 了解更多信息。您可以使用 /ac 作为命令别名。 +bot.autoCraft.help.load=加载配置文件。 +bot.autoCraft.help.list=列出可用配方。 +bot.autoCraft.help.reload=重新加载配置文件。 bot.autoCraft.help.resetcfg=将默认示例配置写入默认位置。 -bot.autoCraft.help.start=开始制作. 用法: /autocraft start <配方名称> -bot.autoCraft.help.stop=停止当前正在进行的合成过程 -bot.autoCraft.help.help=获取命令描述. 用法: /autocraft help <命令名> +bot.autoCraft.help.start=开始制作。用法:/autocraft start <配方名称> +bot.autoCraft.help.stop=停止当前正在进行的制作过程 +bot.autoCraft.help.help=获取命令描述。用法: /autocraft help <命令名> bot.autoCraft.loaded=已成功加载 -bot.autoCraft.start=自动合成启动中: {0} -bot.autoCraft.start_fail=无法启动自动合成。检查你的可用制作材料 {0} -bot.autoCraft.table_not_found=找不到合成列表 -bot.autoCraft.close_inventory=物品栏 #{0} 被AutoCraft关闭 -bot.autoCraft.missing_material=丢失的材料: {0} -bot.autoCraft.aborted=制作失败!检查可用材料. -bot.autoCraft.craft_fail=制作失败!等待的更多材料 -bot.autoCraft.timeout=动作超时!原因: {0} -bot.autoCraft.error.config=分析配置时出错: {0} -bot.autoCraft.exception.empty=空配置文件: {0} -bot.autoCraft.exception.invalid=配置文件无效: {0} -bot.autoCraft.exception.item_miss=配方中缺少物品: {0} -bot.autoCraft.exception.invalid_table=表位置格式无效: {0} -bot.autoCraft.exception.item_name=配方中的物品名称无效 {0} at {1} +bot.autoCraft.start=AutoCraft启动中:{0} +bot.autoCraft.start_fail=无法启动AutoCraft。请检查用于制作{0}的可用材料 +bot.autoCraft.table_not_found=找不到工作台 +bot.autoCraft.close_inventory=物品栏#{0}被AutoCraft关闭 +bot.autoCraft.missing_material=缺失材料:{0} +bot.autoCraft.aborted=制作被终止!请检查可用材料。 +bot.autoCraft.craft_fail=制作失败!等待更多材料 +bot.autoCraft.timeout=动作超时!原因:{0} +bot.autoCraft.error.config=分析配置时出错:{0} +bot.autoCraft.exception.empty=空配置文件:{0} +bot.autoCraft.exception.invalid=配置文件无效:{0} +bot.autoCraft.exception.item_miss=配方中缺少物品:{0} +bot.autoCraft.exception.invalid_table=tablelocation格式无效:{0} +bot.autoCraft.exception.item_name=配方{0}中在{1}的物品名称无效 bot.autoCraft.exception.name_miss=解析配方时缺少配方名称 -bot.autoCraft.exception.slot=配方中的插槽字段无效: {0} -bot.autoCraft.exception.duplicate=指定了重复的配方名称: {0} -bot.autoCraft.debug.no_config=找不到配置,请新建一个. +bot.autoCraft.exception.slot=配方中的栏位字段无效:{0} +bot.autoCraft.exception.duplicate=指定了重复的配方名称:{0} +bot.autoCraft.debug.no_config=找不到配置。请新建一个。 # AutoDrop -bot.autoDrop.cmd=自动删除ChatBot命令 -bot.autoDrop.alias=自动删除ChatBot命令别名 -bot.autoDrop.on=已启用自动放置 -bot.autoDrop.off=已禁用自动放置 -bot.autoDrop.added=添加的项目 {0} -bot.autoDrop.incorrect_name=项目名称不正确 {0}. 请再试一次 -bot.autoDrop.removed=删除的项目 {0} -bot.autoDrop.not_in_list=不在列表中的项目 -bot.autoDrop.no_item=列表中没有项目 -bot.autoDrop.list=总计 {0} 在列表中:\n {1} -bot.autoDrop.switched= 切换到 {0} 模式. -bot.autoDrop.unknown_mode=未知模式. 可用的模式: Include, Exclude, Everything -bot.autoDrop.no_mode=无法从配置中读取删除模式(drop mode)。使用包含模式(include mode) -bot.autoDrop.no_inventory=找不到物品栏 {0}! +bot.autoDrop.cmd=AutoDrop ChatBot命令 +bot.autoDrop.alias=AutoDrop ChatBot命令别名 +bot.autoDrop.on=已启用AutoDrop +bot.autoDrop.off=已禁用AutoDrop +bot.autoDrop.added=已添加物品{0} +bot.autoDrop.incorrect_name=物品名称不正确:{0}。请再试一次。 +bot.autoDrop.removed=已删除物品{0} +bot.autoDrop.not_in_list=物品不在列表中 +bot.autoDrop.no_item=列表中没有物品 +bot.autoDrop.list=列表中总计{0}个物品:\n {1} +bot.autoDrop.switched= 切换到{0}模式。 +bot.autoDrop.unknown_mode=未知模式。可用的模式:Include, Exclude, Everything +bot.autoDrop.no_mode=无法从配置中读取丢弃模式(drop mode)。使用Include模式。 +bot.autoDrop.no_inventory=找不到物品栏{0}! # AutoFish -bot.autoFish.throw=扔钓竿 +bot.autoFish.throw=抛竿 bot.autoFish.caught=钓到鱼了! bot.autoFish.no_rod=手上没有鱼竿,可能用坏了? # AutoRelog -bot.autoRelog.launch=已启动,尝试了{0}次重新连接 +bot.autoRelog.launch=已启动,尝试了{0}次重新连接 bot.autoRelog.no_kick_msg=在没有kick消息文件的情况下初始化 bot.autoRelog.loading=从文件{0}加载消息 -bot.autoRelog.loaded=已加载消息: {0} -bot.autoRelog.not_found=找不到的文件或目录: {0} -bot.autoRelog.curr_dir=当前目录为: {0} -bot.autoRelog.ignore_user_logout=由用户或MCC bot启动的断开连接. 忽略. -bot.autoRelog.disconnect_msg=断开连接的消息: {0} -bot.autoRelog.reconnect_always=忽略kick消息,仍要重新连接. -bot.autoRelog.reconnect=信息包含 '{0}'. 重新连接. -bot.autoRelog.reconnect_ignore=不包含任何已定义关键字的消息,忽略. -bot.autoRelog.wait=在重新连接前等待 {0} 秒... +bot.autoRelog.loaded=已加载消息:{0} +bot.autoRelog.not_found=找不到文件或目录:{0} +bot.autoRelog.curr_dir=当前目录为:{0} +bot.autoRelog.ignore_user_logout=由用户或MCC bot启动的断开连接。忽略。 +bot.autoRelog.disconnect_msg=连接断开,收到消息:{0} +bot.autoRelog.reconnect_always=忽略kick消息,仍要重新连接。 +bot.autoRelog.reconnect=信息包含 '{0}'。重新连接。 +bot.autoRelog.reconnect_ignore=不包含任何已定义关键字的消息,忽略。 +bot.autoRelog.wait=等待{0}秒后重新连接... # AutoRespond bot.autoRespond.loading=正在从'{0}'加载匹配项 bot.autoRespond.file_not_found=找不到文件或目录: '{0}' -bot.autoRespond.loaded_match=加载的匹配项:\n{0} -bot.autoRespond.no_trigger=这个配对永远不会触发:\n{0} -bot.autoRespond.no_action=不匹配的操作:\n{0} -bot.autoRespond.match_run=运行动作: {0} -bot.autoRespond.match=配对: {0}\nregex: {1}\naction: {2}\nactionPrivate: {3}\nactionOther: {4}\nownersOnly: {5}\ncooldown: {6} +bot.autoRespond.loaded_match=加载匹配项:\n{0} +bot.autoRespond.no_trigger=这个匹配永远不会触发:\n{0} +bot.autoRespond.no_action=匹配没有对应操作:\n{0} +bot.autoRespond.match_run=进行操作:{0} +bot.autoRespond.match=match: {0}\nregex: {1}\naction: {2}\nactionPrivate: {3}\nactionOther: {4}\nownersOnly: {5}\ncooldown: {6} # ChatLog bot.chatLog.invalid_file=路径'{0}'包含无效字符。 # Mailer -bot.mailer.init=使用设置初始化邮件程序: -bot.mailer.init.db= - 数据库文件: {0} -bot.mailer.init.ignore= - 忽略列表: {0} -bot.mailer.init.public= - 开放的互动: {0} -bot.mailer.init.max_mails= - 每位玩家最多邮件数: {0} -bot.mailer.init.db_size= - 最大数据库大小: {0} -bot.mailer.init.mail_retention= - 邮件保留数: {0} +bot.mailer.init=使用设置初始化Mailer: +bot.mailer.init.db= - 数据库文件:{0} +bot.mailer.init.ignore= - 忽略列表:{0} +bot.mailer.init.public= - 公开交互:{0} +bot.mailer.init.max_mails= - 每位玩家最多邮件数:{0} +bot.mailer.init.db_size= - 最大数据库大小:{0} +bot.mailer.init.mail_retention= - 邮件保留天数:{0} -bot.mailer.init_fail.db_size=无法启用邮件程序:最大数据库大小必须大于零。请检查设置. -bot.mailer.init_fail.max_mails=无法启用邮件:每个玩家的最大邮件数必须大于零。请检查设置。 -bot.mailer.init_fail.mail_retention=无法启用邮件程序:邮件保留必须大于零。请检查设置。 +bot.mailer.init_fail.db_size=无法启用Mailer:最大数据库大小必须大于0。请检查设置。 +bot.mailer.init_fail.max_mails=无法启用Mailer:每个玩家的最大邮件数必须大于0。请检查设置。 +bot.mailer.init_fail.mail_retention=无法启用Mailer:邮件保留天数必须大于0。请检查设置。 -bot.mailer.create.db=创建新数据库文件: {0} -bot.mailer.create.ignore=创建新的忽略列表: {0} -bot.mailer.load.db=正在加载数据库文件: {0} -bot.mailer.load.ignore=加载忽略列表: +bot.mailer.create.db=创建新数据库文件:{0} +bot.mailer.create.ignore=创建新忽略列表:{0} +bot.mailer.load.db=加载数据库文件:{0} +bot.mailer.load.ignore=加载忽略列表: -bot.mailer.cmd=mailer命令 +bot.mailer.cmd=mailer 命令 -bot.mailer.saving=正在保存邮件: {0} -bot.mailer.user_ignored={0} 已被忽略! +bot.mailer.saving=正在保存邮件:{0} +bot.mailer.user_ignored={0}已被忽略! bot.mailer.process_mails=正在查找要发送的邮件 @ {0} -bot.mailer.delivered=已发送: {0} +bot.mailer.delivered=已发送:{0} bot.mailer.cmd.getmails=--- 数据库中的邮件 ---\n{0} bot.mailer.cmd.getignored=--- 忽略列表 ---\n{0} -bot.mailer.cmd.ignore.added=已补充 {0} 到忽略列表! -bot.mailer.cmd.ignore.removed= {0} 已从忽略列表中删除! -bot.mailer.cmd.ignore.invalid=丢失或无效的名称。用法: {0} +bot.mailer.cmd.ignore.added=添加{0}到忽略列表! +bot.mailer.cmd.ignore.removed={0}已从忽略列表中删除! +bot.mailer.cmd.ignore.invalid=丢失或无效的名称。用法:{0}<用户名> bot.mailer.cmd.help=查看用法 # ReplayCapture bot.replayCapture.cmd=replay 命令 -bot.replayCapture.created=已创建replay文件。 -bot.replayCapture.stopped=记录已停止. -bot.replayCapture.restart=记录已停止,请重新启动程序以启动另一个记录。 +bot.replayCapture.created=已创建重播文件。 +bot.replayCapture.stopped=录制已停止。 +bot.replayCapture.restart=录制已停止。请重新启动程序以进行另一段录制。 # Script -bot.script.not_found=§8[MCC] [{0}] 找不到脚本文件: {1} -bot.script.file_not_found=找不到文件: '{0}' -bot.script.fail=脚本 '{0}' 运行失败 ({1}). -bot.script.pm.loaded=脚本 '{0}' 加载中. +bot.script.not_found=§8[MCC] [{0}] 找不到脚本文件:{1} +bot.script.file_not_found=找不到文件:'{0}' +bot.script.fail=脚本'{0}'运行失败 ({1})。 +bot.script.pm.loaded=脚本'{0}'加载。 # ScriptScheduler bot.scriptScheduler.loading=正在从'{0}'加载任务 -bot.scriptScheduler.not_found=找不到文件: '{0}' -bot.scriptScheduler.loaded_task=已加载任务k:\n{0} -bot.scriptScheduler.no_trigger=这个任务永远不会触发:\n{0} -bot.scriptScheduler.no_action=无任务操作:\n{0} -bot.scriptScheduler.running_time=时间 / 运行的行为: {0} -bot.scriptScheduler.running_inverval=间隔 / 运行的行为: {0} -bot.scriptScheduler.running_login=登录 / 运行的行为: {0} -bot.scriptScheduler.task=首次登录时触发: {0}\n 登录时触发: {1}\n 按时触发: {2}\n 间隔触发: {3}\n 时间间隔: {4}\n 间隔时间: {5}\n 行为: {6} +bot.scriptScheduler.not_found=找不到文件:'{0}' +bot.scriptScheduler.loaded_task=已加载任务:\n{0} +bot.scriptScheduler.no_trigger=这个任务永远不会触发:\n{0} +bot.scriptScheduler.no_action=任务没有对应操作:\n{0} +bot.scriptScheduler.running_time=时间 / 运行中的操作:{0} +bot.scriptScheduler.running_inverval=间隔 / 运行中的操作:{0} +bot.scriptScheduler.running_login=登录 / 运行中的操作:{0} +bot.scriptScheduler.task=triggeronfirstlogin: {0}\n triggeronlogin: {1}\n triggerontime: {2}\n triggeroninterval: {3}\n timevalue: {4}\n timeinterval: {5}\n action: {6} # TestBot -bot.testBot.told=Bot: {0} told me : {1} -bot.testBot.said=Bot: {0} said : {1} +bot.testBot.told=Bot:{0}对我说:{1} +bot.testBot.said=Bot:{0}说:{1} From 8795aab81087dc2c86f73d23fff6fb9e2101d912 Mon Sep 17 00:00:00 2001 From: Marko von Oppen Date: Sun, 6 Mar 2022 19:37:27 +0100 Subject: [PATCH 02/18] Add command to disable Gravity (#1955) Allow disabling gravity (flying) for servers that allow this. /move gravity: show gravity handling status /move gravity on: enable gravity handling (falling) /move gravity off: disable gravity handling (flying) Co-authored-by: ORelio --- MinecraftClient/Commands/Move.cs | 10 ++++++++- MinecraftClient/Mapping/Movement.cs | 29 +++++++++++++++------------ MinecraftClient/Resources/lang/de.ini | 3 +++ MinecraftClient/Resources/lang/en.ini | 2 ++ MinecraftClient/Resources/lang/fr.ini | 2 ++ MinecraftClient/Settings.cs | 1 + 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/MinecraftClient/Commands/Move.cs b/MinecraftClient/Commands/Move.cs index 7b95750b..0af06344 100644 --- a/MinecraftClient/Commands/Move.cs +++ b/MinecraftClient/Commands/Move.cs @@ -8,7 +8,7 @@ namespace MinecraftClient.Commands public class Move : Command { public override string CmdName { get { return "move"; } } - public override string CmdUsage { get { return "move [-f]"; } } + public override string CmdUsage { get { return "move [-f]"; } } public override string CmdDesc { get { return "walk or start walking. \"-f\": force unsafe movements like falling or touching fire"; } } public override string Run(McClient handler, string command, Dictionary localVars) @@ -35,6 +35,14 @@ namespace MinecraftClient.Commands handler.SetTerrainEnabled(false); return Translations.Get("cmd.move.disable"); } + else if (args[0] == "gravity") + { + if (args.Count >= 2) + Settings.GravityEnabled = (args[1] == "on"); + if (Settings.GravityEnabled) + return Translations.Get("cmd.move.gravity.enabled"); + else return Translations.Get("cmd.move.gravity.disabled"); + } else if (handler.GetTerrainEnabled()) { if (args.Count == 1) diff --git a/MinecraftClient/Mapping/Movement.cs b/MinecraftClient/Mapping/Movement.cs index 8590899b..6c947343 100644 --- a/MinecraftClient/Mapping/Movement.cs +++ b/MinecraftClient/Mapping/Movement.cs @@ -21,21 +21,24 @@ namespace MinecraftClient.Mapping /// Updated location after applying gravity public static Location HandleGravity(World world, Location location, ref double motionY) { - Location onFoots = new Location(location.X, Math.Floor(location.Y), location.Z); - Location belowFoots = Move(location, Direction.Down); - if (location.Y > Math.Truncate(location.Y) + 0.0001) + if (Settings.GravityEnabled) { - belowFoots = location; - belowFoots.Y = Math.Truncate(location.Y); + Location onFoots = new Location(location.X, Math.Floor(location.Y), location.Z); + Location belowFoots = Move(location, Direction.Down); + if (location.Y > Math.Truncate(location.Y) + 0.0001) + { + belowFoots = location; + belowFoots.Y = Math.Truncate(location.Y); + } + if (!IsOnGround(world, location) && !IsSwimming(world, location)) + { + while (!IsOnGround(world, belowFoots) && belowFoots.Y >= 1) + belowFoots = Move(belowFoots, Direction.Down); + location = Move2Steps(location, belowFoots, ref motionY, true).Dequeue(); + } + else if (!(world.GetBlock(onFoots).Type.IsSolid())) + location = Move2Steps(location, onFoots, ref motionY, true).Dequeue(); } - if (!IsOnGround(world, location) && !IsSwimming(world, location)) - { - while (!IsOnGround(world, belowFoots) && belowFoots.Y >= 1) - belowFoots = Move(belowFoots, Direction.Down); - location = Move2Steps(location, belowFoots, ref motionY, true).Dequeue(); - } - else if (!(world.GetBlock(onFoots).Type.IsSolid())) - location = Move2Steps(location, onFoots, ref motionY, true).Dequeue(); return location; } diff --git a/MinecraftClient/Resources/lang/de.ini b/MinecraftClient/Resources/lang/de.ini index eda6a17d..e5a9e4b0 100644 --- a/MinecraftClient/Resources/lang/de.ini +++ b/MinecraftClient/Resources/lang/de.ini @@ -311,6 +311,9 @@ cmd.move.dir_fail=Kann nicht in diese Richtung laufen. cmd.move.walk=Gehe nach {0} cmd.move.fail=Konnte Pfad nach {0} nicht berechnen. cmd.move.suggestforce=Weg nach {0} konnte nicht berechnet werden. Benutze den -f Parameter, um unsichere Wege zu aktivieren. +cmd.move.gravity.enabled=Gravitation ist aktiv. +cmd.move.gravity.disabled=Gravitation ist deaktiviert. + # Reco cmd.reco.desc=Starte neu und verbinde erneut zum Server. diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index 5784f441..089fad6b 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -311,6 +311,8 @@ cmd.move.dir_fail=Cannot move in that direction. cmd.move.walk=Walking to {0} cmd.move.fail=Failed to compute path to {0} cmd.move.suggestforce=Failed to compute a safe path to {0}. Try -f parameter to allow unsafe movements. +cmd.move.gravity.enabled=Gravity is enabled. +cmd.move.gravity.disabled=Gravity is disabled. # Reco cmd.reco.desc=restart and reconnect to the server. diff --git a/MinecraftClient/Resources/lang/fr.ini b/MinecraftClient/Resources/lang/fr.ini index 53e127bb..a42399ab 100644 --- a/MinecraftClient/Resources/lang/fr.ini +++ b/MinecraftClient/Resources/lang/fr.ini @@ -311,6 +311,8 @@ cmd.move.dir_fail=Impossible de se déplacer dans cette direction. cmd.move.walk=Marche vers {0} cmd.move.fail=Échec de calcul du chemin vers {0} cmd.move.suggestforce=Échec de calcul du chemin vers {0}. Utilisez -f pour autoriser les mouvements risqués. +cmd.move.gravity.enabled=La gravité est activée. +cmd.move.gravity.disabled=La gravité est désactivée. # Reco cmd.reco.desc=Relancer le programme et se reconnecter au serveur diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index ac790230..4d5f907b 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -93,6 +93,7 @@ namespace MinecraftClient public static bool DisplayChatLinks = true; public static bool DisplayInventoryLayout = true; public static bool TerrainAndMovements = false; + public static bool GravityEnabled = true; public static bool InventoryHandling = false; public static string PrivateMsgsCmdName = "tell"; public static CacheType SessionCaching = CacheType.Disk; From 41950c8b20f0d54528b59fc228e01070328b4f67 Mon Sep 17 00:00:00 2001 From: ORelio Date: Sun, 6 Mar 2022 20:09:40 +0100 Subject: [PATCH 03/18] Fix automated builds Revert to Windows 2019 because support for .NET 4 is dropped on Windows 2022. --- .github/workflows/build-and-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 029f8d21..311cb0d2 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -1,5 +1,5 @@ # This workflow will build the project using .NET 4 then publish to GitHub releases -# Due to running .NET 4 this workflow needs to run on windows-latest +# Due to running .NET 4 this workflow needs to run on windows-2019 (support dropped on windows 2022) # Changes would need to be made for using .NET 5 and later on linux name: Build @@ -10,7 +10,7 @@ on: jobs: build: - runs-on: windows-latest + runs-on: windows-2019 env: PROJECT: "MinecraftClient" From a202f31aafdddef2c862c6fd0ea4f8a0dd91fcf1 Mon Sep 17 00:00:00 2001 From: Leon Heuer Date: Mon, 21 Mar 2022 23:29:16 +0100 Subject: [PATCH 04/18] Update version to 1.18.2 (#1961) --- MinecraftClient/Program.cs | 2 +- MinecraftClient/Protocol/Handlers/PacketType18Handler.cs | 2 +- MinecraftClient/Protocol/Handlers/Protocol18.cs | 1 + MinecraftClient/Protocol/ProtocolHandler.cs | 5 ++++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 12626569..7e8b83c3 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -32,7 +32,7 @@ namespace MinecraftClient public const string Version = MCHighestVersion; public const string MCLowestVersion = "1.4.6"; - public const string MCHighestVersion = "1.18.1"; + public const string MCHighestVersion = "1.18.2"; public static readonly string BuildInfo = null; private static Thread offlinePrompt = null; diff --git a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs index bc675720..31bb3bfe 100644 --- a/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs +++ b/MinecraftClient/Protocol/Handlers/PacketType18Handler.cs @@ -51,7 +51,7 @@ namespace MinecraftClient.Protocol.Handlers public PacketTypePalette GetTypeHandler(int protocol) { PacketTypePalette p; - if (protocol > Protocol18Handler.MC1181Version) + if (protocol > Protocol18Handler.MC1182Version) throw new NotImplementedException(Translations.Get("exception.palette.packet")); if (protocol <= Protocol18Handler.MC18Version) p = new PacketPalette17(); diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 5df75536..1d38b0eb 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -53,6 +53,7 @@ namespace MinecraftClient.Protocol.Handlers internal const int MC117Version = 755; internal const int MC1171Version = 756; internal const int MC1181Version = 757; + internal const int MC1182Version = 758; private int compression_treshold = 0; private bool autocomplete_received = false; diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index da4f7415..86753889 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -127,7 +127,7 @@ namespace MinecraftClient.Protocol int[] supportedVersions_Protocol16 = { 51, 60, 61, 72, 73, 74, 78 }; if (Array.IndexOf(supportedVersions_Protocol16, ProtocolVersion) > -1) return new Protocol16Handler(Client, ProtocolVersion, Handler); - int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757 }; + int[] supportedVersions_Protocol18 = { 4, 5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758 }; if (Array.IndexOf(supportedVersions_Protocol18, ProtocolVersion) > -1) return new Protocol18Handler(Client, ProtocolVersion, Handler, forgeInfo); throw new NotSupportedException(Translations.Get("exception.version_unsupport", ProtocolVersion)); @@ -253,6 +253,8 @@ namespace MinecraftClient.Protocol case "1.18": case "1.18.1": return 757; + case "1.18.2": + return 758; default: return 0; } @@ -317,6 +319,7 @@ namespace MinecraftClient.Protocol case 755: return "1.17"; case 756: return "1.17.1"; case 757: return "1.18.1"; + case 758: return "1.18.2"; default: return "0.0"; } } From cec770da569237612f8bb3b7863dc8154f5570ce Mon Sep 17 00:00:00 2001 From: tobycm <62174797+tobycm@users.noreply.github.com> Date: Fri, 1 Apr 2022 14:18:10 -0700 Subject: [PATCH 05/18] Add a portion of Vietnamese translation (#1982) * Create vi.ini Vietnamese language translate * Add more translation * Add translation to README file --- MinecraftClient/Resources/lang/vi.ini | 501 ++++++++++++++++++++++++++ README-vi-vn.md | 71 ++++ 2 files changed, 572 insertions(+) create mode 100644 MinecraftClient/Resources/lang/vi.ini create mode 100644 README-vi-vn.md diff --git a/MinecraftClient/Resources/lang/vi.ini b/MinecraftClient/Resources/lang/vi.ini new file mode 100644 index 00000000..891add2a --- /dev/null +++ b/MinecraftClient/Resources/lang/vi.ini @@ -0,0 +1,501 @@ +[mcc] +# Messages from MCC itself +mcc.login=Đăng nhập: +mcc.login_basic_io=Hãy nhập địa chỉ email hoặc tên tài khoản của bạn: +mcc.password=Mật khẩu: +mcc.password_basic_io=Hãy nhập mật khẩu cho {0}. +mcc.password_hidden=Password : {0} +mcc.offline=§8Bạn chọn sử dụng chế độ ngoại tuyến. +mcc.session_invalid=§8Phiên không hợp lệ hoặc đã hết hạn. +mcc.session_valid=§8Phiên vẫn còn hợp lệ cho {0}. +mcc.connecting=Đang kết nối tới {0}... +mcc.ip=Địa chỉ máy chủ: +mcc.use_version=§8Sử dụng Minecraft phiên bản {0} (protocol v{1}) +mcc.unknown_version=§8Phiên bản không hợp lệ {0}.\nChuyển sang chế độ nhận diện tự động. +mcc.forge=Đang kiểm tra xem máy chủ có dùng Forge... +mcc.forgeforce=Bắt buộc hỗ trợ Forge. +mcc.resolve=Đang giải quyết {0}... +mcc.found=§8Tìm thấy máy chủ {0}:{1} cho tên miền {2} +mcc.not_found=§8Tìm kiếm SRV thất bại cho {0}\n{1}: {2} +mcc.retrieve=Đang nhận thông tin máy chủ... +mcc.restart=Đang khởi động lại Minecraft Console Client... +mcc.restart_delay=Đang chờ {0} giây trước khi khởi động lại... +mcc.server_version=Phiên bản máy chủ: +mcc.disconnected=Chưa kết nối tới máy chủ nào. Dùng '{0}help' để in ra hướng dẫn. +mcc.press_exit=Hoặc nhấn Enter để đóng Minecraft Console Client +mcc.version_supported=Phiên bản hợp lệ \nĐang đăng nhập +mcc.single_cmd=§7Đã gửi lệnh §8 {0}. +mcc.joined=Đã tham gia máy chủ thành công\nGõ '{0}quit' để thoát máy chủ. +mcc.reconnect=Đang chờ 5 giây ({0} lượt còn lại)... +mcc.disconnect.lost=Mất kết nối. +mcc.disconnect.server=Ngắt kết nối bởi máy chủ. +mcc.disconnect.login=Đăng nhập thất bại. +mcc.link=Link: {0} +mcc.player_dead_respawn=Bạn đã chết. Sẽ tự động hồi sinh trong 1 giây. +mcc.player_dead=Bạn đã chết. Gõ /respawn để hồi sinh +mcc.server_offline=§8Máy chủ đang ở trong chế độ ngoại tuyến. +mcc.session=Đang kiểm tra phiên... +mcc.session_fail=Kiểm tra phiên thất bại. +mcc.server_protocol=§8Phiên bản server: {0} (Giao thức v{1}) +mcc.with_forge=, với Forge +mcc.handshake=§8Bắt tay thành công (ID máy chủ: {0}) +mcc.realms_available=Bạn có quyền tham gia vào những máy chủ Realm này +mcc.realms_join=Dùng realm:[thứ tự] để tham gia máy chủ Realm + + +[debug] +# Messages from MCC Debug Mode +debug.color_test=Color test: Màn hình của bạn sẽ hiển thị {0} +debug.session_cache_ok=§8Đã load thông tin phiên thành công +debug.session_cache_fail=§8Không có phiên nào có thể load. +debug.session_id=Thành công. (session ID: {0}) +debug.crypto=§8Khóa mật mã và hash đã được tạo. +debug.request=§8Đang gửi yêu cầu tới {0} + +[error] +# Error messages from MCC +error.ping=Ping IP thất bại. +error.unsupported=Không thể kết nối tới máy chủ: Phiên bản không hợp lệ. +error.determine=Nhận diện phiên bản máy chủ thất bại. +error.forgeforce=Không thể bắt buộc hỗ trợ Forge cho phiên bản này. +error.login=Đăng nhập Minecraft thất bại: +error.login.migrated=Tài khoản đã migrate, dùng địa chỉ email để đăng nhập. +error.login.server=Đăng nhập máy chủ không có sẵn. Hãy thử lại sau. +error.login.blocked=Sai mật khẩu, IP bị chặn hoặc quá nhiều lượt đăng nhập +error.login.response=Invalid server response. +error.login.premium=User not premium. +error.login.network=Network error. +error.login.ssl=SSL Error. +error.login.unknown=Unknown Error. +error.login.ssl_help=§8It appears that you are using Mono to run this program.\nThe first time, you have to import HTTPS certificates using:\nmozroots --import --ask-remove +error.login.cancel=User cancelled. +error.login_failed=Failed to login to this server. +error.join=Failed to join this server. +error.connect=Failed to connect to this IP. +error.timeout=Connection Timeout +error.unexpect_response=§8Unexpected response from the server (is that a Minecraft server?) +error.invalid_response=§8Invalid response to Handshake packet +error.invalid_encrypt=§8Invalid response to StartEncryption packet +error.version_different=§8Server reports a different version than manually set. Login may not work. +error.no_version_report=§8Server does not report its protocol version, autodetection will not work. +error.connection_timeout=§8A timeout occured while attempting to connect to this IP. +error.forge=§8Forge Login Handshake did not complete successfully +error.forge_encrypt=§8Forge StartEncryption Handshake did not complete successfully +error.setting.str2int=Failed to convert '{0}' into an int. Please check your settings. +error.setting.argument_syntax={0}: Invalid syntax, expecting --argname=value or --section.argname=value +error.setting.unknown_section={0}: Unknown setting section '{1}' +error.setting.unknown_or_invalid={0}: Unknown setting or invalid value +error.http_code=§8Got error code from server: {0} +error.auth=§8Got error code from server while refreshing authentication: {0} +error.realms.ip_error=Cannot retrieve the server IP of your Realms world +error.realms.access_denied=This Realms world does not exist or access was denied +error.realms.server_unavailable=Realms server may require some time to start up. Please retry again later. +error.realms.server_id=Invalid or unknown Realms server ID. +error.realms.disabled=Trying to join a Realms world but Realms support is disabled in config + +[internal command] +# MCC internal help command +icmd.help=help : show brief help about a command. +icmd.unknown=Unknown command '{0}'. Use 'help' for command list. +icmd.list=help . Available commands: {0}. For server help, use '{1}send /help' instead. +icmd.error=OnInternalCommand: Got error from {0}: {1} + +[exception] +# Exception messages threw by MCC +exception.user_logout=User-initiated logout should be done by calling Disconnect() +exception.unknown_direction=Unknown direction +exception.palette.block=Please update block types handling for this Minecraft version. See Material.cs +exception.palette.entity=Please update entity types handling for this Minecraft version. See EntityType.cs +exception.palette.item=Please update item types handling for this Minecraft version. See ItemType.cs +exception.palette.packet=Please update packet type palette for this Minecraft version. See PacketTypePalette.cs +exception.packet_process=Failed to process incoming packet of type {0}. (PacketID: {1}, Protocol: {2}, LoginPhase: {3}, InnerException: {4}). +exception.version_unsupport=The protocol version no.{0} is not supported. +exception.chatbot.init=ChatBot methods should NOT be called in the constructor as API handler is not initialized yet. Override Initialize() or AfterGameJoined() instead to perform initialization tasks. +exception.csrunner.invalid_head=The provided script does not have a valid MCCScript header + +[chatbot] +# ChatBot API +chatbot.reconnect=[{0}] Disconnecting and Reconnecting to the Server + +[filemonitor] +# FileMonitor +filemonitor.init=§8[{0}] Initializing FileSystemWatcher for file: {1} +filemonitor.fail=§8[{0}] Failed to initialize FileSystemWatcher, retrying using Polling + +[extra] +# Inventory, Terrain & Movements, Entity related messages +# Terrain & Movements +extra.terrainandmovement_enabled=Terrain and Movements is now enabled. +extra.terrainandmovement_disabled=§cTerrain & Movements currently not handled for that MC version. +extra.terrainandmovement_required=Please enable Terrain and Movements in the config file first. +# Inventory +extra.inventory_enabled=Inventory handling is now enabled. +extra.inventory_disabled=§cInventories are currently not handled for that MC version. +extra.inventory_required=Please enable InventoryHandling in the config file first. +extra.inventory_interact=Use /inventory to interact with it. +extra.inventory_open=Inventory # {0} opened: {1} +extra.inventory_close=Inventory # {0} closed. +# Entity +extra.entity_disabled=§cEntities are currently not handled for that MC version. +extra.entity_required=Please enable EntityHandling in the config file first. + + +[forge] +# Messages from Forge handler +forge.version=§8Forge protocol version : {0} +forge.send_mod=§8Sending falsified mod list to server... +forge.accept=§8Accepting server mod list... +forge.registry=§8Received registry with {0} entries +forge.registry_2=§8Received registry {0} with {1} entries +forge.accept_registry=§8Accepting server registries... +forge.complete=Forge server connection complete! +forge.with_mod=§8Server is running Forge with {0} mods. +forge.no_mod=§8Server is running Forge without mods. +forge.mod_list=§8Mod list: +# FML2 +forge.fml2.mod=§8Received FML2 Server Mod List +forge.fml2.mod_send=§8Sending back FML2 Client Mod List +forge.fml2.registry=§8Acknowledging FML2 Server Registry: {0} +forge.fml2.config=§8Acknowledging FML2 Server Config: {0} +forge.fml2.unknown=§8Got Unknown FML2 Handshake message no. {0} +forge.fml2.unknown_channel=§8Ignoring Unknown FML2 LoginMessage channel: {0} + +[cache] +# Session Cache +cache.loading=§8Loading Minecraft profiles: {0} +cache.loaded=§8Loaded session: {0}:{1} +cache.converting=§8Converting session cache from disk: {0} +cache.read_fail=§8Failed to read serialized session cache from disk: {0} +cache.malformed=§8Got malformed data while reading serialized session cache from disk: {0} +cache.loading_session=§8Loading session cache from disk: {0} +cache.ignore_string=§8Ignoring session token string '{0}': {1} +cache.ignore_line=§8Ignoring invalid session token line: {0} +cache.read_fail_plain=§8Failed to read session cache from disk: {0} +cache.saving=§8Saving session cache to disk +cache.save_fail=§8Failed to write session cache to disk: {0} + +[proxy] +proxy.connected=§8Connected to proxy {0}:{1} + +[chat] +# Chat Parser +chat.download=§8Downloading '{0}.lang' from Mojang servers... +chat.request=§8Performing request to {0} +chat.done=§8Done. File saved as '{0}' +chat.fail=§8Failed to download the file. +chat.from_dir=§8Defaulting to en_GB.lang from your Minecraft directory. +chat.loaded=§8Translations file loaded. +chat.not_found=§8Translations file not found: '{0}'\nSome messages won't be properly printed without this file. + +[general] +# General message/information (i.e. Done) +general.done=Done +general.fail=Fail +general.bot_unload=This bot will be unloaded. +general.available_cmd=Available commands: {0} + + +[cmd] +# Commands. Naming style: cmd.. + +# Animation +cmd.animation.desc=Swing your arm. + +# ChangeSlot +cmd.changeSlot.desc=Change hotbar +cmd.changeSlot.nan=Could not change slot: Not a Number +cmd.changeSlot.changed=Changed to slot {0} +cmd.changeSlot.fail=Could not change slot + +# Connect +cmd.connect.desc=connect to the specified server. +cmd.connect.unknown=Unknown account '{0}'. +cmd.connect.invalid_ip=Invalid server IP '{0}'. + +# Debug +cmd.debug.desc=toggle debug messages. +cmd.debug.state_on=Debug messages are now ON +cmd.debug.state_off=Debug messages are now OFF + +# Dig +cmd.dig.desc=attempt to break a block +cmd.dig.too_far=You are too far away from this block. +cmd.dig.no_block=No block at this location (Air) +cmd.dig.dig=Attempting to dig block at {0} {1} {2} +cmd.dig.fail=Failed to start digging block. + +# Entitycmd +cmd.entityCmd.attacked=Entity attacked +cmd.entityCmd.used=Entity used +cmd.entityCmd.not_found=Entity not found + +cmd.entityCmd.entity=Entity +cmd.entityCmd.entities=Entities +cmd.entityCmd.nickname=Nickname +cmd.entityCmd.customname=Custom Name +cmd.entityCmd.latency=Latency +cmd.entityCmd.item=Item +cmd.entityCmd.equipment=Equipment +cmd.entityCmd.mainhand=Main Hand +cmd.entityCmd.offhane=Off Hand +cmd.entityCmd.helmet=Helmet +cmd.entityCmd.chestplate=Chestplate +cmd.entityCmd.leggings=Leggings +cmd.entityCmd.boots=Boots +cmd.entityCmd.pose=Pose +cmd.entityCmd.health=Health +cmd.entityCmd.distance=Distance +cmd.entityCmd.location=Location +cmd.entityCmd.type=Type + +# Exit +cmd.exit.desc=disconnect from the server. + +# Health +cmd.health.desc=Display Health and Food saturation. +cmd.health.response=Health: {0}, Saturation: {1}, Level: {2}, TotalExperience: {3} + +# Inventory +cmd.inventory.desc=Inventory command +cmd.inventory.creative_done=Requested {0} x{1} in slot #{2} +cmd.inventory.creative_delete=Requested to clear slot #{0} +cmd.inventory.creative_fail=Failed to request Creative action +cmd.inventory.need_creative=You must be in Creative gamemode +cmd.inventory.container_not_found=Cannot find container, please retry with explicit ID +cmd.inventory.close=Closing Inventoy #{0} +cmd.inventory.close_fail=Failed to close Inventory #{0} +cmd.inventory.not_exist=Inventory #{0} do not exist +cmd.inventory.inventory=Inventory +cmd.inventory.inventories=Inventories +cmd.inventory.hotbar=Your selected hotbar is {0} +cmd.inventory.damage=Damage +cmd.inventory.left=Left +cmd.inventory.right=Right +cmd.inventory.middle=Middle +cmd.inventory.clicking={0} clicking slot {1} in window #{2} +cmd.inventory.no_item=No item in slot #{0} +cmd.inventory.drop=Dropped 1 item from slot #{0} +cmd.inventory.drop_stack=Dropped whole item stack from slot #{0} +# Inventory Help +cmd.inventory.help.basic=Basic usage +cmd.inventory.help.available=Available actions +cmd.inventory.help.help={0}\nUse '/inventory help ' for action help.\n'player' and 'container' can be simplified to 'p' and 'c'.\nNote that parameters in '[]' are optional. +cmd.inventory.help.usage=Usage +cmd.inventory.help.list=List your inventory. +cmd.inventory.help.close=Close an opened container. +cmd.inventory.help.click=Click on an item. +cmd.inventory.help.drop=Drop an item from inventory. +cmd.inventory.help.creativegive=Give item in creative mode. +cmd.inventory.help.creativedelete=Clear slot in creative mode. +cmd.inventory.help.unknown=Unknown action. + +# List +cmd.list.desc=get the player list. +cmd.list.players=PlayerList: {0} + +# Log +cmd.log.desc=log some text to the console. + +# Look +cmd.look.desc=look at direction or coordinates. +cmd.look.unknown=Unknown direction '{0}' +cmd.look.at=Looking at YAW: {0} PITCH: {1} +cmd.look.block=Looking at {0} + +# Move +cmd.move.desc=walk or start walking. +cmd.move.enable=Enabling Terrain and Movements on next server login, respawn or world change. +cmd.move.disable=Disabling Terrain and Movements. +cmd.move.moving=Moving {0} +cmd.move.dir_fail=Cannot move in that direction. +cmd.move.walk=Walking to {0} +cmd.move.fail=Failed to compute path to {0} + +# Reco +cmd.reco.desc=restart and reconnect to the server. + +# Respawn +cmd.respawn.desc=Use this to respawn if you are dead. +cmd.respawn.done=You have respawned. + +# Script +cmd.script.desc=run a script file. + +# Send +cmd.send.desc=send a chat message or command. + +# Set +cmd.set.desc=set a custom %variable%. +cmd.set.format=variable name must be A-Za-z0-9. + +# Sneak +cmd.sneak.desc=Toggles sneaking +cmd.sneak.on=You are sneaking now +cmd.sneak.off=You aren't sneaking anymore + +# DropItem +cmd.dropItem.desc=Drop specified type of items from player inventory or opened container +cmd.dropItem.dropped=Dropped all {0} from inventory #{1} +cmd.dropItem.unknown_item=Unknown item {0} + +# Tps +cmd.tps.desc=Display server current tps (tick per second). May not be accurate +cmd.tps.current=Current tps + +# Useblock +cmd.useblock.desc=Place a block or open chest + +# Useitem +cmd.useitem.desc=Use (left click) an item on the hand +cmd.useitem.use=Used an item + + +[bot] +# ChatBots. Naming style: bot.. + +# AutoAttack +bot.autoAttack.mode=Unknown attack mode: {0}. Using single mode as default. +bot.autoAttack.priority=Unknown priority: {0}. Using distance priority as default. +bot.autoAttack.invalidcooldown=Attack cooldown value cannot be smaller than 0. Using auto as default + +# AutoCraft +bot.autoCraft.cmd=Auto-crafting ChatBot command +bot.autoCraft.alias=Auto-crafting ChatBot command alias +bot.autoCraft.cmd.list=Total {0} recipes loaded: {1} +bot.autoCraft.cmd.resetcfg=Resetting your config to default +bot.autoCraft.recipe_not_exist=Specified recipe name does not exist. Check your config file. +bot.autoCraft.no_recipe_name=Please specify the recipe name you want to craft. +bot.autoCraft.stop=AutoCraft stopped +bot.autoCraft.available_cmd=Available commands: {0}. Use /autocraft help for more information. You may use /ac as command alias. +bot.autoCraft.help.load=Load the config file. +bot.autoCraft.help.list=List loaded recipes name. +bot.autoCraft.help.reload=Reload the config file. +bot.autoCraft.help.resetcfg=Write the default example config to default location. +bot.autoCraft.help.start=Start the crafting. Usage: /autocraft start +bot.autoCraft.help.stop=Stop the current running crafting process +bot.autoCraft.help.help=Get the command description. Usage: /autocraft help +bot.autoCraft.loaded=Successfully loaded +bot.autoCraft.start=Starting AutoCraft: {0} +bot.autoCraft.start_fail=AutoCraft cannot be started. Check your available materials for crafting {0} +bot.autoCraft.table_not_found=table not found +bot.autoCraft.close_inventory=Inventory #{0} was closed by AutoCraft +bot.autoCraft.missing_material=Missing material: {0} +bot.autoCraft.aborted=Crafting aborted! Check your available materials. +bot.autoCraft.craft_fail=Crafting failed! Waiting for more materials +bot.autoCraft.timeout=Action timeout! Reason: {0} +bot.autoCraft.error.config=Error while parsing config: {0} +bot.autoCraft.exception.empty=Empty configuration file: {0} +bot.autoCraft.exception.invalid=Invalid configuration file: {0} +bot.autoCraft.exception.item_miss=Missing item in recipe: {0} +bot.autoCraft.exception.invalid_table=Invalid tablelocation format: {0} +bot.autoCraft.exception.item_name=Invalid item name in recipe {0} at {1} +bot.autoCraft.exception.name_miss=Missing recipe name while parsing a recipe +bot.autoCraft.exception.slot=Invalid slot field in recipe: {0} +bot.autoCraft.exception.duplicate=Duplicate recipe name specified: {0} +bot.autoCraft.debug.no_config=No config found. Writing a new one. + +# AutoDrop +bot.autoDrop.cmd=AutoDrop ChatBot command +bot.autoDrop.alias=AutoDrop ChatBot command alias +bot.autoDrop.on=AutoDrop enabled +bot.autoDrop.off=AutoDrop disabled +bot.autoDrop.added=Added item {0} +bot.autoDrop.incorrect_name=Incorrect item name {0}. Please try again +bot.autoDrop.removed=Removed item {0} +bot.autoDrop.not_in_list=Item not in the list +bot.autoDrop.no_item=No item in the list +bot.autoDrop.list=Total {0} in the list:\n {1} +bot.autoDrop.switched=Switched to {0} mode. +bot.autoDrop.unknown_mode=Unknwon mode. Available modes: Include, Exclude, Everything +bot.autoDrop.no_mode=Cannot read drop mode from config. Using include mode. +bot.autoDrop.no_inventory=Cannot find inventory {0}! + +# AutoFish +bot.autoFish.throw=Threw a fishing rod +bot.autoFish.caught=Caught a fish! +bot.autoFish.no_rod=No Fishing Rod on hand. Maybe broken? + +# AutoRelog +bot.autoRelog.launch=Launching with {0} reconnection attempts +bot.autoRelog.no_kick_msg=Initializing without a kick message file +bot.autoRelog.loading=Loading messages from file: {0} +bot.autoRelog.loaded=Loaded message: {0} +bot.autoRelog.not_found=File not found: {0} +bot.autoRelog.curr_dir=Current directory was: {0} +bot.autoRelog.ignore_user_logout=Disconnection initiated by User or MCC bot. Ignoring. +bot.autoRelog.disconnect_msg=Got disconnected with message: {0} +bot.autoRelog.reconnect_always=Ignoring kick message, reconnecting anyway. +bot.autoRelog.reconnect=Message contains '{0}'. Reconnecting. +bot.autoRelog.reconnect_ignore=Message not containing any defined keywords. Ignoring. +bot.autoRelog.wait=Waiting {0} seconds before reconnecting... + +# AutoRespond +bot.autoRespond.loading=Loading matches from '{0}' +bot.autoRespond.file_not_found=File not found: '{0}' +bot.autoRespond.loaded_match=Loaded match:\n{0} +bot.autoRespond.no_trigger=This match will never trigger:\n{0} +bot.autoRespond.no_action=No action for match:\n{0} +bot.autoRespond.match_run=Running action: {0} +bot.autoRespond.match=match: {0}\nregex: {1}\naction: {2}\nactionPrivate: {3}\nactionOther: {4}\nownersOnly: {5}\ncooldown: {6} + +# ChatLog +bot.chatLog.invalid_file=Path '{0}' contains invalid characters. + +# Mailer +bot.mailer.init=Initializing Mailer with settings: +bot.mailer.init.db= - Database File: {0} +bot.mailer.init.ignore= - Ignore List: {0} +bot.mailer.init.public= - Public Interactions: {0} +bot.mailer.init.max_mails= - Max Mails per Player: {0} +bot.mailer.init.db_size= - Max Database Size: {0} +bot.mailer.init.mail_retention= - Mail Retention: {0} + +bot.mailer.init_fail.db_size=Cannot enable Mailer: Max Database Size must be greater than zero. Please review the settings. +bot.mailer.init_fail.max_mails=Cannot enable Mailer: Max Mails per Player must be greater than zero. Please review the settings. +bot.mailer.init_fail.mail_retention=Cannot enable Mailer: Mail Retention must be greater than zero. Please review the settings. + +bot.mailer.create.db=Creating new database file: {0} +bot.mailer.create.ignore=Creating new ignore list: {0} +bot.mailer.load.db=Loading database file: {0} +bot.mailer.load.ignore=Loading ignore list: + +bot.mailer.cmd=mailer command + +bot.mailer.saving=Saving message: {0} +bot.mailer.user_ignored={0} is ignored! +bot.mailer.process_mails=Looking for mails to send @ {0} +bot.mailer.delivered=Delivered: {0} + +bot.mailer.cmd.getmails=--- Mails in database ---\n{0} +bot.mailer.cmd.getignored=--- Ignore list ---\n{0} +bot.mailer.cmd.ignore.added=Added {0} to the ignore list! +bot.mailer.cmd.ignore.removed=Removed {0} from the ignore list! +bot.mailer.cmd.ignore.invalid=Missing or invalid name. Usage: {0} +bot.mailer.cmd.help=See usage + +# ReplayCapture +bot.replayCapture.cmd=replay command +bot.replayCapture.created=Replay file created. +bot.replayCapture.stopped=Record stopped. +bot.replayCapture.restart=Record was stopped. Restart the program to start another record. + +# Script +bot.script.not_found=§8[MCC] [{0}] Cannot find script file: {1} +bot.script.file_not_found=File not found: '{0}' +bot.script.fail=Script '{0}' failed to run ({1}). +bot.script.pm.loaded=Script '{0}' loaded. + +# ScriptScheduler +bot.scriptScheduler.loading=Loading tasks from '{0}' +bot.scriptScheduler.not_found=File not found: '{0}' +bot.scriptScheduler.loaded_task=Loaded task:\n{0} +bot.scriptScheduler.no_trigger=This task will never trigger:\n{0} +bot.scriptScheduler.no_action=No action for task:\n{0} +bot.scriptScheduler.running_time=Time / Running action: {0} +bot.scriptScheduler.running_inverval=Interval / Running action: {0} +bot.scriptScheduler.running_login=Login / Running action: {0} +bot.scriptScheduler.task=triggeronfirstlogin: {0}\n triggeronlogin: {1}\n triggerontime: {2}\n triggeroninterval: {3}\n timevalue: {4}\n timeinterval: {5}\n action: {6} + +# TestBot +bot.testBot.told=Bot: {0} told me : {1} +bot.testBot.said=Bot: {0} said : {1} diff --git a/README-vi-vn.md b/README-vi-vn.md new file mode 100644 index 00000000..bdcda34c --- /dev/null +++ b/README-vi-vn.md @@ -0,0 +1,71 @@ +Minecraft Console Client +======================== + +[![GitHub Actions build status](https://github.com/MCCTeam/Minecraft-Console-Client/actions/workflows/build-and-release.yml/badge.svg)](https://github.com/MCCTeam/Minecraft-Console-Client/releases/latest) + +Minecraft Console Client (MCC) là một ứng dụng nhẹ cho phép bạn kết nối tới bất kì máy chủ Minecraft nào, gửi lệnh và nhận tin nhắn bằng một cách nhanh và dễ dàng mà không cần phải mở Minecraft. Nó cũng cung cấp nhiều hoạt động tự động mà bạn có thể bật để quản lý và nhiều mục đích khác. + +## Tải 🔽 + +Tải binary ngay tại [đây](https://github.com/MCCTeam/Minecraft-Console-Client/releases/latest). +File exe là .NET binary nên cũng có thể chạy được trên MacOS và Linux + +## Hướng dẫn sử dụng 📚 + +Hãy xem [file cài đặt mẫu](MinecraftClient/config/) có bao gồm hướng dẫn sử dụng [README](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/config#minecraft-console-client-user-manual). + +## Hỗ trợ 🙋 + +Hãy xem [README](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/config#minecraft-console-client-user-manual) và [Thảo luận](https://github.com/MCCTeam/Minecraft-Console-Client/discussions): Có thể câu hỏi của bạn sẽ được trả lời ở đây. Nếu không, hãy mở một [cuộc thảo luận mới](https://github.com/MCCTeam/Minecraft-Console-Client/discussions/new) và hỏi câu hỏi của bạn. Nếu bạn tìm thấy lỗi, hãy báo cáo chúng ở [khu vực vấn đề](https://github.com/MCCTeam/Minecraft-Console-Client/issues). + +## Giúp đỡ chúng tôi ❤️ + +Chúng tôi là một cộng đồng nhỏ nên chúng tôi cần giúp đỡ để cài đặt cập nhật cho những phiên bản mới hơn, sửa lỗi trong ứng dụng và mở rộng kế hoạch. Chúng tôi luôn tìm kiếm những người có động lục để đóng góp. Nếu bạn nghĩ đó có thể là bạn, hãy xem phần [issues](https://github.com/MCCTeam/Minecraft-Console-Client/issues?q=is%3Aissue+is%3Aopen+label%3Awaiting-for%3Acontributor) :) + +## Làm thế nào để đóng góp? 📝 + +Nếu bạn cảm thấy thích đóng góp cho Minecraft Console Client, tuyệt vời, chỉ cần fork repository này và nộp 1 cái pull request trên nhánh *Master*. MCC đang được phân phối bằng những phiên bản development (thường là ổn định) và chúng tôi không còn sử dụng nhánh *Indev*. + +## Dịch Minecraft Console Client 🌍 + +Nếu bạn muốn dịch Minecraft Console Client bằng một ngôn ngữ khác, hãy tải file mẫu này [ở đây](https://github.com/MCCTeam/Minecraft-Console-Client/tree/master/MinecraftClient/Resources/lang) hoặc chỉ cần fork repository này. Khi bạn xong với việc dịch, nộp 1 cái pull request hoặc gửi cho chúng tôi tại [khu vực vấn đề](https://github.com/MCCTeam/Minecraft-Console-Client/issues). + +Để sử dụng file dịch, hãy để nó trong thư mục `lang/mcc/` và chỉnh ngôn ngữ của bạn trong file `.ini` config. Bạn có thể tạo thư mục đó nếu không có. + +Để xem hướng dẫn đặt tên, hãy xem [bình luận này](https://github.com/MCCTeam/Minecraft-Console-Client/pull/1282#issuecomment-711150715). + +## Xây từ gốc 🏗️ + +_The recommended development environment is [Visual Studio](https://visualstudio.microsoft.com/). If you want to build the project without installing a development environment, you may also follow these instructions:_ + +First of all, get a [zip of source code](https://github.com/MCCTeam/Minecraft-Console-Client/archive/master.zip), extract it and navigate to the `MinecraftClient` folder. + +Edit `MinecraftClient.csproj` to set the Build target to `Release` on [line 4](https://github.com/MCCTeam/Minecraft-Console-Client/blob/master/MinecraftClient/MinecraftClient.csproj#L4): + +```xml +Release +``` + +### On Windows 🪟 + +1. Locate `MSBuild.exe` for .NET 4 inside `C:\Windows\Microsoft.NET\Framework\v4.X.XXXXX` +2. Drag and drop `MinecraftClient.csproj` over `MSBuild.exe` to launch the build +3. If the build succeeds, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release` + +### On Mac and Linux 🐧 + +1. Install the [Mono Framework](https://www.mono-project.com/download/stable/#download-lin) if not already installed +2. Run `msbuild MinecraftClient.csproj` in a terminal +3. If the build succeeds, you can find `MinecraftClient.exe` under `MinecraftClient\bin\Release` + +## License ⚖️ + +Unless specifically stated, the code is from the MCC Team or Contributors, and available under CDDL-1.0. Else, the license and original author are mentioned in source file headers. +The main terms of the CDDL-1.0 license are basically the following: + +- You may use the licensed code in whole or in part in any program you desire, regardless of the license of the program as a whole (or rather, as excluding the code you are borrowing). The program itself may be open or closed source, free or commercial. +- However, in all cases, any modifications, improvements, or additions to the CDDL code (any code that is referenced in direct modifications to the CDDL code is considered an addition to the CDDL code, and so is bound by this requirement; e.g. a modification of a math function to use a fast lookup table makes that table itself an addition to the CDDL code, regardless of whether it's in a source code file of its own) must be made publicly and freely available in source, under the CDDL license itself. +- In any program (source or binary) that uses CDDL code, recognition must be given to the source (either project or author) of the CDDL code. As well, modifications to the CDDL code (which must be distributed as source) may not remove notices indicating the ancestry of the code. + +More info at http://qstuff.blogspot.fr/2007/04/why-cddl.html +Full license at http://opensource.org/licenses/CDDL-1.0 From 7e2e90b9f213332cb9a8967d1cee64b8b1ea55d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=BE=D0=BC=D0=B0=20=D0=94=D0=B0=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= <35975332+Nekiplay@users.noreply.github.com> Date: Sat, 2 Apr 2022 21:28:05 +0500 Subject: [PATCH 06/18] Updated Russian Language (#1985) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated Russian Language Removed bad spaces Удалены лишние пробелы * Update ru.ini * Update MinecraftClient/Resources/lang/ru.ini --- MinecraftClient/Resources/lang/ru.ini | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/MinecraftClient/Resources/lang/ru.ini b/MinecraftClient/Resources/lang/ru.ini index f6117d6d..9478e4a9 100644 --- a/MinecraftClient/Resources/lang/ru.ini +++ b/MinecraftClient/Resources/lang/ru.ini @@ -2,14 +2,14 @@ # Messages from MCC itself mcc.login=Логин : mcc.login_basic_io=Пожалуйста, введите имя пользователя или email по вашему выбору. -mcc.password=Пароль : +mcc.password=Пароль: mcc.password_basic_io=Пожалуйста, введите пароль для {0}. -mcc.password_hidden=Пароль : {0} +mcc.password_hidden=Пароль: {0} mcc.offline=§8Вы выбрали запуск в автономном режиме. mcc.session_invalid=§8Кэшированная сессия недействительна или истекла. mcc.session_valid=§8Кэшированная сессия все еще действительна для {0}. mcc.connecting=Подключение к {0}... -mcc.ip=IP сервера : +mcc.ip=IP сервера: mcc.use_version=§8Используется Minecraft версии {0} (протокол v{1}) mcc.unknown_version=§8Неизвестная или не поддерживаемая версия MC {0}.\nПереключение в режим автоопределения. mcc.forge=Проверка, запущен ли на сервере Forge... @@ -20,7 +20,7 @@ mcc.not_found=§8Failed to perform SRV lookup for {0}\n{1}: {2} mcc.retrieve=Получение информации о сервере... mcc.restart=Перезапуск консольного клиента Minecraft... mcc.restart_delay=Ожидание {0} секунд перед перезапуском... -mcc.server_version=Версия сервера : +mcc.server_version=Версия сервера: mcc.disconnected=Не подключен ни к одному серверу. Используйте '{0}help' для получения справки. mcc.press_exit=Нажмите Enter, чтобы выйти из консольного клиента Minecraft. mcc.version_supported=Версия поддерживается.\nВойти в игру... @@ -28,15 +28,15 @@ mcc.single_cmd=§7Команда §8 {0} §7 отправлена. mcc.joined=Сервер был успешно подключен.\nType '{0}quit' для выхода из сервера. mcc.reconnect=Ожидание 5 секунд (осталось {0} попыток)... mcc.disconnect.lost=Соединение было потеряно. -mcc.disconnect.server=Отключен сервером : -mcc.disconnect.login=Войти не удалось : +mcc.disconnect.server=Отключен сервером: +mcc.disconnect.login=Войти не удалось: mcc.link=Ссылка: {0} mcc.player_dead_respawn=Вы мертвы. Автоматически возрождаетесь через 1 секунду. mcc.player_dead=Вы мертвы. Введите /respawn, чтобы возродиться. mcc.server_offline=§8Сервер находится в автономном режиме. mcc.session=Проверка сессии... mcc.session_fail=Не удалось проверить сессию. -mcc.server_protocol=§8Версия сервера : {0} (протокол v{1}) +mcc.server_protocol=§8Версия сервера: {0} (протокол v{1}) mcc.with_forge=, с Forge mcc.handshake=§8Handshake successful. (ID сервера: {0}) mcc.realms_available=У вас есть доступ к следующим мирам Realms @@ -498,4 +498,4 @@ bot.scriptScheduler.task=triggeronfirstlogin: {0}\n triggeronlogin: {1}\n trigge # TestBot bot.testBot.told=Bot: {0} сказал мне : {1} -bot.testBot.said=Бот: {0} сказал : {1} \ No newline at end of file +bot.testBot.said=Бот: {0} сказал: {1} From f77a06e8ec55125f86e636a4d69ef0b7a3363ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B3=A0=E8=BE=B0?= <93849805+Crsuh2er0@users.noreply.github.com> Date: Sun, 3 Apr 2022 01:23:26 +0800 Subject: [PATCH 07/18] Update and improve translation. (#1987) --- MinecraftClient/Resources/lang/zh-CHS.ini | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/MinecraftClient/Resources/lang/zh-CHS.ini b/MinecraftClient/Resources/lang/zh-CHS.ini index b9ab65f6..99a7b21e 100644 --- a/MinecraftClient/Resources/lang/zh-CHS.ini +++ b/MinecraftClient/Resources/lang/zh-CHS.ini @@ -309,8 +309,10 @@ cmd.move.disable=禁用地形和移动。 cmd.move.moving=移动{0} cmd.move.dir_fail=不能朝此方向移动。 cmd.move.walk=移动到{0} -cmd.move.fail=无法计算到达{0}的路径 +cmd.move.fail=无法计算到达{0}的路径。 cmd.move.suggestforce=无法计算安全到达{0}的路径. 请使用 -f 参数允许不安全移动。 +cmd.move.gravity.enabled=重力已开启。 +cmd.move.gravity.disabled=重力已关闭。 # Reco cmd.reco.desc=重新启动并重新连接到服务器。 @@ -336,8 +338,8 @@ cmd.setrndstr.format=setrnd 变量名 字符串1 "\"字符串2\" 字符串3" # Sneak cmd.sneak.desc=切换到潜行 -cmd.sneak.on=现在你在潜行状态 -cmd.sneak.off=你不在潜行状态了 +cmd.sneak.on=现在你在潜行状态。 +cmd.sneak.off=你不在潜行状态了。 # DropItem cmd.dropItem.desc=丢弃玩家物品栏中的指定类型物品或打开的容器 @@ -345,7 +347,7 @@ cmd.dropItem.dropped=已从物品栏#{1}中丢弃所有{0} cmd.dropItem.unknown_item=未知物品:{0} # Tps -cmd.tps.desc=显示服务器当前tps (tick per second)。可能不精确 +cmd.tps.desc=显示服务器当前tps (tick per second)。(可能不精确) cmd.tps.current=当前TPS # Useblock @@ -353,7 +355,7 @@ cmd.useblock.desc=放置一个方块或打开箱子 # Useitem cmd.useitem.desc=使用(左键单击)手上的物品 -cmd.useitem.use=使用了一个物品 +cmd.useitem.use=使用了一个物品。 [bot] From 17dbe10ff3c3fc344e7f6bfa82607340eebeb005 Mon Sep 17 00:00:00 2001 From: ReinforceZwei <39955851+ReinforceZwei@users.noreply.github.com> Date: Wed, 6 Apr 2022 20:28:46 +0800 Subject: [PATCH 08/18] Settings: Make Microsoft as default account type --- MinecraftClient/Resources/config/MinecraftClient.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MinecraftClient/Resources/config/MinecraftClient.ini b/MinecraftClient/Resources/config/MinecraftClient.ini index b3f06176..2faf57f3 100644 --- a/MinecraftClient/Resources/config/MinecraftClient.ini +++ b/MinecraftClient/Resources/config/MinecraftClient.ini @@ -13,7 +13,7 @@ login= password= serverip= -type=mojang # Account type. mojang or microsoft. Also affects interactive login in console. +type=microsoft # Account type. mojang or microsoft. Also affects interactive login in console. method=mcc # Microsoft Account sign-in method. mcc OR browser # Advanced settings From d6220ff779ec221e705dbc7739a20e56e494a45c Mon Sep 17 00:00:00 2001 From: ORelio Date: Sat, 23 Apr 2022 11:50:43 +0200 Subject: [PATCH 09/18] Fix potentual issue with location != operator --- MinecraftClient/Mapping/Location.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Mapping/Location.cs b/MinecraftClient/Mapping/Location.cs index df780573..00f18071 100644 --- a/MinecraftClient/Mapping/Location.cs +++ b/MinecraftClient/Mapping/Location.cs @@ -200,9 +200,9 @@ namespace MinecraftClient.Mapping public static bool operator !=(Location loc1, Location loc2) { if (loc1 == null && loc2 == null) - return true; - if (loc1 == null || loc2 == null) return false; + if (loc1 == null || loc2 == null) + return true; return !loc1.Equals(loc2); } From aeca6a8f533ebebbc78ac63957be5a4420f87562 Mon Sep 17 00:00:00 2001 From: ORelio Date: Sat, 23 Apr 2022 12:00:50 +0200 Subject: [PATCH 10/18] Add thead safety to terrain data (#1999) Allow safely reading terrain data from other threads --- MinecraftClient/Mapping/Chunk.cs | 28 +++++++++- MinecraftClient/Mapping/ChunkColumn.cs | 26 +++++++++- MinecraftClient/Mapping/World.cs | 72 ++++++++++++++++++-------- 3 files changed, 101 insertions(+), 25 deletions(-) diff --git a/MinecraftClient/Mapping/Chunk.cs b/MinecraftClient/Mapping/Chunk.cs index 5b84ecf2..3ae88b73 100644 --- a/MinecraftClient/Mapping/Chunk.cs +++ b/MinecraftClient/Mapping/Chunk.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; namespace MinecraftClient.Mapping { @@ -19,6 +20,11 @@ namespace MinecraftClient.Mapping /// private readonly Block[,,] blocks = new Block[SizeX, SizeY, SizeZ]; + /// + /// Lock for thread safety + /// + private readonly ReaderWriterLockSlim blockLock = new ReaderWriterLockSlim(); + /// /// Read, or set the specified block /// @@ -36,7 +42,16 @@ namespace MinecraftClient.Mapping throw new ArgumentOutOfRangeException("blockY", "Must be between 0 and " + (SizeY - 1) + " (inclusive)"); if (blockZ < 0 || blockZ >= SizeZ) throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)"); - return blocks[blockX, blockY, blockZ]; + + blockLock.EnterReadLock(); + try + { + return blocks[blockX, blockY, blockZ]; + } + finally + { + blockLock.ExitReadLock(); + } } set { @@ -46,7 +61,16 @@ namespace MinecraftClient.Mapping throw new ArgumentOutOfRangeException("blockY", "Must be between 0 and " + (SizeY - 1) + " (inclusive)"); if (blockZ < 0 || blockZ >= SizeZ) throw new ArgumentOutOfRangeException("blockZ", "Must be between 0 and " + (SizeZ - 1) + " (inclusive)"); - blocks[blockX, blockY, blockZ] = value; + + blockLock.EnterWriteLock(); + try + { + blocks[blockX, blockY, blockZ] = value; + } + finally + { + blockLock.ExitWriteLock(); + } } } diff --git a/MinecraftClient/Mapping/ChunkColumn.cs b/MinecraftClient/Mapping/ChunkColumn.cs index 007bdb22..22c9d2ae 100644 --- a/MinecraftClient/Mapping/ChunkColumn.cs +++ b/MinecraftClient/Mapping/ChunkColumn.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; namespace MinecraftClient.Mapping { @@ -17,6 +18,11 @@ namespace MinecraftClient.Mapping /// private readonly Chunk[] chunks = new Chunk[ColumnSize]; + /// + /// Lock for thread safety + /// + private readonly ReaderWriterLockSlim chunkLock = new ReaderWriterLockSlim(); + /// /// Get or set the specified chunk column /// @@ -27,11 +33,27 @@ namespace MinecraftClient.Mapping { get { - return chunks[chunkY]; + chunkLock.EnterReadLock(); + try + { + return chunks[chunkY]; + } + finally + { + chunkLock.ExitReadLock(); + } } set { - chunks[chunkY] = value; + chunkLock.EnterWriteLock(); + try + { + chunks[chunkY] = value; + } + finally + { + chunkLock.ExitWriteLock(); + } } } diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs index 55ceaa75..9a57baae 100644 --- a/MinecraftClient/Mapping/World.cs +++ b/MinecraftClient/Mapping/World.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; namespace MinecraftClient.Mapping { @@ -15,6 +16,11 @@ namespace MinecraftClient.Mapping /// private Dictionary> chunks = new Dictionary>(); + /// + /// Lock for thread safety + /// + private readonly ReaderWriterLockSlim chunksLock = new ReaderWriterLockSlim(); + /// /// Read, set or unload the specified chunk column /// @@ -25,34 +31,50 @@ namespace MinecraftClient.Mapping { get { - //Read a chunk - if (chunks.ContainsKey(chunkX)) - if (chunks[chunkX].ContainsKey(chunkZ)) - return chunks[chunkX][chunkZ]; - return null; + chunksLock.EnterReadLock(); + try + { + //Read a chunk + if (chunks.ContainsKey(chunkX)) + if (chunks[chunkX].ContainsKey(chunkZ)) + return chunks[chunkX][chunkZ]; + return null; + } + finally + { + chunksLock.ExitReadLock(); + } } set { - if (value != null) + chunksLock.EnterWriteLock(); + try { - //Update a chunk column - if (!chunks.ContainsKey(chunkX)) - chunks[chunkX] = new Dictionary(); - chunks[chunkX][chunkZ] = value; - } - else - { - //Unload a chunk column - if (chunks.ContainsKey(chunkX)) + if (value != null) { - if (chunks[chunkX].ContainsKey(chunkZ)) + //Update a chunk column + if (!chunks.ContainsKey(chunkX)) + chunks[chunkX] = new Dictionary(); + chunks[chunkX][chunkZ] = value; + } + else + { + //Unload a chunk column + if (chunks.ContainsKey(chunkX)) { - chunks[chunkX].Remove(chunkZ); - if (chunks[chunkX].Count == 0) - chunks.Remove(chunkX); + if (chunks[chunkX].ContainsKey(chunkZ)) + { + chunks[chunkX].Remove(chunkZ); + if (chunks[chunkX].Count == 0) + chunks.Remove(chunkX); + } } } } + finally + { + chunksLock.ExitWriteLock(); + } } } @@ -117,7 +139,7 @@ namespace MinecraftClient.Mapping { Location doneloc = new Location(x, y, z); Block doneblock = GetBlock(doneloc); - Material blockType = GetBlock(doneloc).Type; + Material blockType = doneblock.Type; if (blockType == block) { list.Add(doneloc); @@ -150,7 +172,15 @@ namespace MinecraftClient.Mapping /// public void Clear() { - chunks = new Dictionary>(); + chunksLock.EnterWriteLock(); + try + { + chunks = new Dictionary>(); + } + finally + { + chunksLock.ExitWriteLock(); + } } /// From 708815fe616ac99517261045aad21e4749865e9e Mon Sep 17 00:00:00 2001 From: Daenges <57369924+Daenges@users.noreply.github.com> Date: Fri, 29 Apr 2022 22:56:41 +0000 Subject: [PATCH 11/18] Improve pathfinding capabilities (#1999) * Add `ClientIsMoving()` API to determine if currently walking/falling * Improve `MoveToLocation()` performance and allow approaching location Co-authored-by: ORelio --- MinecraftClient/ChatBot.cs | 19 +++- MinecraftClient/Mapping/Movement.cs | 155 +++++++++++++++++++--------- MinecraftClient/McClient.cs | 17 ++- 3 files changed, 138 insertions(+), 53 deletions(-) diff --git a/MinecraftClient/ChatBot.cs b/MinecraftClient/ChatBot.cs index f1505ddb..3b37d98b 100644 --- a/MinecraftClient/ChatBot.cs +++ b/MinecraftClient/ChatBot.cs @@ -983,13 +983,26 @@ namespace MinecraftClient /// /// Location to reach /// Allow possible but unsafe locations thay may hurt the player: lava, cactus... - /// Allow non-vanilla teleport instead of computing path, but may cause invalid moves and/or trigger anti-cheat plugins + /// Allow non-vanilla direct teleport instead of computing path, but may cause invalid moves and/or trigger anti-cheat plugins + /// If no valid path can be found, also allow locations within specified distance of destination + /// Do not get closer of destination than specified distance + /// How long to wait before stopping computation (default: 5 seconds) + /// When location is unreachable, computation will reach timeout, then optionally fallback to a close location within maxOffset /// True if a path has been found - protected bool MoveToLocation(Mapping.Location location, bool allowUnsafe = false, bool allowDirectTeleport = false) + protected bool MoveToLocation(Mapping.Location location, bool allowUnsafe = false, bool allowDirectTeleport = false, int maxOffset = 0, int minOffset = 0, TimeSpan? timeout = null) { - return Handler.MoveTo(location, allowUnsafe, allowDirectTeleport); + return Handler.MoveTo(location, allowUnsafe, allowDirectTeleport, maxOffset, minOffset, timeout); } + /// + /// Check if the client is currently processing a Movement. + /// + /// true if a movement is currently handled + protected bool ClientIsMoving() + { + return Handler.ClientIsMoving(); + } + /// /// Look at the specified location /// diff --git a/MinecraftClient/Mapping/Movement.cs b/MinecraftClient/Mapping/Movement.cs index 6c947343..224454cd 100644 --- a/MinecraftClient/Mapping/Movement.cs +++ b/MinecraftClient/Mapping/Movement.cs @@ -1,7 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; +using System.Threading; +using System.Threading.Tasks; namespace MinecraftClient.Mapping { @@ -129,62 +130,120 @@ namespace MinecraftClient.Mapping /// Start location /// Destination location /// Allow possible but unsafe locations + /// If no valid path can be found, also allow locations within specified distance of destination + /// Do not get closer of destination than specified distance + /// How long to wait before stopping computation + /// When location is unreachable, computation will reach timeout, then optionally fallback to a close location within maxOffset /// A list of locations, or null if calculation failed - public static Queue CalculatePath(World world, Location start, Location goal, bool allowUnsafe = false) + public static Queue CalculatePath(World world, Location start, Location goal, bool allowUnsafe, int maxOffset, int minOffset, TimeSpan timeout) { - Queue result = null; - - AutoTimeout.Perform(() => + CancellationTokenSource cts = new CancellationTokenSource(); + Task> pathfindingTask = Task.Factory.StartNew(() => Movement.CalculatePath(world, start, goal, allowUnsafe, maxOffset, minOffset, cts.Token)); + pathfindingTask.Wait(timeout); + if (!pathfindingTask.IsCompleted) { - HashSet ClosedSet = new HashSet(); // The set of locations already evaluated. - HashSet OpenSet = new HashSet(new[] { start }); // The set of tentative nodes to be evaluated, initially containing the start node - Dictionary Came_From = new Dictionary(); // The map of navigated nodes. + cts.Cancel(); + pathfindingTask.Wait(); + } + return pathfindingTask.Result; + } - Dictionary g_score = new Dictionary(); //:= map with default value of Infinity - g_score[start] = 0; // Cost from start along best known path. - // Estimated total cost from start to goal through y. - Dictionary f_score = new Dictionary(); //:= map with default value of Infinity - f_score[start] = (int)start.DistanceSquared(goal); //heuristic_cost_estimate(start, goal) + /// + /// Calculate a path from the start location to the destination location + /// + /// + /// Based on the A* pathfinding algorithm described on Wikipedia + /// + /// + /// Start location + /// Destination location + /// Allow possible but unsafe locations + /// If no valid path can be found, also allow locations within specified distance of destination + /// Do not get closer of destination than specified distance + /// Token for stopping computation after a certain time + /// A list of locations, or null if calculation failed + public static Queue CalculatePath(World world, Location start, Location goal, bool allowUnsafe, int maxOffset, int minOffset, CancellationToken ct) + { - while (OpenSet.Count > 0) + if (minOffset > maxOffset) + throw new ArgumentException("minOffset must be lower or equal to maxOffset", "minOffset"); + + Location current = new Location(); // Location that is currently processed + Location closestGoal = new Location(); // Closest Location to the goal. Used for approaching if goal can not be reached or was not found. + HashSet ClosedSet = new HashSet(); // The set of locations already evaluated. + HashSet OpenSet = new HashSet(new[] { start }); // The set of tentative nodes to be evaluated, initially containing the start node + Dictionary Came_From = new Dictionary(); // The map of navigated nodes. + + Dictionary g_score = new Dictionary(); //:= map with default value of Infinity + g_score[start] = 0; // Cost from start along best known path. + // Estimated total cost from start to goal through y. + Dictionary f_score = new Dictionary(); //:= map with default value of Infinity + f_score[start] = (int)start.DistanceSquared(goal); //heuristic_cost_estimate(start, goal) + + while (OpenSet.Count > 0) + { + current = //the node in OpenSet having the lowest f_score[] value + OpenSet.Select(location => f_score.ContainsKey(location) + ? new KeyValuePair(location, f_score[location]) + : new KeyValuePair(location, int.MaxValue)) + .OrderBy(pair => pair.Value).First().Key; + + // Only assert a value if it is of actual use later + if (maxOffset > 0 && ClosedSet.Count > 0) + // Get the block that currently is closest to the goal + closestGoal = ClosedSet.OrderBy(checkedLocation => checkedLocation.DistanceSquared(goal)).First(); + + // Stop when goal is reached or we are close enough + if (current == goal || (minOffset > 0 && current.DistanceSquared(goal) <= minOffset)) + return ReconstructPath(Came_From, current); + else if (ct.IsCancellationRequested) + break; // Return if we are cancelled + + OpenSet.Remove(current); + ClosedSet.Add(current); + + foreach (Location neighbor in GetAvailableMoves(world, current, allowUnsafe)) { - Location current = //the node in OpenSet having the lowest f_score[] value - OpenSet.Select(location => f_score.ContainsKey(location) - ? new KeyValuePair(location, f_score[location]) - : new KeyValuePair(location, int.MaxValue)) - .OrderBy(pair => pair.Value).First().Key; - if (current == goal) - { //reconstruct_path(Came_From, goal) - List total_path = new List(new[] { current }); - while (Came_From.ContainsKey(current)) - { - current = Came_From[current]; - total_path.Add(current); - } - total_path.Reverse(); - result = new Queue(total_path); - } - OpenSet.Remove(current); - ClosedSet.Add(current); - foreach (Location neighbor in GetAvailableMoves(world, current, allowUnsafe)) - { - if (ClosedSet.Contains(neighbor)) - continue; // Ignore the neighbor which is already evaluated. - int tentative_g_score = g_score[current] + (int)current.DistanceSquared(neighbor); //dist_between(current,neighbor) // length of this path. - if (!OpenSet.Contains(neighbor)) // Discover a new node - OpenSet.Add(neighbor); - else if (tentative_g_score >= g_score[neighbor]) - continue; // This is not a better path. + if (ct.IsCancellationRequested) + break; // Stop searching for blocks if we are cancelled. + if (ClosedSet.Contains(neighbor)) + continue; // Ignore the neighbor which is already evaluated. + int tentative_g_score = g_score[current] + (int)current.DistanceSquared(neighbor); //dist_between(current,neighbor) // length of this path. + if (!OpenSet.Contains(neighbor)) // Discover a new node + OpenSet.Add(neighbor); + else if (tentative_g_score >= g_score[neighbor]) + continue; // This is not a better path. - // This path is the best until now. Record it! - Came_From[neighbor] = current; - g_score[neighbor] = tentative_g_score; - f_score[neighbor] = g_score[neighbor] + (int)neighbor.DistanceSquared(goal); //heuristic_cost_estimate(neighbor, goal) - } + // This path is the best until now. Record it! + Came_From[neighbor] = current; + g_score[neighbor] = tentative_g_score; + f_score[neighbor] = g_score[neighbor] + (int)neighbor.DistanceSquared(goal); //heuristic_cost_estimate(neighbor, goal) } - }, TimeSpan.FromSeconds(5)); + } - return result; + // Goal could not be reached. Set the path to the closest location if close enough + if (maxOffset == int.MaxValue || goal.DistanceSquared(closestGoal) <= maxOffset) + return ReconstructPath(Came_From, closestGoal); + else + return null; + } + + /// + /// Helper function for CalculatePath(). Backtrack from goal to start to reconstruct a step-by-step path. + /// + /// The collection of Locations that leads back to the start + /// Endpoint of our later walk + /// the path that leads to current from the start position + private static Queue ReconstructPath(Dictionary Came_From, Location current) + { + List total_path = new List(new[] { current }); + while (Came_From.ContainsKey(current)) + { + current = Came_From[current]; + total_path.Add(current); + } + total_path.Reverse(); + return new Queue(total_path); } /* ========= LOCATION PROPERTIES ========= */ diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index dfd149f5..94eda171 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -1061,8 +1061,12 @@ namespace MinecraftClient /// Location to reach /// Allow possible but unsafe locations thay may hurt the player: lava, cactus... /// Allow non-vanilla direct teleport instead of computing path, but may cause invalid moves and/or trigger anti-cheat plugins + /// If no valid path can be found, also allow locations within specified distance of destination + /// Do not get closer of destination than specified distance + /// How long to wait until the path is evaluated (default: 5 seconds) + /// When location is unreachable, computation will reach timeout, then optionally fallback to a close location within maxOffset /// True if a path has been found - public bool MoveTo(Location location, bool allowUnsafe = false, bool allowDirectTeleport = false) + public bool MoveTo(Location location, bool allowUnsafe = false, bool allowDirectTeleport = false, int maxOffset = 0, int minOffset = 0, TimeSpan? timeout=null) { lock (locationLock) { @@ -1078,7 +1082,7 @@ namespace MinecraftClient // Calculate path through pathfinding. Path contains a list of 1-block movement that will be divided into steps if (Movement.GetAvailableMoves(world, this.location, allowUnsafe).Contains(location)) path = new Queue(new[] { location }); - else path = Movement.CalculatePath(world, this.location, location, allowUnsafe); + else path = Movement.CalculatePath(world, this.location, location, allowUnsafe, maxOffset, minOffset, timeout ?? TimeSpan.FromSeconds(5)); return path != null; } } @@ -1847,6 +1851,15 @@ namespace MinecraftClient DispatchBotEvent(bot => bot.OnRespawn()); } + /// + /// Check if the client is currently processing a Movement. + /// + /// true if a movement is currently handled + public bool ClientIsMoving() + { + return terrainAndMovementsEnabled && locationReceived && ((steps != null && steps.Count > 0) || (path != null && path.Count > 0)); + } + /// /// Called when the server sends a new player location, /// or if a ChatBot whishes to update the player's location. From b3cc2351ee14d8e4fadc6f0e6115478872143c48 Mon Sep 17 00:00:00 2001 From: Daenges <57369924+Daenges@users.noreply.github.com> Date: Thu, 5 May 2022 18:05:05 +0000 Subject: [PATCH 12/18] CalculatePath: Fix offset calculation, improve approaching (#2013) * Square minOffset and maxOffset to match DistanceSquared * Rewrite squaring * Add minOffset * Implement h-score selection --- MinecraftClient/Mapping/Movement.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Mapping/Movement.cs b/MinecraftClient/Mapping/Movement.cs index 224454cd..fc66ca7a 100644 --- a/MinecraftClient/Mapping/Movement.cs +++ b/MinecraftClient/Mapping/Movement.cs @@ -167,6 +167,10 @@ namespace MinecraftClient.Mapping if (minOffset > maxOffset) throw new ArgumentException("minOffset must be lower or equal to maxOffset", "minOffset"); + + // We always use distance squared so our limits must also be squared. + minOffset *= minOffset; + maxOffset *= maxOffset; Location current = new Location(); // Location that is currently processed Location closestGoal = new Location(); // Closest Location to the goal. Used for approaching if goal can not be reached or was not found. @@ -186,8 +190,10 @@ namespace MinecraftClient.Mapping OpenSet.Select(location => f_score.ContainsKey(location) ? new KeyValuePair(location, f_score[location]) : new KeyValuePair(location, int.MaxValue)) - .OrderBy(pair => pair.Value).First().Key; - + .OrderBy(pair => pair.Value). + // Sort for h-score (f-score - g-score) to get smallest distance to goal if f-scores are equal + ThenBy(pair => f_score[pair.Key]-g_score[pair.Key]).First().Key; + // Only assert a value if it is of actual use later if (maxOffset > 0 && ClosedSet.Count > 0) // Get the block that currently is closest to the goal From 9d3357eeee1cceef7968d6769d333b0b79d394ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Milutinovi=C4=87?= Date: Tue, 28 Jun 2022 13:45:23 +0200 Subject: [PATCH 13/18] Fixed requested changes in the review. Except: Container (TODO) --- MinecraftClient/Inventory/ItemType.cs | 2 +- .../BlockPalettes/BlockPaletteGenerator.cs | 2 +- MinecraftClient/Mapping/EntityType.cs | 34 +- MinecraftClient/Mapping/Material.cs | 1760 ++++++++--------- MinecraftClient/Mapping/Material2Tool.cs | 40 +- MinecraftClient/Program.cs | 36 +- .../Protocol/Handlers/Protocol18.cs | 1726 ++++++++-------- MinecraftClient/Resources/lang/en.ini | 8 +- 8 files changed, 1809 insertions(+), 1799 deletions(-) diff --git a/MinecraftClient/Inventory/ItemType.cs b/MinecraftClient/Inventory/ItemType.cs index abb8ce58..062e93e3 100644 --- a/MinecraftClient/Inventory/ItemType.cs +++ b/MinecraftClient/Inventory/ItemType.cs @@ -1115,6 +1115,6 @@ namespace MinecraftClient.Inventory ZombieHorseSpawnEgg, ZombieSpawnEgg, ZombieVillagerSpawnEgg, - ZombifiedPiglinSpawnEgg + ZombifiedPiglinSpawnEgg, } } diff --git a/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs b/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs index e4563b7d..831b3abe 100644 --- a/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs +++ b/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs @@ -29,7 +29,7 @@ namespace MinecraftClient.Mapping.BlockPalettes /// path to blocks.json /// java -cp minecraft_server.jar net.minecraft.data.Main --reports /// state => block name mappings - public static void GenerateBlockPallete(string blocksJsonFile) + public static void GenerateBlockPalette(string blocksJsonFile) { BlockPaletteGenerator.JsonToClass(blocksJsonFile, "Palette", "Material"); } diff --git a/MinecraftClient/Mapping/EntityType.cs b/MinecraftClient/Mapping/EntityType.cs index 8f7678f1..a0368e98 100644 --- a/MinecraftClient/Mapping/EntityType.cs +++ b/MinecraftClient/Mapping/EntityType.cs @@ -24,26 +24,34 @@ namespace MinecraftClient.Mapping Boat, Cat, CaveSpider, + ChestMinecart, Chicken, Cod, + CommandBlockMinecart, Cow, Creeper, Dolphin, Donkey, DragonFireball, Drowned, + Egg, ElderGuardian, EndCrystal, EnderDragon, Enderman, Endermite, + EnderPearl, Evoker, EvokerFangs, + ExperienceBottle, ExperienceOrb, EyeOfEnder, FallingBlock, + Fireball, FireworkRocket, + FishingBobber, Fox, + FurnaceMinecart, Ghast, Giant, GlowItemFrame, @@ -51,13 +59,13 @@ namespace MinecraftClient.Mapping Goat, Guardian, Hoglin, + HopperMinecart, Horse, Husk, Illusioner, IronGolem, Item, ItemFrame, - Fireball, LeashKnot, LightningBolt, Llama, @@ -65,14 +73,8 @@ namespace MinecraftClient.Mapping MagmaCube, Marker, Minecart, - ChestMinecart, - CommandBlockMinecart, - FurnaceMinecart, - HopperMinecart, - SpawnerMinecart, - TntMinecart, - Mule, Mooshroom, + Mule, Ocelot, Painting, Panda, @@ -82,8 +84,9 @@ namespace MinecraftClient.Mapping Piglin, PiglinBrute, Pillager, + Player, PolarBear, - Tnt, + Potion, Pufferfish, Rabbit, Ravager, @@ -96,19 +99,18 @@ namespace MinecraftClient.Mapping SkeletonHorse, Slime, SmallFireball, - SnowGolem, Snowball, + SnowGolem, + SpawnerMinecart, SpectralArrow, Spider, Squid, Stray, Strider, - Egg, - EnderPearl, - ExperienceBottle, - Potion, - Trident, + Tnt, + TntMinecart, TraderLlama, + Trident, TropicalFish, Turtle, Vex, @@ -125,7 +127,5 @@ namespace MinecraftClient.Mapping ZombieHorse, ZombieVillager, ZombifiedPiglin, - Player, - FishingBobber, } } diff --git a/MinecraftClient/Mapping/Material.cs b/MinecraftClient/Mapping/Material.cs index 99c51a5b..ea5cc704 100644 --- a/MinecraftClient/Mapping/Material.cs +++ b/MinecraftClient/Mapping/Material.cs @@ -14,903 +14,903 @@ /// public enum Material { - Air, - Stone, - Granite, - PolishedGranite, - Diorite, - PolishedDiorite, - Andesite, - PolishedAndesite, - GrassBlock, - Dirt, - CoarseDirt, - Podzol, - Cobblestone, - OakPlanks, - SprucePlanks, - BirchPlanks, - JunglePlanks, - AcaciaPlanks, - DarkOakPlanks, - OakSapling, - SpruceSapling, - BirchSapling, - JungleSapling, - AcaciaSapling, - DarkOakSapling, - Bedrock, - Water, - Lava, - Sand, - RedSand, - Gravel, - GoldOre, - DeepslateGoldOre, - IronOre, - DeepslateIronOre, - CoalOre, - DeepslateCoalOre, - NetherGoldOre, - OakLog, - SpruceLog, - BirchLog, - JungleLog, - AcaciaLog, - DarkOakLog, - StrippedSpruceLog, - StrippedBirchLog, - StrippedJungleLog, - StrippedAcaciaLog, - StrippedDarkOakLog, - StrippedOakLog, - OakWood, - SpruceWood, - BirchWood, - JungleWood, - AcaciaWood, - DarkOakWood, - StrippedOakWood, - StrippedSpruceWood, - StrippedBirchWood, - StrippedJungleWood, - StrippedAcaciaWood, - StrippedDarkOakWood, - OakLeaves, - SpruceLeaves, - BirchLeaves, - JungleLeaves, - AcaciaLeaves, - DarkOakLeaves, - AzaleaLeaves, - FloweringAzaleaLeaves, - Sponge, - WetSponge, - Glass, - LapisOre, - DeepslateLapisOre, - LapisBlock, - Dispenser, - Sandstone, - ChiseledSandstone, - CutSandstone, - NoteBlock, - WhiteBed, - OrangeBed, - MagentaBed, - LightBlueBed, - YellowBed, - LimeBed, - PinkBed, - GrayBed, - LightGrayBed, - CyanBed, - PurpleBed, - BlueBed, - BrownBed, - GreenBed, - RedBed, - BlackBed, - PoweredRail, - DetectorRail, - StickyPiston, - Cobweb, - Grass, - Fern, - DeadBush, - Seagrass, - TallSeagrass, - Piston, - PistonHead, - WhiteWool, - OrangeWool, - MagentaWool, - LightBlueWool, - YellowWool, - LimeWool, - PinkWool, - GrayWool, - LightGrayWool, - CyanWool, - PurpleWool, - BlueWool, - BrownWool, - GreenWool, - RedWool, - BlackWool, - MovingPiston, - Dandelion, - Poppy, - BlueOrchid, - Allium, - AzureBluet, - RedTulip, - OrangeTulip, - WhiteTulip, - PinkTulip, - OxeyeDaisy, - Cornflower, - WitherRose, - LilyOfTheValley, - BrownMushroom, - RedMushroom, - GoldBlock, - IronBlock, - Bricks, - Tnt, - Bookshelf, - MossyCobblestone, - Obsidian, - Torch, - WallTorch, - Fire, - SoulFire, - Spawner, - OakStairs, - Chest, - RedstoneWire, - DiamondOre, - DeepslateDiamondOre, - DiamondBlock, - CraftingTable, - Wheat, - Farmland, - Furnace, - OakSign, - SpruceSign, - BirchSign, - AcaciaSign, - JungleSign, - DarkOakSign, - OakDoor, - Ladder, - Rail, - CobblestoneStairs, - OakWallSign, - SpruceWallSign, - BirchWallSign, - AcaciaWallSign, - JungleWallSign, - DarkOakWallSign, - Lever, - StonePressurePlate, - IronDoor, - OakPressurePlate, - SprucePressurePlate, - BirchPressurePlate, - JunglePressurePlate, - AcaciaPressurePlate, - DarkOakPressurePlate, - RedstoneOre, - DeepslateRedstoneOre, - RedstoneTorch, - RedstoneWallTorch, - StoneButton, - Snow, - Ice, - SnowBlock, - Cactus, - Clay, - SugarCane, - Jukebox, - OakFence, - Pumpkin, - Netherrack, - SoulSand, - SoulSoil, - Basalt, - PolishedBasalt, - SoulTorch, - SoulWallTorch, - Glowstone, - NetherPortal, - CarvedPumpkin, - JackOLantern, - Cake, - Repeater, - WhiteStainedGlass, - OrangeStainedGlass, - MagentaStainedGlass, - LightBlueStainedGlass, - YellowStainedGlass, - LimeStainedGlass, - PinkStainedGlass, - GrayStainedGlass, - LightGrayStainedGlass, - CyanStainedGlass, - PurpleStainedGlass, - BlueStainedGlass, - BrownStainedGlass, - GreenStainedGlass, - RedStainedGlass, - BlackStainedGlass, - OakTrapdoor, - SpruceTrapdoor, - BirchTrapdoor, - JungleTrapdoor, - AcaciaTrapdoor, - DarkOakTrapdoor, - StoneBricks, - MossyStoneBricks, - CrackedStoneBricks, - ChiseledStoneBricks, - InfestedStone, - InfestedCobblestone, - InfestedStoneBricks, - InfestedMossyStoneBricks, - InfestedCrackedStoneBricks, - InfestedChiseledStoneBricks, - BrownMushroomBlock, - RedMushroomBlock, - MushroomStem, - IronBars, - Chain, - GlassPane, - Melon, - AttachedPumpkinStem, - AttachedMelonStem, - PumpkinStem, - MelonStem, - Vine, - GlowLichen, - OakFenceGate, - BrickStairs, - StoneBrickStairs, - Mycelium, - LilyPad, - NetherBricks, - NetherBrickFence, - NetherBrickStairs, - NetherWart, - EnchantingTable, - BrewingStand, - Cauldron, - WaterCauldron, - LavaCauldron, - PowderSnowCauldron, - EndPortal, - EndPortalFrame, - EndStone, - DragonEgg, - RedstoneLamp, - Cocoa, - SandstoneStairs, - EmeraldOre, - DeepslateEmeraldOre, - EnderChest, - TripwireHook, - Tripwire, - EmeraldBlock, - SpruceStairs, - BirchStairs, - JungleStairs, - CommandBlock, - Beacon, - CobblestoneWall, - MossyCobblestoneWall, - FlowerPot, - PottedOakSapling, - PottedSpruceSapling, - PottedBirchSapling, - PottedJungleSapling, - PottedAcaciaSapling, - PottedDarkOakSapling, - PottedFern, - PottedDandelion, - PottedPoppy, - PottedBlueOrchid, - PottedAllium, - PottedAzureBluet, - PottedRedTulip, - PottedOrangeTulip, - PottedWhiteTulip, - PottedPinkTulip, - PottedOxeyeDaisy, - PottedCornflower, - PottedLilyOfTheValley, - PottedWitherRose, - PottedRedMushroom, - PottedBrownMushroom, - PottedDeadBush, - PottedCactus, - Carrots, - Potatoes, - OakButton, - SpruceButton, - BirchButton, - JungleButton, AcaciaButton, - DarkOakButton, - SkeletonSkull, - SkeletonWallSkull, - WitherSkeletonSkull, - WitherSkeletonWallSkull, - ZombieHead, - ZombieWallHead, - PlayerHead, - PlayerWallHead, - CreeperHead, - CreeperWallHead, - DragonHead, - DragonWallHead, - Anvil, - ChippedAnvil, - DamagedAnvil, - TrappedChest, - LightWeightedPressurePlate, - HeavyWeightedPressurePlate, - Comparator, - DaylightDetector, - RedstoneBlock, - NetherQuartzOre, - Hopper, - QuartzBlock, - ChiseledQuartzBlock, - QuartzPillar, - QuartzStairs, - ActivatorRail, - Dropper, - WhiteTerracotta, - OrangeTerracotta, - MagentaTerracotta, - LightBlueTerracotta, - YellowTerracotta, - LimeTerracotta, - PinkTerracotta, - GrayTerracotta, - LightGrayTerracotta, - CyanTerracotta, - PurpleTerracotta, - BlueTerracotta, - BrownTerracotta, - GreenTerracotta, - RedTerracotta, - BlackTerracotta, - WhiteStainedGlassPane, - OrangeStainedGlassPane, - MagentaStainedGlassPane, - LightBlueStainedGlassPane, - YellowStainedGlassPane, - LimeStainedGlassPane, - PinkStainedGlassPane, - GrayStainedGlassPane, - LightGrayStainedGlassPane, - CyanStainedGlassPane, - PurpleStainedGlassPane, - BlueStainedGlassPane, - BrownStainedGlassPane, - GreenStainedGlassPane, - RedStainedGlassPane, - BlackStainedGlassPane, - AcaciaStairs, - DarkOakStairs, - SlimeBlock, - Barrier, - Light, - IronTrapdoor, - Prismarine, - PrismarineBricks, - DarkPrismarine, - PrismarineStairs, - PrismarineBrickStairs, - DarkPrismarineStairs, - PrismarineSlab, - PrismarineBrickSlab, - DarkPrismarineSlab, - SeaLantern, - HayBlock, - WhiteCarpet, - OrangeCarpet, - MagentaCarpet, - LightBlueCarpet, - YellowCarpet, - LimeCarpet, - PinkCarpet, - GrayCarpet, - LightGrayCarpet, - CyanCarpet, - PurpleCarpet, - BlueCarpet, - BrownCarpet, - GreenCarpet, - RedCarpet, - BlackCarpet, - Terracotta, - CoalBlock, - PackedIce, - Sunflower, - Lilac, - RoseBush, - Peony, - TallGrass, - LargeFern, - WhiteBanner, - OrangeBanner, - MagentaBanner, - LightBlueBanner, - YellowBanner, - LimeBanner, - PinkBanner, - GrayBanner, - LightGrayBanner, - CyanBanner, - PurpleBanner, - BlueBanner, - BrownBanner, - GreenBanner, - RedBanner, - BlackBanner, - WhiteWallBanner, - OrangeWallBanner, - MagentaWallBanner, - LightBlueWallBanner, - YellowWallBanner, - LimeWallBanner, - PinkWallBanner, - GrayWallBanner, - LightGrayWallBanner, - CyanWallBanner, - PurpleWallBanner, - BlueWallBanner, - BrownWallBanner, - GreenWallBanner, - RedWallBanner, - BlackWallBanner, - RedSandstone, - ChiseledRedSandstone, - CutRedSandstone, - RedSandstoneStairs, - OakSlab, - SpruceSlab, - BirchSlab, - JungleSlab, - AcaciaSlab, - DarkOakSlab, - StoneSlab, - SmoothStoneSlab, - SandstoneSlab, - CutSandstoneSlab, - PetrifiedOakSlab, - CobblestoneSlab, - BrickSlab, - StoneBrickSlab, - NetherBrickSlab, - QuartzSlab, - RedSandstoneSlab, - CutRedSandstoneSlab, - PurpurSlab, - SmoothStone, - SmoothSandstone, - SmoothQuartz, - SmoothRedSandstone, - SpruceFenceGate, - BirchFenceGate, - JungleFenceGate, - AcaciaFenceGate, - DarkOakFenceGate, - SpruceFence, - BirchFence, - JungleFence, - AcaciaFence, - DarkOakFence, - SpruceDoor, - BirchDoor, - JungleDoor, AcaciaDoor, - DarkOakDoor, - EndRod, - ChorusPlant, - ChorusFlower, - PurpurBlock, - PurpurPillar, - PurpurStairs, - EndStoneBricks, - Beetroots, - GrassPath, - EndGateway, - RepeatingCommandBlock, - ChainCommandBlock, - FrostedIce, - MagmaBlock, - NetherWartBlock, - RedNetherBricks, - BoneBlock, - StructureVoid, - Observer, - ShulkerBox, - WhiteShulkerBox, - OrangeShulkerBox, - MagentaShulkerBox, - LightBlueShulkerBox, - YellowShulkerBox, - LimeShulkerBox, - PinkShulkerBox, - GrayShulkerBox, - LightGrayShulkerBox, - CyanShulkerBox, - PurpleShulkerBox, - BlueShulkerBox, - BrownShulkerBox, - GreenShulkerBox, - RedShulkerBox, - BlackShulkerBox, - WhiteGlazedTerracotta, - OrangeGlazedTerracotta, - MagentaGlazedTerracotta, - LightBlueGlazedTerracotta, - YellowGlazedTerracotta, - LimeGlazedTerracotta, - PinkGlazedTerracotta, - GrayGlazedTerracotta, - LightGrayGlazedTerracotta, - CyanGlazedTerracotta, - PurpleGlazedTerracotta, - BlueGlazedTerracotta, - BrownGlazedTerracotta, - GreenGlazedTerracotta, - RedGlazedTerracotta, - BlackGlazedTerracotta, - WhiteConcrete, - OrangeConcrete, - MagentaConcrete, - LightBlueConcrete, - YellowConcrete, - LimeConcrete, - PinkConcrete, - GrayConcrete, - LightGrayConcrete, - CyanConcrete, - PurpleConcrete, - BlueConcrete, - BrownConcrete, - GreenConcrete, - RedConcrete, - BlackConcrete, - WhiteConcretePowder, - OrangeConcretePowder, - MagentaConcretePowder, - LightBlueConcretePowder, - YellowConcretePowder, - LimeConcretePowder, - PinkConcretePowder, - GrayConcretePowder, - LightGrayConcretePowder, - CyanConcretePowder, - PurpleConcretePowder, - BlueConcretePowder, - BrownConcretePowder, - GreenConcretePowder, - RedConcretePowder, - BlackConcretePowder, - Kelp, - KelpPlant, - DriedKelpBlock, - TurtleEgg, - DeadTubeCoralBlock, - DeadBrainCoralBlock, - DeadBubbleCoralBlock, - DeadFireCoralBlock, - DeadHornCoralBlock, - TubeCoralBlock, - BrainCoralBlock, - BubbleCoralBlock, - FireCoralBlock, - HornCoralBlock, - DeadTubeCoral, - DeadBrainCoral, - DeadBubbleCoral, - DeadFireCoral, - DeadHornCoral, - TubeCoral, - BrainCoral, - BubbleCoral, - FireCoral, - HornCoral, - DeadTubeCoralFan, - DeadBrainCoralFan, - DeadBubbleCoralFan, - DeadFireCoralFan, - DeadHornCoralFan, - TubeCoralFan, - BrainCoralFan, - BubbleCoralFan, - FireCoralFan, - HornCoralFan, - DeadTubeCoralWallFan, - DeadBrainCoralWallFan, - DeadBubbleCoralWallFan, - DeadFireCoralWallFan, - DeadHornCoralWallFan, - TubeCoralWallFan, - BrainCoralWallFan, - BubbleCoralWallFan, - FireCoralWallFan, - HornCoralWallFan, - SeaPickle, - BlueIce, - Conduit, - BambooSapling, - Bamboo, - PottedBamboo, - VoidAir, - CaveAir, - BubbleColumn, - PolishedGraniteStairs, - SmoothRedSandstoneStairs, - MossyStoneBrickStairs, - PolishedDioriteStairs, - MossyCobblestoneStairs, - EndStoneBrickStairs, - StoneStairs, - SmoothSandstoneStairs, - SmoothQuartzStairs, - GraniteStairs, - AndesiteStairs, - RedNetherBrickStairs, - PolishedAndesiteStairs, - DioriteStairs, - PolishedGraniteSlab, - SmoothRedSandstoneSlab, - MossyStoneBrickSlab, - PolishedDioriteSlab, - MossyCobblestoneSlab, - EndStoneBrickSlab, - SmoothSandstoneSlab, - SmoothQuartzSlab, - GraniteSlab, - AndesiteSlab, - RedNetherBrickSlab, - PolishedAndesiteSlab, - DioriteSlab, - BrickWall, - PrismarineWall, - RedSandstoneWall, - MossyStoneBrickWall, - GraniteWall, - StoneBrickWall, - NetherBrickWall, - AndesiteWall, - RedNetherBrickWall, - SandstoneWall, - EndStoneBrickWall, - DioriteWall, - Scaffolding, - Loom, - Barrel, - Smoker, - BlastFurnace, - CartographyTable, - FletchingTable, - Grindstone, - Lectern, - SmithingTable, - Stonecutter, - Bell, - Lantern, - SoulLantern, - Campfire, - SoulCampfire, - SweetBerryBush, - WarpedStem, - StrippedWarpedStem, - WarpedHyphae, - StrippedWarpedHyphae, - WarpedNylium, - WarpedFungus, - WarpedWartBlock, - WarpedRoots, - NetherSprouts, - CrimsonStem, - StrippedCrimsonStem, - CrimsonHyphae, - StrippedCrimsonHyphae, - CrimsonNylium, - CrimsonFungus, - Shroomlight, - WeepingVines, - WeepingVinesPlant, - TwistingVines, - TwistingVinesPlant, - CrimsonRoots, - CrimsonPlanks, - WarpedPlanks, - CrimsonSlab, - WarpedSlab, - CrimsonPressurePlate, - WarpedPressurePlate, - CrimsonFence, - WarpedFence, - CrimsonTrapdoor, - WarpedTrapdoor, - CrimsonFenceGate, - WarpedFenceGate, - CrimsonStairs, - WarpedStairs, - CrimsonButton, - WarpedButton, - CrimsonDoor, - WarpedDoor, - CrimsonSign, - WarpedSign, - CrimsonWallSign, - WarpedWallSign, - StructureBlock, - Jigsaw, - Composter, - Target, - BeeNest, - Beehive, - HoneyBlock, - HoneycombBlock, - NetheriteBlock, + AcaciaFence, + AcaciaFenceGate, + AcaciaLeaves, + AcaciaLog, + AcaciaPlanks, + AcaciaPressurePlate, + AcaciaSapling, + AcaciaSign, + AcaciaSlab, + AcaciaStairs, + AcaciaTrapdoor, + AcaciaWallSign, + AcaciaWood, + ActivatorRail, + Air, + Allium, + AmethystBlock, + AmethystCluster, AncientDebris, - CryingObsidian, - RespawnAnchor, - PottedCrimsonFungus, - PottedWarpedFungus, - PottedCrimsonRoots, - PottedWarpedRoots, - Lodestone, + Andesite, + AndesiteSlab, + AndesiteStairs, + AndesiteWall, + Anvil, + AttachedMelonStem, + AttachedPumpkinStem, + Azalea, + AzaleaLeaves, + AzureBluet, + Bamboo, + BambooSapling, + Barrel, + Barrier, + Basalt, + Beacon, + Bedrock, + Beehive, + BeeNest, + Beetroots, + Bell, + BigDripleaf, + BigDripleafStem, + BirchButton, + BirchDoor, + BirchFence, + BirchFenceGate, + BirchLeaves, + BirchLog, + BirchPlanks, + BirchPressurePlate, + BirchSapling, + BirchSign, + BirchSlab, + BirchStairs, + BirchTrapdoor, + BirchWallSign, + BirchWood, + BlackBanner, + BlackBed, + BlackCandle, + BlackCandleCake, + BlackCarpet, + BlackConcrete, + BlackConcretePowder, + BlackGlazedTerracotta, + BlackShulkerBox, + BlackStainedGlass, + BlackStainedGlassPane, Blackstone, + BlackstoneSlab, BlackstoneStairs, BlackstoneWall, - BlackstoneSlab, + BlackTerracotta, + BlackWallBanner, + BlackWool, + BlastFurnace, + BlueBanner, + BlueBed, + BlueCandle, + BlueCandleCake, + BlueCarpet, + BlueConcrete, + BlueConcretePowder, + BlueGlazedTerracotta, + BlueIce, + BlueOrchid, + BlueShulkerBox, + BlueStainedGlass, + BlueStainedGlassPane, + BlueTerracotta, + BlueWallBanner, + BlueWool, + BoneBlock, + Bookshelf, + BrainCoral, + BrainCoralBlock, + BrainCoralFan, + BrainCoralWallFan, + BrewingStand, + Bricks, + BrickSlab, + BrickStairs, + BrickWall, + BrownBanner, + BrownBed, + BrownCandle, + BrownCandleCake, + BrownCarpet, + BrownConcrete, + BrownConcretePowder, + BrownGlazedTerracotta, + BrownMushroom, + BrownMushroomBlock, + BrownShulkerBox, + BrownStainedGlass, + BrownStainedGlassPane, + BrownTerracotta, + BrownWallBanner, + BrownWool, + BubbleColumn, + BubbleCoral, + BubbleCoralBlock, + BubbleCoralFan, + BubbleCoralWallFan, + BuddingAmethyst, + Cactus, + Cake, + Calcite, + Campfire, + Candle, + CandleCake, + Carrots, + CartographyTable, + CarvedPumpkin, + Cauldron, + CaveAir, + CaveVines, + CaveVinesPlant, + Chain, + ChainCommandBlock, + Chest, + ChippedAnvil, + ChiseledDeepslate, + ChiseledNetherBricks, + ChiseledPolishedBlackstone, + ChiseledQuartzBlock, + ChiseledRedSandstone, + ChiseledSandstone, + ChiseledStoneBricks, + ChorusFlower, + ChorusPlant, + Clay, + CoalBlock, + CoalOre, + CoarseDirt, + CobbledDeepslate, + CobbledDeepslateSlab, + CobbledDeepslateStairs, + CobbledDeepslateWall, + Cobblestone, + CobblestoneSlab, + CobblestoneStairs, + CobblestoneWall, + Cobweb, + Cocoa, + CommandBlock, + Comparator, + Composter, + Conduit, + CopperBlock, + CopperOre, + Cornflower, + CrackedDeepslateBricks, + CrackedDeepslateTiles, + CrackedNetherBricks, + CrackedPolishedBlackstoneBricks, + CrackedStoneBricks, + CraftingTable, + CreeperHead, + CreeperWallHead, + CrimsonButton, + CrimsonDoor, + CrimsonFence, + CrimsonFenceGate, + CrimsonFungus, + CrimsonHyphae, + CrimsonNylium, + CrimsonPlanks, + CrimsonPressurePlate, + CrimsonRoots, + CrimsonSign, + CrimsonSlab, + CrimsonStairs, + CrimsonStem, + CrimsonTrapdoor, + CrimsonWallSign, + CryingObsidian, + CutCopper, + CutCopperSlab, + CutCopperStairs, + CutRedSandstone, + CutRedSandstoneSlab, + CutSandstone, + CutSandstoneSlab, + CyanBanner, + CyanBed, + CyanCandle, + CyanCandleCake, + CyanCarpet, + CyanConcrete, + CyanConcretePowder, + CyanGlazedTerracotta, + CyanShulkerBox, + CyanStainedGlass, + CyanStainedGlassPane, + CyanTerracotta, + CyanWallBanner, + CyanWool, + DamagedAnvil, + Dandelion, + DarkOakButton, + DarkOakDoor, + DarkOakFence, + DarkOakFenceGate, + DarkOakLeaves, + DarkOakLog, + DarkOakPlanks, + DarkOakPressurePlate, + DarkOakSapling, + DarkOakSign, + DarkOakSlab, + DarkOakStairs, + DarkOakTrapdoor, + DarkOakWallSign, + DarkOakWood, + DarkPrismarine, + DarkPrismarineSlab, + DarkPrismarineStairs, + DaylightDetector, + DeadBrainCoral, + DeadBrainCoralBlock, + DeadBrainCoralFan, + DeadBrainCoralWallFan, + DeadBubbleCoral, + DeadBubbleCoralBlock, + DeadBubbleCoralFan, + DeadBubbleCoralWallFan, + DeadBush, + DeadFireCoral, + DeadFireCoralBlock, + DeadFireCoralFan, + DeadFireCoralWallFan, + DeadHornCoral, + DeadHornCoralBlock, + DeadHornCoralFan, + DeadHornCoralWallFan, + DeadTubeCoral, + DeadTubeCoralBlock, + DeadTubeCoralFan, + DeadTubeCoralWallFan, + Deepslate, + DeepslateBricks, + DeepslateBrickSlab, + DeepslateBrickStairs, + DeepslateBrickWall, + DeepslateCoalOre, + DeepslateCopperOre, + DeepslateDiamondOre, + DeepslateEmeraldOre, + DeepslateGoldOre, + DeepslateIronOre, + DeepslateLapisOre, + DeepslateRedstoneOre, + DeepslateTiles, + DeepslateTileSlab, + DeepslateTileStairs, + DeepslateTileWall, + DetectorRail, + DiamondBlock, + DiamondOre, + Diorite, + DioriteSlab, + DioriteStairs, + DioriteWall, + Dirt, + Dispenser, + DragonEgg, + DragonHead, + DragonWallHead, + DriedKelpBlock, + DripstoneBlock, + Dropper, + EmeraldBlock, + EmeraldOre, + EnchantingTable, + EnderChest, + EndGateway, + EndPortal, + EndPortalFrame, + EndRod, + EndStone, + EndStoneBricks, + EndStoneBrickSlab, + EndStoneBrickStairs, + EndStoneBrickWall, + ExposedCopper, + ExposedCutCopper, + ExposedCutCopperSlab, + ExposedCutCopperStairs, + Farmland, + Fern, + Fire, + FireCoral, + FireCoralBlock, + FireCoralFan, + FireCoralWallFan, + FletchingTable, + FloweringAzalea, + FloweringAzaleaLeaves, + FlowerPot, + FrostedIce, + Furnace, + GildedBlackstone, + Glass, + GlassPane, + GlowLichen, + Glowstone, + GoldBlock, + GoldOre, + Granite, + GraniteSlab, + GraniteStairs, + GraniteWall, + Grass, + GrassBlock, + GrassPath, + Gravel, + GrayBanner, + GrayBed, + GrayCandle, + GrayCandleCake, + GrayCarpet, + GrayConcrete, + GrayConcretePowder, + GrayGlazedTerracotta, + GrayShulkerBox, + GrayStainedGlass, + GrayStainedGlassPane, + GrayTerracotta, + GrayWallBanner, + GrayWool, + GreenBanner, + GreenBed, + GreenCandle, + GreenCandleCake, + GreenCarpet, + GreenConcrete, + GreenConcretePowder, + GreenGlazedTerracotta, + GreenShulkerBox, + GreenStainedGlass, + GreenStainedGlassPane, + GreenTerracotta, + GreenWallBanner, + GreenWool, + Grindstone, + HangingRoots, + HayBlock, + HeavyWeightedPressurePlate, + HoneyBlock, + HoneycombBlock, + Hopper, + HornCoral, + HornCoralBlock, + HornCoralFan, + HornCoralWallFan, + Ice, + InfestedChiseledStoneBricks, + InfestedCobblestone, + InfestedCrackedStoneBricks, + InfestedDeepslate, + InfestedMossyStoneBricks, + InfestedStone, + InfestedStoneBricks, + IronBars, + IronBlock, + IronDoor, + IronOre, + IronTrapdoor, + JackOLantern, + Jigsaw, + Jukebox, + JungleButton, + JungleDoor, + JungleFence, + JungleFenceGate, + JungleLeaves, + JungleLog, + JunglePlanks, + JunglePressurePlate, + JungleSapling, + JungleSign, + JungleSlab, + JungleStairs, + JungleTrapdoor, + JungleWallSign, + JungleWood, + Kelp, + KelpPlant, + Ladder, + Lantern, + LapisBlock, + LapisOre, + LargeAmethystBud, + LargeFern, + Lava, + LavaCauldron, + Lectern, + Lever, + Light, + LightBlueBanner, + LightBlueBed, + LightBlueCandle, + LightBlueCandleCake, + LightBlueCarpet, + LightBlueConcrete, + LightBlueConcretePowder, + LightBlueGlazedTerracotta, + LightBlueShulkerBox, + LightBlueStainedGlass, + LightBlueStainedGlassPane, + LightBlueTerracotta, + LightBlueWallBanner, + LightBlueWool, + LightGrayBanner, + LightGrayBed, + LightGrayCandle, + LightGrayCandleCake, + LightGrayCarpet, + LightGrayConcrete, + LightGrayConcretePowder, + LightGrayGlazedTerracotta, + LightGrayShulkerBox, + LightGrayStainedGlass, + LightGrayStainedGlassPane, + LightGrayTerracotta, + LightGrayWallBanner, + LightGrayWool, + LightningRod, + LightWeightedPressurePlate, + Lilac, + LilyOfTheValley, + LilyPad, + LimeBanner, + LimeBed, + LimeCandle, + LimeCandleCake, + LimeCarpet, + LimeConcrete, + LimeConcretePowder, + LimeGlazedTerracotta, + LimeShulkerBox, + LimeStainedGlass, + LimeStainedGlassPane, + LimeTerracotta, + LimeWallBanner, + LimeWool, + Lodestone, + Loom, + MagentaBanner, + MagentaBed, + MagentaCandle, + MagentaCandleCake, + MagentaCarpet, + MagentaConcrete, + MagentaConcretePowder, + MagentaGlazedTerracotta, + MagentaShulkerBox, + MagentaStainedGlass, + MagentaStainedGlassPane, + MagentaTerracotta, + MagentaWallBanner, + MagentaWool, + MagmaBlock, + MediumAmethystBud, + Melon, + MelonStem, + MossBlock, + MossCarpet, + MossyCobblestone, + MossyCobblestoneSlab, + MossyCobblestoneStairs, + MossyCobblestoneWall, + MossyStoneBricks, + MossyStoneBrickSlab, + MossyStoneBrickStairs, + MossyStoneBrickWall, + MovingPiston, + MushroomStem, + Mycelium, + NetherBrickFence, + NetherBricks, + NetherBrickSlab, + NetherBrickStairs, + NetherBrickWall, + NetherGoldOre, + NetheriteBlock, + NetherPortal, + NetherQuartzOre, + Netherrack, + NetherSprouts, + NetherWart, + NetherWartBlock, + NoteBlock, + OakButton, + OakDoor, + OakFence, + OakFenceGate, + OakLeaves, + OakLog, + OakPlanks, + OakPressurePlate, + OakSapling, + OakSign, + OakSlab, + OakStairs, + OakTrapdoor, + OakWallSign, + OakWood, + Observer, + Obsidian, + OrangeBanner, + OrangeBed, + OrangeCandle, + OrangeCandleCake, + OrangeCarpet, + OrangeConcrete, + OrangeConcretePowder, + OrangeGlazedTerracotta, + OrangeShulkerBox, + OrangeStainedGlass, + OrangeStainedGlassPane, + OrangeTerracotta, + OrangeTulip, + OrangeWallBanner, + OrangeWool, + OxeyeDaisy, + OxidizedCopper, + OxidizedCutCopper, + OxidizedCutCopperSlab, + OxidizedCutCopperStairs, + PackedIce, + Peony, + PetrifiedOakSlab, + PinkBanner, + PinkBed, + PinkCandle, + PinkCandleCake, + PinkCarpet, + PinkConcrete, + PinkConcretePowder, + PinkGlazedTerracotta, + PinkShulkerBox, + PinkStainedGlass, + PinkStainedGlassPane, + PinkTerracotta, + PinkTulip, + PinkWallBanner, + PinkWool, + Piston, + PistonHead, + PlayerHead, + PlayerWallHead, + Podzol, + PointedDripstone, + PolishedAndesite, + PolishedAndesiteSlab, + PolishedAndesiteStairs, + PolishedBasalt, PolishedBlackstone, PolishedBlackstoneBricks, - CrackedPolishedBlackstoneBricks, - ChiseledPolishedBlackstone, PolishedBlackstoneBrickSlab, PolishedBlackstoneBrickStairs, PolishedBlackstoneBrickWall, - GildedBlackstone, - PolishedBlackstoneStairs, - PolishedBlackstoneSlab, - PolishedBlackstonePressurePlate, PolishedBlackstoneButton, + PolishedBlackstonePressurePlate, + PolishedBlackstoneSlab, + PolishedBlackstoneStairs, PolishedBlackstoneWall, - ChiseledNetherBricks, - CrackedNetherBricks, - QuartzBricks, - Candle, - WhiteCandle, - OrangeCandle, - MagentaCandle, - LightBlueCandle, - YellowCandle, - LimeCandle, - PinkCandle, - GrayCandle, - LightGrayCandle, - CyanCandle, - PurpleCandle, - BlueCandle, - BrownCandle, - GreenCandle, - RedCandle, - BlackCandle, - CandleCake, - WhiteCandleCake, - OrangeCandleCake, - MagentaCandleCake, - LightBlueCandleCake, - YellowCandleCake, - LimeCandleCake, - PinkCandleCake, - GrayCandleCake, - LightGrayCandleCake, - CyanCandleCake, - PurpleCandleCake, - BlueCandleCake, - BrownCandleCake, - GreenCandleCake, - RedCandleCake, - BlackCandleCake, - AmethystBlock, - BuddingAmethyst, - AmethystCluster, - LargeAmethystBud, - MediumAmethystBud, - SmallAmethystBud, - Tuff, - Calcite, - TintedGlass, - PowderSnow, - SculkSensor, - OxidizedCopper, - WeatheredCopper, - ExposedCopper, - CopperBlock, - CopperOre, - DeepslateCopperOre, - OxidizedCutCopper, - WeatheredCutCopper, - ExposedCutCopper, - CutCopper, - OxidizedCutCopperStairs, - WeatheredCutCopperStairs, - ExposedCutCopperStairs, - CutCopperStairs, - OxidizedCutCopperSlab, - WeatheredCutCopperSlab, - ExposedCutCopperSlab, - CutCopperSlab, - WaxedCopperBlock, - WaxedWeatheredCopper, - WaxedExposedCopper, - WaxedOxidizedCopper, - WaxedOxidizedCutCopper, - WaxedWeatheredCutCopper, - WaxedExposedCutCopper, - WaxedCutCopper, - WaxedOxidizedCutCopperStairs, - WaxedWeatheredCutCopperStairs, - WaxedExposedCutCopperStairs, - WaxedCutCopperStairs, - WaxedOxidizedCutCopperSlab, - WaxedWeatheredCutCopperSlab, - WaxedExposedCutCopperSlab, - WaxedCutCopperSlab, - LightningRod, - PointedDripstone, - DripstoneBlock, - CaveVines, - CaveVinesPlant, - SporeBlossom, - Azalea, - FloweringAzalea, - MossCarpet, - MossBlock, - BigDripleaf, - BigDripleafStem, - SmallDripleaf, - HangingRoots, - RootedDirt, - Deepslate, - CobbledDeepslate, - CobbledDeepslateStairs, - CobbledDeepslateSlab, - CobbledDeepslateWall, PolishedDeepslate, - PolishedDeepslateStairs, PolishedDeepslateSlab, + PolishedDeepslateStairs, PolishedDeepslateWall, - DeepslateTiles, - DeepslateTileStairs, - DeepslateTileSlab, - DeepslateTileWall, - DeepslateBricks, - DeepslateBrickStairs, - DeepslateBrickSlab, - DeepslateBrickWall, - ChiseledDeepslate, - CrackedDeepslateBricks, - CrackedDeepslateTiles, - InfestedDeepslate, - SmoothBasalt, - RawIronBlock, + PolishedDiorite, + PolishedDioriteSlab, + PolishedDioriteStairs, + PolishedGranite, + PolishedGraniteSlab, + PolishedGraniteStairs, + Poppy, + Potatoes, + PottedAcaciaSapling, + PottedAllium, + PottedAzaleaBush, + PottedAzureBluet, + PottedBamboo, + PottedBirchSapling, + PottedBlueOrchid, + PottedBrownMushroom, + PottedCactus, + PottedCornflower, + PottedCrimsonFungus, + PottedCrimsonRoots, + PottedDandelion, + PottedDarkOakSapling, + PottedDeadBush, + PottedFern, + PottedFloweringAzaleaBush, + PottedJungleSapling, + PottedLilyOfTheValley, + PottedOakSapling, + PottedOrangeTulip, + PottedOxeyeDaisy, + PottedPinkTulip, + PottedPoppy, + PottedRedMushroom, + PottedRedTulip, + PottedSpruceSapling, + PottedWarpedFungus, + PottedWarpedRoots, + PottedWhiteTulip, + PottedWitherRose, + PowderSnow, + PowderSnowCauldron, + PoweredRail, + Prismarine, + PrismarineBricks, + PrismarineBrickSlab, + PrismarineBrickStairs, + PrismarineSlab, + PrismarineStairs, + PrismarineWall, + Pumpkin, + PumpkinStem, + PurpleBanner, + PurpleBed, + PurpleCandle, + PurpleCandleCake, + PurpleCarpet, + PurpleConcrete, + PurpleConcretePowder, + PurpleGlazedTerracotta, + PurpleShulkerBox, + PurpleStainedGlass, + PurpleStainedGlassPane, + PurpleTerracotta, + PurpleWallBanner, + PurpleWool, + PurpurBlock, + PurpurPillar, + PurpurSlab, + PurpurStairs, + QuartzBlock, + QuartzBricks, + QuartzPillar, + QuartzSlab, + QuartzStairs, + Rail, RawCopperBlock, RawGoldBlock, - PottedAzaleaBush, - PottedFloweringAzaleaBush, + RawIronBlock, + RedBanner, + RedBed, + RedCandle, + RedCandleCake, + RedCarpet, + RedConcrete, + RedConcretePowder, + RedGlazedTerracotta, + RedMushroom, + RedMushroomBlock, + RedNetherBricks, + RedNetherBrickSlab, + RedNetherBrickStairs, + RedNetherBrickWall, + RedSand, + RedSandstone, + RedSandstoneSlab, + RedSandstoneStairs, + RedSandstoneWall, + RedShulkerBox, + RedStainedGlass, + RedStainedGlassPane, + RedstoneBlock, + RedstoneLamp, + RedstoneOre, + RedstoneTorch, + RedstoneWallTorch, + RedstoneWire, + RedTerracotta, + RedTulip, + RedWallBanner, + RedWool, + Repeater, + RepeatingCommandBlock, + RespawnAnchor, + RootedDirt, + RoseBush, + Sand, + Sandstone, + SandstoneSlab, + SandstoneStairs, + SandstoneWall, + Scaffolding, + SculkSensor, + Seagrass, + SeaLantern, + SeaPickle, + Shroomlight, + ShulkerBox, + SkeletonSkull, + SkeletonWallSkull, + SlimeBlock, + SmallAmethystBud, + SmallDripleaf, + SmithingTable, + Smoker, + SmoothBasalt, + SmoothQuartz, + SmoothQuartzSlab, + SmoothQuartzStairs, + SmoothRedSandstone, + SmoothRedSandstoneSlab, + SmoothRedSandstoneStairs, + SmoothSandstone, + SmoothSandstoneSlab, + SmoothSandstoneStairs, + SmoothStone, + SmoothStoneSlab, + Snow, + SnowBlock, + SoulCampfire, + SoulFire, + SoulLantern, + SoulSand, + SoulSoil, + SoulTorch, + SoulWallTorch, + Spawner, + Sponge, + SporeBlossom, + SpruceButton, + SpruceDoor, + SpruceFence, + SpruceFenceGate, + SpruceLeaves, + SpruceLog, + SprucePlanks, + SprucePressurePlate, + SpruceSapling, + SpruceSign, + SpruceSlab, + SpruceStairs, + SpruceTrapdoor, + SpruceWallSign, + SpruceWood, + StickyPiston, + Stone, + StoneBricks, + StoneBrickSlab, + StoneBrickStairs, + StoneBrickWall, + StoneButton, + Stonecutter, + StonePressurePlate, + StoneSlab, + StoneStairs, + StrippedAcaciaLog, + StrippedAcaciaWood, + StrippedBirchLog, + StrippedBirchWood, + StrippedCrimsonHyphae, + StrippedCrimsonStem, + StrippedDarkOakLog, + StrippedDarkOakWood, + StrippedJungleLog, + StrippedJungleWood, + StrippedOakLog, + StrippedOakWood, + StrippedSpruceLog, + StrippedSpruceWood, + StrippedWarpedHyphae, + StrippedWarpedStem, + StructureBlock, + StructureVoid, + SugarCane, + Sunflower, + SweetBerryBush, + TallGrass, + TallSeagrass, + Target, + Terracotta, + TintedGlass, + Tnt, + Torch, + TrappedChest, + Tripwire, + TripwireHook, + TubeCoral, + TubeCoralBlock, + TubeCoralFan, + TubeCoralWallFan, + Tuff, + TurtleEgg, + TwistingVines, + TwistingVinesPlant, + Vine, + VoidAir, + WallTorch, + WarpedButton, + WarpedDoor, + WarpedFence, + WarpedFenceGate, + WarpedFungus, + WarpedHyphae, + WarpedNylium, + WarpedPlanks, + WarpedPressurePlate, + WarpedRoots, + WarpedSign, + WarpedSlab, + WarpedStairs, + WarpedStem, + WarpedTrapdoor, + WarpedWallSign, + WarpedWartBlock, + Water, + WaterCauldron, + WaxedCopperBlock, + WaxedCutCopper, + WaxedCutCopperSlab, + WaxedCutCopperStairs, + WaxedExposedCopper, + WaxedExposedCutCopper, + WaxedExposedCutCopperSlab, + WaxedExposedCutCopperStairs, + WaxedOxidizedCopper, + WaxedOxidizedCutCopper, + WaxedOxidizedCutCopperSlab, + WaxedOxidizedCutCopperStairs, + WaxedWeatheredCopper, + WaxedWeatheredCutCopper, + WaxedWeatheredCutCopperSlab, + WaxedWeatheredCutCopperStairs, + WeatheredCopper, + WeatheredCutCopper, + WeatheredCutCopperSlab, + WeatheredCutCopperStairs, + WeepingVines, + WeepingVinesPlant, + WetSponge, + Wheat, + WhiteBanner, + WhiteBed, + WhiteCandle, + WhiteCandleCake, + WhiteCarpet, + WhiteConcrete, + WhiteConcretePowder, + WhiteGlazedTerracotta, + WhiteShulkerBox, + WhiteStainedGlass, + WhiteStainedGlassPane, + WhiteTerracotta, + WhiteTulip, + WhiteWallBanner, + WhiteWool, + WitherRose, + WitherSkeletonSkull, + WitherSkeletonWallSkull, + YellowBanner, + YellowBed, + YellowCandle, + YellowCandleCake, + YellowCarpet, + YellowConcrete, + YellowConcretePowder, + YellowGlazedTerracotta, + YellowShulkerBox, + YellowStainedGlass, + YellowStainedGlassPane, + YellowTerracotta, + YellowWallBanner, + YellowWool, + ZombieHead, + ZombieWallHead, } } diff --git a/MinecraftClient/Mapping/Material2Tool.cs b/MinecraftClient/Mapping/Material2Tool.cs index 6ab60c17..d8433808 100644 --- a/MinecraftClient/Mapping/Material2Tool.cs +++ b/MinecraftClient/Mapping/Material2Tool.cs @@ -42,12 +42,9 @@ namespace MinecraftClient.Mapping Material.BrownGlazedTerracotta, Material.BrownShulkerBox, Material.BrownTerracotta, - Material.Cauldron, - Material.WaterCauldron, - Material.LavaCauldron, - Material.PowderSnowCauldron, - Material.Chain, Material.Calcite, + Material.Cauldron, + Material.Chain, Material.ChippedAnvil, Material.ChiseledDeepslate, Material.ChiseledNetherBricks, @@ -58,10 +55,10 @@ namespace MinecraftClient.Mapping Material.ChiseledStoneBricks, Material.CoalBlock, Material.CoalOre, + Material.CobbledDeepslate, Material.CobbledDeepslateSlab, Material.CobbledDeepslateStairs, Material.CobbledDeepslateWall, - Material.CobbledDeepslate, Material.Cobblestone, Material.CobblestoneSlab, Material.CobblestoneStairs, @@ -88,20 +85,20 @@ namespace MinecraftClient.Mapping Material.Deepslate, Material.DeepslateBrickSlab, Material.DeepslateBrickStairs, - Material.DeepslateBricks, Material.DeepslateBrickWall, + Material.DeepslateBricks, Material.DeepslateCoalOre, Material.DeepslateTileSlab, Material.DeepslateTileStairs, - Material.DeepslateTiles, Material.DeepslateTileWall, + Material.DeepslateTiles, Material.DetectorRail, Material.Diorite, Material.DioriteSlab, Material.DioriteStairs, Material.DioriteWall, - Material.DripstoneBlock, Material.Dispenser, + Material.DripstoneBlock, Material.Dropper, Material.EnchantingTable, Material.EndRod, @@ -135,6 +132,7 @@ namespace MinecraftClient.Mapping Material.IronDoor, Material.IronTrapdoor, Material.Lantern, + Material.LavaCauldron, Material.LightBlueConcrete, Material.LightBlueGlazedTerracotta, Material.LightBlueShulkerBox, @@ -203,6 +201,7 @@ namespace MinecraftClient.Mapping Material.PolishedGranite, Material.PolishedGraniteSlab, Material.PolishedGraniteStairs, + Material.PowderSnowCauldron, Material.PoweredRail, Material.Prismarine, Material.PrismarineBrickSlab, @@ -271,6 +270,7 @@ namespace MinecraftClient.Mapping Material.Terracotta, Material.Tuff, Material.WarpedNylium, + Material.WaterCauldron, Material.WhiteConcrete, Material.WhiteGlazedTerracotta, Material.WhiteShulkerBox, @@ -641,7 +641,7 @@ namespace MinecraftClient.Mapping // Liquids private static readonly List bucket = new List() { - Material.Lava, + Material.Lava, Material.Water }; @@ -673,7 +673,7 @@ namespace MinecraftClient.Mapping { if (pickaxeTier0.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheritePickaxe, ItemType.DiamondPickaxe, @@ -685,7 +685,7 @@ namespace MinecraftClient.Mapping } else if (pickaxeTier1.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheritePickaxe, ItemType.DiamondPickaxe, @@ -696,7 +696,7 @@ namespace MinecraftClient.Mapping } else if (pickaxeTier2.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheritePickaxe, ItemType.DiamondPickaxe, @@ -705,7 +705,7 @@ namespace MinecraftClient.Mapping } else if (pickaxeTier3.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheritePickaxe, ItemType.DiamondPickaxe, @@ -713,7 +713,7 @@ namespace MinecraftClient.Mapping } else if (shovel.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheriteShovel, ItemType.DiamondShovel, @@ -725,7 +725,7 @@ namespace MinecraftClient.Mapping } else if (axe.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheriteAxe, ItemType.DiamondAxe, @@ -737,14 +737,14 @@ namespace MinecraftClient.Mapping } else if (shears.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.Shears, }; } else if (sword.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheriteSword, ItemType.DiamondSword, @@ -756,7 +756,7 @@ namespace MinecraftClient.Mapping } else if (hoe.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.NetheriteHoe, ItemType.DiamondHoe, @@ -768,7 +768,7 @@ namespace MinecraftClient.Mapping } else if (bucket.Contains(block)) { - return new ItemType[] + return new ItemType[] { ItemType.Bucket, }; diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index d5ab0c4a..93486d35 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -16,7 +16,7 @@ using MinecraftClient.WinAPI; namespace MinecraftClient { /// - /// Minecraft Console Client by the MCC Team (c) 2012-2021. + /// Minecraft Console Client by the MCC Team (c) 2012-2022. /// Allows to connect to any Minecraft server, send and receive text, automated scripts. /// This source code is released under the CDDL 1.0 License. /// @@ -124,17 +124,19 @@ namespace MinecraftClient { if (!argument.Contains("=")) throw new ArgumentException(Translations.Get("error.setting.argument_syntax", argument)); - + string[] argParts = argument.Substring(2).Split('='); string argName = argParts[0].Trim(); string argValue = argParts[1].Replace("\"", "").Trim(); - if(argName == "data-path") { + if (argName == "data-path") + { Console.WriteLine(dataPath); dataPath = argValue; } - if(argName == "data-generator") { + if (argName == "data-generator") + { dataGenerator = argValue; } } @@ -143,24 +145,24 @@ namespace MinecraftClient if (string.IsNullOrEmpty(dataGenerator) || !(dataGenerator.ToLower().Equals("entity") || dataGenerator.ToLower().Equals("item") || dataGenerator.ToLower().Equals("block"))) { Console.WriteLine(Translations.Get("error.generator.invalid")); - Console.WriteLine(Translations.Get("error.usage") + " MinecraftClient.exe --data-generator="); + Console.WriteLine(Translations.Get("error.usage") + " MinecraftClient.exe --data-generator= --data-path=\"\""); return; } if (string.IsNullOrEmpty(dataPath)) { Console.WriteLine(Translations.Get("error.missing.argument", "--data-path")); - Console.WriteLine(Translations.Get("error.usage") + " MinecraftClient.exe --generate-entity-pallete --data-path=\"\""); + Console.WriteLine(Translations.Get("error.usage") + " MinecraftClient.exe --data-generator= --data-path=\"\""); return; } - if(!File.Exists(dataPath)) + if (!File.Exists(dataPath)) { Console.WriteLine(Translations.Get("error.generator.path", dataPath)); return; } - if(!dataPath.EndsWith(".json")) + if (!dataPath.EndsWith(".json")) { Console.WriteLine(Translations.Get("error.generator.json", dataPath)); return; @@ -170,16 +172,16 @@ namespace MinecraftClient switch (dataGenerator) { - case "entity": + case "entity": EntityPaletteGenerator.GenerateEntityTypes(dataPath); break; - case "item": + case "item": ItemPaletteGenerator.GenerateItemType(dataPath); break; - case "block": - BlockPaletteGenerator.GenerateBlockPallete(dataPath); + case "block": + BlockPaletteGenerator.GenerateBlockPalette(dataPath); break; } @@ -226,7 +228,7 @@ namespace MinecraftClient Console.Write(ConsoleIO.BasicIO ? Translations.Get("mcc.login_basic_io") + "\n" : Translations.Get("mcc.login")); Settings.Login = Console.ReadLine(); } - if (Settings.Password == "" + if (Settings.Password == "" && (Settings.SessionCaching == CacheType.None || !SessionCache.Contains(Settings.Login.ToLower())) && !useBrowser) { @@ -234,14 +236,14 @@ namespace MinecraftClient } // Setup exit cleaning code - ExitCleanUp.Add(delegate () + ExitCleanUp.Add(delegate () { // Do NOT use Program.Exit() as creating new Thread cause program to freeze if (client != null) { client.Disconnect(); ConsoleIO.Reset(); } if (offlinePrompt != null) { offlinePrompt.Abort(); offlinePrompt = null; ConsoleIO.Reset(); } if (Settings.playerHeadAsIcon) { ConsoleIcon.revertToMCCIcon(); } }); - + startupargs = args; InitializeClient(); @@ -294,8 +296,8 @@ namespace MinecraftClient { result = ProtocolHandler.MicrosoftLoginRefresh(session.RefreshToken, out session); } - if (result != ProtocolHandler.LoginResult.Success - && Settings.Password == "" + if (result != ProtocolHandler.LoginResult.Success + && Settings.Password == "" && Settings.AccountType == ProtocolHandler.AccountType.Mojang) RequestPassword(); } diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index ae36ed66..e8ed9d4b 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -88,19 +88,19 @@ namespace MinecraftClient.Protocol.Handlers this.packetPalette = new PacketTypeHandler(protocolVersion, forgeInfo != null).GetTypeHandler(); this.log = handler.GetLogger(); - if (handler.GetTerrainEnabled() && protocolversion > MC1181Version) + if (handler.GetTerrainEnabled() && protocolversion > MC1182Version) { log.Error(Translations.Get("extra.terrainandmovement_disabled")); handler.SetTerrainEnabled(false); } - if (handler.GetInventoryEnabled() && (protocolversion < MC110Version || protocolversion > MC1181Version)) + if (handler.GetInventoryEnabled() && (protocolversion < MC110Version || protocolversion > MC1182Version)) { log.Error(Translations.Get("extra.inventory_disabled")); handler.SetInventoryEnabled(false); } - if (handler.GetEntityHandlingEnabled() && (protocolversion < MC110Version || protocolversion > MC1181Version)) + if (handler.GetEntityHandlingEnabled() && (protocolversion < MC110Version || protocolversion > MC1182Version)) { log.Error(Translations.Get("extra.entity_disabled")); handler.SetEntityHandlingEnabled(false); @@ -109,9 +109,9 @@ namespace MinecraftClient.Protocol.Handlers // Block palette if (protocolversion >= MC113Version) { - if (protocolVersion > MC1181Version && handler.GetTerrainEnabled()) + if (protocolVersion > MC1182Version && handler.GetTerrainEnabled()) throw new NotImplementedException(Translations.Get("exception.palette.block")); - if (protocolVersion == MC1181Version) + if (protocolVersion >= MC1181Version) Block.Palette = new Palette117(); else if (protocolVersion >= MC116Version) Block.Palette = new Palette116(); @@ -126,10 +126,10 @@ namespace MinecraftClient.Protocol.Handlers // Entity palette if (protocolversion >= MC113Version) { - if (protocolversion > MC1181Version && handler.GetEntityHandlingEnabled()) + if (protocolversion > MC1182Version && handler.GetEntityHandlingEnabled()) throw new NotImplementedException(Translations.Get("exception.palette.entity")); - if (protocolversion >= MC117Version) - entityPalette = new EntityPalette117(); + if (protocolversion >= MC117Version) + entityPalette = new EntityPalette117(); else if (protocolversion >= MC1162Version) entityPalette = new EntityPalette1162(); else if (protocolversion >= MC116Version) @@ -145,9 +145,9 @@ namespace MinecraftClient.Protocol.Handlers // Item palette if (protocolversion >= MC1162Version) { - if (protocolversion > MC1181Version && handler.GetInventoryEnabled()) + if (protocolversion > MC1182Version && handler.GetInventoryEnabled()) throw new NotImplementedException(Translations.Get("exception.palette.item")); - if (protocolversion == MC1181Version) + if (protocolversion >= MC1181Version) itemPalette = new ItemPalette118(); else if (protocolversion >= MC117Version) itemPalette = new ItemPalette117(); @@ -280,887 +280,889 @@ namespace MinecraftClient.Protocol.Handlers } // Regular in-game packets else switch (packetPalette.GetIncommingTypeById(packetID)) - { - case PacketTypesIn.KeepAlive: - SendPacket(PacketTypesOut.KeepAlive, packetData); - handler.OnServerKeepAlive(); - break; - case PacketTypesIn.JoinGame: - handler.OnGameJoined(); - int playerEntityID = dataTypes.ReadNextInt(packetData); - handler.OnReceivePlayerEntityID(playerEntityID); + { + case PacketTypesIn.KeepAlive: + SendPacket(PacketTypesOut.KeepAlive, packetData); + handler.OnServerKeepAlive(); + break; + case PacketTypesIn.JoinGame: + handler.OnGameJoined(); + int playerEntityID = dataTypes.ReadNextInt(packetData); + handler.OnReceivePlayerEntityID(playerEntityID); - if (protocolversion >= MC1162Version) - dataTypes.ReadNextBool(packetData); // Is hardcore - 1.16.2 and above - - handler.OnGamemodeUpdate(Guid.Empty, dataTypes.ReadNextByte(packetData)); - - if (protocolversion >= MC116Version) - { - dataTypes.ReadNextByte(packetData); // Previous Gamemode - 1.16 and above - int worldCount = dataTypes.ReadNextVarInt(packetData); // World Count - 1.16 and above - for (int i = 0; i < worldCount; i++) - dataTypes.ReadNextString(packetData); // World Names - 1.16 and above - dataTypes.ReadNextNbt(packetData); // Dimension Codec - 1.16 and above - } - - //Current dimension - String identifier in 1.16, varInt below 1.16, byte below 1.9.1 - if (protocolversion >= MC116Version) - { if (protocolversion >= MC1162Version) - dataTypes.ReadNextNbt(packetData); + dataTypes.ReadNextBool(packetData); // Is hardcore - 1.16.2 and above + + handler.OnGamemodeUpdate(Guid.Empty, dataTypes.ReadNextByte(packetData)); + + if (protocolversion >= MC116Version) + { + dataTypes.ReadNextByte(packetData); // Previous Gamemode - 1.16 and above + int worldCount = dataTypes.ReadNextVarInt(packetData); // World Count - 1.16 and above + for (int i = 0; i < worldCount; i++) + dataTypes.ReadNextString(packetData); // World Names - 1.16 and above + dataTypes.ReadNextNbt(packetData); // Dimension Codec - 1.16 and above + } + + //Current dimension - String identifier in 1.16, varInt below 1.16, byte below 1.9.1 + if (protocolversion >= MC116Version) + { + if (protocolversion >= MC1162Version) + dataTypes.ReadNextNbt(packetData); + else + dataTypes.ReadNextString(packetData); + // TODO handle dimensions for 1.16+, needed for terrain handling + // TODO this data give min and max y which will be needed for chunk collumn handling + this.currentDimension = 0; + } + else if (protocolversion >= MC191Version) + this.currentDimension = dataTypes.ReadNextInt(packetData); else - dataTypes.ReadNextString(packetData); - // TODO handle dimensions for 1.16+, needed for terrain handling - // TODO this data give min and max y which will be needed for chunk collumn handling - this.currentDimension = 0; - } - else if (protocolversion >= MC191Version) - this.currentDimension = dataTypes.ReadNextInt(packetData); - else - this.currentDimension = (sbyte)dataTypes.ReadNextByte(packetData); + this.currentDimension = (sbyte)dataTypes.ReadNextByte(packetData); - if (protocolversion < MC114Version) - dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below - if (protocolversion >= MC116Version) - dataTypes.ReadNextString(packetData); // World Name - 1.16 and above - if (protocolversion >= MC115Version) - dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above + if (protocolversion < MC114Version) + dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below + if (protocolversion >= MC116Version) + dataTypes.ReadNextString(packetData); // World Name - 1.16 and above + if (protocolversion >= MC115Version) + dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above - if (protocolversion >= MC1162Version) - dataTypes.ReadNextVarInt(packetData); // Max Players - 1.16.2 and above - else - dataTypes.ReadNextByte(packetData); // Max Players - 1.16.1 and below - - if (protocolversion < MC116Version) - dataTypes.ReadNextString(packetData); // Level Type - 1.15 and below - if (protocolversion >= MC114Version) - dataTypes.ReadNextVarInt(packetData); // View distance - 1.14 and above - if (protocolversion >= MC1181Version) - dataTypes.ReadNextVarInt(packetData); // Simulation Distance - 1.18 and above - if (protocolversion >= MC18Version) - dataTypes.ReadNextBool(packetData); // Reduced debug info - 1.8 and above - if (protocolversion >= MC115Version) - dataTypes.ReadNextBool(packetData); // Enable respawn screen - 1.15 and above - - if (protocolversion >= MC116Version) - { - dataTypes.ReadNextBool(packetData); // Is Debug - 1.16 and above - dataTypes.ReadNextBool(packetData); // Is Flat - 1.16 and above - } - break; - case PacketTypesIn.ChatMessage: - string message = dataTypes.ReadNextString(packetData); - if (protocolversion >= MC18Version) - { - //Hide system messages or xp bar messages? - byte messageType = dataTypes.ReadNextByte(packetData); - if ((messageType == 1 && !Settings.DisplaySystemMessages) - || (messageType == 2 && !Settings.DisplayXPBarMessages)) - break; - } - handler.OnTextReceived(message, true); - break; - case PacketTypesIn.Respawn: - if (protocolversion >= MC116Version) - { - // TODO handle dimensions for 1.16+, needed for terrain handling if (protocolversion >= MC1162Version) - dataTypes.ReadNextNbt(packetData); + dataTypes.ReadNextVarInt(packetData); // Max Players - 1.16.2 and above else - dataTypes.ReadNextString(packetData); - this.currentDimension = 0; - } - else - { - // 1.15 and below - this.currentDimension = dataTypes.ReadNextInt(packetData); - } - if (protocolversion >= MC116Version) - dataTypes.ReadNextString(packetData); // World Name - 1.16 and above - if (protocolversion < MC114Version) - dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below - if (protocolversion >= MC115Version) - dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above - dataTypes.ReadNextByte(packetData); // Gamemode - if (protocolversion >= MC116Version) - dataTypes.ReadNextByte(packetData); // Previous Game mode - 1.16 and above - if (protocolversion < MC116Version) - dataTypes.ReadNextString(packetData); // Level Type - 1.15 and below - if (protocolversion >= MC116Version) - { - dataTypes.ReadNextBool(packetData); // Is Debug - 1.16 and above - dataTypes.ReadNextBool(packetData); // Is Flat - 1.16 and above - dataTypes.ReadNextBool(packetData); // Copy metadata - 1.16 and above - } - handler.OnRespawn(); - break; - case PacketTypesIn.PlayerPositionAndLook: - // These always need to be read, since we need the field after them for teleport confirm - double x = dataTypes.ReadNextDouble(packetData); - double y = dataTypes.ReadNextDouble(packetData); - double z = dataTypes.ReadNextDouble(packetData); - float yaw = dataTypes.ReadNextFloat(packetData); - float pitch = dataTypes.ReadNextFloat(packetData); - byte locMask = dataTypes.ReadNextByte(packetData); + dataTypes.ReadNextByte(packetData); // Max Players - 1.16.1 and below - // entity handling require player pos for distance calculating - if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled()) - { + if (protocolversion < MC116Version) + dataTypes.ReadNextString(packetData); // Level Type - 1.15 and below + if (protocolversion >= MC114Version) + dataTypes.ReadNextVarInt(packetData); // View distance - 1.14 and above + if (protocolversion >= MC1181Version) + dataTypes.ReadNextVarInt(packetData); // Simulation Distance - 1.18 and above + if (protocolversion >= MC18Version) + dataTypes.ReadNextBool(packetData); // Reduced debug info - 1.8 and above + if (protocolversion >= MC115Version) + dataTypes.ReadNextBool(packetData); // Enable respawn screen - 1.15 and above + + if (protocolversion >= MC116Version) + { + dataTypes.ReadNextBool(packetData); // Is Debug - 1.16 and above + dataTypes.ReadNextBool(packetData); // Is Flat - 1.16 and above + } + break; + case PacketTypesIn.ChatMessage: + string message = dataTypes.ReadNextString(packetData); if (protocolversion >= MC18Version) { - Location location = handler.GetCurrentLocation(); - location.X = (locMask & 1 << 0) != 0 ? location.X + x : x; - location.Y = (locMask & 1 << 1) != 0 ? location.Y + y : y; - location.Z = (locMask & 1 << 2) != 0 ? location.Z + z : z; - handler.UpdateLocation(location, yaw, pitch); + //Hide system messages or xp bar messages? + byte messageType = dataTypes.ReadNextByte(packetData); + if ((messageType == 1 && !Settings.DisplaySystemMessages) + || (messageType == 2 && !Settings.DisplayXPBarMessages)) + break; } - else handler.UpdateLocation(new Location(x, y, z), yaw, pitch); - } - - if (protocolversion >= MC19Version) - { - int teleportID = dataTypes.ReadNextVarInt(packetData); - // Teleport confirm packet - SendPacket(PacketTypesOut.TeleportConfirm, dataTypes.GetVarInt(teleportID)); - } - - if (protocolversion >= MC117Version) dataTypes.ReadNextBool(packetData); - break; - case PacketTypesIn.ChunkData: //TODO implement for 1.17, bit mask is not limited to 0-15 anymore - if (handler.GetTerrainEnabled()) - { - int chunkX = dataTypes.ReadNextInt(packetData); - int chunkZ = dataTypes.ReadNextInt(packetData); - bool chunksContinuous = dataTypes.ReadNextBool(packetData); - if (protocolversion >= MC116Version && protocolversion <= MC1161Version) - dataTypes.ReadNextBool(packetData); // Ignore old data - 1.16 to 1.16.1 only - ushort chunkMask = protocolversion >= MC19Version - ? (ushort)dataTypes.ReadNextVarInt(packetData) - : dataTypes.ReadNextUShort(packetData); - if (protocolversion < MC18Version) + handler.OnTextReceived(message, true); + break; + case PacketTypesIn.Respawn: + if (protocolversion >= MC116Version) { - ushort addBitmap = dataTypes.ReadNextUShort(packetData); - int compressedDataSize = dataTypes.ReadNextInt(packetData); - byte[] compressed = dataTypes.ReadData(compressedDataSize, packetData); - byte[] decompressed = ZlibUtils.Decompress(compressed); - new Task(() => { - pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, addBitmap, currentDimension == 0, chunksContinuous, currentDimension, new Queue(decompressed)); - }).Start(); - } - else - { - if (protocolversion >= MC114Version) - dataTypes.ReadNextNbt(packetData); // Heightmaps - 1.14 and above - int biomesLength = 0; + // TODO handle dimensions for 1.16+, needed for terrain handling if (protocolversion >= MC1162Version) - if (chunksContinuous) - biomesLength = dataTypes.ReadNextVarInt(packetData); // Biomes length - 1.16.2 and above - if (protocolversion >= MC115Version && chunksContinuous) - { - if (protocolversion >= MC1162Version) - { - for (int i = 0; i < biomesLength; i++) - { - // Biomes - 1.16.2 and above - // Don't use ReadNextVarInt because it cost too much time - dataTypes.SkipNextVarInt(packetData); - } - } - else dataTypes.ReadData(1024 * 4, packetData); // Biomes - 1.15 and above - } - int dataSize = dataTypes.ReadNextVarInt(packetData); - new Task(() => { - pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, 0, false, chunksContinuous, currentDimension, packetData); - }).Start(); - } - } - break; - case PacketTypesIn.MapData: - int mapid = dataTypes.ReadNextVarInt(packetData); - byte scale = dataTypes.ReadNextByte(packetData); - bool trackingposition = protocolversion >= MC117Version ? false : dataTypes.ReadNextBool(packetData); - bool locked = false; - if (protocolversion >= MC114Version) - { - locked = dataTypes.ReadNextBool(packetData); - } - if (protocolversion >= MC117Version) - { - trackingposition = dataTypes.ReadNextBool(packetData); - } - int iconcount = dataTypes.ReadNextVarInt(packetData); - handler.OnMapData(mapid, scale, trackingposition, locked, iconcount); - break; - case PacketTypesIn.TradeList: - if ((protocolversion >= MC114Version) && (handler.GetInventoryEnabled())) - { - // MC 1.14 or greater - int windowID = dataTypes.ReadNextVarInt(packetData); - int size = dataTypes.ReadNextByte(packetData); - List trades = new List(); - for (int tradeId = 0; tradeId < size; tradeId++) - { - VillagerTrade trade = dataTypes.ReadNextTrade(packetData, itemPalette); - trades.Add(trade); - } - VillagerInfo villagerInfo = new VillagerInfo() - { - Level = dataTypes.ReadNextVarInt(packetData), - Experience = dataTypes.ReadNextVarInt(packetData), - IsRegularVillager = dataTypes.ReadNextBool(packetData), - CanRestock = dataTypes.ReadNextBool(packetData) - }; - handler.OnTradeList(windowID, trades, villagerInfo); - } - break; - case PacketTypesIn.Title: - if (protocolversion >= MC18Version) - { - int action2 = dataTypes.ReadNextVarInt(packetData); - string titletext = String.Empty; - string subtitletext = String.Empty; - string actionbartext = String.Empty; - string json = String.Empty; - int fadein = -1; - int stay = -1; - int fadeout = -1; - if (protocolversion >= MC110Version) - { - if (action2 == 0) - { - json = titletext; - titletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); - } - else if (action2 == 1) - { - json = subtitletext; - subtitletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); - } - else if (action2 == 2) - { - json = actionbartext; - actionbartext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); - } - else if (action2 == 3) - { - fadein = dataTypes.ReadNextInt(packetData); - stay = dataTypes.ReadNextInt(packetData); - fadeout = dataTypes.ReadNextInt(packetData); - } + dataTypes.ReadNextNbt(packetData); + else + dataTypes.ReadNextString(packetData); + this.currentDimension = 0; } else { - if (action2 == 0) - { - json = titletext; - titletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); - } - else if (action2 == 1) - { - json = subtitletext; - subtitletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); - } - else if (action2 == 2) - { - fadein = dataTypes.ReadNextInt(packetData); - stay = dataTypes.ReadNextInt(packetData); - fadeout = dataTypes.ReadNextInt(packetData); - } + // 1.15 and below + this.currentDimension = dataTypes.ReadNextInt(packetData); } - handler.OnTitle(action2, titletext, subtitletext, actionbartext, fadein, stay, fadeout, json); - } - break; - case PacketTypesIn.MultiBlockChange: - if (handler.GetTerrainEnabled()) - { - if (protocolversion >= MC1162Version) + if (protocolversion >= MC116Version) + dataTypes.ReadNextString(packetData); // World Name - 1.16 and above + if (protocolversion < MC114Version) + dataTypes.ReadNextByte(packetData); // Difficulty - 1.13 and below + if (protocolversion >= MC115Version) + dataTypes.ReadNextLong(packetData); // Hashed world seed - 1.15 and above + dataTypes.ReadNextByte(packetData); // Gamemode + if (protocolversion >= MC116Version) + dataTypes.ReadNextByte(packetData); // Previous Game mode - 1.16 and above + if (protocolversion < MC116Version) + dataTypes.ReadNextString(packetData); // Level Type - 1.15 and below + if (protocolversion >= MC116Version) { - long chunkSection = dataTypes.ReadNextLong(packetData); - int sectionX = (int)(chunkSection >> 42); - int sectionY = (int)((chunkSection << 44) >> 44); - int sectionZ = (int)((chunkSection << 22) >> 42); - dataTypes.ReadNextBool(packetData); // Useless boolean - int blocksSize = dataTypes.ReadNextVarInt(packetData); - for (int i = 0; i < blocksSize; i++) - { - ulong block = (ulong)dataTypes.ReadNextVarLong(packetData); - int blockId = (int)(block >> 12); - int localX = (int)((block >> 8) & 0x0F); - int localZ = (int)((block >> 4) & 0x0F); - int localY = (int)(block & 0x0F); + dataTypes.ReadNextBool(packetData); // Is Debug - 1.16 and above + dataTypes.ReadNextBool(packetData); // Is Flat - 1.16 and above + dataTypes.ReadNextBool(packetData); // Copy metadata - 1.16 and above + } + handler.OnRespawn(); + break; + case PacketTypesIn.PlayerPositionAndLook: + // These always need to be read, since we need the field after them for teleport confirm + double x = dataTypes.ReadNextDouble(packetData); + double y = dataTypes.ReadNextDouble(packetData); + double z = dataTypes.ReadNextDouble(packetData); + float yaw = dataTypes.ReadNextFloat(packetData); + float pitch = dataTypes.ReadNextFloat(packetData); + byte locMask = dataTypes.ReadNextByte(packetData); - Block b = new Block((ushort)blockId); - int blockX = (sectionX * 16) + localX; - int blockY = (sectionY * 16) + localY; - int blockZ = (sectionZ * 16) + localZ; - var l = new Location(blockX, blockY, blockZ); - handler.GetWorld().SetBlock(l, b); + // entity handling require player pos for distance calculating + if (handler.GetTerrainEnabled() || handler.GetEntityHandlingEnabled()) + { + if (protocolversion >= MC18Version) + { + Location location = handler.GetCurrentLocation(); + location.X = (locMask & 1 << 0) != 0 ? location.X + x : x; + location.Y = (locMask & 1 << 1) != 0 ? location.Y + y : y; + location.Z = (locMask & 1 << 2) != 0 ? location.Z + z : z; + handler.UpdateLocation(location, yaw, pitch); } + else handler.UpdateLocation(new Location(x, y, z), yaw, pitch); } - else + + if (protocolversion >= MC19Version) + { + int teleportID = dataTypes.ReadNextVarInt(packetData); + // Teleport confirm packet + SendPacket(PacketTypesOut.TeleportConfirm, dataTypes.GetVarInt(teleportID)); + } + + if (protocolversion >= MC117Version) dataTypes.ReadNextBool(packetData); + break; + case PacketTypesIn.ChunkData: //TODO implement for 1.17, bit mask is not limited to 0-15 anymore + if (handler.GetTerrainEnabled()) { int chunkX = dataTypes.ReadNextInt(packetData); int chunkZ = dataTypes.ReadNextInt(packetData); - int recordCount = protocolversion < MC18Version - ? (int)dataTypes.ReadNextShort(packetData) - : dataTypes.ReadNextVarInt(packetData); - - for (int i = 0; i < recordCount; i++) + bool chunksContinuous = dataTypes.ReadNextBool(packetData); + if (protocolversion >= MC116Version && protocolversion <= MC1161Version) + dataTypes.ReadNextBool(packetData); // Ignore old data - 1.16 to 1.16.1 only + ushort chunkMask = protocolversion >= MC19Version + ? (ushort)dataTypes.ReadNextVarInt(packetData) + : dataTypes.ReadNextUShort(packetData); + if (protocolversion < MC18Version) { - byte locationXZ; - ushort blockIdMeta; - int blockY; - - if (protocolversion < MC18Version) + ushort addBitmap = dataTypes.ReadNextUShort(packetData); + int compressedDataSize = dataTypes.ReadNextInt(packetData); + byte[] compressed = dataTypes.ReadData(compressedDataSize, packetData); + byte[] decompressed = ZlibUtils.Decompress(compressed); + new Task(() => { - blockIdMeta = dataTypes.ReadNextUShort(packetData); - blockY = (ushort)dataTypes.ReadNextByte(packetData); - locationXZ = dataTypes.ReadNextByte(packetData); - } - else - { - locationXZ = dataTypes.ReadNextByte(packetData); - blockY = (ushort)dataTypes.ReadNextByte(packetData); - blockIdMeta = (ushort)dataTypes.ReadNextVarInt(packetData); - } - - int blockX = locationXZ >> 4; - int blockZ = locationXZ & 0x0F; - Block block = new Block(blockIdMeta); - handler.GetWorld().SetBlock(new Location(chunkX, chunkZ, blockX, blockY, blockZ), block); + pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, addBitmap, currentDimension == 0, chunksContinuous, currentDimension, new Queue(decompressed)); + }).Start(); } - } - } - break; - case PacketTypesIn.BlockChange: - if (handler.GetTerrainEnabled()) - { - if (protocolversion < MC18Version) - { - int blockX = dataTypes.ReadNextInt(packetData); - int blockY = dataTypes.ReadNextByte(packetData); - int blockZ = dataTypes.ReadNextInt(packetData); - short blockId = (short)dataTypes.ReadNextVarInt(packetData); - byte blockMeta = dataTypes.ReadNextByte(packetData); - handler.GetWorld().SetBlock(new Location(blockX, blockY, blockZ), new Block(blockId, blockMeta)); - } - else - { - handler.GetWorld().SetBlock(dataTypes.ReadNextLocation(packetData), new Block((ushort)dataTypes.ReadNextVarInt(packetData))); - } - } - break; - case PacketTypesIn.MapChunkBulk: - if (protocolversion < MC19Version && handler.GetTerrainEnabled()) - { - int chunkCount; - bool hasSkyLight; - Queue chunkData = packetData; - - //Read global fields - if (protocolversion < MC18Version) - { - chunkCount = dataTypes.ReadNextShort(packetData); - int compressedDataSize = dataTypes.ReadNextInt(packetData); - hasSkyLight = dataTypes.ReadNextBool(packetData); - byte[] compressed = dataTypes.ReadData(compressedDataSize, packetData); - byte[] decompressed = ZlibUtils.Decompress(compressed); - chunkData = new Queue(decompressed); - } - else - { - hasSkyLight = dataTypes.ReadNextBool(packetData); - chunkCount = dataTypes.ReadNextVarInt(packetData); - } - - //Read chunk records - int[] chunkXs = new int[chunkCount]; - int[] chunkZs = new int[chunkCount]; - ushort[] chunkMasks = new ushort[chunkCount]; - ushort[] addBitmaps = new ushort[chunkCount]; - for (int chunkColumnNo = 0; chunkColumnNo < chunkCount; chunkColumnNo++) - { - chunkXs[chunkColumnNo] = dataTypes.ReadNextInt(packetData); - chunkZs[chunkColumnNo] = dataTypes.ReadNextInt(packetData); - chunkMasks[chunkColumnNo] = dataTypes.ReadNextUShort(packetData); - addBitmaps[chunkColumnNo] = protocolversion < MC18Version - ? dataTypes.ReadNextUShort(packetData) - : (ushort)0; - } - - //Process chunk records - for (int chunkColumnNo = 0; chunkColumnNo < chunkCount; chunkColumnNo++) - pTerrain.ProcessChunkColumnData(chunkXs[chunkColumnNo], chunkZs[chunkColumnNo], chunkMasks[chunkColumnNo], addBitmaps[chunkColumnNo], hasSkyLight, true, currentDimension, chunkData); - } - break; - case PacketTypesIn.UnloadChunk: - if (protocolversion >= MC19Version && handler.GetTerrainEnabled()) - { - int chunkX = dataTypes.ReadNextInt(packetData); - int chunkZ = dataTypes.ReadNextInt(packetData); - handler.GetWorld()[chunkX, chunkZ] = null; - } - break; - case PacketTypesIn.PlayerInfo: - if (protocolversion >= MC18Version) - { - int action = dataTypes.ReadNextVarInt(packetData); - int numActions = dataTypes.ReadNextVarInt(packetData); - for (int i = 0; i < numActions; i++) - { - Guid uuid = dataTypes.ReadNextUUID(packetData); - switch (action) + else { - case 0x00: //Player Join - string name = dataTypes.ReadNextString(packetData); - int propNum = dataTypes.ReadNextVarInt(packetData); - for (int p = 0; p < propNum; p++) + if (protocolversion >= MC114Version) + dataTypes.ReadNextNbt(packetData); // Heightmaps - 1.14 and above + int biomesLength = 0; + if (protocolversion >= MC1162Version) + if (chunksContinuous) + biomesLength = dataTypes.ReadNextVarInt(packetData); // Biomes length - 1.16.2 and above + if (protocolversion >= MC115Version && chunksContinuous) + { + if (protocolversion >= MC1162Version) { - string key = dataTypes.ReadNextString(packetData); - string val = dataTypes.ReadNextString(packetData); - if (dataTypes.ReadNextBool(packetData)) - dataTypes.ReadNextString(packetData); + for (int i = 0; i < biomesLength; i++) + { + // Biomes - 1.16.2 and above + // Don't use ReadNextVarInt because it cost too much time + dataTypes.SkipNextVarInt(packetData); + } } - handler.OnGamemodeUpdate(uuid, dataTypes.ReadNextVarInt(packetData)); - dataTypes.ReadNextVarInt(packetData); - if (dataTypes.ReadNextBool(packetData)) - dataTypes.ReadNextString(packetData); - handler.OnPlayerJoin(uuid, name); - break; - case 0x01: //Update gamemode - handler.OnGamemodeUpdate(uuid, dataTypes.ReadNextVarInt(packetData)); - break; - case 0x02: //Update latency - int latency = dataTypes.ReadNextVarInt(packetData); - handler.OnLatencyUpdate(uuid, latency); //Update latency; - break; - case 0x03: //Update display name - if (dataTypes.ReadNextBool(packetData)) - dataTypes.ReadNextString(packetData); - break; - case 0x04: //Player Leave - handler.OnPlayerLeave(uuid); - break; - default: - //Unknown player list item type - break; + else dataTypes.ReadData(1024 * 4, packetData); // Biomes - 1.15 and above + } + int dataSize = dataTypes.ReadNextVarInt(packetData); + new Task(() => + { + pTerrain.ProcessChunkColumnData(chunkX, chunkZ, chunkMask, 0, false, chunksContinuous, currentDimension, packetData); + }).Start(); } } - } - else //MC 1.7.X does not provide UUID in tab-list updates - { - string name = dataTypes.ReadNextString(packetData); - bool online = dataTypes.ReadNextBool(packetData); - short ping = dataTypes.ReadNextShort(packetData); - Guid FakeUUID = new Guid(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(name)).Take(16).ToArray()); - if (online) - handler.OnPlayerJoin(FakeUUID, name); - else handler.OnPlayerLeave(FakeUUID); - } - break; - case PacketTypesIn.TabComplete: - if (protocolversion >= MC113Version) - { - autocomplete_transaction_id = dataTypes.ReadNextVarInt(packetData); - dataTypes.ReadNextVarInt(packetData); // Start of text to replace - dataTypes.ReadNextVarInt(packetData); // Length of text to replace - } - - int autocomplete_count = dataTypes.ReadNextVarInt(packetData); - autocomplete_result.Clear(); - - for (int i = 0; i < autocomplete_count; i++) - { - autocomplete_result.Add(dataTypes.ReadNextString(packetData)); - if (protocolversion >= MC113Version) + break; + case PacketTypesIn.MapData: + int mapid = dataTypes.ReadNextVarInt(packetData); + byte scale = dataTypes.ReadNextByte(packetData); + bool trackingposition = protocolversion >= MC117Version ? false : dataTypes.ReadNextBool(packetData); + bool locked = false; + if (protocolversion >= MC114Version) { - // Skip optional tooltip for each tab-complete result - if (dataTypes.ReadNextBool(packetData)) - dataTypes.ReadNextString(packetData); + locked = dataTypes.ReadNextBool(packetData); } - } - - autocomplete_received = true; - break; - case PacketTypesIn.PluginMessage: - String channel = dataTypes.ReadNextString(packetData); - // Length is unneeded as the whole remaining packetData is the entire payload of the packet. - if (protocolversion < MC18Version) - pForge.ReadNextVarShort(packetData); - handler.OnPluginChannelMessage(channel, packetData.ToArray()); - return pForge.HandlePluginMessage(channel, packetData, ref currentDimension); - case PacketTypesIn.Disconnect: - handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); - return false; - case PacketTypesIn.SetCompression: - if (protocolversion >= MC18Version && protocolversion < MC19Version) - compression_treshold = dataTypes.ReadNextVarInt(packetData); - break; - case PacketTypesIn.OpenWindow: - if (handler.GetInventoryEnabled()) - { - if (protocolversion < MC114Version) + if (protocolversion >= MC117Version) { - // MC 1.13 or lower - byte windowID = dataTypes.ReadNextByte(packetData); - string type = dataTypes.ReadNextString(packetData).Replace("minecraft:", "").ToUpper(); - ContainerTypeOld inventoryType = (ContainerTypeOld)Enum.Parse(typeof(ContainerTypeOld), type); - string title = dataTypes.ReadNextString(packetData); - byte slots = dataTypes.ReadNextByte(packetData); - Container inventory = new Container(windowID, inventoryType, ChatParser.ParseText(title)); - handler.OnInventoryOpen(windowID, inventory); + trackingposition = dataTypes.ReadNextBool(packetData); } - else + int iconcount = dataTypes.ReadNextVarInt(packetData); + handler.OnMapData(mapid, scale, trackingposition, locked, iconcount); + break; + case PacketTypesIn.TradeList: + if ((protocolversion >= MC114Version) && (handler.GetInventoryEnabled())) { // MC 1.14 or greater int windowID = dataTypes.ReadNextVarInt(packetData); - int windowType = dataTypes.ReadNextVarInt(packetData); - string title = dataTypes.ReadNextString(packetData); - Container inventory = new Container(windowID, windowType, ChatParser.ParseText(title)); - handler.OnInventoryOpen(windowID, inventory); + int size = dataTypes.ReadNextByte(packetData); + List trades = new List(); + for (int tradeId = 0; tradeId < size; tradeId++) + { + VillagerTrade trade = dataTypes.ReadNextTrade(packetData, itemPalette); + trades.Add(trade); + } + VillagerInfo villagerInfo = new VillagerInfo() + { + Level = dataTypes.ReadNextVarInt(packetData), + Experience = dataTypes.ReadNextVarInt(packetData), + IsRegularVillager = dataTypes.ReadNextBool(packetData), + CanRestock = dataTypes.ReadNextBool(packetData) + }; + handler.OnTradeList(windowID, trades, villagerInfo); } - } - break; - case PacketTypesIn.CloseWindow: - if (handler.GetInventoryEnabled()) - { - byte windowID = dataTypes.ReadNextByte(packetData); - lock (window_actions) { window_actions[windowID] = 0; } - handler.OnInventoryClose(windowID); - } - break; - case PacketTypesIn.WindowItems: - if (handler.GetInventoryEnabled()) - { - byte windowId = dataTypes.ReadNextByte(packetData); - - int stateId = -1; - - if(protocolversion >= MC1181Version) - stateId = dataTypes.ReadNextVarInt(packetData); - - int elements = dataTypes.ReadNextVarInt(packetData); - Dictionary inventorySlots = new Dictionary(); - for (short slotId = 0; slotId < elements; slotId++) - { - Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); - if (item != null) - inventorySlots[slotId] = item; - } - handler.OnWindowItems(windowId, inventorySlots); - } - break; - case PacketTypesIn.SetSlot: - if (handler.GetInventoryEnabled()) - { - byte windowID = dataTypes.ReadNextByte(packetData); - - int stateId = -1; - - if(protocolversion >= MC1181Version) - stateId = dataTypes.ReadNextVarInt(packetData); - - short slotID = dataTypes.ReadNextShort(packetData); - Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); - handler.OnSetSlot(windowID, slotID, item); - } - break; - case PacketTypesIn.WindowConfirmation: - if (handler.GetInventoryEnabled()) - { - byte windowID = dataTypes.ReadNextByte(packetData); - short actionID = dataTypes.ReadNextShort(packetData); - bool accepted = dataTypes.ReadNextBool(packetData); - if (!accepted) - { - SendWindowConfirmation(windowID, actionID, accepted); - } - } - break; - case PacketTypesIn.ResourcePackSend: - string url = dataTypes.ReadNextString(packetData); - string hash = dataTypes.ReadNextString(packetData); - bool forced = true; // Assume forced for MC 1.16 and below - if (protocolversion >= MC117Version) - { - forced = dataTypes.ReadNextBool(packetData); - String forcedMessage = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); - } - // Some server plugins may send invalid resource packs to probe the client and we need to ignore them (issue #1056) - if (!url.StartsWith("http") && hash.Length != 40) // Some server may have null hash value break; - //Send back "accepted" and "successfully loaded" responses for plugins or server config making use of resource pack mandatory - byte[] responseHeader = new byte[0]; - if (protocolversion < MC110Version) //MC 1.10 does not include resource pack hash in responses - responseHeader = dataTypes.ConcatBytes(dataTypes.GetVarInt(hash.Length), Encoding.UTF8.GetBytes(hash)); - SendPacket(PacketTypesOut.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(3))); //Accepted pack - SendPacket(PacketTypesOut.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(0))); //Successfully loaded - break; - case PacketTypesIn.SpawnEntity: - if (handler.GetEntityHandlingEnabled()) - { - Entity entity = dataTypes.ReadNextEntity(packetData, entityPalette, false); - handler.OnSpawnEntity(entity); - } - break; - case PacketTypesIn.EntityEquipment: - if (handler.GetEntityHandlingEnabled()) - { - int entityid = dataTypes.ReadNextVarInt(packetData); - if (protocolversion >= MC116Version) + case PacketTypesIn.Title: + if (protocolversion >= MC18Version) { - bool hasNext; - do + int action2 = dataTypes.ReadNextVarInt(packetData); + string titletext = String.Empty; + string subtitletext = String.Empty; + string actionbartext = String.Empty; + string json = String.Empty; + int fadein = -1; + int stay = -1; + int fadeout = -1; + if (protocolversion >= MC110Version) { - byte bitsData = dataTypes.ReadNextByte(packetData); - // Top bit set if another entry follows, and otherwise unset if this is the last item in the array - hasNext = (bitsData >> 7) == 1 ? true : false; - int slot2 = bitsData >> 1; - Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); - handler.OnEntityEquipment(entityid, slot2, item); - } while (hasNext); - } - else - { - int slot2 = dataTypes.ReadNextVarInt(packetData); - Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); - handler.OnEntityEquipment(entityid, slot2, item); - } - } - break; - case PacketTypesIn.SpawnLivingEntity: - if (handler.GetEntityHandlingEnabled()) - { - Entity entity = dataTypes.ReadNextEntity(packetData, entityPalette, true); - // packet before 1.15 has metadata at the end - // this is not handled in dataTypes.ReadNextEntity() - // we are simply ignoring leftover data in packet - handler.OnSpawnEntity(entity); - } - break; - case PacketTypesIn.SpawnPlayer: - if (handler.GetEntityHandlingEnabled()) - { - int EntityID = dataTypes.ReadNextVarInt(packetData); - Guid UUID = dataTypes.ReadNextUUID(packetData); - double X = dataTypes.ReadNextDouble(packetData); - double Y = dataTypes.ReadNextDouble(packetData); - double Z = dataTypes.ReadNextDouble(packetData); - byte Yaw = dataTypes.ReadNextByte(packetData); - byte Pitch = dataTypes.ReadNextByte(packetData); - - Location EntityLocation = new Location(X, Y, Z); - - handler.OnSpawnPlayer(EntityID, UUID, EntityLocation, Yaw, Pitch); - } - break; - case PacketTypesIn.EntityEffect: - if (handler.GetEntityHandlingEnabled()) - { - int entityid = dataTypes.ReadNextVarInt(packetData); - Inventory.Effects effect = Effects.Speed; - if (Enum.TryParse(dataTypes.ReadNextByte(packetData).ToString(), out effect)) - { - int amplifier = dataTypes.ReadNextByte(packetData); - int duration = dataTypes.ReadNextVarInt(packetData); - byte flags = dataTypes.ReadNextByte(packetData); - handler.OnEntityEffect(entityid, effect, amplifier, duration, flags); - } - } - break; - case PacketTypesIn.DestroyEntities: - if (handler.GetEntityHandlingEnabled()) - { - int EntityCount = dataTypes.ReadNextVarInt(packetData); - int[] EntitiesList = new int[EntityCount]; - for (int i = 0; i < EntityCount; i++) - { - EntitiesList[i] = dataTypes.ReadNextVarInt(packetData); - } - handler.OnDestroyEntities(EntitiesList); - } - break; - case PacketTypesIn.DestroyEntity: - if (handler.GetEntityHandlingEnabled()) - { - handler.OnDestroyEntities(new [] { dataTypes.ReadNextVarInt(packetData) }); - } - break; - case PacketTypesIn.EntityPosition: - if (handler.GetEntityHandlingEnabled()) - { - int EntityID = dataTypes.ReadNextVarInt(packetData); - Double DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); - Double DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); - Double DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); - bool OnGround = dataTypes.ReadNextBool(packetData); - DeltaX = DeltaX / (128 * 32); - DeltaY = DeltaY / (128 * 32); - DeltaZ = DeltaZ / (128 * 32); - handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround); - } - break; - case PacketTypesIn.EntityPositionAndRotation: - if (handler.GetEntityHandlingEnabled()) - { - int EntityID = dataTypes.ReadNextVarInt(packetData); - Double DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); - Double DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); - Double DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); - byte _yaw = dataTypes.ReadNextByte(packetData); - byte _pitch = dataTypes.ReadNextByte(packetData); - bool OnGround = dataTypes.ReadNextBool(packetData); - DeltaX = DeltaX / (128 * 32); - DeltaY = DeltaY / (128 * 32); - DeltaZ = DeltaZ / (128 * 32); - handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround); - } - break; - case PacketTypesIn.EntityProperties: - if (handler.GetEntityHandlingEnabled()) - { - int EntityID = dataTypes.ReadNextVarInt(packetData); - int NumberOfProperties = protocolversion >= MC117Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); - Dictionary keys = new Dictionary(); - for (int i = 0; i < NumberOfProperties; i++) - { - string _key = dataTypes.ReadNextString(packetData); - Double _value = dataTypes.ReadNextDouble(packetData); - - List op0 = new List(); - List op1 = new List(); - List op2 = new List(); - int NumberOfModifiers = dataTypes.ReadNextVarInt(packetData); - for (int j = 0; j < NumberOfModifiers; j++) - { - dataTypes.ReadNextUUID(packetData); - Double amount = dataTypes.ReadNextDouble(packetData); - byte operation = dataTypes.ReadNextByte(packetData); - switch (operation) + if (action2 == 0) { - case 0: op0.Add(amount); break; - case 1: op1.Add(amount); break; - case 2: op2.Add(amount + 1); break; + json = titletext; + titletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); + } + else if (action2 == 1) + { + json = subtitletext; + subtitletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); + } + else if (action2 == 2) + { + json = actionbartext; + actionbartext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); + } + else if (action2 == 3) + { + fadein = dataTypes.ReadNextInt(packetData); + stay = dataTypes.ReadNextInt(packetData); + fadeout = dataTypes.ReadNextInt(packetData); } } - if (op0.Count > 0) _value += op0.Sum(); - if (op1.Count > 0) _value *= 1 + op1.Sum(); - if (op2.Count > 0) _value *= op2.Aggregate((a, _x) => a * _x); - keys.Add(_key, _value); + else + { + if (action2 == 0) + { + json = titletext; + titletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); + } + else if (action2 == 1) + { + json = subtitletext; + subtitletext = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); + } + else if (action2 == 2) + { + fadein = dataTypes.ReadNextInt(packetData); + stay = dataTypes.ReadNextInt(packetData); + fadeout = dataTypes.ReadNextInt(packetData); + } + } + handler.OnTitle(action2, titletext, subtitletext, actionbartext, fadein, stay, fadeout, json); } - handler.OnEntityProperties(EntityID, keys); - } - break; - case PacketTypesIn.EntityMetadata: - if (handler.GetEntityHandlingEnabled()) - { - int EntityID = dataTypes.ReadNextVarInt(packetData); - Dictionary metadata = dataTypes.ReadNextMetadata(packetData, itemPalette); - int healthField = protocolversion >= MC114Version ? 8 : 7; // Health is field no. 7 in 1.10+ and 8 in 1.14+ - if (metadata.ContainsKey(healthField) && metadata[healthField] != null && metadata[healthField].GetType() == typeof(float)) - handler.OnEntityHealth(EntityID, (float)metadata[healthField]); - handler.OnEntityMetadata(EntityID, metadata); - } - break; - case PacketTypesIn.EntityStatus: - if (handler.GetEntityHandlingEnabled()) - { - int entityId = dataTypes.ReadNextInt(packetData); - byte status = dataTypes.ReadNextByte(packetData); - handler.OnEntityStatus(entityId, status); - } - break; - case PacketTypesIn.TimeUpdate: - long WorldAge = dataTypes.ReadNextLong(packetData); - long TimeOfday = dataTypes.ReadNextLong(packetData); - handler.OnTimeUpdate(WorldAge, TimeOfday); - break; - case PacketTypesIn.EntityTeleport: - if (handler.GetEntityHandlingEnabled()) - { - int EntityID = dataTypes.ReadNextVarInt(packetData); - Double X = dataTypes.ReadNextDouble(packetData); - Double Y = dataTypes.ReadNextDouble(packetData); - Double Z = dataTypes.ReadNextDouble(packetData); - byte EntityYaw = dataTypes.ReadNextByte(packetData); - byte EntityPitch = dataTypes.ReadNextByte(packetData); - bool OnGround = dataTypes.ReadNextBool(packetData); - handler.OnEntityTeleport(EntityID, X, Y, Z, OnGround); - } - break; - case PacketTypesIn.UpdateHealth: - float health = dataTypes.ReadNextFloat(packetData); - int food; - if (protocolversion >= MC18Version) - food = dataTypes.ReadNextVarInt(packetData); - else - food = dataTypes.ReadNextShort(packetData); - dataTypes.ReadNextFloat(packetData); // Food Saturation - handler.OnUpdateHealth(health, food); - break; - case PacketTypesIn.SetExperience: - float experiencebar = dataTypes.ReadNextFloat(packetData); - int level = dataTypes.ReadNextVarInt(packetData); - int totalexperience = dataTypes.ReadNextVarInt(packetData); - handler.OnSetExperience(experiencebar, level, totalexperience); - break; - case PacketTypesIn.Explosion: - Location explosionLocation = new Location(dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData)); - float explosionStrength = dataTypes.ReadNextFloat(packetData); - int explosionBlockCount = protocolversion >= MC117Version - ? dataTypes.ReadNextVarInt(packetData) - : dataTypes.ReadNextInt(packetData); - // Ignoring additional fields (records, pushback) - handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); - break; - case PacketTypesIn.HeldItemChange: - byte slot = dataTypes.ReadNextByte(packetData); - handler.OnHeldItemChange(slot); - break; - case PacketTypesIn.ScoreboardObjective: - string objectivename = dataTypes.ReadNextString(packetData); - byte mode = dataTypes.ReadNextByte(packetData); - string objectivevalue = String.Empty; - int type2 = -1; - if (mode == 0 || mode == 2) - { - objectivevalue = dataTypes.ReadNextString(packetData); - type2 = dataTypes.ReadNextVarInt(packetData); - } - handler.OnScoreboardObjective(objectivename, mode, objectivevalue, type2); - break; - case PacketTypesIn.UpdateScore: - string entityname = dataTypes.ReadNextString(packetData); - byte action3 = dataTypes.ReadNextByte(packetData); - string objectivename2 = null; - int value = -1; - if (action3 != 1 || protocolversion >= MC18Version) - objectivename2 = dataTypes.ReadNextString(packetData); - if (action3 != 1) - value = dataTypes.ReadNextVarInt(packetData); - handler.OnUpdateScore(entityname, action3, objectivename2, value); - break; - case PacketTypesIn.BlockBreakAnimation: - if (handler.GetEntityHandlingEnabled() && handler.GetTerrainEnabled()) - { - int playerId = dataTypes.ReadNextVarInt(packetData); - Location blockLocation = dataTypes.ReadNextLocation(packetData); - byte stage = dataTypes.ReadNextByte(packetData); - handler.OnBlockBreakAnimation(playerId, blockLocation, stage); - } - break; - case PacketTypesIn.EntityAnimation: - if (handler.GetEntityHandlingEnabled()) - { - int playerId2 = dataTypes.ReadNextVarInt(packetData); - byte animation = dataTypes.ReadNextByte(packetData); - handler.OnEntityAnimation(playerId2, animation); - } - break; - default: - return false; //Ignored packet - } + break; + case PacketTypesIn.MultiBlockChange: + if (handler.GetTerrainEnabled()) + { + if (protocolversion >= MC1162Version) + { + long chunkSection = dataTypes.ReadNextLong(packetData); + int sectionX = (int)(chunkSection >> 42); + int sectionY = (int)((chunkSection << 44) >> 44); + int sectionZ = (int)((chunkSection << 22) >> 42); + dataTypes.ReadNextBool(packetData); // Useless boolean + int blocksSize = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < blocksSize; i++) + { + ulong block = (ulong)dataTypes.ReadNextVarLong(packetData); + int blockId = (int)(block >> 12); + int localX = (int)((block >> 8) & 0x0F); + int localZ = (int)((block >> 4) & 0x0F); + int localY = (int)(block & 0x0F); + + Block b = new Block((ushort)blockId); + int blockX = (sectionX * 16) + localX; + int blockY = (sectionY * 16) + localY; + int blockZ = (sectionZ * 16) + localZ; + var l = new Location(blockX, blockY, blockZ); + handler.GetWorld().SetBlock(l, b); + } + } + else + { + int chunkX = dataTypes.ReadNextInt(packetData); + int chunkZ = dataTypes.ReadNextInt(packetData); + int recordCount = protocolversion < MC18Version + ? (int)dataTypes.ReadNextShort(packetData) + : dataTypes.ReadNextVarInt(packetData); + + for (int i = 0; i < recordCount; i++) + { + byte locationXZ; + ushort blockIdMeta; + int blockY; + + if (protocolversion < MC18Version) + { + blockIdMeta = dataTypes.ReadNextUShort(packetData); + blockY = (ushort)dataTypes.ReadNextByte(packetData); + locationXZ = dataTypes.ReadNextByte(packetData); + } + else + { + locationXZ = dataTypes.ReadNextByte(packetData); + blockY = (ushort)dataTypes.ReadNextByte(packetData); + blockIdMeta = (ushort)dataTypes.ReadNextVarInt(packetData); + } + + int blockX = locationXZ >> 4; + int blockZ = locationXZ & 0x0F; + Block block = new Block(blockIdMeta); + handler.GetWorld().SetBlock(new Location(chunkX, chunkZ, blockX, blockY, blockZ), block); + } + } + } + break; + case PacketTypesIn.BlockChange: + if (handler.GetTerrainEnabled()) + { + if (protocolversion < MC18Version) + { + int blockX = dataTypes.ReadNextInt(packetData); + int blockY = dataTypes.ReadNextByte(packetData); + int blockZ = dataTypes.ReadNextInt(packetData); + short blockId = (short)dataTypes.ReadNextVarInt(packetData); + byte blockMeta = dataTypes.ReadNextByte(packetData); + handler.GetWorld().SetBlock(new Location(blockX, blockY, blockZ), new Block(blockId, blockMeta)); + } + else + { + handler.GetWorld().SetBlock(dataTypes.ReadNextLocation(packetData), new Block((ushort)dataTypes.ReadNextVarInt(packetData))); + } + } + break; + case PacketTypesIn.MapChunkBulk: + if (protocolversion < MC19Version && handler.GetTerrainEnabled()) + { + int chunkCount; + bool hasSkyLight; + Queue chunkData = packetData; + + //Read global fields + if (protocolversion < MC18Version) + { + chunkCount = dataTypes.ReadNextShort(packetData); + int compressedDataSize = dataTypes.ReadNextInt(packetData); + hasSkyLight = dataTypes.ReadNextBool(packetData); + byte[] compressed = dataTypes.ReadData(compressedDataSize, packetData); + byte[] decompressed = ZlibUtils.Decompress(compressed); + chunkData = new Queue(decompressed); + } + else + { + hasSkyLight = dataTypes.ReadNextBool(packetData); + chunkCount = dataTypes.ReadNextVarInt(packetData); + } + + //Read chunk records + int[] chunkXs = new int[chunkCount]; + int[] chunkZs = new int[chunkCount]; + ushort[] chunkMasks = new ushort[chunkCount]; + ushort[] addBitmaps = new ushort[chunkCount]; + for (int chunkColumnNo = 0; chunkColumnNo < chunkCount; chunkColumnNo++) + { + chunkXs[chunkColumnNo] = dataTypes.ReadNextInt(packetData); + chunkZs[chunkColumnNo] = dataTypes.ReadNextInt(packetData); + chunkMasks[chunkColumnNo] = dataTypes.ReadNextUShort(packetData); + addBitmaps[chunkColumnNo] = protocolversion < MC18Version + ? dataTypes.ReadNextUShort(packetData) + : (ushort)0; + } + + //Process chunk records + for (int chunkColumnNo = 0; chunkColumnNo < chunkCount; chunkColumnNo++) + pTerrain.ProcessChunkColumnData(chunkXs[chunkColumnNo], chunkZs[chunkColumnNo], chunkMasks[chunkColumnNo], addBitmaps[chunkColumnNo], hasSkyLight, true, currentDimension, chunkData); + } + break; + case PacketTypesIn.UnloadChunk: + if (protocolversion >= MC19Version && handler.GetTerrainEnabled()) + { + int chunkX = dataTypes.ReadNextInt(packetData); + int chunkZ = dataTypes.ReadNextInt(packetData); + handler.GetWorld()[chunkX, chunkZ] = null; + } + break; + case PacketTypesIn.PlayerInfo: + if (protocolversion >= MC18Version) + { + int action = dataTypes.ReadNextVarInt(packetData); + int numActions = dataTypes.ReadNextVarInt(packetData); + for (int i = 0; i < numActions; i++) + { + Guid uuid = dataTypes.ReadNextUUID(packetData); + switch (action) + { + case 0x00: //Player Join + string name = dataTypes.ReadNextString(packetData); + int propNum = dataTypes.ReadNextVarInt(packetData); + for (int p = 0; p < propNum; p++) + { + string key = dataTypes.ReadNextString(packetData); + string val = dataTypes.ReadNextString(packetData); + if (dataTypes.ReadNextBool(packetData)) + dataTypes.ReadNextString(packetData); + } + handler.OnGamemodeUpdate(uuid, dataTypes.ReadNextVarInt(packetData)); + dataTypes.ReadNextVarInt(packetData); + if (dataTypes.ReadNextBool(packetData)) + dataTypes.ReadNextString(packetData); + handler.OnPlayerJoin(uuid, name); + break; + case 0x01: //Update gamemode + handler.OnGamemodeUpdate(uuid, dataTypes.ReadNextVarInt(packetData)); + break; + case 0x02: //Update latency + int latency = dataTypes.ReadNextVarInt(packetData); + handler.OnLatencyUpdate(uuid, latency); //Update latency; + break; + case 0x03: //Update display name + if (dataTypes.ReadNextBool(packetData)) + dataTypes.ReadNextString(packetData); + break; + case 0x04: //Player Leave + handler.OnPlayerLeave(uuid); + break; + default: + //Unknown player list item type + break; + } + } + } + else //MC 1.7.X does not provide UUID in tab-list updates + { + string name = dataTypes.ReadNextString(packetData); + bool online = dataTypes.ReadNextBool(packetData); + short ping = dataTypes.ReadNextShort(packetData); + Guid FakeUUID = new Guid(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(name)).Take(16).ToArray()); + if (online) + handler.OnPlayerJoin(FakeUUID, name); + else handler.OnPlayerLeave(FakeUUID); + } + break; + case PacketTypesIn.TabComplete: + if (protocolversion >= MC113Version) + { + autocomplete_transaction_id = dataTypes.ReadNextVarInt(packetData); + dataTypes.ReadNextVarInt(packetData); // Start of text to replace + dataTypes.ReadNextVarInt(packetData); // Length of text to replace + } + + int autocomplete_count = dataTypes.ReadNextVarInt(packetData); + autocomplete_result.Clear(); + + for (int i = 0; i < autocomplete_count; i++) + { + autocomplete_result.Add(dataTypes.ReadNextString(packetData)); + if (protocolversion >= MC113Version) + { + // Skip optional tooltip for each tab-complete result + if (dataTypes.ReadNextBool(packetData)) + dataTypes.ReadNextString(packetData); + } + } + + autocomplete_received = true; + break; + case PacketTypesIn.PluginMessage: + String channel = dataTypes.ReadNextString(packetData); + // Length is unneeded as the whole remaining packetData is the entire payload of the packet. + if (protocolversion < MC18Version) + pForge.ReadNextVarShort(packetData); + handler.OnPluginChannelMessage(channel, packetData.ToArray()); + return pForge.HandlePluginMessage(channel, packetData, ref currentDimension); + case PacketTypesIn.Disconnect: + handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, ChatParser.ParseText(dataTypes.ReadNextString(packetData))); + return false; + case PacketTypesIn.SetCompression: + if (protocolversion >= MC18Version && protocolversion < MC19Version) + compression_treshold = dataTypes.ReadNextVarInt(packetData); + break; + case PacketTypesIn.OpenWindow: + if (handler.GetInventoryEnabled()) + { + if (protocolversion < MC114Version) + { + // MC 1.13 or lower + byte windowID = dataTypes.ReadNextByte(packetData); + string type = dataTypes.ReadNextString(packetData).Replace("minecraft:", "").ToUpper(); + ContainerTypeOld inventoryType = (ContainerTypeOld)Enum.Parse(typeof(ContainerTypeOld), type); + string title = dataTypes.ReadNextString(packetData); + byte slots = dataTypes.ReadNextByte(packetData); + Container inventory = new Container(windowID, inventoryType, ChatParser.ParseText(title)); + handler.OnInventoryOpen(windowID, inventory); + } + else + { + // MC 1.14 or greater + int windowID = dataTypes.ReadNextVarInt(packetData); + int windowType = dataTypes.ReadNextVarInt(packetData); + string title = dataTypes.ReadNextString(packetData); + Container inventory = new Container(windowID, windowType, ChatParser.ParseText(title)); + handler.OnInventoryOpen(windowID, inventory); + } + } + break; + case PacketTypesIn.CloseWindow: + if (handler.GetInventoryEnabled()) + { + byte windowID = dataTypes.ReadNextByte(packetData); + lock (window_actions) { window_actions[windowID] = 0; } + handler.OnInventoryClose(windowID); + } + break; + case PacketTypesIn.WindowItems: + if (handler.GetInventoryEnabled()) + { + byte windowId = dataTypes.ReadNextByte(packetData); + + int stateId = -1; + + if (protocolversion >= MC1181Version) + stateId = dataTypes.ReadNextVarInt(packetData); + + int elements = dataTypes.ReadNextVarInt(packetData); + Dictionary inventorySlots = new Dictionary(); + for (short slotId = 0; slotId < elements; slotId++) + { + Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); + if (item != null) + inventorySlots[slotId] = item; + } + handler.OnWindowItems(windowId, inventorySlots); + } + break; + case PacketTypesIn.SetSlot: + if (handler.GetInventoryEnabled()) + { + byte windowID = dataTypes.ReadNextByte(packetData); + + int stateId = -1; + + if (protocolversion >= MC1181Version) + stateId = dataTypes.ReadNextVarInt(packetData); + + short slotID = dataTypes.ReadNextShort(packetData); + Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); + handler.OnSetSlot(windowID, slotID, item); + } + break; + case PacketTypesIn.WindowConfirmation: + if (handler.GetInventoryEnabled()) + { + byte windowID = dataTypes.ReadNextByte(packetData); + short actionID = dataTypes.ReadNextShort(packetData); + bool accepted = dataTypes.ReadNextBool(packetData); + if (!accepted) + { + SendWindowConfirmation(windowID, actionID, accepted); + } + } + break; + case PacketTypesIn.ResourcePackSend: + string url = dataTypes.ReadNextString(packetData); + string hash = dataTypes.ReadNextString(packetData); + bool forced = true; // Assume forced for MC 1.16 and below + if (protocolversion >= MC117Version) + { + forced = dataTypes.ReadNextBool(packetData); + String forcedMessage = ChatParser.ParseText(dataTypes.ReadNextString(packetData)); + } + // Some server plugins may send invalid resource packs to probe the client and we need to ignore them (issue #1056) + if (!url.StartsWith("http") && hash.Length != 40) // Some server may have null hash value + break; + //Send back "accepted" and "successfully loaded" responses for plugins or server config making use of resource pack mandatory + byte[] responseHeader = new byte[0]; + if (protocolversion < MC110Version) //MC 1.10 does not include resource pack hash in responses + responseHeader = dataTypes.ConcatBytes(dataTypes.GetVarInt(hash.Length), Encoding.UTF8.GetBytes(hash)); + SendPacket(PacketTypesOut.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(3))); //Accepted pack + SendPacket(PacketTypesOut.ResourcePackStatus, dataTypes.ConcatBytes(responseHeader, dataTypes.GetVarInt(0))); //Successfully loaded + break; + case PacketTypesIn.SpawnEntity: + if (handler.GetEntityHandlingEnabled()) + { + Entity entity = dataTypes.ReadNextEntity(packetData, entityPalette, false); + handler.OnSpawnEntity(entity); + } + break; + case PacketTypesIn.EntityEquipment: + if (handler.GetEntityHandlingEnabled()) + { + int entityid = dataTypes.ReadNextVarInt(packetData); + if (protocolversion >= MC116Version) + { + bool hasNext; + do + { + byte bitsData = dataTypes.ReadNextByte(packetData); + // Top bit set if another entry follows, and otherwise unset if this is the last item in the array + hasNext = (bitsData >> 7) == 1 ? true : false; + int slot2 = bitsData >> 1; + Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); + handler.OnEntityEquipment(entityid, slot2, item); + } while (hasNext); + } + else + { + int slot2 = dataTypes.ReadNextVarInt(packetData); + Item item = dataTypes.ReadNextItemSlot(packetData, itemPalette); + handler.OnEntityEquipment(entityid, slot2, item); + } + } + break; + case PacketTypesIn.SpawnLivingEntity: + if (handler.GetEntityHandlingEnabled()) + { + Entity entity = dataTypes.ReadNextEntity(packetData, entityPalette, true); + // packet before 1.15 has metadata at the end + // this is not handled in dataTypes.ReadNextEntity() + // we are simply ignoring leftover data in packet + handler.OnSpawnEntity(entity); + } + break; + case PacketTypesIn.SpawnPlayer: + if (handler.GetEntityHandlingEnabled()) + { + int EntityID = dataTypes.ReadNextVarInt(packetData); + Guid UUID = dataTypes.ReadNextUUID(packetData); + double X = dataTypes.ReadNextDouble(packetData); + double Y = dataTypes.ReadNextDouble(packetData); + double Z = dataTypes.ReadNextDouble(packetData); + byte Yaw = dataTypes.ReadNextByte(packetData); + byte Pitch = dataTypes.ReadNextByte(packetData); + + Location EntityLocation = new Location(X, Y, Z); + + handler.OnSpawnPlayer(EntityID, UUID, EntityLocation, Yaw, Pitch); + } + break; + case PacketTypesIn.EntityEffect: + if (handler.GetEntityHandlingEnabled()) + { + int entityid = dataTypes.ReadNextVarInt(packetData); + Inventory.Effects effect = Effects.Speed; + if (Enum.TryParse(dataTypes.ReadNextByte(packetData).ToString(), out effect)) + { + int amplifier = dataTypes.ReadNextByte(packetData); + int duration = dataTypes.ReadNextVarInt(packetData); + byte flags = dataTypes.ReadNextByte(packetData); + handler.OnEntityEffect(entityid, effect, amplifier, duration, flags); + } + } + break; + case PacketTypesIn.DestroyEntities: + if (handler.GetEntityHandlingEnabled()) + { + int EntityCount = dataTypes.ReadNextVarInt(packetData); + int[] EntitiesList = new int[EntityCount]; + for (int i = 0; i < EntityCount; i++) + { + EntitiesList[i] = dataTypes.ReadNextVarInt(packetData); + } + handler.OnDestroyEntities(EntitiesList); + } + break; + case PacketTypesIn.DestroyEntity: + if (handler.GetEntityHandlingEnabled()) + { + handler.OnDestroyEntities(new[] { dataTypes.ReadNextVarInt(packetData) }); + } + break; + case PacketTypesIn.EntityPosition: + if (handler.GetEntityHandlingEnabled()) + { + int EntityID = dataTypes.ReadNextVarInt(packetData); + Double DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); + Double DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); + Double DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); + bool OnGround = dataTypes.ReadNextBool(packetData); + DeltaX = DeltaX / (128 * 32); + DeltaY = DeltaY / (128 * 32); + DeltaZ = DeltaZ / (128 * 32); + handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround); + } + break; + case PacketTypesIn.EntityPositionAndRotation: + if (handler.GetEntityHandlingEnabled()) + { + int EntityID = dataTypes.ReadNextVarInt(packetData); + Double DeltaX = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); + Double DeltaY = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); + Double DeltaZ = Convert.ToDouble(dataTypes.ReadNextShort(packetData)); + byte _yaw = dataTypes.ReadNextByte(packetData); + byte _pitch = dataTypes.ReadNextByte(packetData); + bool OnGround = dataTypes.ReadNextBool(packetData); + DeltaX = DeltaX / (128 * 32); + DeltaY = DeltaY / (128 * 32); + DeltaZ = DeltaZ / (128 * 32); + handler.OnEntityPosition(EntityID, DeltaX, DeltaY, DeltaZ, OnGround); + } + break; + case PacketTypesIn.EntityProperties: + if (handler.GetEntityHandlingEnabled()) + { + int EntityID = dataTypes.ReadNextVarInt(packetData); + int NumberOfProperties = protocolversion >= MC117Version ? dataTypes.ReadNextVarInt(packetData) : dataTypes.ReadNextInt(packetData); + Dictionary keys = new Dictionary(); + for (int i = 0; i < NumberOfProperties; i++) + { + string _key = dataTypes.ReadNextString(packetData); + Double _value = dataTypes.ReadNextDouble(packetData); + + List op0 = new List(); + List op1 = new List(); + List op2 = new List(); + int NumberOfModifiers = dataTypes.ReadNextVarInt(packetData); + for (int j = 0; j < NumberOfModifiers; j++) + { + dataTypes.ReadNextUUID(packetData); + Double amount = dataTypes.ReadNextDouble(packetData); + byte operation = dataTypes.ReadNextByte(packetData); + switch (operation) + { + case 0: op0.Add(amount); break; + case 1: op1.Add(amount); break; + case 2: op2.Add(amount + 1); break; + } + } + if (op0.Count > 0) _value += op0.Sum(); + if (op1.Count > 0) _value *= 1 + op1.Sum(); + if (op2.Count > 0) _value *= op2.Aggregate((a, _x) => a * _x); + keys.Add(_key, _value); + } + handler.OnEntityProperties(EntityID, keys); + } + break; + case PacketTypesIn.EntityMetadata: + if (handler.GetEntityHandlingEnabled()) + { + int EntityID = dataTypes.ReadNextVarInt(packetData); + Dictionary metadata = dataTypes.ReadNextMetadata(packetData, itemPalette); + int healthField = protocolversion >= MC114Version ? 8 : 7; // Health is field no. 7 in 1.10+ and 8 in 1.14+ + if (metadata.ContainsKey(healthField) && metadata[healthField] != null && metadata[healthField].GetType() == typeof(float)) + handler.OnEntityHealth(EntityID, (float)metadata[healthField]); + handler.OnEntityMetadata(EntityID, metadata); + } + break; + case PacketTypesIn.EntityStatus: + if (handler.GetEntityHandlingEnabled()) + { + int entityId = dataTypes.ReadNextInt(packetData); + byte status = dataTypes.ReadNextByte(packetData); + handler.OnEntityStatus(entityId, status); + } + break; + case PacketTypesIn.TimeUpdate: + long WorldAge = dataTypes.ReadNextLong(packetData); + long TimeOfday = dataTypes.ReadNextLong(packetData); + handler.OnTimeUpdate(WorldAge, TimeOfday); + break; + case PacketTypesIn.EntityTeleport: + if (handler.GetEntityHandlingEnabled()) + { + int EntityID = dataTypes.ReadNextVarInt(packetData); + Double X = dataTypes.ReadNextDouble(packetData); + Double Y = dataTypes.ReadNextDouble(packetData); + Double Z = dataTypes.ReadNextDouble(packetData); + byte EntityYaw = dataTypes.ReadNextByte(packetData); + byte EntityPitch = dataTypes.ReadNextByte(packetData); + bool OnGround = dataTypes.ReadNextBool(packetData); + handler.OnEntityTeleport(EntityID, X, Y, Z, OnGround); + } + break; + case PacketTypesIn.UpdateHealth: + float health = dataTypes.ReadNextFloat(packetData); + int food; + if (protocolversion >= MC18Version) + food = dataTypes.ReadNextVarInt(packetData); + else + food = dataTypes.ReadNextShort(packetData); + dataTypes.ReadNextFloat(packetData); // Food Saturation + handler.OnUpdateHealth(health, food); + break; + case PacketTypesIn.SetExperience: + float experiencebar = dataTypes.ReadNextFloat(packetData); + int level = dataTypes.ReadNextVarInt(packetData); + int totalexperience = dataTypes.ReadNextVarInt(packetData); + handler.OnSetExperience(experiencebar, level, totalexperience); + break; + case PacketTypesIn.Explosion: + Location explosionLocation = new Location(dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData), dataTypes.ReadNextFloat(packetData)); + float explosionStrength = dataTypes.ReadNextFloat(packetData); + int explosionBlockCount = protocolversion >= MC117Version + ? dataTypes.ReadNextVarInt(packetData) + : dataTypes.ReadNextInt(packetData); + // Ignoring additional fields (records, pushback) + handler.OnExplosion(explosionLocation, explosionStrength, explosionBlockCount); + break; + case PacketTypesIn.HeldItemChange: + byte slot = dataTypes.ReadNextByte(packetData); + handler.OnHeldItemChange(slot); + break; + case PacketTypesIn.ScoreboardObjective: + string objectivename = dataTypes.ReadNextString(packetData); + byte mode = dataTypes.ReadNextByte(packetData); + string objectivevalue = String.Empty; + int type2 = -1; + if (mode == 0 || mode == 2) + { + objectivevalue = dataTypes.ReadNextString(packetData); + type2 = dataTypes.ReadNextVarInt(packetData); + } + handler.OnScoreboardObjective(objectivename, mode, objectivevalue, type2); + break; + case PacketTypesIn.UpdateScore: + string entityname = dataTypes.ReadNextString(packetData); + byte action3 = dataTypes.ReadNextByte(packetData); + string objectivename2 = null; + int value = -1; + if (action3 != 1 || protocolversion >= MC18Version) + objectivename2 = dataTypes.ReadNextString(packetData); + if (action3 != 1) + value = dataTypes.ReadNextVarInt(packetData); + handler.OnUpdateScore(entityname, action3, objectivename2, value); + break; + case PacketTypesIn.BlockBreakAnimation: + if (handler.GetEntityHandlingEnabled() && handler.GetTerrainEnabled()) + { + int playerId = dataTypes.ReadNextVarInt(packetData); + Location blockLocation = dataTypes.ReadNextLocation(packetData); + byte stage = dataTypes.ReadNextByte(packetData); + handler.OnBlockBreakAnimation(playerId, blockLocation, stage); + } + break; + case PacketTypesIn.EntityAnimation: + if (handler.GetEntityHandlingEnabled()) + { + int playerId2 = dataTypes.ReadNextVarInt(packetData); + byte animation = dataTypes.ReadNextByte(packetData); + handler.OnEntityAnimation(playerId2, animation); + } + break; + default: + return false; //Ignored packet + } return true; //Packet processed } catch (Exception innerException) @@ -1235,7 +1237,7 @@ namespace MinecraftClient.Protocol.Handlers List clone = packetData.ToList(); handler.OnNetworkPacket(packetID, clone, login_phase, false); } - + //The inner packet byte[] the_packet = dataTypes.ConcatBytes(dataTypes.GetVarInt(packetID), packetData.ToArray()); @@ -1904,21 +1906,21 @@ namespace MinecraftClient.Protocol.Handlers switch (action) { - case WindowActionType.LeftClick: button = 0; break; - case WindowActionType.RightClick: button = 1; break; - case WindowActionType.MiddleClick: button = 2; mode = 3; break; - case WindowActionType.ShiftClick: button = 0; mode = 1; item = new Item(ItemType.Null, 0, null); break; - case WindowActionType.DropItem: button = 0; mode = 4; item = new Item(ItemType.Null, 0, null); break; - case WindowActionType.DropItemStack: button = 1; mode = 4; item = new Item(ItemType.Null, 0, null); break; - case WindowActionType.StartDragLeft: button = 0; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; - case WindowActionType.StartDragRight: button = 4; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; - case WindowActionType.StartDragMiddle: button = 8; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; - case WindowActionType.EndDragLeft: button = 2; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; - case WindowActionType.EndDragRight: button = 6; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; - case WindowActionType.EndDragMiddle: button = 10; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; - case WindowActionType.AddDragLeft: button = 1; mode = 5; item = new Item(ItemType.Null, 0, null); break; - case WindowActionType.AddDragRight: button = 5; mode = 5; item = new Item(ItemType.Null, 0, null); break; - case WindowActionType.AddDragMiddle: button = 9; mode = 5; item = new Item(ItemType.Null, 0, null); break; + case WindowActionType.LeftClick: button = 0; break; + case WindowActionType.RightClick: button = 1; break; + case WindowActionType.MiddleClick: button = 2; mode = 3; break; + case WindowActionType.ShiftClick: button = 0; mode = 1; item = new Item(ItemType.Null, 0, null); break; + case WindowActionType.DropItem: button = 0; mode = 4; item = new Item(ItemType.Null, 0, null); break; + case WindowActionType.DropItemStack: button = 1; mode = 4; item = new Item(ItemType.Null, 0, null); break; + case WindowActionType.StartDragLeft: button = 0; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; + case WindowActionType.StartDragRight: button = 4; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; + case WindowActionType.StartDragMiddle: button = 8; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; + case WindowActionType.EndDragLeft: button = 2; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; + case WindowActionType.EndDragRight: button = 6; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; + case WindowActionType.EndDragMiddle: button = 10; mode = 5; item = new Item(ItemType.Null, 0, null); slotId = -999; break; + case WindowActionType.AddDragLeft: button = 1; mode = 5; item = new Item(ItemType.Null, 0, null); break; + case WindowActionType.AddDragRight: button = 5; mode = 5; item = new Item(ItemType.Null, 0, null); break; + case WindowActionType.AddDragMiddle: button = 9; mode = 5; item = new Item(ItemType.Null, 0, null); break; } List packet = new List(); @@ -2031,7 +2033,7 @@ namespace MinecraftClient.Protocol.Handlers catch (System.IO.IOException) { return false; } catch (ObjectDisposedException) { return false; } } - + public bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags) { if (protocolversion <= MC113Version) @@ -2050,7 +2052,7 @@ namespace MinecraftClient.Protocol.Handlers catch (System.IO.IOException) { return false; } catch (ObjectDisposedException) { return false; } } - else { return false; } + else { return false; } } public bool SendWindowConfirmation(byte windowID, short actionID, bool accepted) diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index 089fad6b..c6db23d3 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -41,7 +41,8 @@ mcc.with_forge=, with Forge mcc.handshake=§8Handshake successful. (Server ID: {0}) mcc.realms_available=You have access to the following Realms worlds mcc.realms_join=Use realms: as server IP to join a Realms world - +mcc.generator.generating=Generating {0} palette using the dataset: {1} +mcc.generator.done=Succesfully generated {0} palette using the dataset: {1} [debug] # Messages from MCC Debug Mode @@ -92,6 +93,11 @@ error.realms.access_denied=This Realms world does not exist or access was denied error.realms.server_unavailable=Realms server may require some time to start up. Please retry again later. error.realms.server_id=Invalid or unknown Realms server ID. error.realms.disabled=Trying to join a Realms world but Realms support is disabled in config +error.missing.argument=You are missing argument {0} +error.usage=Usage: +error.generator.invalid=Invalid usage of the generator command! +error.generator.path=Invalid data path provided! (The path either does not exists or you have made a typo) +error.generator.json=The provided path must be a path to a file that is in .json format! [internal command] # MCC internal help command From dc0021d99092e99f892aa1e6a51a8940c44a1cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Milutinovi=C4=87?= Date: Tue, 28 Jun 2022 17:09:08 +0200 Subject: [PATCH 14/18] Fixed entity health update event (This will also fix the Auto Attack bot) --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index e8ed9d4b..81aae204 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1059,7 +1059,14 @@ namespace MinecraftClient.Protocol.Handlers { int EntityID = dataTypes.ReadNextVarInt(packetData); Dictionary metadata = dataTypes.ReadNextMetadata(packetData, itemPalette); - int healthField = protocolversion >= MC114Version ? 8 : 7; // Health is field no. 7 in 1.10+ and 8 in 1.14+ + + int healthField = 7; // From 1.10 to 1.14 (excluding 1.14) + + if (protocolversion >= MC114Version && protocolversion <= MC1165Version) + healthField = 8; + else if (protocolversion >= MC117Version) + healthField = 9; + if (metadata.ContainsKey(healthField) && metadata[healthField] != null && metadata[healthField].GetType() == typeof(float)) handler.OnEntityHealth(EntityID, (float)metadata[healthField]); handler.OnEntityMetadata(EntityID, metadata); From b5c4cd75668a79b3e9bec232c99d591059721983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Milutinovi=C4=87?= Date: Tue, 28 Jun 2022 17:37:16 +0200 Subject: [PATCH 15/18] Fixed Auto Attack bot (forgot to add a method to a commit before) Tested on 1.18.2 --- MinecraftClient/ChatBots/AutoAttack.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/ChatBots/AutoAttack.cs b/MinecraftClient/ChatBots/AutoAttack.cs index fae80faa..2fabee56 100644 --- a/MinecraftClient/ChatBots/AutoAttack.cs +++ b/MinecraftClient/ChatBots/AutoAttack.cs @@ -100,7 +100,7 @@ namespace MinecraftClient.ChatBots } } } - + if (entitiesToAttack.ContainsKey(priorityEntity)) { // check entity distance and health again @@ -144,6 +144,22 @@ namespace MinecraftClient.ChatBots } } + public override void OnEntityHealth(Entity entity, float health) + { + if (!entity.Type.IsHostile()) + return; + + if (entitiesToAttack.ContainsKey(entity.ID)) + { + entitiesToAttack[entity.ID].Health = health; + + if (entitiesToAttack[entity.ID].Health <= 0) + { + entitiesToAttack.Remove(entity.ID); + } + } + } + public override void OnEntityMove(Entity entity) { shouldAttackEntity(entity); From 3d8c1121591118e00f7777ff345f5657a7b5143d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Milutinovi=C4=87?= Date: Fri, 1 Jul 2022 18:59:58 +0200 Subject: [PATCH 16/18] Implemented "Click Window" for 1.18 (now sending the new required fields), formated few files with Visual Studio formatting. PS: left debug for people to see, I'll remove it once everything is working --- MinecraftClient/Inventory/Container.cs | 5 ++ MinecraftClient/McClient.cs | 15 +++--- .../Protocol/Handlers/DataTypes.cs | 19 +++++++- .../Protocol/Handlers/Protocol16.cs | 24 ++++++---- .../Protocol/Handlers/Protocol18.cs | 47 +++++++++++++++++-- MinecraftClient/Protocol/IMinecraftCom.cs | 10 ++-- .../Protocol/IMinecraftComHandler.cs | 3 +- 7 files changed, 94 insertions(+), 29 deletions(-) diff --git a/MinecraftClient/Inventory/Container.cs b/MinecraftClient/Inventory/Container.cs index 85f3e9a8..b39892b6 100644 --- a/MinecraftClient/Inventory/Container.cs +++ b/MinecraftClient/Inventory/Container.cs @@ -25,6 +25,11 @@ namespace MinecraftClient.Inventory /// public string Title; + /// + /// state of container + /// + public int StateID; + /// /// Container Items /// diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs index 94eda171..9d0fbf7c 100644 --- a/MinecraftClient/McClient.cs +++ b/MinecraftClient/McClient.cs @@ -1066,7 +1066,7 @@ namespace MinecraftClient /// How long to wait until the path is evaluated (default: 5 seconds) /// When location is unreachable, computation will reach timeout, then optionally fallback to a close location within maxOffset /// True if a path has been found - public bool MoveTo(Location location, bool allowUnsafe = false, bool allowDirectTeleport = false, int maxOffset = 0, int minOffset = 0, TimeSpan? timeout=null) + public bool MoveTo(Location location, bool allowUnsafe = false, bool allowDirectTeleport = false, int maxOffset = 0, int minOffset = 0, TimeSpan? timeout = null) { lock (locationLock) { @@ -1244,7 +1244,7 @@ namespace MinecraftClient item = inventories[windowId].Items[slotId]; // Inventory update must be after sending packet - bool result = handler.SendWindowAction(windowId, slotId, action, item); + bool result = handler.SendWindowAction(windowId, slotId, action, item, inventories[windowId].Items, inventories[windowId].StateID); // Update our inventory base on action type var inventory = GetInventory(windowId); @@ -1707,7 +1707,7 @@ namespace MinecraftClient /// Teleporting to other entityies is NOT implemented yet public bool Spectate(Entity entity) { - if(entity.Type == EntityType.Player) + if (entity.Type == EntityType.Player) { return SpectateByUUID(entity.UUID); } @@ -1723,9 +1723,9 @@ namespace MinecraftClient /// UUID of player/entity to teleport to public bool SpectateByUUID(Guid UUID) { - if(GetGamemode() == 3) + if (GetGamemode() == 3) { - if(InvokeRequired) + if (InvokeRequired) return InvokeOnMainThread(() => SpectateByUUID(UUID)); return handler.SendSpectate(UUID); } @@ -1855,7 +1855,7 @@ namespace MinecraftClient /// Check if the client is currently processing a Movement. /// /// true if a movement is currently handled - public bool ClientIsMoving() + public bool ClientIsMoving() { return terrainAndMovementsEnabled && locationReceived && ((steps != null && steps.Count > 0) || (path != null && path.Count > 0)); } @@ -2030,11 +2030,12 @@ namespace MinecraftClient /// /// Inventory ID /// Item list, key = slot ID, value = Item information - public void OnWindowItems(byte inventoryID, Dictionary itemList) + public void OnWindowItems(byte inventoryID, Dictionary itemList, int stateId) { if (inventories.ContainsKey(inventoryID)) { inventories[inventoryID].Items = itemList; + inventories[inventoryID].StateID = stateId; DispatchBotEvent(bot => bot.OnInventoryUpdate(inventoryID)); } } diff --git a/MinecraftClient/Protocol/Handlers/DataTypes.cs b/MinecraftClient/Protocol/Handlers/DataTypes.cs index 93c6562e..3bcacf7b 100644 --- a/MinecraftClient/Protocol/Handlers/DataTypes.cs +++ b/MinecraftClient/Protocol/Handlers/DataTypes.cs @@ -401,7 +401,7 @@ namespace MinecraftClient.Protocol.Handlers { entityType = entityPalette.FromId(ReadNextByte(cache), living); } - + Double entityX = ReadNextDouble(cache); Double entityY = ReadNextDouble(cache); Double entityZ = ReadNextDouble(cache); @@ -1028,6 +1028,23 @@ namespace MinecraftClient.Protocol.Handlers return slotData.ToArray(); } + public string ByteArrayToString(byte[] ba) + { + return BitConverter.ToString(ba).Replace("-", " "); + } + + public byte[] GetSlotsArray(Dictionary items, ItemPalette itemPalette) + { + byte[] slotsArray = new byte[items.Count]; + + foreach (KeyValuePair item in items) + { + slotsArray = ConcatBytes(slotsArray, GetShort((short)item.Key), GetItemSlot(item.Value, itemPalette)); + } + + return slotsArray; + } + /// /// Get protocol block face from Direction /// diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index c0b04c33..c7e0b9ef 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -94,7 +94,8 @@ namespace MinecraftClient.Protocol.Handlers int nbr = 0; switch (id) { - case 0x00: byte[] keepalive = new byte[5] { 0, 0, 0, 0, 0 }; + case 0x00: + byte[] keepalive = new byte[5] { 0, 0, 0, 0, 0 }; Receive(keepalive, 1, 4, SocketFlags.None); handler.OnServerKeepAlive(); Send(keepalive); break; @@ -183,11 +184,13 @@ namespace MinecraftClient.Protocol.Handlers case 0xCF: if (protocolversion > 51) { readNextString(); readData(1); readNextString(); } readData(4); break; case 0xD0: if (protocolversion > 51) { readData(1); readNextString(); } break; case 0xD1: if (protocolversion > 51) { readNextTeamData(); } break; - case 0xFA: string channel = readNextString(); + case 0xFA: + string channel = readNextString(); byte[] payload = readNextByteArray(); handler.OnPluginChannelMessage(channel, payload); break; - case 0xFF: string reason = readNextString(); + case 0xFF: + string reason = readNextString(); handler.OnConnectionLost(ChatBot.DisconnectReason.InGameKick, reason); break; default: return false; //unknown packet! } @@ -666,12 +669,12 @@ namespace MinecraftClient.Protocol.Handlers } catch (SocketException) { return false; } } - + public bool SendUpdateSign(Location location, string line1, string line2, string line3, string line4) { return false; //Currently not implemented } - + public bool SendBrandInfo(string brandInfo) { return false; //Only supported since MC 1.7 @@ -701,23 +704,23 @@ namespace MinecraftClient.Protocol.Handlers { return false; //Currently not implemented } - + public bool SendInteractEntity(int EntityID, int type, int hand) { return false; //Currently not implemented } - + public bool UpdateCommandBlock(Location location, string command, CommandBlockMode mode, CommandBlockFlags flags) { return false; //Currently not implemented } - + public bool SendUseItem(int hand) { return false; //Currently not implemented } - public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item) + public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, Dictionary Items, int stateId) { return false; //Currently not implemented } @@ -759,7 +762,8 @@ namespace MinecraftClient.Protocol.Handlers /// packet Data public bool SendPluginChannelPacket(string channel, byte[] data) { - try { + try + { byte[] channelLength = BitConverter.GetBytes((short)channel.Length); Array.Reverse(channelLength); diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 81aae204..aa51647f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -850,7 +850,7 @@ namespace MinecraftClient.Protocol.Handlers if (item != null) inventorySlots[slotId] = item; } - handler.OnWindowItems(windowId, inventorySlots); + handler.OnWindowItems(windowId, inventorySlots, stateId); } break; case PacketTypesIn.SetSlot: @@ -1895,7 +1895,7 @@ namespace MinecraftClient.Protocol.Handlers catch (ObjectDisposedException) { return false; } } - public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item) + public bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, Dictionary items, int stateId) { try { @@ -1931,14 +1931,51 @@ namespace MinecraftClient.Protocol.Handlers } List packet = new List(); + + log.Info("Window id: " + windowId + " - State id: " + stateId + " - Slot id: " + slotId + " - Mode: " + mode); + log.Info("Bytes > " + (byte)windowId + " - State id: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(stateId)) + " - Slot id: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(slotId)) + " - Mode: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(mode))); + packet.Add((byte)windowId); - packet.AddRange(dataTypes.GetShort((short)slotId)); + + // 1.18+ + if (protocolversion > MC1171Version) + { + packet.AddRange(dataTypes.GetVarInt(stateId)); + packet.AddRange(dataTypes.GetShort((short)slotId)); + } + // 1.17.1 + else if (protocolversion == MC1171Version) + { + packet.AddRange(dataTypes.GetShort((short)slotId)); + packet.AddRange(dataTypes.GetVarInt(stateId)); + } + // Older + else + { + packet.AddRange(dataTypes.GetShort((short)slotId)); + } + packet.Add(button); if (protocolversion < MC117Version) packet.AddRange(dataTypes.GetShort(actionNumber)); - if (protocolversion >= MC19Version) + if (protocolversion >= MC1165Version) packet.AddRange(dataTypes.GetVarInt(mode)); - else packet.Add(mode); + + // 1.17+ + if (protocolversion >= MC117Version) + { + byte[] arrayOfSlots = dataTypes.GetSlotsArray(items, itemPalette); + + log.Info("Length: " + sizeof(byte) * arrayOfSlots.Length); + log.Info("Array: " + dataTypes.ByteArrayToString(arrayOfSlots)); + + packet.AddRange(dataTypes.GetVarInt(sizeof(byte) * arrayOfSlots.Length)); + packet.AddRange(arrayOfSlots); + } + packet.AddRange(dataTypes.GetItemSlot(item, itemPalette)); + + log.Info("Packet data: " + dataTypes.ByteArrayToString(packet.ToArray())); + SendPacket(PacketTypesOut.ClickWindow, packet); return true; } diff --git a/MinecraftClient/Protocol/IMinecraftCom.cs b/MinecraftClient/Protocol/IMinecraftCom.cs index 54d19e77..97aaca35 100644 --- a/MinecraftClient/Protocol/IMinecraftCom.cs +++ b/MinecraftClient/Protocol/IMinecraftCom.cs @@ -94,7 +94,7 @@ namespace MinecraftClient.Protocol /// packet Data /// True if message was successfully sent bool SendPluginChannelPacket(string channel, byte[] data); - + /// /// Send Entity Action packet to the server. /// @@ -102,7 +102,7 @@ namespace MinecraftClient.Protocol /// Type of packet to send /// True if packet was successfully sent bool SendEntityAction(int EntityID, int type); - + /// /// Send a held item change packet to the server. /// @@ -140,7 +140,7 @@ namespace MinecraftClient.Protocol /// Z coordinate for "interact at" /// True if packet was successfully sent bool SendInteractEntity(int EntityID, int type, float X, float Y, float Z); - + /// /// Send an entity interaction packet to the server. /// @@ -165,7 +165,7 @@ namespace MinecraftClient.Protocol /// Action to perform /// Item in the clicked slot /// True if packet was successfully sent - bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item); + bool SendWindowAction(int windowId, int slotId, WindowActionType action, Item item, Dictionary Items, int stateId); /// /// Request Creative Mode item creation into regular/survival Player Inventory @@ -220,7 +220,7 @@ namespace MinecraftClient.Protocol /// New line 4 /// True if packet was succcessfully sent bool SendUpdateSign(Location location, string line1, string line2, string line3, string line4); - + /// /// Update command block /// diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 107875c0..2b63d5e7 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -263,7 +263,8 @@ namespace MinecraftClient.Protocol /// /// Inventory ID /// Item list - void OnWindowItems(byte inventoryID, Dictionary itemList); + /// State ID + void OnWindowItems(byte inventoryID, Dictionary itemList, int stateId); /// /// Called when a single slot has been updated inside an inventory From 7c364731f51342aeb01216e6d288d5a7a2d5363f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Milutinovi=C4=87?= Date: Fri, 1 Jul 2022 19:02:53 +0200 Subject: [PATCH 17/18] Reverted a mistake --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index aa51647f..0dee10df 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1957,8 +1957,9 @@ namespace MinecraftClient.Protocol.Handlers packet.Add(button); if (protocolversion < MC117Version) packet.AddRange(dataTypes.GetShort(actionNumber)); - if (protocolversion >= MC1165Version) + if (protocolversion >= MC19Version) packet.AddRange(dataTypes.GetVarInt(mode)); + else packet.Add(mode); // 1.17+ if (protocolversion >= MC117Version) From 00d78ee81cd54e5eede0a6a8c032a5290168019c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Milutinovi=C4=87?= Date: Tue, 5 Jul 2022 09:29:40 +0200 Subject: [PATCH 18/18] Fixed the array length issue --- MinecraftClient/Protocol/Handlers/Protocol18.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 0dee10df..f4cb507f 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -1966,10 +1966,10 @@ namespace MinecraftClient.Protocol.Handlers { byte[] arrayOfSlots = dataTypes.GetSlotsArray(items, itemPalette); - log.Info("Length: " + sizeof(byte) * arrayOfSlots.Length); + log.Info("Length: " + dataTypes.ByteArrayToString(dataTypes.GetVarInt(arrayOfSlots.Length)) + " (" + arrayOfSlots.Length + ")"); log.Info("Array: " + dataTypes.ByteArrayToString(arrayOfSlots)); - packet.AddRange(dataTypes.GetVarInt(sizeof(byte) * arrayOfSlots.Length)); + packet.AddRange(dataTypes.GetVarInt(arrayOfSlots.Length)); packet.AddRange(arrayOfSlots); }