MCLF-CN / docs

公开的实现规范/文档
12 stars 0 forks source link

[New Feature] 在启动器显示来自第三方 Yggdrasil 验证服务器的公告 #1

Open tnqzh123 opened 7 months ago

tnqzh123 commented 7 months ago

我希望各位当前可以先集中精力完善技术规范(即这个 API 该怎么设计),至少先把公告 API 的技术标准推动到一个可用的程度,这才是最重要的。

至于「启动器该如何展示公告」、「如何规范公告发布者的行为」,如果实在纠结这方面内容,可以以后再聊。


检查项

您是什么类型的用户

第三方网站管理 / 负责人(MC 相关的)

利益相关:LittleSkin 创始人 & 产品经理、Blessing Skin Team 成员

请简单的说一下您的想法

如题,在启动器中显示来自第三方 Yggdrasil 验证服务器的公告。

它能解决什么样的问题/带来什么样的帮助

如果第三方 Yggdrasil 验证服务器有重要公告,则可以通过启动器将公告发送给每一个用户,并且可以确保用户是能够收到通知的。

例如,由于近期 MCBBS 源暂时下线,HMCL 无法正常下载和更新 authlib-injector,当玩家通过外置登录启动游戏时会报错「无法访问登录服务器,账户信息刷新失败」——即使这个问题并不是由 Yggdrasil 验证服务器导致的。LittleSkin 针对这个问题早已在网站内发布了公告,但我们在用户交流群内仍然收到了大量的此类问题相关的咨询。

来自用户的截图

此外,目前许多服务器使用 Blessing Skin Server 自建皮肤站并将其作为服务器专用的 Yggdrasil 验证服务器,如启动器支持显示来自第三方 Yggdrasil 验证服务器的公告,服务器管理员就可以将服务器的公告方便且高效地发送给每一个玩家,而不需要玩家主动通过 QQ 群或论坛等方式去了解服务器最新公告。

期望的结果

在启动器中显示来自第三方 Yggdrasil 验证服务器的公告

弹出公告的时机以及公告的显示位置可以由启动器自行指定,我建议在以下时机显示:

显示公告时应向用户明确表示这些公告是「来自 Yggdrasil 验证服务器的公告」,以免用户将第三方 Yggdrasil 验证服务器的公告误认为是启动器开发者发布的公告。最好能直接说明公告是来自哪个 Yggdrasil 验证服务器,如「来自 LittleSkin 的公告」,以方便用户区分。

参考概念设计(以 HMCL 为例):

