6.3 KiB
6.3 KiB
Bug修复:访客模式下最后登录时间错误更新
问题描述
在原始代码中,当玩家处于访客模式访问其他玩家的农场时,被访问玩家的最后登录时间会被意外更新。这是一个严重的数据完整性问题,因为:
- 数据不准确:被访问玩家实际上没有登录,但最后登录时间被更新了
- 逻辑错误:只有玩家真正登录时,最后登录时间才应该被更新
- 影响统计:这会影响玩家活跃度统计和排行榜数据的准确性
问题根源
原始问题代码
def update_crops_growth(self):
"""更新所有玩家的作物生长状态"""
# 获取所有玩家存档文件
save_files = glob.glob(os.path.join("game_saves", "*.json"))
for save_file in save_files:
try:
# 从文件名提取账号ID
account_id = os.path.basename(save_file).split('.')[0]
# 加载玩家数据
player_data = self.load_player_data(account_id)
# ... 更新作物生长状态 ...
# 如果有作物更新,保存玩家数据
if growth_updated:
self.save_player_data(account_id, player_data) # 问题在这里!
问题分析:
- 系统遍历所有玩家存档文件,包括离线玩家
- 当保存玩家数据时,可能会触发其他逻辑更新最后登录时间
- 访客模式下,被访问玩家的数据被加载和保存,导致时间戳更新
修复方案
1. 只更新在线玩家的作物生长状态
def update_crops_growth(self):
"""更新所有玩家的作物生长状态"""
# 只更新在线玩家的作物生长状态,避免影响离线玩家的数据
for client_id, user_info in self.user_data.items():
if not user_info.get("logged_in", False):
continue
username = user_info.get("username")
if not username:
continue
try:
# 加载玩家数据
player_data = self.load_player_data(username)
# ... 更新作物生长状态 ...
# 如果有作物更新,保存玩家数据
if growth_updated:
self.save_player_data(username, player_data)
修复要点:
- ✅ 只遍历在线玩家(
self.user_data) - ✅ 检查玩家登录状态(
logged_in: True) - ✅ 避免处理离线玩家的数据
2. 优化访客模式的数据推送
def _push_crop_update_to_player(self, account_id, player_data):
# ... 现有代码 ...
if visiting_mode and visiting_target:
# 如果处于访问模式,发送被访问玩家的更新数据
# 注意:这里只读取数据,不修改被访问玩家的数据
target_player_data = self.load_player_data(visiting_target)
if target_player_data:
# 检查被访问玩家是否也在线
target_client_id = None
for cid, user_info in self.user_data.items():
if user_info.get("username") == visiting_target and user_info.get("logged_in", False):
target_client_id = cid
break
update_message = {
"type": "crop_update",
"farm_lots": target_player_data.get("farm_lots", []),
"timestamp": time.time(),
"is_visiting": True,
"visited_player": visiting_target,
"target_online": target_client_id is not None # 新增:标记被访问玩家是否在线
}
优化要点:
- ✅ 明确标注只读取数据,不修改
- ✅ 检查被访问玩家是否在线
- ✅ 提供在线状态信息给客户端
修复效果
修复前的问题
-
错误场景:
- 玩家A访问玩家B的农场
- 系统更新所有玩家的作物生长状态
- 玩家B的数据被加载、修改、保存
- 玩家B的最后登录时间被意外更新
-
数据污染:
玩家B实际最后登录:2024-01-01 10:00:00 被访问后错误更新为:2024-01-02 15:30:00 ❌ 错误!
修复后的正确行为
-
正确场景:
- 玩家A访问玩家B的农场
- 系统只更新在线玩家(玩家A)的作物生长状态
- 玩家B的数据只被读取,不被修改
- 玩家B的最后登录时间保持不变
-
数据准确:
玩家B实际最后登录:2024-01-01 10:00:00 访问后仍然保持:2024-01-01 10:00:00 ✅ 正确!
测试验证
测试用例1:访客模式数据完整性
- 玩家A登录游戏
- 玩家A访问离线玩家B的农场
- 等待作物生长更新周期
- 检查玩家B的最后登录时间是否保持不变
预期结果:玩家B的最后登录时间不应该改变
测试用例2:在线玩家正常更新
- 玩家A和玩家B都在线
- 玩家A访问玩家B的农场
- 等待作物生长更新周期
- 检查两个玩家的作物是否正常生长
预期结果:两个玩家的作物都应该正常生长
测试用例3:离线玩家数据保护
- 确保有离线玩家的存档文件
- 在线玩家进行游戏操作
- 检查离线玩家的数据是否被意外修改
预期结果:离线玩家的数据应该保持不变
代码审查要点
在未来的开发中,需要注意以下几点:
-
数据修改原则:
- 只修改当前在线玩家的数据
- 访问其他玩家数据时,优先使用只读操作
- 避免在定时任务中修改离线玩家数据
-
时间戳更新:
- 最后登录时间只在真正登录时更新
- 避免在数据保存时自动更新时间戳
- 区分数据修改和时间戳更新的逻辑
-
访客模式处理:
- 明确区分访客模式和正常模式
- 访客模式下只读取数据,不修改
- 提供足够的状态信息给客户端
总结
这个bug修复确保了:
- ✅ 数据完整性:只有真正登录的玩家才会更新最后登录时间
- ✅ 性能优化:只处理在线玩家的数据,减少不必要的文件操作
- ✅ 逻辑正确:访客模式下不会影响被访问玩家的数据
- ✅ 可维护性:代码逻辑更清晰,易于理解和维护
通过这个修复,游戏的数据统计将更加准确,玩家的隐私和数据完整性得到更好的保护。