关于Minecraft服务器出现所谓“回档”问题的深层剖析

您所在的位置:网站首页 mc服务器老掉线怎么回事 关于Minecraft服务器出现所谓“回档”问题的深层剖析

关于Minecraft服务器出现所谓“回档”问题的深层剖析

2024-07-10 08:01| 来源: 网络整理| 查看: 265

     此专栏有关MC服务器特性,内容较为简单,其中可能有错误之处,望各位大佬指正,专栏仅仅代表个人发现bug的历程以及解决的办法,不一定代表bug的真实特性(因为有可能有错)

描述问题

    相信正常的mc服务器玩家在玩服务器的时候或多或少地都会遇到所谓“回档”的问题,这个问题并不是真正意义上的“回档”,而是个人层面上的“回档”

    这个问题简述一下大概是这样的:

        “玩家加入服务器,并成功成为服务器的合法玩家,玩了亿会儿之后玩家下线,第二天早晨玩家加入游戏,网络以及账户等十分正常,但是登录服务器之后,背包、位置等所有可因为玩家在游戏内做出的动作而改变的变量全部被还原为一个新玩家的状态,出现所谓”回档“的问题,但是这个世界文件内所有之前的改变还是保存的”

    这阴间bug刚开始在基岩版出现,我们以为又是什么基岩版专属特权,后来Java版也陆续出现,这个时候我们才意识到这个bug的严重性

    bug的共同点我们寻找了很久,应该都是“玩家在退出服务器然后进入服务器之间的这一时间段内,服务器被关闭过”,并且,到目前为止,所有的小游戏服务器(包括hypixel之类的)都没有出现过此类问题,只有正常玩家自己租用的服务器,即满足可以重启的服务器条件的服务器出现过此类现象;初步推断,可能是这些小游戏服务器很少重启或者停止运行,并且他们的服务器体量较大,延迟更小,拥有较为良好的自主开发的踢人系统,一旦名字重复的档案出现将直接重连

   解释问题

    这阴间bug的原因我们寻找了很久,最后终于有了突破,突破点最容易找的就是ops.json

    这里我们用Java版海绵端的ops.json作为示范

ops.json文件内容

    ops.json文件是用来记录服务器当前存档内所有op(管理员,权限等级默认为4)的相关信息,包括UUID、名字、权限等级以及OP是否可以无视玩家限制进入服务器

    这些信息之中,关键的是UUID以及玩家的名字

    我们就拿"sha_bi_"这个玩家来做例子

    第一次记录内,UUID为3461f2c5-5e31-4f8e-8659-5d4cd8a20cb0

    第二次记录内,UUID为7919814f-db7c-370d-ae89-0c1303931550

    可以发现,UUID发生了变化

    那么,UUID在mc服务器中怎样进行工作?UUID是什么?

 UUID在mc服务器的用途如下

UUID工作流程

    那么,UUID是什么?

    UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。

       ......

    UUID是国际标准化组织(ISO)提出的一个概念。UUID是一个128比特的数值,这个数值可以通过一定的算法计算出来。为了提高效率,常用的UUID可缩短至16位。UUID用来识别属性类型,在所有空间和时间上被视为唯一的标识。一般来说,可以保证这个值是真正唯一的任何地方产生的任意一个UUID都不会有相同的值。使用UUID的一个好处是可以为新的服务创建新的标识符。这样一来,客户端在查找一个服务时,只需要在它的服务查找请求中指出与某类服务(或某个特定服务)有关的UUID,如果服务的提供者能将可用的服务与这个UUID相匹配,就返回一个响应。

                                                                                                          ————百度百科 “UUID"

    由此我们可以推断出,UUID适合在具有随机数的领域使用

    那么,让我们来看看UUID的编码规则

①    1~8位采用系统时间,在系统时间上精确到毫秒级保证时间上的唯一性

②    9~16位采用底层的IP地址,在服务器集群中的唯一性

③    17~24位采用当前对象的HashCode值,在一个内部对象上的唯一性

④    25~32位采用调用方法的一个随机数,在一个对象内的毫秒级的唯一性

    如果我们根据服务器中"sha_bi_"的两次UUID来看,造成错误的,1~8位和25~32位可以直接排除:因为这两样都需要使用到时间变量,而时间变量的最小单位是毫秒,随机数依靠毫秒改变,而玩家的记录不可能在同一毫秒内被同时注册,所以1~8位和25~32位直接排除

    而9~16位的底层IP地址在同一个用户体现不同的问题,其实是正常现象,理解有一点难度

    全球范围内的IP数量是有限的,不能满足所有用户的需求,所以运营商需要实时调整IP,所以每一个用户的IP不是固定的,所以根据底层IP生成的UUID自然不同

    排除了这些之后,只能留下HashCode上的差异(Hash Code在编码内容以及原理上十分复杂,这里不做阐述,有兴趣的可以百度)

    Hash Code由于其性质,所以可能会出现变动、意外碰撞等问题,所以在生成UUID时,一旦服务器重启,很大概率将会直接导致玩家拥有的UUID没有办法和服务器当时的UUID对上号,服务器将会把玩家识别为新玩家并重新同步,然后为改名玩家新创建一个存档

    

解决问题

    刚开始,在基岩版时,我们认为这可能是由于Microsoft账户在国内的不稳定性所造成的,于是我们尝试使用梯子稳定Microsoft和Xbox状态,在确认两个账户没有问题之后,我们尝试多次登录多个私人服务器以及官方提供的领域,情况如下表(国内正常网络测试)

基岩版服务器测试表

    由此可见,此阴间bug不是由于Microsoft账户导致,故账户方法没有办法解决这个bug

    于是我们尝试删除服务器内多余的空白档案,因为档案的记录依靠时间来,在文件内容靠后位置的是更早的记录,在文件内容靠前的是更晚的记录

判定示意图

    我们发现这将有几率使档案记录回溯,此方法是有几率可行的

    如果想完全避免这么麻烦的事情,建议不要重启服务器

总结问题

    建议在开服之前想好任何配置,包括但不限于Server.properties内的参数、端口设置、IP设置、黑白名单设定、玩法设计等,总之,开服需谨慎,尽量避免重启,等待官方解决问题,出现bug第一时间安慰自己,不要暴躁,想办法解决问题,例如备份你的存档或者立即关闭你的服务器并还原存档之类的,总之办法总比困难多,实在不行换个world文件夹,你死大家一起死,如果你是个大佬,建议想想办法,为人民着想

    创作专栏实属不易,建议三连加关注^_^



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3