如题,请问如何脱离MC的环境,通过玩家的ID计算出离线模式下的UUID,需求是因为某些插件的数据库主键为UUID,做查询系统时没法做在服务器里面(用插件做个后端也太重了点),所以需要计算UUID,有API也可以,但是最好是源码,因为怕API不稳定。
我java水平不太好,简单翻了一下bukkit和spigot,只找到了这个,也没看懂具体怎么实现的
https://hub.spigotmc.org/stash/p ... it/CraftServer.java
我java水平不太好,简单翻了一下bukkit和spigot,只找到了这个,也没看懂具体怎么实现的
https://hub.spigotmc.org/stash/p ... it/CraftServer.java

就是对用户名前加上 OfflinePlayer:,然后对这个字符串的 utf-8 的取 md5,然后做几个位运算。
也就是 uuid v3 了,绝大多数的语言都有 uuid 的库的,直接调就行。这有一个 php 的实现 https://gist.github.com/games647/2b6a00a8fc21fd3b88375f03c9e2e603
也就是 uuid v3 了,绝大多数的语言都有 uuid 的库的,直接调就行。这有一个 php 的实现 https://gist.github.com/games647/2b6a00a8fc21fd3b88375f03c9e2e603
xmdhs 发表于 2021-8-4 02:11
就是对用户名前加上 OfflinePlayer:,然后对这个字符串的 utf-8 的取 md5,然后做几个位运算。
也就是 uui ...
是我孤陋寡闻了,我在wiki.vg看到过OfflinePlayer:这个前缀,但是我之前不知道不同语言的UUID是对同一个标准的实现,谢谢啦
xmdhs 发表于 2021-8-4 02:11
就是对用户名前加上 OfflinePlayer:,然后对这个字符串的 utf-8 的取 md5,然后做几个位运算。
也就是 uui ...
我查了一下UUID v3的算法,好像是要一个字符串加上另一个被称作namespace的UUID,但是我找了一下午也没找到离线模式的namespace是什么……
stydxm 发表于 2021-8-4 20:02
我查了一下UUID v3的算法,好像是要一个字符串加上另一个被称作namespace的UUID,但是我找了一下午也没找 ...
就是 nil 了,或者自己简单的实现实现下也不是不可以的
- package main
- import (
- "crypto/md5"
- "fmt"
- "github.com/google/uuid"
- )
- func main() {
- h := md5.New()
- h.Write([]byte(`OfflinePlayer:xmdhs`))
- s := h.Sum(nil)
- var uuid uuid.UUID
- copy(uuid[:], s)
- uuid[6] = (uuid[6] & 0x0f) | uint8((3&0xf)<<4)
- uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
- fmt.Println(uuid)
- }
本帖最后由 stydxm 于 2021-8-13 10:18 编辑
我研究了几天还是没搞懂nil是什么意思,能不能再讲解下
主要是没看懂那段php里面的($data[6]) & 0x0f | 0x30和$data[8]) & 0x3f | 0x80,还有大佬这段里面的$data[8]) & 0x3f | 0x80和(uuid[8] & 0x3f) | 0x80 
xmdhs 发表于 2021-8-4 20:21
就是 nil 了,或者自己简单的实现实现下也不是不可以的
我研究了几天还是没搞懂nil是什么意思,能不能再讲解下


stydxm 发表于 2021-8-13 10:11
我研究了几天还是没搞懂nil是什么意思,能不能再讲解下
你直接说你用的啥语言吧,我给你写个例子。
xmdhs 发表于 2021-8-13 10:15
你直接说你用的啥语言吧,我给你写个例子。
主要是没看懂那段php里面的$data[6]) & 0x0f | 0x30和$data[8]) & 0x3f | 0x80,还有大佬这段里面的($data[8]) & 0x3f | 0x80和(uuid[8] & 0x3f) | 0x80
语言的话java python js cpp我都看得懂,偏偏不会php和在5楼发的那个(好像是go?)
stydxm 发表于 2021-8-13 10:18
主要是没看懂那段php里面的$data[6]) & 0x0f | 0x30和$data[8]) & 0x3f | 0x80,还有大佬这段里面的($data ...
位操作不是基本所有语言都差不多吗,比如 java
- public static UUID nameUUIDFromBytes(byte[] name) {
- MessageDigest md;
- try {
- md = MessageDigest.getInstance("MD5");
- } catch (NoSuchAlgorithmException nsae) {
- throw new InternalError("MD5 not supported", nsae);
- }
- byte[] md5Bytes = md.digest(name);
- md5Bytes[6] &= 0x0f; /* clear version */
- md5Bytes[6] |= 0x30; /* set to version 3 */
- md5Bytes[8] &= 0x3f; /* clear variant */
- md5Bytes[8] |= 0x80; /* set to IETF variant */
- return new UUID(md5Bytes);
- }
也就是不弄什么 namespace
.............
我记得好像通过
UUID#nameUUIDFromBytes方法就可以了啊。。。
UUID是Java自带的类
也就是说,使用UUID.nameUUIDFromBytes("OfflinePlayer:XXXXXXXXXX".getBytes())就可以得到离线玩家UUID了
其中XXXX就是离线玩家ID
UUID#nameUUIDFromBytes方法就可以了啊。。。
UUID是Java自带的类
也就是说,使用UUID.nameUUIDFromBytes("OfflinePlayer:XXXXXXXXXX".getBytes())就可以得到离线玩家UUID了
其中XXXX就是离线玩家ID
stydxm 发表于 2021-8-13 11:58
可是我写的项目不是java的
好吧,那当我没说(
.............