diff --git a/Server/SMYMongoDBAPI.py b/Server/SMYMongoDBAPI.py index 5e1c7c6..016baab 100644 --- a/Server/SMYMongoDBAPI.py +++ b/Server/SMYMongoDBAPI.py @@ -140,36 +140,6 @@ class SMYMongoDBAPI: except Exception as e: self.logger.error(f"获取游戏配置失败 [{config_type}]: {e}") return None - - def get_daily_checkin_config(self) -> Optional[Dict[str, Any]]: - """ - 获取每日签到配置 - - Returns: - Dict: 每日签到配置数据 - """ - try: - collection = self.get_collection("gameconfig") - - # 使用已知的文档ID查找 - object_id = ObjectId("687cce278e77ba00a7414ba2") - result = collection.find_one({"_id": object_id}) - - if result: - # 移除MongoDB的_id字段 - if "_id" in result: - del result["_id"] - - self.logger.info("成功获取每日签到配置") - return result - else: - self.logger.warning("未找到每日签到配置") - return None - - except Exception as e: - self.logger.error(f"获取每日签到配置失败: {e}") - return None - def set_game_config(self, config_type: str, config_data: Dict[str, Any]) -> bool: """ 设置游戏配置 @@ -205,6 +175,37 @@ class SMYMongoDBAPI: except Exception as e: self.logger.error(f"设置游戏配置异常 [{config_type}]: {e}") return False + + + #=====================每日签到系统====================== + def get_daily_checkin_config(self) -> Optional[Dict[str, Any]]: + """ + 获取每日签到配置 + + Returns: + Dict: 每日签到配置数据 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID查找 + object_id = ObjectId("687cce278e77ba00a7414ba2") + result = collection.find_one({"_id": object_id}) + + if result: + # 移除MongoDB的_id字段 + if "_id" in result: + del result["_id"] + + self.logger.info("成功获取每日签到配置") + return result + else: + self.logger.warning("未找到每日签到配置") + return None + + except Exception as e: + self.logger.error(f"获取每日签到配置失败: {e}") + return None def update_daily_checkin_config(self, config_data: Dict[str, Any]) -> bool: """ @@ -240,7 +241,10 @@ class SMYMongoDBAPI: except Exception as e: self.logger.error(f"更新每日签到配置异常: {e}") return False - + #=====================每日签到系统====================== + + + #=====================幸运抽奖系统====================== def get_lucky_draw_config(self) -> Optional[Dict[str, Any]]: """ 获取幸运抽奖配置 @@ -306,7 +310,10 @@ class SMYMongoDBAPI: except Exception as e: self.logger.error(f"更新幸运抽奖配置异常: {e}") return False - + #=====================幸运抽奖系统====================== + + + #=====================新手大礼包系统====================== def get_new_player_config(self) -> Optional[Dict[str, Any]]: """ 获取新手大礼包配置 @@ -372,7 +379,10 @@ class SMYMongoDBAPI: except Exception as e: self.logger.error(f"更新新手大礼包配置异常: {e}") return False - + #=====================新手大礼包系统====================== + + + #=====================智慧树系统====================== def get_wisdom_tree_config(self) -> Optional[Dict[str, Any]]: """ 获取智慧树配置 @@ -438,7 +448,79 @@ class SMYMongoDBAPI: except Exception as e: self.logger.error(f"更新智慧树配置异常: {e}") return False + #=====================智慧树系统====================== + + + #=====================稻草人系统====================== + def get_scare_crow_config(self) -> Optional[Dict[str, Any]]: + """ + 获取稻草人配置 + + Returns: + Dict: 稻草人配置数据 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID查找 + object_id = ObjectId("687cea258e77ba00a7414ba8") + result = collection.find_one({"_id": object_id}) + + if result: + # 移除MongoDB的_id字段和updated_at字段 + if "_id" in result: + del result["_id"] + if "updated_at" in result: + del result["updated_at"] + + self.logger.info("成功获取稻草人配置") + return result + else: + self.logger.warning("未找到稻草人配置") + return None + + except Exception as e: + self.logger.error(f"获取稻草人配置失败: {e}") + return None + def update_scare_crow_config(self, config_data: Dict[str, Any]) -> bool: + """ + 更新稻草人配置 + + Args: + config_data: 配置数据 + + Returns: + bool: 是否成功 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID更新 + object_id = ObjectId("687cea258e77ba00a7414ba8") + + # 添加更新时间 + update_data = { + "updated_at": datetime.now(), + **config_data + } + + result = collection.replace_one({"_id": object_id}, update_data) + + if result.acknowledged and result.matched_count > 0: + self.logger.info("成功更新稻草人配置") + return True + else: + self.logger.error("更新稻草人配置失败") + return False + + except Exception as e: + self.logger.error(f"更新稻草人配置异常: {e}") + return False + #=====================稻草人系统====================== + + + #=====================在线礼包系统====================== def get_online_gift_config(self) -> Optional[Dict[str, Any]]: """ 获取在线礼包配置 @@ -504,7 +586,216 @@ class SMYMongoDBAPI: except Exception as e: self.logger.error(f"更新在线礼包配置异常: {e}") return False + #=====================在线礼包系统====================== + + + #=====================道具配置系统====================== + def get_item_config(self) -> Optional[Dict[str, Any]]: + """ + 获取道具配置 + + Returns: + Dict: 道具配置数据 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID查找 + object_id = ObjectId("687cf17c8e77ba00a7414baa") + result = collection.find_one({"_id": object_id}) + + if result: + # 移除MongoDB的_id字段和updated_at字段 + if "_id" in result: + del result["_id"] + if "updated_at" in result: + del result["updated_at"] + + self.logger.info("成功获取道具配置") + return result + else: + self.logger.warning("未找到道具配置") + return None + + except Exception as e: + self.logger.error(f"获取道具配置失败: {e}") + return None + def update_item_config(self, config_data: Dict[str, Any]) -> bool: + """ + 更新道具配置 + + Args: + config_data: 配置数据 + + Returns: + bool: 是否成功 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID更新 + object_id = ObjectId("687cf17c8e77ba00a7414baa") + + # 添加更新时间 + update_data = { + "updated_at": datetime.now(), + **config_data + } + + result = collection.replace_one({"_id": object_id}, update_data) + + if result.acknowledged and result.matched_count > 0: + self.logger.info("成功更新道具配置") + return True + else: + self.logger.error("更新道具配置失败") + return False + + except Exception as e: + self.logger.error(f"更新道具配置异常: {e}") + return False + #=====================道具配置系统====================== + + + #=====================宠物配置系统====================== + def get_pet_config(self) -> Optional[Dict[str, Any]]: + """ + 获取宠物配置 + + Returns: + Dict: 宠物配置数据 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID查找 + object_id = ObjectId("687cf59b8e77ba00a7414bab") + result = collection.find_one({"_id": object_id}) + + if result: + # 移除MongoDB的_id字段和updated_at字段 + if "_id" in result: + del result["_id"] + if "updated_at" in result: + del result["updated_at"] + + self.logger.info("成功获取宠物配置") + return result + else: + self.logger.warning("未找到宠物配置") + return None + + except Exception as e: + self.logger.error(f"获取宠物配置失败: {e}") + return None + + def update_pet_config(self, config_data: Dict[str, Any]) -> bool: + """ + 更新宠物配置 + + Args: + config_data: 配置数据 + + Returns: + bool: 是否成功 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID更新 + object_id = ObjectId("687cf59b8e77ba00a7414bab") + + # 添加更新时间 + update_data = { + "updated_at": datetime.now(), + **config_data + } + + result = collection.replace_one({"_id": object_id}, update_data) + + if result.acknowledged and result.matched_count > 0: + self.logger.info("成功更新宠物配置") + return True + else: + self.logger.error("更新宠物配置失败") + return False + + except Exception as e: + self.logger.error(f"更新宠物配置异常: {e}") + return False + #=====================宠物配置系统====================== + + + #=====================体力系统====================== + def get_stamina_config(self) -> Optional[Dict[str, Any]]: + """ + 获取体力系统配置 + + Returns: + Dict: 体力系统配置数据 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID查找 + object_id = ObjectId("687cefba8e77ba00a7414ba9") + result = collection.find_one({"_id": object_id}) + + if result: + # 移除MongoDB的_id字段和updated_at字段 + if "_id" in result: + del result["_id"] + if "updated_at" in result: + del result["updated_at"] + + self.logger.info("成功获取体力系统配置") + return result + else: + self.logger.warning("未找到体力系统配置") + return None + + except Exception as e: + self.logger.error(f"获取体力系统配置失败: {e}") + return None + + def update_stamina_config(self, config_data: Dict[str, Any]) -> bool: + """ + 更新体力系统配置 + + Args: + config_data: 配置数据 + + Returns: + bool: 是否成功 + """ + try: + collection = self.get_collection("gameconfig") + + # 使用已知的文档ID更新 + object_id = ObjectId("687cefba8e77ba00a7414ba9") + + # 添加更新时间 + update_data = { + "updated_at": datetime.now(), + **config_data + } + + result = collection.replace_one({"_id": object_id}, update_data) + + if result.acknowledged and result.matched_count > 0: + self.logger.info("成功更新体力系统配置") + return True + else: + self.logger.error("更新体力系统配置失败") + return False + + except Exception as e: + self.logger.error(f"更新体力系统配置异常: {e}") + return False + #=====================体力系统====================== + + # ========================= 通用数据库操作 ========================= def insert_document(self, collection_name: str, document: Dict[str, Any]) -> Optional[str]: @@ -682,8 +973,33 @@ def test_api(): else: print("✗ 获取在线礼包配置失败") + # 测试获取稻草人配置 + print("\n6. 测试获取稻草人配置:") + scare_crow_config = api.get_scare_crow_config() + if scare_crow_config: + print("✓ 成功获取稻草人配置") + scare_crow_types = scare_crow_config.get("稻草人类型", {}) + modify_cost = scare_crow_config.get("修改稻草人配置花费", "N/A") + print(f"稻草人类型数量: {len(scare_crow_types)}") + print(f"修改费用: {modify_cost}金币") + else: + print("✗ 获取稻草人配置失败") + + # 测试获取宠物配置 + print("\n7. 测试获取宠物配置:") + pet_config = api.get_pet_config() + if pet_config: + print("✓ 成功获取宠物配置") + pets = pet_config.get("宠物", {}) + print(f"宠物类型数量: {len(pets)}") + if pets: + first_pet = list(pets.values())[0] + print(f"示例宠物属性: {list(first_pet.keys())[:3]}...") + else: + print("✗ 获取宠物配置失败") + # 测试查找所有游戏配置 - print("\n6. 测试查找游戏配置集合:") + print("\n8. 测试查找游戏配置集合:") try: configs = api.find_documents("gameconfig") print(f"找到 {len(configs)} 个配置文档") diff --git a/Server/TCPGameServer.py b/Server/TCPGameServer.py index 614c02d..468dce6 100644 --- a/Server/TCPGameServer.py +++ b/Server/TCPGameServer.py @@ -2300,112 +2300,11 @@ class TCPGameServer(TCPServer): - -#==========================购买道具处理========================== - #处理购买道具请求 - def _handle_buy_item(self, client_id, message): - """处理购买道具请求""" - # 检查用户是否已登录 - logged_in, response = self._check_user_logged_in(client_id, "购买道具", "buy_item") - if not logged_in: - return self.send_data(client_id, response) - - # 获取玩家数据 - player_data, username, response = self._load_player_data_with_check(client_id, "buy_item") - if not player_data: - return self.send_data(client_id, response) - - item_name = message.get("item_name", "") - item_cost = message.get("item_cost", 0) - quantity = message.get("quantity", 1) # 获取购买数量,默认为1 - - # 确保购买数量为正整数 - if not isinstance(quantity, int) or quantity <= 0: - quantity = 1 - - # 加载道具配置 - item_config = self._load_item_config() - if not item_config: - return self._send_action_error(client_id, "buy_item", "服务器无法加载道具数据") - - # 检查道具是否存在 - if item_name not in item_config: - return self._send_action_error(client_id, "buy_item", "该道具不存在") - - # 验证价格是否正确 - actual_cost = item_config[item_name].get("花费", 0) - if item_cost != actual_cost: - return self._send_action_error(client_id, "buy_item", f"道具价格验证失败,实际价格为{actual_cost}元") - - # 处理批量购买 - return self._process_item_purchase(client_id, player_data, username, item_name, item_config[item_name], quantity) - - #处理道具购买逻辑 - def _process_item_purchase(self, client_id, player_data, username, item_name, item_info, quantity=1): - """处理道具购买逻辑""" - unit_cost = item_info.get("花费", 0) - total_cost = unit_cost * quantity - - # 检查玩家金钱 - if player_data["money"] < total_cost: - return self._send_action_error(client_id, "buy_item", f"金钱不足,无法购买此道具。需要{total_cost}元,当前只有{player_data['money']}元") - - # 扣除金钱 - player_data["money"] -= total_cost - - # 将道具添加到道具背包 - item_found = False - - # 确保道具背包存在 - if "道具背包" not in player_data: - player_data["道具背包"] = [] - - for item in player_data["道具背包"]: - if item.get("name") == item_name: - item["count"] += quantity - item_found = True - break - - if not item_found: - player_data["道具背包"].append({ - "name": item_name, - "count": quantity - }) - - # 保存玩家数据 - self.save_player_data(username, player_data) - - self.log('INFO', f"玩家 {username} 购买了 {quantity} 个道具 {item_name},花费 {total_cost} 元", 'SERVER') - - return self.send_data(client_id, { - "type": "action_response", - "action_type": "buy_item", - "success": True, - "message": f"成功购买 {quantity} 个 {item_name}", - "updated_data": { - "money": player_data["money"], - "道具背包": player_data["道具背包"] - } - }) - - #加载道具配置数据 - def _load_item_config(self): - """从item_config.json加载道具配置数据""" - try: - with open("config/item_config.json", 'r', encoding='utf-8') as file: - return json.load(file) - except Exception as e: - self.log('ERROR', f"无法加载道具数据: {str(e)}", 'SERVER') - return {} -#==========================购买道具处理========================== - - - #==========================购买宠物处理========================== #处理购买宠物请求 def _handle_buy_pet(self, client_id, message): """处理购买宠物请求""" - # 检查用户是否已登录 + # 检查用户登录状态 logged_in, response = self._check_user_logged_in(client_id, "购买宠物", "buy_pet") if not logged_in: return self.send_data(client_id, response) @@ -2415,35 +2314,46 @@ class TCPGameServer(TCPServer): if not player_data: return self.send_data(client_id, response) + # 获取请求参数 pet_name = message.get("pet_name", "") pet_cost = message.get("pet_cost", 0) + # 验证宠物购买条件 + validation_result = self._validate_pet_purchase(pet_name, pet_cost, player_data) + if not validation_result["success"]: + return self._send_action_error(client_id, "buy_pet", validation_result["message"]) + + # 处理宠物购买 + return self._process_pet_purchase(client_id, player_data, username, pet_name, validation_result["pet_info"]) + + def _validate_pet_purchase(self, pet_name, pet_cost, player_data): + """验证宠物购买条件""" # 加载宠物配置 pet_config = self._load_pet_config() if not pet_config: - return self._send_action_error(client_id, "buy_pet", "服务器无法加载宠物数据") + return {"success": False, "message": "服务器无法加载宠物数据"} # 检查宠物是否存在 if pet_name not in pet_config: - return self._send_action_error(client_id, "buy_pet", "该宠物不存在") + return {"success": False, "message": "该宠物不存在"} - # 检查宠物是否可购买 pet_info = pet_config[pet_name] purchase_info = pet_info.get("购买信息", {}) - if not purchase_info.get("能否购买", False): - return self._send_action_error(client_id, "buy_pet", "该宠物不可购买") - # 验证价格是否正确 + # 检查宠物是否可购买 + if not purchase_info.get("能否购买", False): + return {"success": False, "message": "该宠物不可购买"} + + # 验证价格 actual_cost = purchase_info.get("购买价格", 0) if pet_cost != actual_cost: - return self._send_action_error(client_id, "buy_pet", f"宠物价格验证失败,实际价格为{actual_cost}元") + return {"success": False, "message": f"宠物价格验证失败,实际价格为{actual_cost}元"} # 检查玩家是否已拥有该宠物 if self._player_has_pet(player_data, pet_name): - return self._send_action_error(client_id, "buy_pet", f"你已经拥有 {pet_name} 了!") + return {"success": False, "message": f"你已经拥有 {pet_name} 了!"} - # 处理宠物购买 - return self._process_pet_purchase(client_id, player_data, username, pet_name, pet_info) + return {"success": True, "pet_info": pet_info} #处理宠物购买逻辑 def _process_pet_purchase(self, client_id, player_data, username, pet_name, pet_info): @@ -2453,43 +2363,20 @@ class TCPGameServer(TCPServer): # 检查玩家金钱 if player_data["money"] < pet_cost: - return self._send_action_error(client_id, "buy_pet", f"金钱不足,无法购买此宠物。需要{pet_cost}元,当前只有{player_data['money']}元") + return self._send_action_error(client_id, "buy_pet", + f"金钱不足,无法购买此宠物。需要{pet_cost}元,当前只有{player_data['money']}元") - # 扣除金钱 + # 扣除金钱并添加宠物 player_data["money"] -= pet_cost + pet_instance = self._create_pet_instance(pet_info, username, pet_name) - # 确保宠物背包存在 + # 确保宠物背包存在并添加宠物 if "宠物背包" not in player_data: player_data["宠物背包"] = [] - - # 创建宠物实例数据 - 复制宠物配置的完整JSON数据 - import copy - pet_instance = copy.deepcopy(pet_info) - - # 为购买的宠物设置独特的ID和主人信息 - import time - current_time = time.time() - unique_id = str(int(current_time * 1000)) # 使用时间戳作为唯一ID - - # 更新基本信息 - if "基本信息" in pet_instance: - pet_instance["基本信息"]["宠物主人"] = username - pet_instance["基本信息"]["宠物ID"] = unique_id - pet_instance["基本信息"]["宠物名称"] = f"{username}的{pet_name}" - - # 设置宠物生日(详细时间) - import datetime - now = datetime.datetime.now() - birthday = f"{now.year}年{now.month}月{now.day}日{now.hour}时{now.minute}分{now.second}秒" - pet_instance["基本信息"]["生日"] = birthday - pet_instance["基本信息"]["年龄"] = 0 # 刚出生年龄为0 - - # 将宠物添加到宠物背包 player_data["宠物背包"].append(pet_instance) - # 保存玩家数据 + # 保存数据并返回响应 self.save_player_data(username, player_data) - self.log('INFO', f"玩家 {username} 购买了宠物 {pet_name},花费 {pet_cost} 元", 'SERVER') return self.send_data(client_id, { @@ -2503,6 +2390,31 @@ class TCPGameServer(TCPServer): } }) + def _create_pet_instance(self, pet_info, username, pet_name): + """创建宠物实例""" + import copy + import time + import datetime + + # 复制宠物配置数据 + pet_instance = copy.deepcopy(pet_info) + + # 生成唯一ID和设置基本信息 + unique_id = str(int(time.time() * 1000)) + now = datetime.datetime.now() + birthday = f"{now.year}年{now.month}月{now.day}日{now.hour}时{now.minute}分{now.second}秒" + + if "基本信息" in pet_instance: + pet_instance["基本信息"].update({ + "宠物主人": username, + "宠物ID": unique_id, + "宠物名称": f"{username}的{pet_name}", + "生日": birthday, + "年龄": 0 + }) + + return pet_instance + #检查玩家是否已拥有某种宠物 def _player_has_pet(self, player_data, pet_name): """检查玩家是否已拥有指定类型的宠物""" @@ -2516,12 +2428,28 @@ class TCPGameServer(TCPServer): #加载宠物配置数据 def _load_pet_config(self): - """从pet_data.json加载宠物配置数据""" + """优先从MongoDB加载宠物配置数据,失败时回退到JSON文件""" try: + # 优先从MongoDB加载 + if hasattr(self, 'mongo_api') and self.mongo_api: + config = self.mongo_api.get_pet_config() + if config: + self.log('INFO', "成功从MongoDB加载宠物配置", 'SERVER') + return config + else: + self.log('WARNING', "MongoDB中未找到宠物配置,回退到JSON文件", 'SERVER') + + # 回退到JSON文件 with open("config/pet_data.json", 'r', encoding='utf-8') as file: - return json.load(file) + config = json.load(file) + self.log('INFO', "从JSON文件加载宠物配置", 'SERVER') + return config + + except json.JSONDecodeError as e: + self.log('ERROR', f"宠物配置JSON解析错误: {str(e)}", 'SERVER') + return {} except Exception as e: - self.log('ERROR', f"无法加载宠物数据: {str(e)}", 'SERVER') + self.log('ERROR', f"加载宠物配置失败: {str(e)}", 'SERVER') return {} # 将巡逻宠物ID转换为完整宠物数据 @@ -3847,69 +3775,173 @@ class TCPGameServer(TCPServer): +#==========================购买道具处理========================== + #处理购买道具请求 + def _handle_buy_item(self, client_id, message): + """处理购买道具请求""" + # 检查用户是否已登录 + logged_in, response = self._check_user_logged_in(client_id, "购买道具", "buy_item") + if not logged_in: + return self.send_data(client_id, response) + + # 获取玩家数据 + player_data, username, response = self._load_player_data_with_check(client_id, "buy_item") + if not player_data: + return self.send_data(client_id, response) + + # 解析请求参数 + item_name = message.get("item_name", "") + item_cost = message.get("item_cost", 0) + quantity = max(1, int(message.get("quantity", 1))) # 确保购买数量为正整数 + + # 验证道具配置 + item_config = self._load_item_config() + if not item_config: + return self._send_action_error(client_id, "buy_item", "服务器无法加载道具数据") + + if item_name not in item_config: + return self._send_action_error(client_id, "buy_item", "该道具不存在") + + # 验证价格 + actual_cost = item_config[item_name].get("花费", 0) + if item_cost != actual_cost: + return self._send_action_error(client_id, "buy_item", f"道具价格验证失败,实际价格为{actual_cost}元") + + # 处理购买 + return self._process_item_purchase(client_id, player_data, username, item_name, item_config[item_name], quantity) + + #处理道具购买逻辑 + def _process_item_purchase(self, client_id, player_data, username, item_name, item_info, quantity=1): + """处理道具购买逻辑""" + unit_cost = item_info.get("花费", 0) + total_cost = unit_cost * quantity + + # 检查金钱是否足够 + if player_data["money"] < total_cost: + return self._send_action_error(client_id, "buy_item", + f"金钱不足,需要{total_cost}元,当前只有{player_data['money']}元") + + # 扣除金钱并添加道具 + player_data["money"] -= total_cost + self._add_item_to_inventory(player_data, item_name, quantity) + + # 保存数据并记录日志 + self.save_player_data(username, player_data) + self.log('INFO', f"玩家 {username} 购买了 {quantity} 个道具 {item_name},花费 {total_cost} 元", 'SERVER') + + return self.send_data(client_id, { + "type": "action_response", + "action_type": "buy_item", + "success": True, + "message": f"成功购买 {quantity} 个 {item_name}", + "updated_data": { + "money": player_data["money"], + "道具背包": player_data["道具背包"] + } + }) + + def _add_item_to_inventory(self, player_data, item_name, quantity): + """将道具添加到玩家背包""" + if "道具背包" not in player_data: + player_data["道具背包"] = [] + + # 查找是否已有该道具 + for item in player_data["道具背包"]: + if item.get("name") == item_name: + item["count"] += quantity + return + + # 添加新道具 + player_data["道具背包"].append({ + "name": item_name, + "count": quantity + }) + + #加载道具配置数据 + def _load_item_config(self): + """优先从MongoDB加载道具配置数据,失败时回退到JSON文件""" + # 首先尝试从MongoDB加载 + if self.mongo_api and self.mongo_api.is_connected(): + try: + config = self.mongo_api.get_item_config() + if config: + self.log('INFO', '成功从MongoDB加载道具配置', 'SERVER') + return config + else: + self.log('WARNING', 'MongoDB中未找到道具配置,回退到JSON文件', 'SERVER') + except Exception as e: + self.log('WARNING', f'从MongoDB加载道具配置失败: {e},回退到JSON文件', 'SERVER') + + # 回退到JSON文件 + try: + with open("config/item_config.json", 'r', encoding='utf-8') as file: + config = json.load(file) + self.log('INFO', '从JSON文件加载道具配置', 'SERVER') + return config + except json.JSONDecodeError as e: + self.log('ERROR', f'JSON文件格式错误: {e}', 'SERVER') + return {} + except Exception as e: + self.log('ERROR', f'无法加载道具数据: {e}', 'SERVER') + return {} +#==========================购买道具处理========================== + + #==========================道具使用处理========================== def _handle_use_item(self, client_id, message): """处理使用道具请求""" - print(f"调试:服务器收到道具使用请求") - print(f" - client_id: {client_id}") - print(f" - message: {message}") - # 检查用户是否已登录 logged_in, response = self._check_user_logged_in(client_id, "使用道具", "use_item") if not logged_in: - print(f"错误:用户未登录") return self.send_data(client_id, response) # 获取玩家数据 player_data, username, response = self._load_player_data_with_check(client_id, "use_item") if not player_data: - print(f"错误:无法加载玩家数据") return self.send_data(client_id, response) + # 解析请求参数 lot_index = message.get("lot_index", -1) item_name = message.get("item_name", "") use_type = message.get("use_type", "") target_username = message.get("target_username", "") - print(f"调试:解析参数") - print(f" - username: {username}") - print(f" - lot_index: {lot_index}") - print(f" - item_name: {item_name}") - print(f" - use_type: {use_type}") - print(f" - target_username: {target_username}") - # 验证参数 - if not item_name: - return self._send_action_error(client_id, "use_item", "道具名称不能为空") - - if not use_type: - return self._send_action_error(client_id, "use_item", "使用类型不能为空") + if not item_name or not use_type: + return self._send_action_error(client_id, "use_item", "道具名称和使用类型不能为空") # 检查玩家是否拥有该道具 if not self._has_item_in_inventory(player_data, item_name): return self._send_action_error(client_id, "use_item", f"您没有 {item_name}") - # 确定操作目标 + # 确定操作目标并处理 if target_username and target_username != username: # 访问模式:对别人的作物使用道具 - target_player_data = self.load_player_data(target_username) - if not target_player_data: - return self._send_action_error(client_id, "use_item", f"无法找到玩家 {target_username} 的数据") - - # 验证地块索引 - if lot_index < 0 or lot_index >= len(target_player_data.get("farm_lots", [])): - return self._send_action_error(client_id, "use_item", "无效的地块索引") - - target_lot = target_player_data["farm_lots"][lot_index] - return self._process_item_use_visiting(client_id, player_data, username, target_player_data, target_username, target_lot, lot_index, item_name, use_type) + return self._handle_visiting_item_use(client_id, player_data, username, target_username, lot_index, item_name, use_type) else: # 正常模式:对自己的作物使用道具 - if lot_index < 0 or lot_index >= len(player_data.get("farm_lots", [])): - return self._send_action_error(client_id, "use_item", "无效的地块索引") - - lot = player_data["farm_lots"][lot_index] - return self._process_item_use_normal(client_id, player_data, username, lot, lot_index, item_name, use_type) + return self._handle_normal_item_use(client_id, player_data, username, lot_index, item_name, use_type) + + def _handle_normal_item_use(self, client_id, player_data, username, lot_index, item_name, use_type): + """处理正常模式下的道具使用""" + if lot_index < 0 or lot_index >= len(player_data.get("farm_lots", [])): + return self._send_action_error(client_id, "use_item", "无效的地块索引") + + lot = player_data["farm_lots"][lot_index] + return self._process_item_use_normal(client_id, player_data, username, lot, lot_index, item_name, use_type) + + def _handle_visiting_item_use(self, client_id, player_data, username, target_username, lot_index, item_name, use_type): + """处理访问模式下的道具使用""" + target_player_data = self.load_player_data(target_username) + if not target_player_data: + return self._send_action_error(client_id, "use_item", f"无法找到玩家 {target_username} 的数据") + + if lot_index < 0 or lot_index >= len(target_player_data.get("farm_lots", [])): + return self._send_action_error(client_id, "use_item", "无效的地块索引") + + target_lot = target_player_data["farm_lots"][lot_index] + return self._process_item_use_visiting(client_id, player_data, username, target_player_data, target_username, target_lot, lot_index, item_name, use_type) def _has_item_in_inventory(self, player_data, item_name): """检查玩家是否拥有指定道具""" @@ -4759,118 +4791,100 @@ class TCPGameServer(TCPServer): #==========================宠物使用道具处理========================== def _handle_use_pet_item(self, client_id, message): """处理宠物使用道具请求""" - # 检查用户是否已登录 + # 检查用户登录状态 logged_in, response = self._check_user_logged_in(client_id, "宠物使用道具", "use_pet_item") if not logged_in: return self.send_data(client_id, response) - # 获取请求参数 + # 验证请求参数 item_name = message.get("item_name", "") pet_id = message.get("pet_id", "") - if not item_name or not pet_id: - return self.send_data(client_id, { - "type": "use_pet_item_response", - "success": False, - "message": "缺少必要参数" - }) + return self._send_pet_item_error(client_id, "缺少必要参数") # 获取玩家数据 username = self.user_data[client_id]["username"] player_data = self.load_player_data(username) - if not player_data: - return self.send_data(client_id, { - "type": "use_pet_item_response", - "success": False, - "message": "玩家数据加载失败" - }) + return self._send_pet_item_error(client_id, "玩家数据加载失败") - # 检查道具是否存在 + # 验证道具和宠物 + validation_result = self._validate_pet_item_use(player_data, item_name, pet_id) + if not validation_result["success"]: + return self._send_pet_item_error(client_id, validation_result["message"]) + + # 处理道具使用 + return self._execute_pet_item_use(client_id, player_data, username, + validation_result["item_index"], + validation_result["pet_index"], + item_name, pet_id) + + def _validate_pet_item_use(self, player_data, item_name, pet_id): + """验证宠物道具使用条件""" + # 检查道具 item_bag = player_data.get("道具背包", []) - item_found = False item_index = -1 - for i, item in enumerate(item_bag): - if item.get("name") == item_name: - if item.get("count", 0) > 0: - item_found = True - item_index = i - break + if item.get("name") == item_name and item.get("count", 0) > 0: + item_index = i + break - if not item_found: - return self.send_data(client_id, { - "type": "use_pet_item_response", - "success": False, - "message": f"道具 {item_name} 不足" - }) + if item_index == -1: + return {"success": False, "message": f"道具 {item_name} 不足"} - # 检查宠物是否存在 + # 检查宠物 pet_bag = player_data.get("宠物背包", []) - pet_found = False pet_index = -1 - for i, pet in enumerate(pet_bag): if pet.get("基本信息", {}).get("宠物ID") == pet_id: - pet_found = True pet_index = i break - if not pet_found: - return self.send_data(client_id, { - "type": "use_pet_item_response", - "success": False, - "message": "找不到指定的宠物" - }) + if pet_index == -1: + return {"success": False, "message": "找不到指定的宠物"} - # 处理道具使用 + return {"success": True, "item_index": item_index, "pet_index": pet_index} + + def _execute_pet_item_use(self, client_id, player_data, username, item_index, pet_index, item_name, pet_id): + """执行宠物道具使用""" try: - success, result_message, updated_pet = self._process_pet_item_use( - item_name, pet_bag[pet_index] - ) + item_bag = player_data["道具背包"] + pet_bag = player_data["宠物背包"] + + # 处理道具效果 + success, result_message, updated_pet = self._process_pet_item_use(item_name, pet_bag[pet_index]) if success: - # 更新宠物数据 + # 更新数据 pet_bag[pet_index] = updated_pet - - # 减少道具数量 item_bag[item_index]["count"] -= 1 if item_bag[item_index]["count"] <= 0: item_bag.pop(item_index) - # 保存玩家数据 + # 保存并记录 self.save_player_data(username, player_data) + self.log('INFO', f"用户 {username} 对宠物 {pet_id} 使用道具 {item_name} 成功", 'PET_ITEM') - # 发送成功响应 - response = { + return self.send_data(client_id, { "type": "use_pet_item_response", "success": True, "message": result_message, - "updated_data": { - "宠物背包": pet_bag, - "道具背包": item_bag - } - } - - self.log('INFO', f"用户 {username} 对宠物 {pet_id} 使用道具 {item_name} 成功", 'PET_ITEM') - + "updated_data": {"宠物背包": pet_bag, "道具背包": item_bag} + }) else: - # 发送失败响应 - response = { - "type": "use_pet_item_response", - "success": False, - "message": result_message - } - - return self.send_data(client_id, response) - + return self._send_pet_item_error(client_id, result_message) + except Exception as e: self.log('ERROR', f"宠物使用道具处理失败: {str(e)}", 'PET_ITEM') - return self.send_data(client_id, { - "type": "use_pet_item_response", - "success": False, - "message": "道具使用处理失败" - }) + return self._send_pet_item_error(client_id, "道具使用处理失败") + + def _send_pet_item_error(self, client_id, message): + """发送宠物道具使用错误响应""" + return self.send_data(client_id, { + "type": "use_pet_item_response", + "success": False, + "message": message + }) def _process_pet_item_use(self, item_name, pet_data): """处理具体的宠物道具使用逻辑""" @@ -5069,7 +5083,6 @@ class TCPGameServer(TCPServer): - #==========================道具配置数据处理========================== #处理客户端请求道具配置数据 def _handle_item_config_request(self, client_id): @@ -5093,7 +5106,6 @@ class TCPGameServer(TCPServer): - #==========================升级土地处理========================== #处理升级土地请求 def _handle_upgrade_land(self, client_id, message): @@ -5464,10 +5476,24 @@ class TCPGameServer(TCPServer): def _load_stamina_config(self): """加载体力系统配置""" + # 优先从MongoDB加载配置 + if self.use_mongodb and self.mongo_api and self.mongo_api.is_connected(): + try: + config_data = self.mongo_api.get_stamina_config() + if config_data: + self.log('INFO', '成功从MongoDB加载体力系统配置', 'SERVER') + return config_data.get("体力系统配置", {}) + else: + self.log('WARNING', '从MongoDB获取体力系统配置失败,回退到JSON文件', 'SERVER') + except Exception as e: + self.log('ERROR', f'从MongoDB加载体力系统配置时发生错误: {e},回退到JSON文件', 'SERVER') + + # 回退到JSON文件 try: config_path = os.path.join(os.path.dirname(__file__), "config", "stamina_config.json") with open(config_path, 'r', encoding='utf-8') as file: config_data = json.load(file) + self.log('INFO', '从JSON文件加载体力系统配置', 'SERVER') return config_data.get("体力系统配置", {}) except FileNotFoundError: self.log('WARNING', f"体力系统配置文件未找到,使用默认配置", 'SERVER') @@ -5479,10 +5505,20 @@ class TCPGameServer(TCPServer): } except json.JSONDecodeError as e: self.log('ERROR', f"体力系统配置文件格式错误: {e}", 'SERVER') - return {} + return { + "最大体力值": 20, + "每小时恢复体力": 1, + "恢复间隔秒数": 3600, + "新玩家初始体力": 20 + } except Exception as e: self.log('ERROR', f"加载体力系统配置时发生错误: {e}", 'SERVER') - return {} + return { + "最大体力值": 20, + "每小时恢复体力": 1, + "恢复间隔秒数": 3600, + "新玩家初始体力": 20 + } #==========================点赞玩家处理========================== @@ -8293,12 +8329,35 @@ class TCPGameServer(TCPServer): def _load_scare_crow_config(self): """加载稻草人配置""" + # 优先从MongoDB加载配置 + try: + if hasattr(self, 'mongo_api') and self.mongo_api and self.mongo_api.is_connected(): + config = self.mongo_api.get_scare_crow_config() + if config: + self.log('INFO', "成功从MongoDB加载稻草人配置", 'SERVER') + return config + else: + self.log('WARNING', "MongoDB中未找到稻草人配置,回退到JSON文件", 'SERVER') + except Exception as e: + self.log('ERROR', f"从MongoDB加载稻草人配置失败: {str(e)},回退到JSON文件", 'SERVER') + + # 回退到从JSON文件加载 try: with open("config/scare_crow_config.json", 'r', encoding='utf-8') as file: - return json.load(file) + config = json.load(file) + self.log('INFO', "成功从JSON文件加载稻草人配置", 'SERVER') + return config except Exception as e: self.log('ERROR', f"无法加载稻草人配置: {str(e)}", 'SERVER') - return {} + # 返回默认配置 + return { + "稻草人类型": { + "稻草人1": {"图片": "res://assets/道具图片/稻草人1.webp", "价格": 1000}, + "稻草人2": {"图片": "res://assets/道具图片/稻草人2.webp", "价格": 1000}, + "稻草人3": {"图片": "res://assets/道具图片/稻草人3.webp", "价格": 1000} + }, + "修改稻草人配置花费": 300 + } def _send_buy_scare_crow_error(self, client_id, message): """发送购买稻草人错误响应""" diff --git a/Server/__pycache__/SMYMongoDBAPI.cpython-313.pyc b/Server/__pycache__/SMYMongoDBAPI.cpython-313.pyc index 8eac005..6c728eb 100644 Binary files a/Server/__pycache__/SMYMongoDBAPI.cpython-313.pyc and b/Server/__pycache__/SMYMongoDBAPI.cpython-313.pyc differ diff --git a/Server/__pycache__/TCPGameServer.cpython-313.pyc b/Server/__pycache__/TCPGameServer.cpython-313.pyc index 41499a1..7f7ee6e 100644 Binary files a/Server/__pycache__/TCPGameServer.cpython-313.pyc and b/Server/__pycache__/TCPGameServer.cpython-313.pyc differ diff --git a/Server/config/initial_player_data_template.json b/Server/config/initial_player_data_template.json index bb664df..adc919d 100644 --- a/Server/config/initial_player_data_template.json +++ b/Server/config/initial_player_data_template.json @@ -19,6 +19,7 @@ "个人简介": "个人简介", "稻草人配置": { "已拥有稻草人类型": [ + "稻草人1" ], "稻草人展示类型": "", "稻草人昵称": "稻草人", diff --git a/Server/game_saves/2143323382.json b/Server/game_saves/2143323382.json index 66320b0..13a83bb 100644 --- a/Server/game_saves/2143323382.json +++ b/Server/game_saves/2143323382.json @@ -1,13 +1,13 @@ { - "experience": 90, + "experience": 455, "level": 36, - "money": 200802715, + "money": 200797815, "farm_name": "柚大青の小农场", "player_name": "柚大青", "user_name": "2143323382", "user_password": "tyh@19900420", - "last_login_time": "2025年07月20日21时00分40秒", - "total_login_time": "6时45分52秒", + "last_login_time": "2025年07月20日22时15分13秒", + "total_login_time": "6时47分9秒", "farm_lots": [ { "crop_type": "", @@ -132,26 +132,35 @@ }, { "crop_type": "杂交树1", - "grow_time": 14976, + "grow_time": 21042, "is_dead": false, "is_diged": true, "is_planted": true, "max_grow_time": 21600, "已浇水": false, - "已施肥": false, - "土地等级": 3 + "已施肥": true, + "土地等级": 3, + "施肥时间": 1753019866.8176558, + "施肥类型": "农家肥", + "施肥倍数": 2.0, + "施肥持续时间": 1800, + "浇水时间": 1753019871.817958 }, { "crop_type": "杂交树2", - "grow_time": 15468, + "grow_time": 21636, "is_dead": false, "is_diged": true, "is_planted": true, "max_grow_time": 25200, "已浇水": false, - "已施肥": false, + "已施肥": true, "土地等级": 3, - "浇水时间": 1753003230.8845751 + "浇水时间": 1753019874.5774846, + "施肥时间": 1753019862.2419734, + "施肥类型": "农家肥", + "施肥倍数": 2.0, + "施肥持续时间": 1800 }, { "crop_type": "", @@ -868,6 +877,111 @@ "品质系统": { "宠物品质": "COMMON" } + }, + { + "场景路径": "res://Scene/Pet/BigBeetle.tscn", + "基本信息": { + "宠物主人": "2143323382", + "宠物名称": "2143323382的大甲虫", + "队伍标识": "team1", + "宠物ID": "1753020931947", + "宠物类型": "大甲虫", + "生日": "2025年7月20日22时15分31秒", + "年龄": 0, + "性格": "活泼", + "简介": "", + "爱好": "" + }, + "等级经验": { + "宠物等级": 1, + "当前经验": 0, + "最大经验": 100, + "亲密度": 0, + "最大亲密度": 1000 + }, + "购买信息": { + "能否购买": true, + "购买价格": 1000, + "出售价格": 500 + }, + "生命与防御": { + "最大生命值": 200, + "当前生命值": 200, + "生命恢复速度": 1, + "最大护盾值": 0, + "当前护盾值": 0, + "护盾恢复速度": 0, + "最大护甲值": 100, + "当前护甲值": 100 + }, + "基础攻击属性": { + "攻击类型": "MELEE", + "基础攻击伤害": 25, + "攻击距离": 100, + "暴击率": 0.1, + "暴击伤害倍数": 1.5, + "生命汲取": 0.1, + "护甲穿透": 0 + }, + "近战攻击": { + "近战额外伤害": 0, + "近战攻击速度": 1 + }, + "远程攻击": { + "远程额外伤害": 0, + "远程攻击速度": 1, + "远程攻击模式": "SINGLE", + "子弹速度": 300 + }, + "散弹攻击": { + "散弹数量": 5, + "散弹扩散角度": 45 + }, + "多发射击": { + "多发射击行数": 2, + "多发射击列数": 3, + "多发射击间距": 30 + }, + "加特林属性": { + "加特林子弹数量": 8, + "加特林射击间隔": 0.1, + "加特林冷却时间": 2 + }, + "穿透属性": { + "穿透数量": 3 + }, + "移动与闪避": { + "移动速度": 100, + "闪避率": 0.05, + "击退力度": 300, + "击退抗性": 0 + }, + "元素属性": { + "元素类型": "NONE", + "元素克制额外伤害": 50 + }, + "特殊属性": { + "控制抗性": 0, + "伤害反弹": 0, + "死亡免疫": false, + "狂暴阈值": 0.3, + "狂暴状态伤害倍数": 1.5 + }, + "特殊机制开关": { + "启用伤害反弹机制": false, + "启用狂暴模式机制": false, + "启用死亡免疫机制": false, + "启用援助召唤机制": false, + "启用死亡重生机制": false + }, + "援助系统": { + "援助触发阈值": 0.2, + "援助召唤数量": 2, + "援助召唤间隔": 5 + }, + "品质系统": { + "宠物品质": "COMMON" + } } ], "巡逻宠物": [ @@ -876,41 +990,13 @@ "出战宠物": [ "1751716398095" ], - "稻草人配置": { - "已拥有稻草人类型": [ - "稻草人1", - "稻草人2", - "稻草人3" - ], - "稻草人展示类型": "稻草人3", - "稻草人昵称": "柚大青的稻草人", - "稻草人说的话": { - "第一句话": { - "内容": "233", - "颜色": "52dceeff" - }, - "第三句话": { - "内容": "888", - "颜色": "ac52ffff" - }, - "第二句话": { - "内容": "666", - "颜色": "80d5ffff" - }, - "第四句话": { - "内容": "哈哈哈", - "颜色": "f881ffff" - } - }, - "稻草人昵称颜色": "b38282ff" - }, "签到历史": { "2025年07月12日21时05分47秒": "金币249 经验75 土豆x3", "2025年07月13日07时26分04秒": "金币302 经验63 土豆x5 小麦x3" }, "在线礼包": { "当前日期": "2025-07-20", - "今日在线时长": 999999.271807432174683, + "今日在线时长": 999999.2718074322, "已领取礼包": [], "登录时间": 1753003043.7163484 }, @@ -923,10 +1009,10 @@ "领取时间": "2025-07-20 20:21:04" }, "体力系统": { - "当前体力值": 20, - "最大体力值": 20, + "当前体力值": 24, + "最大体力值": 25, "上次刷新时间": "2025-07-20", - "上次恢复时间": 1753003043.7066433 + "上次恢复时间": 1753018615.8492067 }, "道具背包": [ { @@ -935,11 +1021,39 @@ }, { "name": "农家肥", - "count": 5 + "count": 4 }, { "name": "水桶", - "count": 4 + "count": 3 + }, + { + "name": "荆棘护甲", + "count": 1 + }, + { + "name": "时运-镰刀", + "count": 1 + }, + { + "name": "精准采集-镰刀", + "count": 1 + }, + { + "name": "金坷垃", + "count": 1 + }, + { + "name": "水壶", + "count": 1 + }, + { + "name": "杀虫剂", + "count": 1 + }, + { + "name": "除草剂", + "count": 1 } ], "玩家小卖部": [], @@ -959,5 +1073,33 @@ "当前生命值": 102, "高度": 20, "上次护理时间": 1753014929 + }, + "稻草人配置": { + "已拥有稻草人类型": [ + "稻草人1", + "稻草人2", + "稻草人3" + ], + "稻草人展示类型": "稻草人2", + "稻草人昵称": "稻草人", + "稻草人说的话": { + "第一句话": { + "内容": "第一句话", + "颜色": "52dceeff" + }, + "第二句话": { + "内容": "第二句话", + "颜色": "80d5ffff" + }, + "第三句话": { + "内容": "第三句话", + "颜色": "ac52ffff" + }, + "第四句话": { + "内容": "第四句话", + "颜色": "f881ffff" + } + }, + "稻草人昵称颜色": "b38282ff" } } \ No newline at end of file