会话与在线状态检测
基本信息
| 属性 | 值 |
|---|---|
| 主类 | com.sintinium.oauth.login.LoginUtil |
| 作用对象 | net.minecraft.client.Minecraft#session(字段名 field_71449_j) |
| 在线判定 | Mojang MinecraftSessionService.hasJoinedServer |
| 缓存窗口 | 10 秒 |
功能
两个职责:
- 在线判定 —— 多人游戏界面打开时实时检测当前 Session 是否仍被 Mojang 接受。
- Session 写入 —— Microsoft 登录完成后,把新 Session 反射写回
Minecraft.session,并主动触发一次在线判定刷新缓存。
在线状态判定
入口
GuiEventHandler.multiplayerScreenOpen在按钮添加后启一条新线程调用LoginUtil.isOnline()- 根据返回值通过
TextWidget.setText/setColor切换显示文字与颜色
判定逻辑(isOnline())
if (!needsRefresh && now - lastCheck < 10s) return wasOnline
needsRefresh = false
lastCheck = System.currentTimeMillis()
sessionService.joinServer(uuid, session.token, randomUuid())
return sessionService.hasJoinedServer(uuid, randomUuid).isComplete()
任一异常(典型 AuthenticationException)→ wasOnline = false; return false。
视觉表现
| 返回值 | 文字 | 颜色 |
|---|---|---|
true |
Status: online |
0x55FF55(浅绿) |
false |
Status: offline |
0xFF5555(浅红) |
| 初次调用 | Status: loading |
默认白色 0xFFFFFF |
注意:Status: loading 是 TextWidget 初始文本,仅在 GuiEventHandler.multiplayerScreenOpen 启动判定线程之前显示;线程结束后即被替换。
Session 写入
loginMs(MinecraftProfile profile)
把 Microsoft 链路拿到的 MinecraftProfile 包装为 net.minecraft.util.Session(Session.Type.MOJANG)然后调用 setSession(...)。accessToken 直接作为 Session.token 写入。
setSession(Session session)
- 设
needsRefresh = true并立即updateOnlineStatus(),避免返回旧缓存 - 通过
cpw.mods.fml.relauncher.ReflectionHelper.findField(Minecraft.class, "field_71449_j", "session")定位 Session 字段 field.setAccessible(true)后field.set(Minecraft.getMinecraft(), session)- 失败时只
e.printStackTrace(),不通知用户
状态机
| 字段 | 含义 |
|---|---|
needsRefresh = true |
下次 isOnline() 必须重算,不走缓存 |
needsRefresh = false |
可走 10 秒缓存 |
wasOnline |
上次真实在线判定的结果 |
lastCheck |
上次真实判定的系统毫秒时间戳 |
触发刷新
- 多人界面打开 → 自动刷新
setSession(...)完成后 → 强制刷新- 缓存命中窗口 = 10 秒
已知限制
joinServer与hasJoinedServer各用不同的随机 UUID(一个用Session.func_148256_e(),一个UUID.randomUUID())—— 调用顺序与 Mojang 标准实现一致,但每次按钮开启多人界面都会向 sessionserver.mojang.com 发起两次请求- 缓存命中窗口固定 10 秒,强行按按钮刷新需要 10 秒后才生效
相关条目
- Microsoft 登录流程 - 完成链路后调用
LoginUtil.loginMs(profile) - OAuth 登录系统 - 状态文字由
GuiEventHandler注入