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


xmdhs
就是对用户名前加上 OfflinePlayer:,然后对这个字符串的 utf-8 的取 md5,然后做几个位运算。

也就是 uuid v3 了,绝大多数的语言都有 uuid 的库的,直接调就行。这有一个 php 的实现 https://gist.github.com/games647/2b6a00a8fc21fd3b88375f03c9e2e603

stydxm
xmdhs 发表于 2021-8-4 02:11
就是对用户名前加上 OfflinePlayer:,然后对这个字符串的 utf-8 的取 md5,然后做几个位运算。

也就是 uui ...

是我孤陋寡闻了,我在wiki.vg看到过OfflinePlayer:这个前缀,但是我之前不知道不同语言的UUID是对同一个标准的实现,谢谢啦

stydxm
xmdhs 发表于 2021-8-4 02:11
就是对用户名前加上 OfflinePlayer:,然后对这个字符串的 utf-8 的取 md5,然后做几个位运算。

也就是 uui ...

我查了一下UUID v3的算法,好像是要一个字符串加上另一个被称作namespace的UUID,但是我找了一下午也没找到离线模式的namespace是什么……

xmdhs
stydxm 发表于 2021-8-4 20:02
我查了一下UUID v3的算法,好像是要一个字符串加上另一个被称作namespace的UUID,但是我找了一下午也没找 ...

就是 nil 了,或者自己简单的实现实现下也不是不可以的
  1. package main

  2. import (
  3.         "crypto/md5"
  4.         "fmt"

  5.         "github.com/google/uuid"
  6. )

  7. func main() {
  8.         h := md5.New()
  9.         h.Write([]byte(`OfflinePlayer:xmdhs`))
  10.         s := h.Sum(nil)
  11.         var uuid uuid.UUID
  12.         copy(uuid[:], s)
  13.         uuid[6] = (uuid[6] & 0x0f) | uint8((3&0xf)<<4)
  14.         uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
  15.         fmt.Println(uuid)
  16. }
复制代码

stydxm
本帖最后由 stydxm 于 2021-8-13 10:18 编辑
xmdhs 发表于 2021-8-4 20:21
就是 nil 了,或者自己简单的实现实现下也不是不可以的

我研究了几天还是没搞懂nil是什么意思,能不能再讲解下主要是没看懂那段php里面的($data[6]) & 0x0f | 0x30和$data[8]) & 0x3f | 0x80,还有大佬这段里面的$data[8]) & 0x3f | 0x80和(uuid[8] & 0x3f) | 0x80

xmdhs
stydxm 发表于 2021-8-13 10:11
我研究了几天还是没搞懂nil是什么意思,能不能再讲解下

你直接说你用的啥语言吧,我给你写个例子。

stydxm
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?)

xmdhs
stydxm 发表于 2021-8-13 10:18
主要是没看懂那段php里面的$data[6]) & 0x0f | 0x30和$data[8]) & 0x3f | 0x80,还有大佬这段里面的($data ...

位操作不是基本所有语言都差不多吗,比如 java
  1. public static UUID nameUUIDFromBytes(byte[] name) {
  2.         MessageDigest md;
  3.         try {
  4.             md = MessageDigest.getInstance("MD5");
  5.         } catch (NoSuchAlgorithmException nsae) {
  6.             throw new InternalError("MD5 not supported", nsae);
  7.         }
  8.         byte[] md5Bytes = md.digest(name);
  9.         md5Bytes[6]  &= 0x0f;  /* clear version        */
  10.         md5Bytes[6]  |= 0x30;  /* set to version 3     */
  11.         md5Bytes[8]  &= 0x3f;  /* clear variant        */
  12.         md5Bytes[8]  |= 0x80;  /* set to IETF variant  */
  13.         return new UUID(md5Bytes);
  14.     }
复制代码


也就是不弄什么 namespace

804282955
.............

贺兰兰
我记得好像通过
UUID#nameUUIDFromBytes方法就可以了啊。。。
UUID是Java自带的类
也就是说,使用UUID.nameUUIDFromBytes("OfflinePlayer:XXXXXXXXXX".getBytes())就可以得到离线玩家UUID了
其中XXXX就是离线玩家ID

stydxm
贺兰兰 发表于 2021-8-13 11:49
我记得好像通过
UUID#nameUUIDFromBytes方法就可以了啊。。。
UUID是Java自带的类

可是我写的项目不是java的

贺兰兰
stydxm 发表于 2021-8-13 11:58
可是我写的项目不是java的

好吧,那当我没说(

武士的荣光
.............

第一页 上一页 下一页 最后一页