我有多个 Spigot 实例在 Bungeecord 服务器上运行。我有一个插件可以在每台服务器上进行自定义配置文件管理。该配置文件管理插件读取和写入 Mongo 数据库。所有代码都工作得很好,我不是来这里看代码的。
但是,我的问题是这样的。当玩家从一台服务器转移到另一台服务器时,在配置文件再次加载到目标服务器上之前,数据不会同步(写入数据库),这会导致加载旧数据。因为这个人的统计数据和经济没有得到正确反射(reflect)。现在,如果他们登录,切换到迷你游戏服务器,玩游戏,然后赚取金币,然后退出服务器(注销),那么统计数据将在下次登录时正确反射(reflect)。
配置文件管理器在 PlayerJoinEvent 上加载配置文件内容数据写入(保存)于 PlayerQuitEvent和 PlayerKickEvent .
解决这个问题的最佳方法是什么?有人可以指出我正确的方向吗?
编辑:Electroniccat 在官方 Spigot IRC 上表示,玩家在与之前的服务器断开连接之前会开始连接到目标服务器。既然这确实有道理,那么解决这个问题的最佳方法是什么?
最佳答案
我建议在 MongoDB 中的玩家个人资料中添加一个状态变量。
然后,使用蹦极插件或类似插件来检测玩家何时开始交换服务器;将状态设置为正在保存
。
当您在 PlayerQuitEvent
上保存玩家数据时,将状态设置为已保存
。
然后,当玩家登录时,在 PlayerJoin
上确保状态已已保存
。如果不是,请添加一个等待几秒钟的计时器(我建议实际上在 AsyncPlayerPreLoginEvent
上进行加载,这样登录就会被延迟,并且他们不会带着空的配置文件四处走动) -- 并确保计时器继续尝试(最多 3 次),直到状态被保存
。如果尝试 3 次后仍未保存,则踢出玩家/阻止登录(尽管这不应该发生)。确保尝试之间有足够的延迟。
我不知道为什么你会遇到这个问题,因为我之前曾使用 Mongo 作为蹦极服务器,并且在玩家配置文件方面从未遇到过这个问题。
另一种选择是通过 redis 进行配置文件缓存,通过保存间隔和休假时保持更新。 或者发布/订阅或插件消息传递,将配置文件数据发送到 bungee 实例并让它处理保存配置文件。
确保在玩家登录并加载个人资料后立即将状态设置为保存
。否则,该数据将无法及时推送以供读取,因为 join 事件是在 bungee 退出之前触发的。 (也许使用 boolean 值而不是“保存”/“保存”会更好)
时间表:
(状态 1 = 已保存,状态 0 = 等待保存)
初始加入蹦极:加载配置文件,加载配置文件后设置状态:0
切换服务器:
目标服务器上的 AsyncPlayerPreLoginEvent 触发:检查配置文件是否已加载(如果 status=1),如果是,则设置 status: 0
。第一次尝试时可能不会出现这种情况,因此每隔大约 20-40 个滴答声就有一个计时器来重新尝试
源服务器上的 PlayerQuitEvent 触发:更新状态:1
,使用相同的更新将配置文件保存到 mongo。然后,这将允许目标服务器上的 AsyncPlayerPreLoginEvent 加载配置文件。
我建议通过 redis 使用缓存,因为它与 mongo 配合得很好,并且会使这种情况更容易处理,特别是在加载时间方面。
关于java - Bungeecord 玩家传输上的 Mongo 数据库配置文件同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45274958/