MC和UUID
对于多数MC玩家来说,他只需要知道,每个正版MC玩家无论怎么改名,都对应着唯一的一串UUID就好了。
一些服务器运营者可能会要求玩家提供他们的正版ID。你可以在这里查询,https://minecraftuuid.com/——当然,是如果这网站还没倒闭的前提下。给他“Player UUID”,就是很多横杠的那个。
为啥不给他我的用户名?
MCID更像用户名,它长得像TaoismDeepLake这样,可以更改。
UUID是一串很长的数字、字母串,长得像54860ea1-ae08-454f-a58a-b41215a90876这样,不能更改。所以,很多技术性问题上,都是使用UUID去判定是不是同一个玩家的。
有的地方,比如https://minecraftuuid.com/,还会提供一个删掉横杠的版本(Trimmed UUID),像54860ea1ae08454fa58ab41215a90876,这个版本没什么用。主要常用的还是上面那俩。如果有人跟你要正版UUID,那么提供有横杠的那个就行。
普通玩家看到这里就行了。下面的部分是给开发者看的。
UUID,也就是Universal Unique Identifier,全局唯一标识符,在代码里是UUID类,很多时候也直接用字符串表示。不只是MC正版账户有UUID,MC里也不是只有玩家有UUID。
这东西怎么用?UUID是一个抽象概念,问这个东西怎么用,就像是问“微积分怎么用”一样,答案是场合对的时候就用。
用在什么场合?需要判断“是不是同一个东西”的时候,或者是“函数的参数要求你传UUID”的时候。具体来说,我在MOD中使用的时候,处理属性修饰符(Attribute Modifier),以及标识对应玩家的时候用的最多。
有的时候,你需要获取特定的UUID,也有的时候,你随便找个UUID生成器,随机出几个格式正确的就行。
什么时候需要获取特定的UUID?
某个事情的UUID已经被人规定过了。
例子1:你希望某件道具记住自己的主人是谁,主人使用的时候,造成伤害+1。这个时候,你就可以把玩家player.getUUID()所得的结果记录进道具的nbt里。之后,只要判断手持player的UUID是否与之相等,就知道是不是所记录的玩家,就实现判断主人的效果了。
例子2:举例来说,你需要做一件胸甲,但这个盔甲有攻击百分比加成。这个时候,你就需要找到MC自身对于胸甲栏属性使用的UUID,比如说是uuid1,在getAttrModifier之类的接口里写
list.add(new (属性名,uuid1, 1,0.1))之类的东西。那么,为什么这里非要塞个uuid不可呢?
因为,如果你不指定UUID,这里就会随机一个UUID,而且每次随机都不同。
玩家穿上胸甲,就应该获得这个加成,脱掉的时候,就应该失去这个加成。由于每次需要计算加成内容的时候,都是现场计算的,所以为了确保能失去这个加成,就要确保每次返回的UUID一致。不然,如果穿上时给的是uuid1,脱下的时候试图用uuid2去找,那就会失去对它的控制,野在里面了。这种情况一旦发生,想要精确干掉就会特别麻烦,基本只能不分青红皂白地删掉该属性的所有修饰符,才能去掉野的属性修饰符。还有更离谱的,那就是脱下再穿上之后,因为UUID不同,所以会被认为是新的修改器,以至于又增加一份;玩家每次穿脱,就能把属性加一倍。
诚然,这里不一定非要用mc原版对于胸甲规定的UUID,但是也没必要非单独开一个新的。你固然可以给每一类你的装备都规定一个UUID,写在代码里,
static UUID SOME_ID = UUID.fromString("某个刚生成的一大串UUID");这样就好了,但我更推荐使用原版所提供的的UUID。其值随版本可能有变化,大概是在ItemArmor之类的地方里可以找到。
什么时候需要新增一个UUID?
上面例子2的末尾其实提到了一种,那就是你希望定义一种新的属性修改器的时候。比如,“戒指”的属性修改器。又或者,生命属性可能同时有一个百分比增加,还有个固定值增加,这时候你就需要两个不同的UUID。
那么,怎么新增呢?
https://www.zxgj.cn/g/uuid
https://www.uuid.online/
有很多的UUID生成器,随便搜一下“UUID生成“就能搜到,点击生成就可以随机到一个从没人用过的。虽然,不同的随机生成器理论上有可能生成重复,但那属于概率不可能事件,概率低到像是……一杯水自发地,上半部分沸腾、下半部分结冰一样。
不要自己乱发挥,比如写出“aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa”这样的uuid。要知道,自己乱发挥很容易和别人撞,就像是很多人随便设个密码的时候,会设置12345、11111这样的密码。此外,找个生成器也没费多少劲,老老实实使用正确的方式即可。
——为什么用UUID,不用其他的东西?
举例来说,我在代码里,缓存一下Player/PlayerEntity/EntityPlayer的对象引用可以吗?
有的时候是可以的,有的时候不行。
如果这个对象只是在函数内部引用,确保它的作用域之内,玩家不会下线再上线就可以。
比如有人开了一个服务器,有一个玩家登录了,那么服务器会创建一个它的玩家对象,我们记做player1;然后他退了,过一段时间又登录回来了,这时候服务器会重新给他再创建一个玩家对象,我们叫它player2。如果你只是缓存了player1的引用,那么player2并不等于player1,就没办法实现前面说的“记住主人”的功能了。
但是,如果是一个函数之内,比如某个道具的use函数,之内,前面先记住某个道具的使用者,然后立刻获取周围的所有实体列表,这个时候利用判断对象的方式,去判断那些实体里哪个是使用者,这件事就是ok的。
以上,应邀作文。

