0.引言
Moogletroupeさん亦对本文的发表有贡献。
Twitter:https://twitter.com/moogletroupe
继《诗人演奏的通信过程》 ,5.1版本更新了诗人演奏的通信格式与演奏方式,笔者将新版的相关内容进行了整理。
主要内容依旧包括如下几方面
-
5.1中的演奏通信格式
-
5.1中的诗人演奏系统通信机制
-
从机制中得出的结论
同样是惯例没兴趣看的可以跳到第三章结论部分
1. 5.1中的演奏通信格式
客户端->服务器的演奏数据包
数据格式的解析
从5.x版本开始,SE为了应对雷达和ACT,在每个版本更新都会修改packet的opcode,因此本文将不再分析opcode的具体值
与4.X版本的变化在于,现在版本(5.x)的演奏内容从之前的时间间隔变成了Slot的方式
从第33个字节起
-
每个字节为1个Slot,内容为Note Number
-
1个Slot为50ms,即现版本的最小按键为50ms
-
Note的范围在0x18-0x3C,0xFE和0xFF,即0x18=24为C3
-
Note是以标准midi的note为准
2. 5.1中的诗人演奏系统通信机制
❎注意:以下内容仅为笔者根据目前现象进行的猜想,不保证为实际游戏程序的逻辑,所有内容仅有效于国服5.1版本中❎
2-1.键盘采集
- 键盘采集的速度/间隔与客户端的FPS有关,FPS越大采集速度越快,但是最大采集速度为1秒20个按键。
- 客户端不仅仅会采集键盘的按下事件(KeyDown),也会采集键盘的抬起事件(KeyUp)
2-2.数据包组成
- 每个数据包包含过去500ms内的按键信息
- 之前文章中提到的乐器休眠现在已经修改,系统会在按键后的500毫秒准时发出数据包
- 不是每个按键的keydown和keyup都会被采集到,可能会出现包内连续发送note但是没有FE的情形也是正常的。
- 笔者测试时由于网络问题或网络库问题,时而会发现演奏包偶尔会延迟100-200ms才发送出。
2-3.通信机制
-
数据包的发送间隔为500ms
-
当一个按键包发送后,客户端还会持续发送数据包5次,保持2500ms连续,但是包内容没有任何Note,全部为FF
-
当检测到上一个按键的键盘抬起事件时,也会发送一包数据。与按键按下时一样,这包数据也会使客户端唤醒 ,会重置2500ms的计数器。
例:玩家在0秒的时候按下按键,3秒后客户端休眠,在第4秒抬起按键,此时客户端会从休眠中唤醒,发送6包数据后再次进入休眠状态
-
以长笛为代表的管弦乐器,系统会在第4秒自动发送FE停止数据包
-
在5.1更新中,系统自动发送FE停止了长笛等乐器的演奏后,玩家手动keyup相应按键会再次触发FE的数据包发送3秒。
3.从机制中得出的结论
-
喜迎最小间隔修改->50ms
如今可以实现更多有趣的玩法,比如吉他的扫弦,比如各类即兴演奏
-
喜迎休眠删除
如今可以长时间挂机也能保证演奏的基本正确
-
引申:midi的精度
因为50ms slot的存在,原本的精度为100ms,现在为±50ms
但是如果中途因为keyup按键信息被采集到,从而插入了FE,则会导致实际误差大于50ms,约为100ms左右
因此需要在midi处理的时候将NoteOff信号提前或者延后来规避该问题。