点击展开 / 关闭 (我在 Snipaste 里截完图直接随手画的,我知道很丑,放这里只是提供一个设计思路,「明确说明是来自验证服务器的公告」忘记画了,大家知道就行) ![参考概念设计](https://github.com/MCLF-CN/docs/assets/16630630/23a6d6b4-da78-4ee7-8ea6-aa6c4bb7ad59)

是否有对这个方案的相关链接?

目前只有 LittleSkin 实现了获取站点公告的 API,但 API 文档尚未撰写完成,完成后会在本 Issue 内更新。

在此先简述一下目前 LittleSkin 的方案:

点此展开 / 关闭 首先,第三方 Yggdrasil 验证服务器在 [API 元数据](https://github.com/yushijinhun/authlib-injector/wiki/Yggdrasil-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83#api-%E5%85%83%E6%95%B0%E6%8D%AE%E8%8E%B7%E5%8F%96) 中添加一条公告链接(`meta.links.announcement`): ```json { "meta": { "serverName": "LittleSkin", "links": { "announcement": "https://littleskin.cn/api/announcements", "..." }, "..." }, "..." } ``` 启动器通过自身的 HTTP 库向 API 元数据中 `meta.links.announcement` 中的链接发起 GET 请求,响应体为 JSON 格式,内容示例如下: ```json [ { "severity": "fatal", "expand": true, "color": "red", "id": "11111111-1111-1111-1111-111111111111", "title": "Announcement #1", "priority": 100, "content": "This is the content of announcement #1.", "timestamp": 1706628946.219189 }, { "severity": "info", "expand": false, "color": "green", "id": "22222222-2222-2222-2222-222222222222", "title": "Announcement #2", "priority": 50, "content": "This is the content of announcement #2.", "timestamp": 1706638471.219189 } ] ``` JSON 最外层为一个数组,数组中每个对象都表示一则公告。如数组内容为空,则表明 Yggdrasil 验证服务器当前没有公告。 公告对象中应包含以下字段: - `id` 字段表示公告的 ID,以 32 位有符号 UUID 表示 - `color` 字段表示 LittleSkin 网站中显示该公告的 div 的底色,LittleSkin 通过颜色标识公告的严重程度,取值为 Bootstrap 4 的 [颜色](https://getbootstrap.com/docs/4.0/utilities/colors/) 的别名,具体取值及颜色代码包括: - `red`(`danger` 的别名),`#d33242` - `yellow`(`warning` 的别名),`#f9c000` - `green`(`success` 的别名),`#40a73f` - `cyan`(`info` 的别名),`#3ba2b9` - `blue`(`primary` 的别名),`#2f7cff` - `gray`(`secondary` 的别名),`#6d757d` - `black`,`#000000` - `white`,`#ffffff` - `light`,`#f8f9fa` - `dark`,`#353a40` - `title` 字段为公告标题,纯文本 - `content` 字段为公告内容,可能包含 HTML 标签 - `priority` 字段为公告的优先级,优先级越高的公告显示在越上方,同优先级的情况下根据 `color` 字段的取值,`red` > `yellow` > others,同 `color` 的情况下发布时间越晚的公告显示在越上方 - `severity` 字段为公告的严重程度(重要性),取值及含义分别为: - `fatal`:_n. A fatality; an event that leads to death._ - 最严重的公告,必须传达给每一个用户,且需要用户理解公告内容,否则可能导致严重后果,应用场景就例如我在上面提到的「由于近期 MCBBS 源下线导致 HMCL 无法更新 authlib-injector 导致无法启动游戏,这种问题如何解决」的公告 - `warning`:_n. Something spoken or written that is intended to warn._ - 没有 `fatal` 那么严重,但仍然比较重要,需要传达给每一个用户,一般不至于导致特别严重的后果,应用场景例如服务器维护公告 - `info`:_n. (informal) information._ - 不怎么重要的公告,用户知晓即可,但即使不知道也不会导致任何后果,应用场景例如服务器或站点活动通知 - `expand` 字段表示该公告是否默认展开(LittleSkin 的站点公告是折叠式的) - `timestamp` 字段为公告的发布时间,以 Unix 时间戳的形式表示 **注意:先前在群内讨论时针对「使用 `color` 字段标识公告严重程度」、「`content` 字段的值应该包含什么样的内容(纯文本、HTML 或 Markdown)」等特性存在争议,应在本 Issue 内讨论完善。**

authlib-injector 有一个 proposal 与本 Issue 描述的功能类似,但更简单。考虑到第三方 Yggdrasil 验证服务器可能同时会有不止一条公告,且可能有展示富文本或优先级 / 严重程度的需求,实际应用场景中该 proposal 无法完全满足需求。

附注

注意:先前在群内讨论时针对 LittleSkin 目前使用的方案中「使用 color 字段标识公告严重程度」、「content 字段的值应该包含什么样的内容(纯文本、HTML 或 Markdown)」等特性存在争议,应在本 Issue 内讨论完善。

ZhaiSoul commented 7 months ago

考虑到不同启动器的UI布局都不一样,我认为应该需要考虑好公告的展示形式。 而且这玩意儿侵入性比较强,容易对用户造成困扰。

不同等级的公告也许可以用不同的展示方式?例如普通公告就不会展示完,只显示个大概,点击后可以查看完整。警告类公告可以显示完整。严重类公告可以在启动器启动对应账户的情况下弹窗显示,但用户可以关掉并不再显示。

以及最重要的,该功能应该做成用户可选订阅,还是强制订阅?

IceCream-QAQ commented 7 months ago

我建议对公告添加一个 id 标识符,用以在启动器客户端处理展示一次,后续不再展示。 并且对重要公共添加一个标识符,使得可以每次展示。

tnqzh123 commented 7 months ago

@ZhaiSoul

考虑到不同启动器的UI布局都不一样,我认为应该需要考虑好公告的展示形式。

不同等级的公告也许可以用不同的展示方式?例如普通公告就不会展示完,只显示个大概,点击后可以查看完整。警告类公告可以显示完整。严重类公告可以在启动器启动对应账户的情况下弹窗显示,但用户可以关掉并不再显示。

公告展示形式可以由启动器自行设计,保证公告内容能有效传达到用户就可以。上面给出的概念设计只是提供一个设计思路。

而且这玩意儿侵入性比较强,容易对用户造成困扰。

我认为公告这种东西就应该是强侵入性的,才能达到「有效通知用户」的目的。若重要公告不能有效地传达给用户,导致用户无法启动游戏 / 无法登录服务器,不仅会给用户带来困扰,也会给第三方 Yggdrasil 验证服务器造成一定的客服压力。

对于严重程度不高的公告(例如服务器活动公告)可以使用较为温和的方式展示公告,但对于严重程度较高的公告,应通过弹窗等强侵入性的方式去通知用户,以确保公告能有效传达到用户。

还是那句话:公告展示形式可以由启动器自行设计,保证公告内容能有效传达到用户就可以。

以及最重要的,该功能应该做成用户可选订阅,还是强制订阅?

应该强制订阅,如果做成可选订阅的话也应该默认订阅。否则可能会因为用户没有主动订阅公告而导致重要公告无法有效传达给用户,与该功能的设计初衷不符。


@IceCream-QAQ

我建议对公告添加一个 id 标识符,用以在启动器客户端处理展示一次,后续不再展示。

公告标识符已经有了,现在 LittleSkin 的方案里面公告对象中 id 字段就是。

并且对重要公共添加一个标识符,使得可以每次展示。

考虑增加一个 severity 字段,取值 fatalwarninginfo,标识公告的严重程度?

IceCream-QAQ commented 7 months ago

@tnqzh123 虽然 各个启动器 风格,UI 设计均不相同,可能无法按照同样的规则设计 UI 展示内容。 但我们仍要对通知内容做一个标准规范。

比如什么情况下需要弹窗通知,什么情况下需要展示信息。 以及这个信息是否需要等待确认后再启动 Minecraft。

弹出公告的时机以及公告的显示位置可以由启动器自行指定

启动器端并不直接涉及 皮肤站 及 Yggdrasil 服务的业务,并不能直接理解各个级别到底代表什么。 需要明确规定各个等级的通知都代表什么需要做什么。 然后启动器开发者再结合各自的风格,去设计各自的 UI 方案。

既然是规范,就应该讲各个规则落到实际。 即规范启动器,也规范公告提供者。 使得启动器开发者可以直接理解其业务,也能让公告提供者能按照想法展示公告。

tnqzh123 commented 7 months ago

@IceCream-QAQ

启动器端并不直接涉及 皮肤站 及 Yggdrasil 服务的业务,并不能直接理解各个级别到底代表什么。

即规范启动器,也规范公告提供者。

考虑增加一个 severity 字段,取值 fatalwarninginfo,标识公告的严重程度?

我觉得这三个值的意思已经相当明确、相当语义化了:

如果有人在知道 severity 的取值是这三个的情况下还乱发公告(事实上,如果想让发布的公告能在启动器中显示,就必须先了解这个规范),我只能评价为这人不是蠢就是坏。

需要明确规定各个等级的通知都代表什么需要做什么。

使得启动器开发者可以直接理解其业务,也能让公告提供者能按照想法展示公告。

这种事情如果你让我来说,那就是所有公告按 priority 排序,加上 color 里指定的底色,然后全部信息轰炸给用户,就像我上面给出的概念设计一样。但这显然不是最优解,也显然不是所有启动器都适合这么做。

每个启动器的情况都不一样,比如:

你也说了「各个启动器的风格,UI 设计均不相同,可能无法按照同样的规则设计 UI 展示内容」,没办法写一个统一的设计规范然后让所有启动器都必须遵守,这不现实。

所以我希望「该在什么时机展示公告、用何种方式展示公告」可以由启动器自己设计,只要按照「保证公告内容能有效传达到用户」的原则来就可以。我在上面也有建议启动器应该在什么场景下展示公告,可以参考下。

如果一定要我说我想让启动器做成什么样,我只能说:

zkitefly commented 7 months ago

或许可以在启动游戏时弹出公告?

tnqzh123 commented 7 months ago

@zkitefly

或许可以在启动游戏时弹出公告?

我认为这个时机有点不太合适,因为有些公告会需要用户在启动游戏前阅读(比如最开始提到的「由于近期 MCBBS 源下线导致 HMCL 无法更新 authlib-injector 导致无法启动游戏,这种问题如何解决」的公告,就需要用户先在启动器设置内修改下载源再启动游戏),而且在游戏启动时弹出的话,对于原版这种启动速度较快的客户端,可能用户还没看完公告游戏就进入主界面了,感觉可能会干扰到用户进行游戏。

我认为最好还是在游戏启动前就向用户展示公告,或者提供一个指引让用户去查看公告。

当然,最后启动器采用什么样的设计,还是由启动器开发者说了算。

Silverteal commented 7 months ago

最终的展现形式和场景仍然需要启动器开发者自行决定,但是标准可以为此提供一些建议。例如“严重级别”字段,我们可以定义每个严重级别,然后建议验证服务器在什么情况下使用什么严重级别,启动器开发者则应该了解什么级别代表什么意思,自行选定展现形式,最后达到”对不同的启动器,同一个严重级别可以达到类似的提示效果“的目的。

我倒是认为部分颗粒度可以下放到具体的运营者,如”此公告确认前阻止游戏启动“,”此公告应醒目(弹窗)展示“,未必要用到”严重级别“。

同时还有一点,这类公告是否需要避免滥用?对于普通的服务器活动使用这类公告是否合适?验证服务器现在已经是集合服务器玩家账号管理,皮肤管理(可能还有公告管理)的综合解决方案了(甚至有些还是公用的,参见LittleSkin)。再往后发展可能得给BSS加统一通行证的功能了2333

如果要求启动启动器时就弹出验证服务器公告,感觉验证服务器有点过于侵入性了(管得太多了)……

burningtnt commented 7 months ago

不同公告类型的表现可以后续继续讨论,至于强制阻止游戏启动,这个侵入性太大了,会被用户骂的……

说白了,所有直接指明 UI 的样式,都没有任何意义

关于 content 属性,个人希望是设计成一个 object, 包括 text, markdown 等属性,可以让启动器自己选择渲染所支持的类型

tnqzh123 commented 7 months ago

@burningtnt

关于 content 属性,个人希望是设计成一个 object, 包括 text, markdown 等属性,可以让启动器自己选择渲染所支持的类型

如果验证服务器只支持部分属性(比如只支持 plaintext 或者只支持 markdown),启动器开发者能接受吗?会考虑 fallback 到渲染其他支持的属性吗?

同时添加两种格式的文本感觉有点麻烦…如果启动器能自行把 Markdown 的格式 escape 掉会更好

tnqzh123 commented 7 months ago

@Silverteal

同时还有一点,这类公告是否需要避免滥用?

避免滥用这方面感觉不是启动器可以做到的,毕竟不可能针对每个第三方 Yggdrasil 验证服务器都做审计,如果要维护一个 blocklist 什么的也还是太麻烦了。

对于普通的服务器活动使用这类公告是否合适?

我认为是合适的,既然服务器已经自建 Yggdrasil 验证服务器了,那验证服务器的公告也约等于服务器公告了。而且对提升服务器玩家活跃度和转化率方面应该会有一定的帮助。

Silverteal commented 7 months ago

避免滥用这方面感觉不是启动器可以做到的,毕竟不可能针对每个第三方 Yggdrasil 验证服务器都做审计,如果要维护一个 blocklist 什么的也还是太麻烦了。

我的意思是明确这类公告“应该用来干什么”,防止使用者在无意识的情况下出现类似“运营商用0级短信推广告”这种情况

tnqzh123 commented 7 months ago

@Silverteal

我的意思是明确这类公告“应该用来干什么”,防止使用者在无意识的情况下出现类似“运营商用0级短信推广告”这种情况

那这就不能叫「避免 滥用」,应该叫「规范公告发布者的行为」,但很明显只靠一纸规范是做不到的。规范只相当于一种君子协定,实际公告发布者会往公告里面塞什么东西,不论是规范起草者还是启动器都没法管——不然国产 GPU 现在已经超 A 赶 N 了。

我们当然可以在规范中添加这方面的说明(事实上,我也在稍早一些的 comment 中说明了 severity 字段各个取值的含义),但我还是建议放弃「仅凭规范中的说明就能真正规范公告发布者的行为」这种不现实的想法。

Silverteal commented 7 months ago

@Silverteal

我的意思是明确这类公告“应该用来干什么”,防止使用者在无意识的情况下出现类似“运营商用0级短信推广告”这种情况

那这就不能叫「避免 滥用」,应该叫「规范公告发布者的行为」,但很明显只靠一纸规范是做不到的。规范只相当于一种君子协定,实际公告发布者会往公告里面塞什么东西,不论是规范起草者还是启动器都没法管——不然国产 GPU 现在已经超 A 赶 N 了。

我们当然可以在规范中添加这方面的说明(事实上,我也在稍早一些的 comment 中说明了 severity 字段各个取值的含义),但我还是建议放弃「仅凭规范中的说明就能真正规范公告发布者的行为」这种不现实的想法。

当然。所以我会强调“无意识的情况”。

tnqzh123 commented 7 months ago

我希望各位当前可以先集中精力完善技术规范(即这个 API 该怎么设计),至少先把公告 API 的技术标准推动到一个可用的程度,这才是最重要的。

至于「启动器该如何展示公告」、「如何规范公告发布者的行为」,如果实在纠结这方面内容,可以以后再聊。

ZhaiSoul commented 7 months ago

内容 title | content

title标题为纯文本 使用markdown来作为content正文(关闭html渲染以保证安全)

等级 severity

通过severity字段,将公告分为三个等级:

紧急(fatal):

尽可能弹窗显示,会中断用户操作。用户必须要点击确认后,才可进行下一步操作。 将通过id来判断该公告是否显示过,用户可以点击“不再显示”即可下次启动时不显示该条公告。 紧急弹出类的公告只能有一条,剩余的将无法弹出显示,而是显示在公告列表中;默认只弹出第一条fatal公告。

tips: 对于不能添加多个第三方验证账号的启动器,可启动时获取到公告就弹出显示;对于可以同时登录多个第三方验证账号的,可以只在启动游戏时弹出并阻止游戏启动。

警告(warning ):

醒目提醒,与紧急fatal相比,除了可以弹窗提示,但可以不中断用户操作。

tips: 如果是可登录多个第三方验证账号的启动器,相比fatal,他不会中断游戏的启动流程。

提醒(info):

不能中断用户操作,只显示标题,可点击或者鼠标指针放上去后显示完整的公告。

其他信息: 所有类型的公告均会显示在列表之中(由启动器自行设计公告列表) 弹窗只会弹一个,例如同时有紧急和警告类型的公告时,按优先级只弹出紧急的公告。除非紧急公告被用户选择不再显示了,才显示下一个(紧急类型的公告,如果没有,则显示警告类)公告。 所有公告将能够在公告列表页面统一展示。 公告顺序优先按照紧急程度,然后按照在数组内的顺序。

鉴权

请求该接口时带上Bearer accesstoken的鉴权Header,用于鉴权,可以针对不同用户发送特定的消息。

公告列表

能够在UI上显示具体的公告列表,将所有公告聚合起来,用户可自行点击查看。 info类公告也默认只能在这里看到。

tips: 公告的数量目前暂不做上限。

显示内容

在公告列表以及公告内容中,需要显示以下提示信息: 该公告信息由 {xxx} 提供,请注意鉴别内容真伪。

xxx为第三方Yggdrasil源的meta信息中提供的名称。

其他的自行发挥。

范例

Json如下:

[{
        "//": "公告唯一ID,使用GUID生成,统一带'-'符号,不符合的直接抛弃",
        "id": "D94A49E4-8195-4F88-8A70-2CC2B99EBEA3",
        "//": "公告紧急程度等级,fatal | warning | info",
        "severity": "fatal",
        "//": "公告标题,纯文本实现",
        "title": "这里是公告的标题",
        "//": "正文内容,为markdown格式",
        "content": "This is the content of announcement #1.",
        "//": "秒级的时间戳",
        "timestamp": 1707285144
    },
    {
        "id": "36CBB2FF-62F6-41DE-B905-1838B88D19B2",
        "severity": "warning",
        "title": "这里是公告的标题",
        "content": "This is the content of announcement #2.",
        "timestamp": 1707285688
    }
]

C#例子

using (var wb = new WebClient()) {
    // 必须加上自己启动器的UserAgent
    wb.Headers.Add(HttpRequestHeader.UserAgent, "BakaXL/3.0");
    // 同时带上AccessToken,给网站鉴权用
    wb.Headers.Add(System.Net.HttpRequestHeader.Authorization, $"Bearer {AccessToken}");
    // 不要忘记使用UTF-8
    wb.Encoding = Encoding.UTF8;

    // apiUrl从第三方Yggdrasil源的meata数据中的links/announcement中获取
    // 一定要使用异步,尽可能别阻塞主线程
    var json = await wb.DownloadStringTaskAsync($"{apiUrl}");
}
burningtnt commented 7 months ago

获取信息时能否支持按照上一次已经展示的公告的 ID 查询?这样可以减小网络通讯的数据量

ZhaiSoul commented 7 months ago

获取信息时能否支持按照上一次已经展示的公告的 ID 查询?这样可以减小网络通讯的数据量

考虑到可能存在针对特定用户的通知,不建议这么做

tnqzh123 commented 7 months ago

@burningtnt

获取信息时能否支持按照上一次已经展示的公告的 ID 查询?这样可以减小网络通讯的数据量

没看懂,麻烦细说。

burningtnt commented 7 months ago

即,按照原有的格式,每次服务器响应时要提供完整的公告信息。 如果能够在 query arg 中加入 from_id=,用于表明上一次获取时查询到的公告 ID,可以:

Silverteal commented 7 months ago

关于在正文中使用Markdown有些不同意见:

我们或许不能假设所有启动器都有能力渲染富文本(如:命令行启动器,虽然非常少见),在弹窗中引入图片和样式对某些启动器来说也有可能是一个开发负担(如:PCL2的弹窗系统据我所知并不支持使用图片,那个弹窗的大小也塞不下什么图片,类似的情况也存在于SCL),并有微小的可能带来一些安全问题(引入了外源文件)。

我认为UTF-8编码的纯文本是更合适的,作为展示富文本的替代方案,或许可以考虑增加一个可选的"more_info"字段,内容为一个URL,用于跳转到公告全文。

tnqzh123 commented 7 months ago

@burningtnt

如果能够在 query arg 中加入 from_id=,用于表明上一次获取时查询到的公告 ID

用最后一次查询公告的时间戳更好吧?

也可以采用最后一条公告的发布时间的时间戳,这样方便 CDN 进行缓存。

大幅减小活跃玩家网络通讯的数据量

在现在的网络环境下,我不认为这几 KB 的流量会造成什么负担。

公告 API 当然可以实现这个功能,但我觉得这个需求有点没事找事,不应该成为强制性的标准。

非活跃玩家也可以看到所有下线期间的公告

公告是有时效性的,已经过期了的公告我认为不应该再展示给用户,应该由验证服务器在数组中删除。

zkitefly commented 7 months ago

Screenshot_2024-02-07-21-58-18-00_c8a66bc90793a73eafa5773962b202df.jpg

FCL 新版本增加了自己的公告栏,或许可以作为参考(

zkitefly commented 7 months ago

我认为还要 api 适配多语言的功能

tnqzh123 commented 7 months ago

@zkitefly

我认为还要 api 适配多语言的功能

Blessing Skin Server 一直支持多语言。只要在向 Yggdrasil 验证服务器发起请求时带上 Accept-Language 头部,或在 URL 参数中加上 lang 参数(取值均为 ISO 639 中规定的语言代码,但 zh_CNzh_TW 是个例外),就会返回对应语言的文本——前提是站点运营者为对应语言设置了对应的本地化文本,否则会 fallback 回默认语言(对于 LittleSkin 来说是简体中文 zh_CN)。

我建议采用后者的方式,这样方便公告内容被 CDN 缓存。

Silverteal commented 7 months ago

@zkitefly

我认为还要 api 适配多语言的功能

Blessing Skin Server 一直支持多语言。只要在向 Yggdrasil 验证服务器发起请求时带上 Accept-Language 头部,或在 URL 参数中加上 lang 参数(取值均为 ISO 639 中规定的语言代码,但 zh_CNzh_TW 是个例外),就会返回对应语言的文本——前提是站点运营者为对应语言设置了对应的本地化文本,否则会 fallback 回默认语言(对于 LittleSkin 来说是英语 en)。

我建议采用后者的方式,这样方便公告内容被 CDN 缓存。

关于语言代码,我更建议使用RFC 1766,其中语言部分使用ISO 639-1,可选的变体部分使用ISO 3166-1 alpha-2

Silverteal commented 7 months ago

获取信息时能否支持按照上一次已经展示的公告的 ID 查询?这样可以减小网络通讯的数据量

过期的公告显然应该移除,因此启动器不能只检索新的公告,应该拉取完整的网络列表(本地中的某些公告可能已经移除了)并重新创建本地的公告列表,最后再检查“是否阅读过”等来决定后续情况,所以这个没太大必要。

Silverteal commented 7 months ago

发散一下,如果请求时带上令牌,可以直接变成针对用户的消息中心hh

zkitefly commented 7 months ago

我在思考,如果有多个验证服务器该怎么显示?

Silverteal commented 7 months ago

@zkitefly

首帖好像有一部分回答了这个问题

弹出公告的时机以及公告的显示位置可以由启动器自行指定,我建议在以下时机显示:

  • 用户添加验证服务器,启动器获取完 API 元数据后
  • 用户登录外置登录账号,输入用户名及密码前
  • 用户选择外置登录启动游戏时

    • 先显示来自 Yggdrasil 验证服务器的公告,用户确认后再启动游戏