我有几个Spigot在一个bungeecord服务器上运行的实例。我有一个插件,可以在每个服务器上进行自定义配置文件管理。此配置文件管理插件读取和写入Mongo数据库。所有代码都运行正常,我不在这里代码。
然而,我的问题是这个。当播放器从一个服务器转移到另一个服务器时,在配置文件再次加载到目标服务器上导致旧数据被加载之前,数据不会同步(写入数据库)。因此,人们的统计数据和经济状况都没有得到正确反映。现在,如果他们登录,切换到迷你游戏服务器,玩游戏,然后赚取金币,他们退出服务器(退出),然后统计数据将在下次登录时正确反映。
概要文件管理器在PlayerJoinEvent上加载个人资料内容,并在PlayerQuitEvent和PlayerKickEvent上写入(保存)数据。
解决此问题的最佳方法是什么?有人可以指出我正确的方向吗?
编辑:electroniccat在官方的Spigot IRC上说玩家在与之前的服务器断开连接之前就开始连接到目标服务器。由于这确实有意义,解决这个问题的最佳方法是什么?答案 0 :(得分:2)
我建议在MongoDB中为您的播放器配置文件添加状态变量。
然后,使用蹦极插件或类似物来检测玩家何时开始交换服务器;将状态设置为saving
。
当您保存播放器数据on PlayerQuitEvent
时,请将状态设置为saved
。
然后,当玩家登录时,在PlayerJoin
上确保状态为saved
。如果不是,请添加等待几秒钟的计时器(我建议实际上在AsyncPlayerPreLoginEvent
上加载,这样登录会延迟,并且他们不会带着空的配置文件走动) - 和确保计时器继续尝试(可能最多3次),直到状态为saved
。如果3次尝试通过且仍未保存,请踢玩家/阻止登录(尽管不应该这样)。确保尝试之间有足够的延迟。
我不确定你为什么会遇到这个问题,因为之前我曾使用过Mongo作为一个蹦极服务器而且从未遇到过这个问题。
另一种选择是通过redis进行配置文件缓存,通过保存间隔和休假保持更新。 或者发布/发布或插件消息传递,将配置文件数据发送到bungee实例并让它处理保存配置文件。
确保在玩家登录并加载其个人资料后立即将状态设置为saving
。否则,不会及时推送此数据以进行读取,因为在退出bungee之前触发了join事件。 (也许使用布尔而不是'保存'/'保存'也会更好)
时间轴:
(状态1 =保存,状态0 =等待保存)
首次加入bungee:加载个人资料,加载个人资料后设置status: 0
切换服务器:
目标服务器上的AsyncPlayerPreLoginEvent触发:检查是否加载了配置文件(如果状态= 1),如果设置为status: 0
。这可能不是第一次尝试的情况,因此每次约20-40个刻度重新尝试一次计时器
源服务器上的PlayerQuitEvent触发:更新status: 1
,将配置文件保存到具有相同更新的mongo。然后,这将允许目标服务器上的AsyncPlayerPreLoginEvent加载配置文件。
我建议通过redis使用缓存,因为它与mongo配合得很好,并且会使这种情况更容易处理,特别是在加载时间方面。