开发日志:关于高级合奏同步功能
1. 5.1之前的常见方法
嗯目前比较流行的BMP也好,一木的MIDI2FFXIV也好,包括2.5之前版本的[大合奏!]也好,对于合奏的共识就是【所有人在同一时间进行演奏】 这样的方法。
包括官方在5.1追加的合奏辅助功能,虽然还没实装,但是也是通过合奏节拍器倒计时同时启动的方式,来让所有玩家跟着节拍器来演奏就是了。
就是这里的节拍器倒计时,提前两个小节让大家在同一时间进行按键。
然而虽然理想很丰满,在多人的合奏中大家也发现了问题最多的地方还是【傻肥太多了!】 这样的总是忘记设时间或者忘记点准备。以前曾经想过的对策就是建个服务器来进行控制包的发送,但是看到了官方这个节拍器之后突然有了个新的想法,那就是——
2. 使用战斗倒计时来开始演奏?
在之前的文章中笔者写了通过抓包来进行演奏同步的方案。那么换一个思路,游戏中有没有哪种数据包能够同时传给所有人,还包含一定的时间信息?
答案呼之欲出,除了聊天信息就只剩下战斗倒计时了。经过一番解析后,战斗倒计时的数据格式如下
蓝色:Opcode =0x011E
黄色:Unix时间戳
绿色:发送者的用户ID
橙色:倒计时时间:5-30分别对应05~0x1E
粉色:发送者的用户名
那么开发思路就很简单了,收到0x011E的数据包之后,直接将合奏时间设置成x秒后就可以了,嗯白猫真聪明。
3. 那么古尔丹……停止呢?
远程停止也同样是找一个数据包,它有以下特性
- 能发送给限定范围的所有人(也就是小队里的人)
- 能够发送多次,而且方便操作
考虑到远程停止不需要进行定时等操作,只需要接受即可,所以选择还是挺多的。简单调查后,基本上锁定了两个数据包,分别是准备确认和场景标记
场景标记的数据包格式
绿色: Opcode=0x0272
粉色: Unix时间戳
其他的目测是type(ABC点/取消)和坐标位置,问题不大不用管也可以。
需要注意的是场景标记的数据包发送条件是【小队中有人标记或者取消了场景标记】,如果原本没有标记又点了取消全部的话,实际上是不会有数据包发送的。
准备确认的数据包格式
绿色:Opcode=0x011C
粉色:Unix时间戳
黄色:目测是小队成员的ID号
蓝色:发起确认的成员名字
需要注意的是,0x011C这个opcode,每个小队成员更新准备状态的时候都会发送一次,发送的来源则是该小队成员名字,因此如果用准备确认来充当停止命令,实际上会收到多条停止消息。
4. 并不愉快的星龙祭 上篇
实装了2和3功能的2.5版本上线后,进行内部测试时就发现了几个问题,比如准备确认的包并不能及时收到,倒计时的包也偶尔收不到的现象
经过调查后,判断应该是使用的socket抓包方法性能过低的问题,于是换成了Machina库,虽然还是socket抓包,但是至少可以保证相对快速的收到应当收到的包。
5. 并不愉快的星龙祭 下篇
解决了4所述问题后,接下来的测试中又陆续出现了
-
收不到任何网络数据包
-
收到数据包但是同步效果差
这两个现象
简单分析后,问题1的原因在于更换为machina库后,没有进行windows防火墙的注册,因此socket方式抓包被屏蔽掉了。解决方法则是手动在防火墙添加程序放行,或者使用旧版程序注册路径后替换文件。
问题2的原因应当是服务器发到小队成员的到达时间有误差造成的,也就是同一小队的A和B虽然服务器同时发送了战斗倒计时命令,但是因为接收时间有差异,因此设置的时间(若干秒后)也有几百毫秒的差异。
解决方法目前考虑的则是使用数据包内自带的unix时间戳,加上战斗倒计时的延迟后用来设置演奏时间,可能需要考虑下时区问题,不过unix时间戳不分时区的话应该是没啥问题的。
6. 总结
- 2.5.2.5中已经实装了使用战斗倒计时进行合奏开始命令的逻辑
- 由于若干原因导致无法使用该功能的,请自行设置防火墙或者等待下一个版本发布
- 由于最开始考虑不周,当前版本的倒计时同步在不同网络环境下存在较大延迟
- 但是下个版本应该就能解决了!最好的永远是下个版本!
你好!刚发现你们的APP、猫娘们的确很可爱 =^.^=
我是一位北美玩家,Songbirds奏乐团的组织者和MiqoMusicPlayer的作者。(这位美籍华侨的国语非常差、请谅解)我们只从去年就开始研究怎样能最佳利用当时刚推出的合奏功能来操作我们的八人乐团。功能虽然挺棒但仍然有各方面的问题。例如即使你所有的诗人在1ms以内同时开始奏乐、服务器也会造成高达几百毫秒的延迟。在美国和欧洲比较流行的游戏工具都很朴实所以无法解决问题。因此只好开发我们自己的工具。我利用Machina库计算延迟定位然后调节MIDI里的定时。请参考以下视频:
https://streamable.com/j0j4y
如果有任何关于合奏功能问题请不用客气,我会尽力帮助。祝你们好运!