优化项目架构
This commit is contained in:
46
SproutFarm-Backend/.dockerignore
Normal file
46
SproutFarm-Backend/.dockerignore
Normal file
@@ -0,0 +1,46 @@
|
||||
# Docker相关文件
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
|
||||
# Git相关
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Python缓存
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
.Python
|
||||
*.so
|
||||
|
||||
# IDE和编辑器
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# 系统文件
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# 日志文件
|
||||
*.log
|
||||
|
||||
# 临时文件
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# 文档
|
||||
*.md
|
||||
help.txt
|
||||
|
||||
# 服务配置文件
|
||||
*.service
|
||||
start.bat
|
||||
start.sh
|
||||
|
||||
# 其他不需要的文件
|
||||
console_demo.py
|
||||
1064
SproutFarm-Backend/ConsoleCommandsAPI.py
Normal file
1064
SproutFarm-Backend/ConsoleCommandsAPI.py
Normal file
File diff suppressed because it is too large
Load Diff
41
SproutFarm-Backend/Dockerfile
Normal file
41
SproutFarm-Backend/Dockerfile
Normal file
@@ -0,0 +1,41 @@
|
||||
# 使用Python 3.13.2官方镜像作为基础镜像
|
||||
FROM python:3.13.2-slim
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置环境变量
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV LANG=C.UTF-8
|
||||
ENV LC_ALL=C.UTF-8
|
||||
|
||||
# 配置apt使用阿里云镜像源
|
||||
RUN echo "deb https://mirrors.aliyun.com/debian/ bookworm main" > /etc/apt/sources.list && \
|
||||
echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main" >> /etc/apt/sources.list && \
|
||||
echo "deb https://mirrors.aliyun.com/debian-security/ bookworm-security main" >> /etc/apt/sources.list
|
||||
|
||||
# 复制requirements.txt并安装Python依赖
|
||||
COPY requirements.txt .
|
||||
# 配置pip使用国内镜像源
|
||||
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \
|
||||
pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn && \
|
||||
pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 复制所有源代码
|
||||
COPY . .
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p config game_saves chat __pycache__
|
||||
|
||||
# 设置目录权限
|
||||
RUN chmod -R 755 /app
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 6060
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD python -c "import socket; s = socket.socket(); s.settimeout(5); s.connect(('localhost', 6060)); s.close()" || exit 1
|
||||
|
||||
# 启动命令
|
||||
CMD ["python", "TCPGameServer.py"]
|
||||
543
SproutFarm-Backend/QQEmailSendAPI.py
Normal file
543
SproutFarm-Backend/QQEmailSendAPI.py
Normal file
@@ -0,0 +1,543 @@
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.application import MIMEApplication
|
||||
from email.header import Header
|
||||
import random
|
||||
import string
|
||||
import json
|
||||
import os
|
||||
|
||||
# 邮件发送配置
|
||||
SENDER_EMAIL = '3205788256@qq.com' # 发件人邮箱
|
||||
SENDER_AUTH_CODE = 'szcaxvbftusqddhi' # 授权码
|
||||
SMTP_SERVER = 'smtp.qq.com' # QQ邮箱SMTP服务器
|
||||
SMTP_PORT = 465 # QQ邮箱SSL端口
|
||||
|
||||
# 验证码缓存文件
|
||||
VERIFICATION_CACHE_FILE = os.path.join("config", "verification_codes.json")
|
||||
|
||||
class QQMailAPI:
|
||||
"""QQ邮箱发送邮件API类"""
|
||||
|
||||
def __init__(self, sender_email, authorization_code):
|
||||
"""
|
||||
初始化邮箱配置
|
||||
:param sender_email: 发送方QQ邮箱地址
|
||||
:param authorization_code: QQ邮箱授权码
|
||||
"""
|
||||
self.sender_email = sender_email
|
||||
self.authorization_code = authorization_code
|
||||
self.smtp_server = 'smtp.qq.com'
|
||||
self.smtp_port = 465 # SSL端口
|
||||
|
||||
# 发送纯文本邮件
|
||||
def send_text_email(self, receiver_email, subject, content, cc_emails=None):
|
||||
"""
|
||||
发送纯文本邮件
|
||||
:param receiver_email: 接收方邮箱地址(单个)
|
||||
:param subject: 邮件主题
|
||||
:param content: 邮件正文内容
|
||||
:param cc_emails: 抄送邮箱列表
|
||||
:return: 发送成功返回True,失败返回False
|
||||
"""
|
||||
try:
|
||||
# 创建邮件对象
|
||||
message = MIMEText(content, 'plain', 'utf-8')
|
||||
message['From'] = Header(self.sender_email, 'utf-8')
|
||||
message['To'] = Header(receiver_email, 'utf-8')
|
||||
message['Subject'] = Header(subject, 'utf-8')
|
||||
|
||||
# 添加抄送
|
||||
if cc_emails:
|
||||
message['Cc'] = Header(",".join(cc_emails), 'utf-8')
|
||||
all_receivers = [receiver_email] + cc_emails
|
||||
else:
|
||||
all_receivers = [receiver_email]
|
||||
|
||||
# 连接SMTP服务器并发送邮件
|
||||
with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server:
|
||||
server.login(self.sender_email, self.authorization_code)
|
||||
server.sendmail(self.sender_email, all_receivers, message.as_string())
|
||||
|
||||
print(f"邮件发送成功:主题='{subject}', 收件人='{receiver_email}'")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"邮件发送失败:{str(e)}")
|
||||
return False
|
||||
|
||||
# 发送HTML格式邮件,可带附件
|
||||
def send_html_email(self, receiver_email, subject, html_content, cc_emails=None, attachments=None):
|
||||
"""
|
||||
发送HTML格式邮件,可带附件
|
||||
:param receiver_email: 接收方邮箱地址(单个)
|
||||
:param subject: 邮件主题
|
||||
:param html_content: HTML格式的邮件正文
|
||||
:param cc_emails: 抄送邮箱列表
|
||||
:param attachments: 附件文件路径列表
|
||||
:return: 发送成功返回True,失败返回False
|
||||
"""
|
||||
try:
|
||||
# 创建带附件的邮件对象
|
||||
message = MIMEMultipart()
|
||||
message['From'] = Header(self.sender_email, 'utf-8')
|
||||
message['To'] = Header(receiver_email, 'utf-8')
|
||||
message['Subject'] = Header(subject, 'utf-8')
|
||||
|
||||
# 添加抄送
|
||||
if cc_emails:
|
||||
message['Cc'] = Header(",".join(cc_emails), 'utf-8')
|
||||
all_receivers = [receiver_email] + cc_emails
|
||||
else:
|
||||
all_receivers = [receiver_email]
|
||||
|
||||
# 添加HTML正文
|
||||
message.attach(MIMEText(html_content, 'html', 'utf-8'))
|
||||
|
||||
# 添加附件
|
||||
if attachments:
|
||||
for file_path in attachments:
|
||||
try:
|
||||
with open(file_path, 'rb') as file:
|
||||
attachment = MIMEApplication(file.read(), _subtype="octet-stream")
|
||||
attachment.add_header('Content-Disposition', 'attachment', filename=file_path.split("/")[-1])
|
||||
message.attach(attachment)
|
||||
except Exception as e:
|
||||
print(f"添加附件失败 {file_path}: {str(e)}")
|
||||
|
||||
# 连接SMTP服务器并发送邮件
|
||||
with smtplib.SMTP_SSL(self.smtp_server, self.smtp_port) as server:
|
||||
server.login(self.sender_email, self.authorization_code)
|
||||
server.sendmail(self.sender_email, all_receivers, message.as_string())
|
||||
|
||||
print(f"HTML邮件发送成功:主题='{subject}', 收件人='{receiver_email}'")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"HTML邮件发送失败:{str(e)}")
|
||||
return False
|
||||
|
||||
class EmailVerification:
|
||||
|
||||
#生成指定长度的随机验证码
|
||||
@staticmethod
|
||||
def generate_verification_code(length=6):
|
||||
"""
|
||||
生成指定长度的随机验证码
|
||||
|
||||
参数:
|
||||
length (int): 验证码长度,默认6位
|
||||
|
||||
返回:
|
||||
str: 生成的验证码
|
||||
"""
|
||||
# 生成包含大写字母和数字的验证码
|
||||
chars = string.ascii_uppercase + string.digits
|
||||
return ''.join(random.choice(chars) for _ in range(length))
|
||||
|
||||
#发送验证码邮件到QQ邮箱
|
||||
@staticmethod
|
||||
def send_verification_email(qq_number, verification_code, email_type="register"):
|
||||
"""
|
||||
发送验证码邮件到QQ邮箱
|
||||
|
||||
参数:
|
||||
qq_number (str): 接收者QQ号
|
||||
verification_code (str): 验证码
|
||||
email_type (str): 邮件类型,"register" 或 "reset_password"
|
||||
|
||||
返回:
|
||||
bool: 发送成功返回True,否则返回False
|
||||
str: 成功或错误信息
|
||||
"""
|
||||
receiver_email = f"{qq_number}@qq.com"
|
||||
|
||||
# 根据邮件类型设置不同的内容
|
||||
if email_type == "reset_password":
|
||||
email_title = "【萌芽农场】密码重置验证码"
|
||||
email_purpose = "重置萌芽农场游戏账号密码"
|
||||
email_color = "#FF6B35" # 橙红色,表示警告性操作
|
||||
else:
|
||||
email_title = "【萌芽农场】注册验证码"
|
||||
email_purpose = "注册萌芽农场游戏账号"
|
||||
email_color = "#4CAF50" # 绿色,表示正常操作
|
||||
|
||||
# 创建邮件内容
|
||||
message = MIMEText(f'''
|
||||
<html>
|
||||
<body>
|
||||
<div style="font-family: Arial, sans-serif; color: #333;">
|
||||
<h2 style="color: {email_color};">萌芽农场 - 邮箱验证码</h2>
|
||||
<p>亲爱的玩家,您好!</p>
|
||||
<p>您正在{email_purpose},您的验证码是:</p>
|
||||
<div style="background-color: #f2f2f2; padding: 10px; font-size: 24px; font-weight: bold; color: {email_color}; text-align: center; margin: 20px 0;">
|
||||
{verification_code}
|
||||
</div>
|
||||
<p>该验证码有效期为5分钟,请勿泄露给他人。</p>
|
||||
<p>如果这不是您本人的操作,请忽略此邮件。</p>
|
||||
<p style="margin-top: 30px; font-size: 12px; color: #999;">
|
||||
本邮件由系统自动发送,请勿直接回复。
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
''', 'html', 'utf-8')
|
||||
|
||||
# 修正From头格式,符合QQ邮箱的要求
|
||||
message['From'] = SENDER_EMAIL
|
||||
message['To'] = receiver_email
|
||||
message['Subject'] = Header(email_title, 'utf-8')
|
||||
|
||||
try:
|
||||
# 使用SSL/TLS连接而不是STARTTLS
|
||||
smtp_obj = smtplib.SMTP_SSL(SMTP_SERVER, 465)
|
||||
smtp_obj.login(SENDER_EMAIL, SENDER_AUTH_CODE)
|
||||
smtp_obj.sendmail(SENDER_EMAIL, [receiver_email], message.as_string())
|
||||
smtp_obj.quit()
|
||||
return True, "验证码发送成功"
|
||||
except Exception as e:
|
||||
return False, f"发送验证码失败: {str(e)}"
|
||||
|
||||
#保存验证码到MongoDB(优先)或缓存文件(备用)
|
||||
@staticmethod
|
||||
def save_verification_code(qq_number, verification_code, expiry_time=300, code_type="register"):
|
||||
"""
|
||||
保存验证码到MongoDB(优先)或缓存文件(备用)
|
||||
|
||||
参数:
|
||||
qq_number (str): QQ号
|
||||
verification_code (str): 验证码
|
||||
expiry_time (int): 过期时间(秒),默认5分钟
|
||||
code_type (str): 验证码类型,"register" 或 "reset_password"
|
||||
|
||||
返回:
|
||||
bool: 保存成功返回True,否则返回False
|
||||
"""
|
||||
import time
|
||||
|
||||
# 优先尝试使用MongoDB
|
||||
try:
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
import os
|
||||
# 根据环境动态选择MongoDB配置
|
||||
if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true':
|
||||
environment = "production"
|
||||
else:
|
||||
environment = "test"
|
||||
mongo_api = SMYMongoDBAPI(environment)
|
||||
if mongo_api.is_connected():
|
||||
success = mongo_api.save_verification_code(qq_number, verification_code, expiry_time, code_type)
|
||||
if success:
|
||||
print(f"[验证码系统-MongoDB] 为QQ {qq_number} 保存{code_type}验证码: {verification_code}")
|
||||
return True
|
||||
else:
|
||||
print(f"[验证码系统-MongoDB] 保存失败,尝试使用JSON文件")
|
||||
except Exception as e:
|
||||
print(f"[验证码系统-MongoDB] MongoDB保存失败: {str(e)},尝试使用JSON文件")
|
||||
|
||||
# MongoDB失败,使用JSON文件备用
|
||||
# 创建目录(如果不存在)
|
||||
os.makedirs(os.path.dirname(VERIFICATION_CACHE_FILE), exist_ok=True)
|
||||
|
||||
# 读取现有的验证码数据
|
||||
verification_data = {}
|
||||
if os.path.exists(VERIFICATION_CACHE_FILE):
|
||||
try:
|
||||
with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file:
|
||||
verification_data = json.load(file)
|
||||
except Exception as e:
|
||||
print(f"读取验证码文件失败: {str(e)}")
|
||||
verification_data = {}
|
||||
|
||||
# 添加新的验证码
|
||||
expire_at = time.time() + expiry_time
|
||||
current_time = time.time()
|
||||
|
||||
# 创建验证码记录,包含更多信息用于调试
|
||||
verification_data[qq_number] = {
|
||||
"code": verification_code,
|
||||
"expire_at": expire_at,
|
||||
"code_type": code_type,
|
||||
"created_at": current_time,
|
||||
"used": False # 新增:标记验证码是否已使用
|
||||
}
|
||||
|
||||
# 保存到文件
|
||||
try:
|
||||
with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file:
|
||||
json.dump(verification_data, file, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"[验证码系统-JSON] 为QQ {qq_number} 保存{code_type}验证码: {verification_code}, 过期时间: {expire_at}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"保存验证码失败: {str(e)}")
|
||||
return False
|
||||
|
||||
#验证用户输入的验证码(优先使用MongoDB)
|
||||
@staticmethod
|
||||
def verify_code(qq_number, input_code, code_type="register"):
|
||||
"""
|
||||
验证用户输入的验证码(优先使用MongoDB)
|
||||
|
||||
参数:
|
||||
qq_number (str): QQ号
|
||||
input_code (str): 用户输入的验证码
|
||||
code_type (str): 验证码类型,"register" 或 "reset_password"
|
||||
|
||||
返回:
|
||||
bool: 验证成功返回True,否则返回False
|
||||
str: 成功或错误信息
|
||||
"""
|
||||
import time
|
||||
|
||||
# 优先尝试使用MongoDB
|
||||
try:
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
import os
|
||||
# 根据环境动态选择MongoDB配置
|
||||
if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true':
|
||||
environment = "production"
|
||||
else:
|
||||
environment = "test"
|
||||
mongo_api = SMYMongoDBAPI(environment)
|
||||
if mongo_api.is_connected():
|
||||
success, message = mongo_api.verify_verification_code(qq_number, input_code, code_type)
|
||||
print(f"[验证码系统-MongoDB] QQ {qq_number} 验证结果: {success}, 消息: {message}")
|
||||
return success, message
|
||||
except Exception as e:
|
||||
print(f"[验证码系统-MongoDB] MongoDB验证失败: {str(e)},尝试使用JSON文件")
|
||||
|
||||
# MongoDB失败,使用JSON文件备用
|
||||
# 检查缓存文件是否存在
|
||||
if not os.path.exists(VERIFICATION_CACHE_FILE):
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 缓存文件不存在")
|
||||
return False, "验证码不存在或已过期"
|
||||
|
||||
# 读取验证码数据
|
||||
try:
|
||||
with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file:
|
||||
verification_data = json.load(file)
|
||||
except Exception as e:
|
||||
print(f"[验证码系统-JSON] 读取验证码文件失败: {str(e)}")
|
||||
return False, "验证码数据损坏"
|
||||
|
||||
# 检查该QQ号是否有验证码
|
||||
if qq_number not in verification_data:
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 没有找到验证码记录")
|
||||
return False, "验证码不存在,请重新获取"
|
||||
|
||||
# 获取存储的验证码信息
|
||||
code_info = verification_data[qq_number]
|
||||
stored_code = code_info.get("code", "")
|
||||
expire_at = code_info.get("expire_at", 0)
|
||||
stored_code_type = code_info.get("code_type", "register")
|
||||
is_used = code_info.get("used", False)
|
||||
created_at = code_info.get("created_at", 0)
|
||||
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证码详情: 存储码={stored_code}, 输入码={input_code}, 类型={stored_code_type}, 已使用={is_used}, 创建时间={created_at}")
|
||||
|
||||
# 检查验证码类型是否匹配
|
||||
if stored_code_type != code_type:
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码类型不匹配,存储类型={stored_code_type}, 请求类型={code_type}")
|
||||
return False, f"验证码类型不匹配,请重新获取{code_type}验证码"
|
||||
|
||||
# 检查验证码是否已被使用
|
||||
if is_used:
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码已被使用")
|
||||
return False, "验证码已被使用,请重新获取"
|
||||
|
||||
# 检查验证码是否过期
|
||||
current_time = time.time()
|
||||
if current_time > expire_at:
|
||||
# 移除过期的验证码
|
||||
del verification_data[qq_number]
|
||||
with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file:
|
||||
json.dump(verification_data, file, indent=2, ensure_ascii=False)
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码已过期")
|
||||
return False, "验证码已过期,请重新获取"
|
||||
|
||||
# 验证码比较(不区分大小写)
|
||||
if input_code.upper() == stored_code.upper():
|
||||
# 验证成功,标记为已使用而不是删除
|
||||
verification_data[qq_number]["used"] = True
|
||||
verification_data[qq_number]["used_at"] = current_time
|
||||
|
||||
try:
|
||||
with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file:
|
||||
json.dump(verification_data, file, indent=2, ensure_ascii=False)
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证成功: 验证码已标记为已使用")
|
||||
return True, "验证码正确"
|
||||
except Exception as e:
|
||||
print(f"[验证码系统-JSON] 标记验证码已使用时失败: {str(e)}")
|
||||
return True, "验证码正确" # 即使标记失败,验证还是成功的
|
||||
else:
|
||||
print(f"[验证码系统-JSON] QQ {qq_number} 验证失败: 验证码不匹配")
|
||||
return False, "验证码错误"
|
||||
|
||||
#清理过期的验证码和已使用的验证码(优先使用MongoDB)
|
||||
@staticmethod
|
||||
def clean_expired_codes():
|
||||
"""
|
||||
清理过期的验证码和已使用的验证码(优先使用MongoDB)
|
||||
"""
|
||||
import time
|
||||
|
||||
# 优先尝试使用MongoDB
|
||||
try:
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
import os
|
||||
# 根据环境动态选择MongoDB配置
|
||||
if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true':
|
||||
environment = "production"
|
||||
else:
|
||||
environment = "test"
|
||||
mongo_api = SMYMongoDBAPI(environment)
|
||||
if mongo_api.is_connected():
|
||||
expired_count = mongo_api.clean_expired_verification_codes()
|
||||
print(f"[验证码系统-MongoDB] 清理完成,删除了 {expired_count} 个过期验证码")
|
||||
return expired_count
|
||||
except Exception as e:
|
||||
print(f"[验证码系统-MongoDB] MongoDB清理失败: {str(e)},尝试使用JSON文件")
|
||||
|
||||
# MongoDB失败,使用JSON文件备用
|
||||
if not os.path.exists(VERIFICATION_CACHE_FILE):
|
||||
return
|
||||
|
||||
try:
|
||||
with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file:
|
||||
verification_data = json.load(file)
|
||||
|
||||
current_time = time.time()
|
||||
removed_keys = []
|
||||
|
||||
# 找出过期的验证码和已使用的验证码(超过1小时)
|
||||
for qq_number, code_info in verification_data.items():
|
||||
expire_at = code_info.get("expire_at", 0)
|
||||
is_used = code_info.get("used", False)
|
||||
used_at = code_info.get("used_at", 0)
|
||||
|
||||
should_remove = False
|
||||
|
||||
# 过期的验证码
|
||||
if current_time > expire_at:
|
||||
should_remove = True
|
||||
print(f"[验证码清理-JSON] 移除过期验证码: QQ {qq_number}")
|
||||
|
||||
# 已使用超过1小时的验证码
|
||||
elif is_used and used_at > 0 and (current_time - used_at) > 3600:
|
||||
should_remove = True
|
||||
print(f"[验证码清理-JSON] 移除已使用的验证码: QQ {qq_number}")
|
||||
|
||||
if should_remove:
|
||||
removed_keys.append(qq_number)
|
||||
|
||||
# 移除标记的验证码
|
||||
for key in removed_keys:
|
||||
del verification_data[key]
|
||||
|
||||
# 保存更新后的数据
|
||||
if removed_keys:
|
||||
with open(VERIFICATION_CACHE_FILE, 'w', encoding='utf-8') as file:
|
||||
json.dump(verification_data, file, indent=2, ensure_ascii=False)
|
||||
print(f"[验证码清理-JSON] 共清理了 {len(removed_keys)} 个验证码")
|
||||
|
||||
except Exception as e:
|
||||
print(f"清理验证码失败: {str(e)}")
|
||||
|
||||
#获取验证码状态(优先使用MongoDB)
|
||||
@staticmethod
|
||||
def get_verification_status(qq_number):
|
||||
"""
|
||||
获取验证码状态(优先使用MongoDB)
|
||||
|
||||
参数:
|
||||
qq_number (str): QQ号
|
||||
|
||||
返回:
|
||||
dict: 验证码状态信息
|
||||
"""
|
||||
import time
|
||||
|
||||
# 优先尝试使用MongoDB
|
||||
try:
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
import os
|
||||
# 根据环境动态选择MongoDB配置
|
||||
if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true':
|
||||
environment = "production"
|
||||
else:
|
||||
environment = "test"
|
||||
mongo_api = SMYMongoDBAPI(environment)
|
||||
if mongo_api.is_connected():
|
||||
verification_codes = mongo_api.get_verification_codes()
|
||||
if verification_codes and qq_number in verification_codes:
|
||||
code_info = verification_codes[qq_number]
|
||||
current_time = time.time()
|
||||
|
||||
return {
|
||||
"status": "found",
|
||||
"code": code_info.get("code", ""),
|
||||
"code_type": code_info.get("code_type", "unknown"),
|
||||
"used": code_info.get("used", False),
|
||||
"expired": current_time > code_info.get("expire_at", 0),
|
||||
"created_at": code_info.get("created_at", 0),
|
||||
"expire_at": code_info.get("expire_at", 0),
|
||||
"used_at": code_info.get("used_at", 0),
|
||||
"source": "mongodb"
|
||||
}
|
||||
else:
|
||||
return {"status": "no_code", "source": "mongodb"}
|
||||
except Exception as e:
|
||||
print(f"[验证码系统-MongoDB] MongoDB状态查询失败: {str(e)},尝试使用JSON文件")
|
||||
|
||||
# MongoDB失败,使用JSON文件备用
|
||||
if not os.path.exists(VERIFICATION_CACHE_FILE):
|
||||
return {"status": "no_cache_file"}
|
||||
|
||||
try:
|
||||
with open(VERIFICATION_CACHE_FILE, 'r', encoding='utf-8') as file:
|
||||
verification_data = json.load(file)
|
||||
|
||||
if qq_number not in verification_data:
|
||||
return {"status": "no_code"}
|
||||
|
||||
code_info = verification_data[qq_number]
|
||||
current_time = time.time()
|
||||
|
||||
return {
|
||||
"status": "found",
|
||||
"code": code_info.get("code", ""),
|
||||
"code_type": code_info.get("code_type", "unknown"),
|
||||
"used": code_info.get("used", False),
|
||||
"expired": current_time > code_info.get("expire_at", 0),
|
||||
"created_at": code_info.get("created_at", 0),
|
||||
"expire_at": code_info.get("expire_at", 0),
|
||||
"used_at": code_info.get("used_at", 0),
|
||||
"source": "json"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
return {"status": "error", "message": str(e)}
|
||||
|
||||
|
||||
# 测试邮件发送
|
||||
if __name__ == "__main__":
|
||||
# 清理过期验证码
|
||||
EmailVerification.clean_expired_codes()
|
||||
|
||||
# 生成验证码
|
||||
test_qq = input("请输入测试QQ号: ")
|
||||
verification_code = EmailVerification.generate_verification_code()
|
||||
print(f"生成的验证码: {verification_code}")
|
||||
|
||||
# 发送测试邮件
|
||||
success, message = EmailVerification.send_verification_email(test_qq, verification_code)
|
||||
print(f"发送结果: {success}, 消息: {message}")
|
||||
|
||||
if success:
|
||||
# 保存验证码
|
||||
EmailVerification.save_verification_code(test_qq, verification_code)
|
||||
|
||||
# 测试验证
|
||||
test_input = input("请输入收到的验证码: ")
|
||||
verify_success, verify_message = EmailVerification.verify_code(test_qq, test_input)
|
||||
print(f"验证结果: {verify_success}, 消息: {verify_message}")
|
||||
1518
SproutFarm-Backend/SMYMongoDBAPI.py
Normal file
1518
SproutFarm-Backend/SMYMongoDBAPI.py
Normal file
File diff suppressed because it is too large
Load Diff
507
SproutFarm-Backend/SpecialFarm.py
Normal file
507
SproutFarm-Backend/SpecialFarm.py
Normal file
@@ -0,0 +1,507 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
特殊农场管理系统
|
||||
作者: AI Assistant
|
||||
功能: 管理特殊农场的自动种植和维护
|
||||
"""
|
||||
|
||||
import time
|
||||
import random
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
from bson import ObjectId
|
||||
|
||||
#杂交农场666-种植杂交树1,杂交树2-每天0点种植
|
||||
#花卉农场520-随机种植各种花卉-星期一,星期三,星期五,星期日零点种植
|
||||
#瓜果农场333-随机种植各种瓜果-星期二,星期四,星期六零点种植
|
||||
#小麦谷222-全屏种植小麦-每天0点种植
|
||||
#稻香111-全屏种植稻谷-每天0点种植
|
||||
#幸运农场888-随机种植1-80个幸运草和幸运花-星期一零点种植
|
||||
|
||||
|
||||
|
||||
class SpecialFarmManager:
|
||||
#初始化特殊农场管理器
|
||||
def __init__(self, environment=None):
|
||||
"""
|
||||
初始化特殊农场管理器
|
||||
|
||||
Args:
|
||||
environment: 环境类型,"test" 或 "production",如果为None则自动检测
|
||||
"""
|
||||
# 如果没有指定环境,使用与TCPGameServer相同的环境检测逻辑
|
||||
if environment is None:
|
||||
import os
|
||||
if os.path.exists('/.dockerenv') or os.environ.get('PRODUCTION', '').lower() == 'true':
|
||||
environment = "production"
|
||||
else:
|
||||
environment = "test"
|
||||
|
||||
self.environment = environment
|
||||
self.mongo_api = SMYMongoDBAPI(environment)
|
||||
|
||||
# 设置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('special_farm.log', encoding='utf-8'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
# 特殊农场配置
|
||||
self.special_farms = {
|
||||
"杂交农场": {
|
||||
"object_id": "689b4b9286cf953f2f4e56ee",
|
||||
"crops": ["杂交树1", "杂交树2"],
|
||||
"description": "专门种植杂交树的特殊农场"
|
||||
},
|
||||
"花卉农场": {
|
||||
"object_id": "689bec6286cf953f2f4e56f1",
|
||||
"crops": ["郁金香", "牵牛花", "百合花", "栀子花", "玫瑰花", "向日葵", "藏红花", "幸运花"],
|
||||
"description": "盛产各种美丽花卉的特殊农场",
|
||||
"plant_type": "random_flowers" # 标记为随机花卉种植类型
|
||||
},
|
||||
"瓜果农场": {
|
||||
"object_id": "689bf73886cf953f2f4e56fa",
|
||||
"crops": ["西瓜", "南瓜", "哈密瓜", "葫芦", "黄瓜", "龙果", "菠萝", "芒果"],
|
||||
"description": "盛产各种瓜果的农场",
|
||||
"plant_type": "random_fruits" # 标记为随机瓜果种植类型
|
||||
},
|
||||
"小麦谷": {
|
||||
"object_id": "689bf9a886cf953f2f4e56fd",
|
||||
"crops": ["小麦"],
|
||||
"description": "盛产小麦的农场",
|
||||
"plant_type": "single_wheat" # 标记为单一小麦种植类型
|
||||
},
|
||||
"稻香": {
|
||||
"object_id": "689bf9ac86cf953f2f4e56fe",
|
||||
"crops": ["稻谷"],
|
||||
"description": "盛产稻谷的农场",
|
||||
"plant_type": "single_rice" # 标记为单一稻谷种植类型
|
||||
},
|
||||
"幸运农场": {
|
||||
"object_id": "689c027886cf953f2f4e56ff",
|
||||
"crops": ["幸运草", "幸运花"],
|
||||
"description": "盛产幸运草和幸运花的农场",
|
||||
"plant_type": "random_lucky" # 标记为随机幸运植物种植类型
|
||||
}
|
||||
}
|
||||
|
||||
self.logger.info(f"特殊农场管理器初始化完成 - 环境: {environment}")
|
||||
|
||||
#获取作物系统数据
|
||||
def get_crop_data(self):
|
||||
"""
|
||||
获取作物配置数据
|
||||
|
||||
Returns:
|
||||
dict: 作物配置数据
|
||||
"""
|
||||
try:
|
||||
crop_config = self.mongo_api.get_crop_data_config()
|
||||
if crop_config:
|
||||
# 移除MongoDB相关字段
|
||||
if "_id" in crop_config:
|
||||
del crop_config["_id"]
|
||||
if "config_type" in crop_config:
|
||||
del crop_config["config_type"]
|
||||
if "updated_at" in crop_config:
|
||||
del crop_config["updated_at"]
|
||||
return crop_config
|
||||
else:
|
||||
self.logger.error("无法获取作物配置数据")
|
||||
return {}
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取作物配置数据时出错: {str(e)}")
|
||||
return {}
|
||||
|
||||
#通过文档ID获取农场数据
|
||||
def get_player_data_by_object_id(self, object_id):
|
||||
"""
|
||||
通过ObjectId获取玩家数据
|
||||
|
||||
Args:
|
||||
object_id: MongoDB文档ID
|
||||
|
||||
Returns:
|
||||
dict: 玩家数据,如果未找到返回None
|
||||
"""
|
||||
try:
|
||||
collection = self.mongo_api.get_collection("playerdata")
|
||||
oid = ObjectId(object_id)
|
||||
player_data = collection.find_one({"_id": oid})
|
||||
|
||||
if player_data:
|
||||
self.logger.info(f"成功获取玩家数据: {player_data.get('玩家昵称', 'Unknown')}")
|
||||
return player_data
|
||||
else:
|
||||
self.logger.warning(f"未找到ObjectId为 {object_id} 的玩家数据")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"获取玩家数据时出错: {str(e)}")
|
||||
return None
|
||||
|
||||
#通过文档ID保存农场数据
|
||||
def save_player_data_by_object_id(self, object_id, player_data):
|
||||
"""
|
||||
通过ObjectId保存玩家数据
|
||||
|
||||
Args:
|
||||
object_id: MongoDB文档ID
|
||||
player_data: 玩家数据
|
||||
|
||||
Returns:
|
||||
bool: 是否保存成功
|
||||
"""
|
||||
try:
|
||||
collection = self.mongo_api.get_collection("playerdata")
|
||||
oid = ObjectId(object_id)
|
||||
|
||||
# 更新最后登录时间
|
||||
player_data["最后登录时间"] = datetime.now().strftime("%Y年%m月%d日%H时%M分%S秒")
|
||||
|
||||
result = collection.replace_one({"_id": oid}, player_data)
|
||||
|
||||
if result.acknowledged and result.matched_count > 0:
|
||||
self.logger.info(f"成功保存玩家数据: {player_data.get('玩家昵称', 'Unknown')}")
|
||||
return True
|
||||
else:
|
||||
self.logger.error(f"保存玩家数据失败: ObjectId {object_id}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"保存玩家数据时出错: {str(e)}")
|
||||
return False
|
||||
|
||||
#在指定农场种植作物
|
||||
def plant_crops_in_farm(self, farm_name):
|
||||
"""
|
||||
为指定特殊农场种植作物
|
||||
|
||||
Args:
|
||||
farm_name: 农场名称
|
||||
|
||||
Returns:
|
||||
bool: 是否种植成功
|
||||
"""
|
||||
if farm_name not in self.special_farms:
|
||||
self.logger.error(f"未知的特殊农场: {farm_name}")
|
||||
return False
|
||||
|
||||
farm_config = self.special_farms[farm_name]
|
||||
object_id = farm_config["object_id"]
|
||||
available_crops = farm_config["crops"]
|
||||
|
||||
# 获取玩家数据
|
||||
player_data = self.get_player_data_by_object_id(object_id)
|
||||
if not player_data:
|
||||
return False
|
||||
|
||||
# 获取作物配置
|
||||
crop_data = self.get_crop_data()
|
||||
if not crop_data:
|
||||
self.logger.error("无法获取作物配置,跳过种植")
|
||||
return False
|
||||
|
||||
# 检查作物是否存在
|
||||
for crop_name in available_crops:
|
||||
if crop_name not in crop_data:
|
||||
self.logger.error(f"作物 {crop_name} 不存在于作物配置中")
|
||||
return False
|
||||
|
||||
# 获取农场土地
|
||||
farm_lands = player_data.get("农场土地", [])
|
||||
if not farm_lands:
|
||||
self.logger.error(f"农场 {farm_name} 没有土地数据")
|
||||
return False
|
||||
|
||||
planted_count = 0
|
||||
plant_type = farm_config.get("plant_type", "normal")
|
||||
|
||||
# 遍历所有土地,先开垦再种植作物
|
||||
for i, land in enumerate(farm_lands):
|
||||
# 根据农场类型选择作物
|
||||
if plant_type == "random_flowers":
|
||||
# 花卉农场:随机种植各种花卉,种满所有土地
|
||||
crop_name = random.choice(available_crops)
|
||||
should_plant = True # 100%种植率,种满所有土地
|
||||
elif plant_type == "random_fruits":
|
||||
# 瓜果农场:随机种植各种瓜果,种满所有土地
|
||||
crop_name = random.choice(available_crops)
|
||||
should_plant = True # 100%种植率,种满所有土地
|
||||
elif plant_type == "single_wheat":
|
||||
# 小麦谷:全屏种植小麦,种满所有土地
|
||||
crop_name = "小麦"
|
||||
should_plant = True # 100%种植率,种满所有土地
|
||||
elif plant_type == "single_rice":
|
||||
# 稻香:全屏种植稻谷,种满所有土地
|
||||
crop_name = "稻谷"
|
||||
should_plant = True # 100%种植率,种满所有土地
|
||||
elif plant_type == "random_lucky":
|
||||
# 幸运农场:随机种植1-80个幸运草和幸运花
|
||||
crop_name = random.choice(available_crops)
|
||||
# 随机决定是否种植,确保总数在1-80之间
|
||||
target_plants = random.randint(1, min(80, len(farm_lands)))
|
||||
should_plant = planted_count < target_plants
|
||||
else:
|
||||
# 普通农场:按原逻辑随机选择
|
||||
crop_name = random.choice(available_crops)
|
||||
should_plant = True
|
||||
|
||||
if should_plant:
|
||||
crop_info = crop_data[crop_name]
|
||||
|
||||
# 更新土地数据(先开垦,再种植)
|
||||
land.update({
|
||||
"is_diged": True, # 确保土地已开垦
|
||||
"is_planted": True,
|
||||
"crop_type": crop_name,
|
||||
"grow_time": 0, # 立即成熟
|
||||
"max_grow_time": crop_info.get("生长时间", 21600),
|
||||
"is_dead": False,
|
||||
"已浇水": True,
|
||||
"已施肥": True,
|
||||
"土地等级": 0
|
||||
})
|
||||
|
||||
# 清除施肥时间戳
|
||||
if "施肥时间" in land:
|
||||
del land["施肥时间"]
|
||||
|
||||
planted_count += 1
|
||||
else:
|
||||
# 留空的土地:只开垦不种植
|
||||
land.update({
|
||||
"is_diged": True,
|
||||
"is_planted": False,
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"max_grow_time": 3,
|
||||
"is_dead": False,
|
||||
"已浇水": False,
|
||||
"已施肥": False,
|
||||
"土地等级": 0
|
||||
})
|
||||
|
||||
# 清除施肥时间戳
|
||||
if "施肥时间" in land:
|
||||
del land["施肥时间"]
|
||||
|
||||
# 保存玩家数据
|
||||
if self.save_player_data_by_object_id(object_id, player_data):
|
||||
self.logger.info(f"成功为 {farm_name} 种植了 {planted_count} 块土地的作物")
|
||||
return True
|
||||
else:
|
||||
self.logger.error(f"保存 {farm_name} 数据失败")
|
||||
return False
|
||||
|
||||
#每日维护任务
|
||||
def daily_maintenance(self):
|
||||
"""
|
||||
每日维护任务
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
self.logger.info("开始执行特殊农场维护任务...")
|
||||
|
||||
success_count = 0
|
||||
total_farms = 0
|
||||
current_time = datetime.now()
|
||||
current_weekday = current_time.weekday() # 0=Monday, 1=Tuesday, ..., 6=Sunday
|
||||
current_time_str = current_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
for farm_name in self.special_farms.keys():
|
||||
# 检查农场是否需要在今天维护
|
||||
should_maintain = True
|
||||
|
||||
if farm_name == "瓜果农场":
|
||||
# 瓜果农场只在星期二(1)、四(3)、六(5)维护
|
||||
if current_weekday not in [1, 3, 5]:
|
||||
should_maintain = False
|
||||
self.logger.info(f"瓜果农场今日({['周一','周二','周三','周四','周五','周六','周日'][current_weekday]})不需要维护")
|
||||
elif farm_name == "幸运农场":
|
||||
# 幸运农场只在星期一(0)维护
|
||||
if current_weekday != 0:
|
||||
should_maintain = False
|
||||
self.logger.info(f"幸运农场今日({['周一','周二','周三','周四','周五','周六','周日'][current_weekday]})不需要维护")
|
||||
|
||||
if should_maintain:
|
||||
total_farms += 1
|
||||
try:
|
||||
if self.plant_crops_in_farm(farm_name):
|
||||
success_count += 1
|
||||
self.logger.info(f"农场 {farm_name} 维护完成")
|
||||
|
||||
# 更新维护时间记录
|
||||
try:
|
||||
farm_config = self.special_farms[farm_name]
|
||||
object_id = farm_config["object_id"]
|
||||
player_data = self.get_player_data_by_object_id(object_id)
|
||||
if player_data:
|
||||
player_data["特殊农场最后维护时间"] = current_time_str
|
||||
self.save_player_data_by_object_id(object_id, player_data)
|
||||
except Exception as record_error:
|
||||
self.logger.error(f"更新 {farm_name} 维护时间记录失败: {str(record_error)}")
|
||||
else:
|
||||
self.logger.error(f"农场 {farm_name} 维护失败")
|
||||
except Exception as e:
|
||||
self.logger.error(f"维护农场 {farm_name} 时出错: {str(e)}")
|
||||
|
||||
self.logger.info(f"维护任务完成: {success_count}/{total_farms} 个农场维护成功")
|
||||
|
||||
#启动定时任务调度器(后台线程模式)
|
||||
def start_scheduler(self):
|
||||
"""
|
||||
启动定时任务调度器(后台线程模式)
|
||||
"""
|
||||
import threading
|
||||
|
||||
self.logger.info("特殊农场定时任务调度器已启动")
|
||||
self.logger.info("维护任务将在每天凌晨0点执行")
|
||||
|
||||
# 检查是否需要立即执行维护任务
|
||||
self._check_and_run_initial_maintenance()
|
||||
|
||||
# 在后台线程中运行调度循环
|
||||
def scheduler_loop():
|
||||
last_maintenance_date = None
|
||||
|
||||
while True:
|
||||
try:
|
||||
now = datetime.now()
|
||||
current_date = now.strftime("%Y-%m-%d")
|
||||
|
||||
# 检查是否到了零点且今天还没有执行过维护
|
||||
if (now.hour == 0 and now.minute == 0 and
|
||||
last_maintenance_date != current_date):
|
||||
self.logger.info("零点维护时间到,开始执行维护任务...")
|
||||
self.daily_maintenance()
|
||||
last_maintenance_date = current_date
|
||||
|
||||
time.sleep(60) # 每分钟检查一次
|
||||
except Exception as e:
|
||||
self.logger.error(f"调度器运行时出错: {str(e)}")
|
||||
time.sleep(60)
|
||||
|
||||
# 启动后台线程
|
||||
scheduler_thread = threading.Thread(target=scheduler_loop, daemon=True)
|
||||
scheduler_thread.start()
|
||||
self.logger.info("特殊农场调度器已在后台线程启动")
|
||||
|
||||
#检查是否需要执行初始维护任务
|
||||
def _check_and_run_initial_maintenance(self):
|
||||
"""
|
||||
检查是否需要执行初始维护任务
|
||||
避免服务器重启时重复执行
|
||||
"""
|
||||
try:
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# 检查今天是否已经执行过维护任务
|
||||
current_time = datetime.now()
|
||||
today = current_time.strftime("%Y-%m-%d")
|
||||
current_weekday = current_time.weekday() # 0=Monday, 1=Tuesday, ..., 6=Sunday
|
||||
|
||||
# 获取特殊农场数据,检查最后维护时间
|
||||
for farm_name, farm_config in self.special_farms.items():
|
||||
object_id = farm_config["object_id"]
|
||||
player_data = self.get_player_data_by_object_id(object_id)
|
||||
|
||||
# 检查农场是否需要在今天维护
|
||||
should_maintain = True
|
||||
if farm_name == "瓜果农场":
|
||||
# 瓜果农场只在星期二(1)、四(3)、六(5)维护
|
||||
if current_weekday not in [1, 3, 5]:
|
||||
should_maintain = False
|
||||
self.logger.info(f"瓜果农场今日({['周一','周二','周三','周四','周五','周六','周日'][current_weekday]})不需要维护")
|
||||
elif farm_name == "幸运农场":
|
||||
# 幸运农场只在星期一(0)维护
|
||||
if current_weekday != 0:
|
||||
should_maintain = False
|
||||
self.logger.info(f"幸运农场今日({['周一','周二','周三','周四','周五','周六','周日'][current_weekday]})不需要维护")
|
||||
|
||||
if should_maintain and player_data:
|
||||
last_maintenance = player_data.get("特殊农场最后维护时间", "")
|
||||
|
||||
# 如果今天还没有维护过,则执行维护
|
||||
if not last_maintenance or not last_maintenance.startswith(today):
|
||||
self.logger.info(f"检测到 {farm_name} 今日尚未维护,执行维护任务...")
|
||||
if self.plant_crops_in_farm(farm_name):
|
||||
# 更新维护时间记录
|
||||
player_data["特殊农场最后维护时间"] = current_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
self.save_player_data_by_object_id(object_id, player_data)
|
||||
else:
|
||||
self.logger.info(f"{farm_name} 今日已维护过,跳过初始维护")
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"检查初始维护任务时出错: {str(e)}")
|
||||
# 如果检查失败,执行一次维护作为备用
|
||||
self.logger.info("执行备用维护任务...")
|
||||
self.daily_maintenance()
|
||||
|
||||
#停止定时任务调度器
|
||||
def stop_scheduler(self):
|
||||
"""
|
||||
停止定时任务调度器
|
||||
"""
|
||||
try:
|
||||
# 设置停止标志(如果需要的话)
|
||||
self.logger.info("特殊农场定时任务调度器已停止")
|
||||
except Exception as e:
|
||||
self.logger.error(f"停止定时任务调度器时出错: {str(e)}")
|
||||
|
||||
#手动执行维护任务
|
||||
def manual_maintenance(self, farm_name=None):
|
||||
"""
|
||||
手动执行维护任务
|
||||
|
||||
Args:
|
||||
farm_name: 指定农场名称,如果为None则维护所有农场
|
||||
"""
|
||||
if farm_name:
|
||||
if farm_name in self.special_farms:
|
||||
self.logger.info(f"手动维护农场: {farm_name}")
|
||||
return self.plant_crops_in_farm(farm_name)
|
||||
else:
|
||||
self.logger.error(f"未知的农场名称: {farm_name}")
|
||||
return False
|
||||
else:
|
||||
self.logger.info("手动维护所有特殊农场")
|
||||
self.daily_maintenance()
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""
|
||||
主函数
|
||||
"""
|
||||
import sys
|
||||
|
||||
# 检查命令行参数
|
||||
environment = "production"
|
||||
if len(sys.argv) > 1:
|
||||
if sys.argv[1] in ["test", "production"]:
|
||||
environment = sys.argv[1]
|
||||
else:
|
||||
print("使用方法: python SpecialFarm.py [test|production]")
|
||||
sys.exit(1)
|
||||
|
||||
# 创建特殊农场管理器
|
||||
manager = SpecialFarmManager(environment)
|
||||
|
||||
# 检查是否为手动模式
|
||||
if len(sys.argv) > 2 and sys.argv[2] == "manual":
|
||||
# 手动执行维护
|
||||
farm_name = sys.argv[3] if len(sys.argv) > 3 else None
|
||||
manager.manual_maintenance(farm_name)
|
||||
else:
|
||||
# 启动定时任务
|
||||
manager.start_scheduler()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
10447
SproutFarm-Backend/TCPGameServer.py
Normal file
10447
SproutFarm-Backend/TCPGameServer.py
Normal file
File diff suppressed because it is too large
Load Diff
361
SproutFarm-Backend/TCPServer.py
Normal file
361
SproutFarm-Backend/TCPServer.py
Normal file
@@ -0,0 +1,361 @@
|
||||
import socket
|
||||
import threading
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
import logging
|
||||
import colorama
|
||||
from datetime import datetime
|
||||
|
||||
# 初始化colorama以支持跨平台彩色终端输出
|
||||
colorama.init()
|
||||
|
||||
# 自定义日志格式化器,带有颜色和分类
|
||||
class MinecraftStyleFormatter(logging.Formatter):
|
||||
"""Minecraft风格的日志格式化器,带有颜色和分类"""
|
||||
|
||||
# ANSI颜色代码
|
||||
COLORS = {
|
||||
'RESET': colorama.Fore.RESET,
|
||||
'BLACK': colorama.Fore.BLACK,
|
||||
'RED': colorama.Fore.RED,
|
||||
'GREEN': colorama.Fore.GREEN,
|
||||
'YELLOW': colorama.Fore.YELLOW,
|
||||
'BLUE': colorama.Fore.BLUE,
|
||||
'MAGENTA': colorama.Fore.MAGENTA,
|
||||
'CYAN': colorama.Fore.CYAN,
|
||||
'WHITE': colorama.Fore.WHITE,
|
||||
'BRIGHT_BLACK': colorama.Fore.LIGHTBLACK_EX,
|
||||
'BRIGHT_RED': colorama.Fore.LIGHTRED_EX,
|
||||
'BRIGHT_GREEN': colorama.Fore.LIGHTGREEN_EX,
|
||||
'BRIGHT_YELLOW': colorama.Fore.LIGHTYELLOW_EX,
|
||||
'BRIGHT_BLUE': colorama.Fore.LIGHTBLUE_EX,
|
||||
'BRIGHT_MAGENTA': colorama.Fore.LIGHTMAGENTA_EX,
|
||||
'BRIGHT_CYAN': colorama.Fore.LIGHTCYAN_EX,
|
||||
'BRIGHT_WHITE': colorama.Fore.LIGHTWHITE_EX,
|
||||
}
|
||||
|
||||
# 日志级别颜色(类似于Minecraft)
|
||||
LEVEL_COLORS = {
|
||||
'DEBUG': COLORS['BRIGHT_BLACK'],
|
||||
'INFO': COLORS['WHITE'],
|
||||
'WARNING': COLORS['YELLOW'],
|
||||
'ERROR': COLORS['RED'],
|
||||
'CRITICAL': COLORS['BRIGHT_RED'],
|
||||
}
|
||||
|
||||
# 类别及其颜色
|
||||
CATEGORIES = {
|
||||
'SERVER': COLORS['BRIGHT_CYAN'],
|
||||
'NETWORK': COLORS['BRIGHT_GREEN'],
|
||||
'CLIENT': COLORS['BRIGHT_YELLOW'],
|
||||
'SYSTEM': COLORS['BRIGHT_MAGENTA'],
|
||||
}
|
||||
|
||||
def format(self, record):
|
||||
# 获取日志级别颜色
|
||||
level_color = self.LEVEL_COLORS.get(record.levelname, self.COLORS['WHITE'])
|
||||
|
||||
# 从记录名称中确定类别,默认为SERVER
|
||||
category_name = getattr(record, 'category', 'SERVER')
|
||||
category_color = self.CATEGORIES.get(category_name, self.COLORS['WHITE'])
|
||||
|
||||
# 格式化时间戳,类似于Minecraft:[HH:MM:SS]
|
||||
timestamp = datetime.now().strftime('%H:%M:%S')
|
||||
|
||||
# 格式化消息
|
||||
formatted_message = f"{self.COLORS['BRIGHT_BLACK']}[{timestamp}] {category_color}[{category_name}] {level_color}{record.levelname}: {record.getMessage()}{self.COLORS['RESET']}"
|
||||
|
||||
return formatted_message
|
||||
|
||||
|
||||
class TCPServer:
|
||||
def __init__(self, host='127.0.0.1', port=9000, buffer_size=4096):
|
||||
"""初始化TCP服务器"""
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.buffer_size = buffer_size
|
||||
self.socket = None
|
||||
self.clients = {} # 存储客户端连接 {client_id: (socket, address)}
|
||||
self.running = False
|
||||
self.client_buffers = {} # 每个客户端的消息缓冲区
|
||||
|
||||
# 配置日志
|
||||
self._setup_logging()
|
||||
|
||||
def _setup_logging(self):
|
||||
"""设置Minecraft风格的日志系统"""
|
||||
# 创建日志器
|
||||
self.logger = logging.getLogger('TCPServer')
|
||||
self.logger.setLevel(logging.INFO)
|
||||
|
||||
# 清除任何现有的处理器
|
||||
if self.logger.handlers:
|
||||
self.logger.handlers.clear()
|
||||
|
||||
# 创建控制台处理器
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
|
||||
# 设置格式化器
|
||||
formatter = MinecraftStyleFormatter()
|
||||
console_handler.setFormatter(formatter)
|
||||
|
||||
# 添加处理器到日志器
|
||||
self.logger.addHandler(console_handler)
|
||||
|
||||
def log(self, level, message, category='SERVER'):
|
||||
"""使用指定的分类和级别记录日志"""
|
||||
record = logging.LogRecord(
|
||||
name=self.logger.name,
|
||||
level=getattr(logging, level),
|
||||
pathname='',
|
||||
lineno=0,
|
||||
msg=message,
|
||||
args=(),
|
||||
exc_info=None
|
||||
)
|
||||
record.category = category
|
||||
|
||||
# 检查是否存在控制台输入锁,如果存在则使用锁来避免打乱命令输入
|
||||
if hasattr(self, '_console_input_lock'):
|
||||
with self._console_input_lock:
|
||||
self.logger.handle(record)
|
||||
else:
|
||||
self.logger.handle(record)
|
||||
|
||||
def start(self):
|
||||
"""启动服务器"""
|
||||
try:
|
||||
# 创建TCP套接字
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # 禁用Nagle算法
|
||||
|
||||
# 绑定地址和监听
|
||||
self.socket.bind((self.host, self.port))
|
||||
self.socket.listen(5)
|
||||
|
||||
self.running = True
|
||||
self.log('INFO', f"服务器启动,监听 {self.host}:{self.port}", 'SERVER')
|
||||
|
||||
# 接受客户端连接的主循环
|
||||
self._accept_clients()
|
||||
|
||||
except Exception as e:
|
||||
self.log('ERROR', f"服务器启动错误: {e}", 'SYSTEM')
|
||||
self.stop()
|
||||
|
||||
def _accept_clients(self):
|
||||
"""接受客户端连接的循环"""
|
||||
while self.running:
|
||||
try:
|
||||
# 接受新的客户端连接
|
||||
client_socket, address = self.socket.accept()
|
||||
client_id = f"{address[0]}:{address[1]}"
|
||||
|
||||
self.log('INFO', f"新客户端连接: {client_id}", 'NETWORK')
|
||||
|
||||
# 存储客户端信息
|
||||
self.clients[client_id] = (client_socket, address)
|
||||
self.client_buffers[client_id] = ""
|
||||
|
||||
# 创建处理线程
|
||||
client_thread = threading.Thread(
|
||||
target=self._handle_client,
|
||||
args=(client_id,)
|
||||
)
|
||||
client_thread.daemon = True
|
||||
client_thread.start()
|
||||
|
||||
# 通知客户端连接成功
|
||||
self.send_data(client_id, {"type": "connection_status", "status": "connected"})
|
||||
|
||||
except KeyboardInterrupt:
|
||||
self.log('INFO', "收到中断信号,服务器停止中...", 'SYSTEM')
|
||||
break
|
||||
except Exception as e:
|
||||
self.log('ERROR', f"接受连接时出错: {e}", 'NETWORK')
|
||||
time.sleep(1) # 避免CPU过度使用
|
||||
|
||||
def _handle_client(self, client_id):
|
||||
"""处理客户端消息的线程"""
|
||||
client_socket, _ = self.clients.get(client_id, (None, None))
|
||||
if not client_socket:
|
||||
return
|
||||
|
||||
# 设置超时,用于定期检查连接状态
|
||||
client_socket.settimeout(30)
|
||||
|
||||
while self.running and client_id in self.clients:
|
||||
try:
|
||||
# 接收数据
|
||||
data = client_socket.recv(self.buffer_size)
|
||||
|
||||
if not data:
|
||||
# 客户端断开连接
|
||||
self.log('INFO', f"客户端 {client_id} 断开连接", 'CLIENT')
|
||||
self._remove_client(client_id)
|
||||
break
|
||||
|
||||
# 处理接收的数据
|
||||
self._process_data(client_id, data)
|
||||
|
||||
except socket.timeout:
|
||||
# 发送保活消息
|
||||
try:
|
||||
self.send_data(client_id, {"type": "ping"})
|
||||
except:
|
||||
self.log('INFO', f"客户端 {client_id} 连接超时", 'CLIENT')
|
||||
self._remove_client(client_id)
|
||||
break
|
||||
except Exception as e:
|
||||
self.log('ERROR', f"处理客户端 {client_id} 数据时出错: {e}", 'CLIENT')
|
||||
self._remove_client(client_id)
|
||||
break
|
||||
|
||||
def _process_data(self, client_id, data):
|
||||
"""处理从客户端接收的数据"""
|
||||
# 将接收的字节添加到缓冲区
|
||||
try:
|
||||
decoded_data = data.decode('utf-8')
|
||||
self.client_buffers[client_id] += decoded_data
|
||||
|
||||
# 处理可能包含多条JSON消息的缓冲区
|
||||
self._process_buffer(client_id)
|
||||
|
||||
except UnicodeDecodeError as e:
|
||||
self.log('ERROR', f"解码客户端 {client_id} 数据出错: {e}", 'CLIENT')
|
||||
|
||||
def _process_buffer(self, client_id):
|
||||
"""处理客户端消息缓冲区"""
|
||||
buffer = self.client_buffers.get(client_id, "")
|
||||
|
||||
# 按换行符分割消息
|
||||
while '\n' in buffer:
|
||||
message_end = buffer.find('\n')
|
||||
message_text = buffer[:message_end].strip()
|
||||
buffer = buffer[message_end + 1:]
|
||||
|
||||
# 处理非空消息
|
||||
if message_text:
|
||||
try:
|
||||
# 解析JSON消息
|
||||
message = json.loads(message_text)
|
||||
self.log('INFO', f"从客户端 {client_id} 接收JSON: {message}", 'CLIENT')
|
||||
|
||||
# 处理消息 - 实现自定义逻辑
|
||||
self._handle_message(client_id, message)
|
||||
|
||||
except json.JSONDecodeError:
|
||||
# 非JSON格式,作为原始文本处理
|
||||
self.log('INFO', f"从客户端 {client_id} 接收文本: {message_text}", 'CLIENT')
|
||||
self._handle_raw_message(client_id, message_text)
|
||||
|
||||
# 更新缓冲区
|
||||
self.client_buffers[client_id] = buffer
|
||||
|
||||
def _handle_message(self, client_id, message):
|
||||
"""处理JSON消息 - 可被子类覆盖以实现自定义逻辑"""
|
||||
# 默认实现:简单回显
|
||||
response = {
|
||||
"type": "response",
|
||||
"original": message,
|
||||
"timestamp": time.time()
|
||||
}
|
||||
self.send_data(client_id, response)
|
||||
|
||||
def _handle_raw_message(self, client_id, message):
|
||||
"""处理原始文本消息 - 可被子类覆盖以实现自定义逻辑"""
|
||||
# 默认实现:简单回显
|
||||
response = {
|
||||
"type": "text_response",
|
||||
"content": f"收到: {message}",
|
||||
"timestamp": time.time()
|
||||
}
|
||||
self.send_data(client_id, response)
|
||||
|
||||
def send_data(self, client_id, data):
|
||||
"""向指定客户端发送JSON数据"""
|
||||
if client_id not in self.clients:
|
||||
self.log('WARNING', f"客户端 {client_id} 不存在,无法发送数据", 'NETWORK')
|
||||
return False
|
||||
|
||||
client_socket, _ = self.clients[client_id]
|
||||
|
||||
try:
|
||||
# 转换为JSON字符串,添加换行符
|
||||
if isinstance(data, (dict, list)):
|
||||
message = json.dumps(data) + '\n'
|
||||
else:
|
||||
message = str(data) + '\n'
|
||||
|
||||
# 发送数据
|
||||
client_socket.sendall(message.encode('utf-8'))
|
||||
return True
|
||||
except Exception as e:
|
||||
self.log('ERROR', f"向客户端 {client_id} 发送数据时出错: {e}", 'NETWORK')
|
||||
self._remove_client(client_id)
|
||||
return False
|
||||
|
||||
def broadcast(self, data, exclude=None):
|
||||
"""向所有客户端广播消息,可选排除特定客户端"""
|
||||
exclude = exclude or []
|
||||
for client_id in list(self.clients.keys()):
|
||||
if client_id not in exclude:
|
||||
self.send_data(client_id, data)
|
||||
|
||||
def _remove_client(self, client_id):
|
||||
"""断开并移除客户端连接"""
|
||||
if client_id in self.clients:
|
||||
client_socket, _ = self.clients[client_id]
|
||||
try:
|
||||
client_socket.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
del self.clients[client_id]
|
||||
if client_id in self.client_buffers:
|
||||
del self.client_buffers[client_id]
|
||||
|
||||
self.log('INFO', f"客户端 {client_id} 已移除", 'CLIENT')
|
||||
|
||||
def stop(self):
|
||||
"""停止服务器"""
|
||||
self.running = False
|
||||
|
||||
# 关闭所有客户端连接
|
||||
for client_id in list(self.clients.keys()):
|
||||
self._remove_client(client_id)
|
||||
|
||||
# 关闭服务器套接字
|
||||
if self.socket:
|
||||
try:
|
||||
self.socket.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.log('INFO', "服务器已停止", 'SERVER')
|
||||
|
||||
|
||||
# 使用示例
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
# 创建并启动服务器
|
||||
server = TCPServer()
|
||||
|
||||
# 以阻塞方式启动服务器
|
||||
server_thread = threading.Thread(target=server.start)
|
||||
server_thread.daemon = True
|
||||
server_thread.start()
|
||||
|
||||
# 运行直到按Ctrl+C
|
||||
print("服务器运行中,按Ctrl+C停止...")
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n程序被用户中断")
|
||||
if 'server' in locals():
|
||||
server.stop()
|
||||
sys.exit(0)
|
||||
254
SproutFarm-Backend/WSRemoteCmdApi.py
Normal file
254
SproutFarm-Backend/WSRemoteCmdApi.py
Normal file
@@ -0,0 +1,254 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
WebSocket协议的服务器远程命令API
|
||||
作者: AI Assistant
|
||||
功能: 提供基于WebSocket的远程控制台命令执行功能
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import websockets
|
||||
import json
|
||||
import threading
|
||||
import time
|
||||
from typing import Dict, Any, Optional
|
||||
from ConsoleCommandsAPI import ConsoleCommandsAPI
|
||||
|
||||
class WSRemoteCmdApi:
|
||||
"""WebSocket远程命令API服务器"""
|
||||
|
||||
def __init__(self, game_server, host="0.0.0.0", port=7071, auth_key="mengya2024"):
|
||||
"""
|
||||
初始化WebSocket远程命令API服务器
|
||||
|
||||
Args:
|
||||
game_server: 游戏服务器实例
|
||||
host: WebSocket服务器监听地址
|
||||
port: WebSocket服务器监听端口
|
||||
auth_key: 认证密钥
|
||||
"""
|
||||
self.game_server = game_server
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.auth_key = auth_key
|
||||
self.server = None
|
||||
self.clients = {} # 存储已连接的客户端
|
||||
self.console_api = ConsoleCommandsAPI(game_server)
|
||||
self.running = False
|
||||
|
||||
async def register_client(self, websocket, path=None):
|
||||
"""注册新的客户端连接"""
|
||||
client_id = f"{websocket.remote_address[0]}:{websocket.remote_address[1]}_{int(time.time())}"
|
||||
self.clients[client_id] = {
|
||||
"websocket": websocket,
|
||||
"authenticated": False,
|
||||
"connect_time": time.time()
|
||||
}
|
||||
|
||||
try:
|
||||
# 发送欢迎消息
|
||||
await self.send_message(websocket, {
|
||||
"type": "welcome",
|
||||
"message": "欢迎连接到萌芽农场远程控制台",
|
||||
"server_version": getattr(self.game_server, 'server_version', '2.2.0'),
|
||||
"require_auth": True
|
||||
})
|
||||
|
||||
# 处理客户端消息
|
||||
async for message in websocket:
|
||||
await self.handle_message(client_id, message)
|
||||
|
||||
except websockets.exceptions.ConnectionClosed:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(f"❌ 客户端 {client_id} 连接处理出错: {str(e)}")
|
||||
finally:
|
||||
# 清理客户端连接
|
||||
if client_id in self.clients:
|
||||
del self.clients[client_id]
|
||||
print(f"🔌 客户端 {client_id} 已断开连接")
|
||||
|
||||
async def handle_message(self, client_id: str, message: str):
|
||||
"""处理客户端消息"""
|
||||
try:
|
||||
data = json.loads(message)
|
||||
message_type = data.get("type", "")
|
||||
|
||||
if message_type == "auth":
|
||||
await self.handle_auth(client_id, data)
|
||||
elif message_type == "command":
|
||||
await self.handle_command(client_id, data)
|
||||
elif message_type == "ping":
|
||||
await self.handle_ping(client_id, data)
|
||||
else:
|
||||
await self.send_error(client_id, f"未知消息类型: {message_type}")
|
||||
|
||||
except json.JSONDecodeError:
|
||||
await self.send_error(client_id, "无效的JSON格式")
|
||||
except Exception as e:
|
||||
await self.send_error(client_id, f"处理消息时出错: {str(e)}")
|
||||
|
||||
async def handle_auth(self, client_id: str, data: Dict[str, Any]):
|
||||
"""处理客户端认证"""
|
||||
if client_id not in self.clients:
|
||||
return
|
||||
|
||||
provided_key = data.get("auth_key", "")
|
||||
|
||||
if provided_key == self.auth_key:
|
||||
self.clients[client_id]["authenticated"] = True
|
||||
await self.send_message(self.clients[client_id]["websocket"], {
|
||||
"type": "auth_result",
|
||||
"success": True,
|
||||
"message": "认证成功,欢迎使用远程控制台"
|
||||
})
|
||||
print(f"✅ 客户端 {client_id} 认证成功")
|
||||
else:
|
||||
await self.send_message(self.clients[client_id]["websocket"], {
|
||||
"type": "auth_result",
|
||||
"success": False,
|
||||
"message": "认证失败,密钥错误"
|
||||
})
|
||||
print(f"❌ 客户端 {client_id} 认证失败")
|
||||
|
||||
async def handle_command(self, client_id: str, data: Dict[str, Any]):
|
||||
"""处理控制台命令"""
|
||||
if client_id not in self.clients:
|
||||
return
|
||||
|
||||
# 检查是否已认证
|
||||
if not self.clients[client_id]["authenticated"]:
|
||||
await self.send_error(client_id, "请先进行认证")
|
||||
return
|
||||
|
||||
command = data.get("command", "").strip()
|
||||
if not command:
|
||||
await self.send_error(client_id, "命令不能为空")
|
||||
return
|
||||
|
||||
# 执行命令并捕获输出
|
||||
try:
|
||||
# 重定向标准输出来捕获命令执行结果
|
||||
import io
|
||||
import sys
|
||||
|
||||
old_stdout = sys.stdout
|
||||
sys.stdout = captured_output = io.StringIO()
|
||||
|
||||
# 执行命令
|
||||
success = self.console_api.process_command(command)
|
||||
|
||||
# 恢复标准输出
|
||||
sys.stdout = old_stdout
|
||||
output = captured_output.getvalue()
|
||||
|
||||
# 发送执行结果
|
||||
await self.send_message(self.clients[client_id]["websocket"], {
|
||||
"type": "command_result",
|
||||
"command": command,
|
||||
"success": success,
|
||||
"output": output if output else ("命令执行成功" if success else "命令执行失败")
|
||||
})
|
||||
|
||||
print(f"📝 客户端 {client_id} 执行命令: {command} - {'成功' if success else '失败'}")
|
||||
|
||||
except Exception as e:
|
||||
await self.send_error(client_id, f"执行命令时出错: {str(e)}")
|
||||
|
||||
async def handle_ping(self, client_id: str, data: Dict[str, Any]):
|
||||
"""处理ping请求"""
|
||||
if client_id not in self.clients:
|
||||
return
|
||||
|
||||
await self.send_message(self.clients[client_id]["websocket"], {
|
||||
"type": "pong",
|
||||
"timestamp": time.time()
|
||||
})
|
||||
|
||||
async def send_message(self, websocket, data: Dict[str, Any]):
|
||||
"""发送消息到客户端"""
|
||||
try:
|
||||
message = json.dumps(data, ensure_ascii=False)
|
||||
await websocket.send(message)
|
||||
except Exception as e:
|
||||
print(f"❌ 发送消息失败: {str(e)}")
|
||||
|
||||
async def send_error(self, client_id: str, error_message: str):
|
||||
"""发送错误消息到客户端"""
|
||||
if client_id in self.clients:
|
||||
await self.send_message(self.clients[client_id]["websocket"], {
|
||||
"type": "error",
|
||||
"message": error_message
|
||||
})
|
||||
|
||||
def start_server(self):
|
||||
"""启动WebSocket服务器"""
|
||||
if self.running:
|
||||
return
|
||||
|
||||
async def run_server_async():
|
||||
try:
|
||||
self.server = await websockets.serve(
|
||||
self.register_client,
|
||||
self.host,
|
||||
self.port
|
||||
)
|
||||
|
||||
self.running = True
|
||||
print(f"🌐 WebSocket远程控制台服务器已启动: ws://{self.host}:{self.port}")
|
||||
print(f"🔑 认证密钥: {self.auth_key}")
|
||||
|
||||
# 保持服务器运行
|
||||
await self.server.wait_closed()
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ WebSocket服务器启动失败: {str(e)}")
|
||||
self.running = False
|
||||
|
||||
def run_server():
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
try:
|
||||
loop.run_until_complete(run_server_async())
|
||||
except Exception as e:
|
||||
print(f"❌ WebSocket服务器线程异常: {str(e)}")
|
||||
self.running = False
|
||||
|
||||
# 在新线程中运行WebSocket服务器
|
||||
server_thread = threading.Thread(target=run_server, daemon=True)
|
||||
server_thread.start()
|
||||
|
||||
def stop_server(self):
|
||||
"""停止WebSocket服务器"""
|
||||
if not self.running:
|
||||
return
|
||||
|
||||
self.running = False
|
||||
|
||||
# 关闭所有客户端连接
|
||||
for client_id, client_info in list(self.clients.items()):
|
||||
try:
|
||||
asyncio.create_task(client_info["websocket"].close())
|
||||
except:
|
||||
pass
|
||||
|
||||
self.clients.clear()
|
||||
|
||||
if self.server:
|
||||
try:
|
||||
self.server.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
print("🌐 WebSocket远程控制台服务器已停止")
|
||||
|
||||
def get_status(self) -> Dict[str, Any]:
|
||||
"""获取服务器状态"""
|
||||
return {
|
||||
"running": self.running,
|
||||
"host": self.host,
|
||||
"port": self.port,
|
||||
"connected_clients": len(self.clients),
|
||||
"authenticated_clients": len([c for c in self.clients.values() if c["authenticated"]])
|
||||
}
|
||||
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/CropSystem.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/CropSystem.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/DataManager.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/DataManager.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/QQEmailSend.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/QQEmailSend.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/QQEmailSendAPI.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/QQEmailSendAPI.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/SMYMongoDBAPI.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/SMYMongoDBAPI.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/SpecialFarm.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/SpecialFarm.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/TCPGameServer.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/TCPGameServer.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/TCPGameServer_New.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/TCPGameServer_New.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/TCPServer.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/TCPServer.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/UserAuth.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/UserAuth.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/WSRemoteCmdApi.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/WSRemoteCmdApi.cpython-313.pyc
Normal file
Binary file not shown.
BIN
SproutFarm-Backend/__pycache__/web_admin.cpython-313.pyc
Normal file
BIN
SproutFarm-Backend/__pycache__/web_admin.cpython-313.pyc
Normal file
Binary file not shown.
121
SproutFarm-Backend/deploy.sh
Normal file
121
SproutFarm-Backend/deploy.sh
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 萌芽农场服务器 Docker 部署脚本
|
||||
# 使用方法: ./deploy.sh [start|stop|restart|logs|status]
|
||||
|
||||
set -e
|
||||
|
||||
CONTAINER_NAME="mengyafarm-server"
|
||||
IMAGE_NAME="mengyafarm-server"
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
echo "萌芽农场服务器 Docker 部署脚本"
|
||||
echo "使用方法: $0 [命令]"
|
||||
echo ""
|
||||
echo "可用命令:"
|
||||
echo " start - 启动服务器"
|
||||
echo " stop - 停止服务器"
|
||||
echo " restart - 重启服务器"
|
||||
echo " logs - 查看日志"
|
||||
echo " status - 查看状态"
|
||||
echo " build - 重新构建镜像"
|
||||
echo " help - 显示此帮助信息"
|
||||
}
|
||||
|
||||
# 检查Docker是否安装
|
||||
check_docker() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "❌ Docker 未安装,请先安装 Docker"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
echo "❌ Docker Compose 未安装,请先安装 Docker Compose"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 启动服务器
|
||||
start_server() {
|
||||
echo "🚀 启动萌芽农场服务器..."
|
||||
|
||||
# 启动容器
|
||||
docker-compose up -d
|
||||
|
||||
echo "✅ 服务器启动成功!"
|
||||
}
|
||||
|
||||
# 停止服务器
|
||||
stop_server() {
|
||||
echo "⏹️ 停止萌芽农场服务器..."
|
||||
docker-compose down
|
||||
echo "✅ 服务器已停止"
|
||||
}
|
||||
|
||||
# 重启服务器
|
||||
restart_server() {
|
||||
echo "🔄 重启萌芽农场服务器..."
|
||||
docker-compose restart
|
||||
echo "✅ 服务器重启完成"
|
||||
}
|
||||
|
||||
# 查看日志
|
||||
show_logs() {
|
||||
echo "📝 查看服务器日志 (按 Ctrl+C 退出)..."
|
||||
docker-compose logs -f
|
||||
}
|
||||
|
||||
# 查看状态
|
||||
show_status() {
|
||||
echo "📊 服务器状态:"
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
if docker-compose ps | grep -q "Up"; then
|
||||
echo "✅ 服务器正在运行"
|
||||
echo "🔗 端口映射: 6060:6060"
|
||||
else
|
||||
echo "❌ 服务器未运行"
|
||||
fi
|
||||
}
|
||||
|
||||
# 构建镜像
|
||||
build_image() {
|
||||
echo "🔨 重新构建镜像..."
|
||||
docker-compose build --no-cache
|
||||
echo "✅ 镜像构建完成"
|
||||
}
|
||||
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
check_docker
|
||||
|
||||
case "${1:-help}" in
|
||||
"start")
|
||||
start_server
|
||||
;;
|
||||
"stop")
|
||||
stop_server
|
||||
;;
|
||||
"restart")
|
||||
restart_server
|
||||
;;
|
||||
"logs")
|
||||
show_logs
|
||||
;;
|
||||
"status")
|
||||
show_status
|
||||
;;
|
||||
"build")
|
||||
build_image
|
||||
;;
|
||||
"help"|*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
32
SproutFarm-Backend/docker-compose.yml
Normal file
32
SproutFarm-Backend/docker-compose.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mengyafarm-server:
|
||||
build: .
|
||||
container_name: mengyafarm-server
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "7070:7070"
|
||||
volumes:
|
||||
# 持久化游戏存档
|
||||
- ./game_saves:/app/game_saves
|
||||
# 持久化配置文件
|
||||
- ./config:/app/config
|
||||
# 持久化聊天日志
|
||||
- ./chat:/app/chat
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
- LANG=C.UTF-8
|
||||
- LC_ALL=C.UTF-8
|
||||
- PRODUCTION=true
|
||||
networks:
|
||||
- mengyafarm-network
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
|
||||
networks:
|
||||
mengyafarm-network:
|
||||
driver: bridge
|
||||
85
SproutFarm-Backend/logs/server_monitor_20250815.log
Normal file
85
SproutFarm-Backend/logs/server_monitor_20250815.log
Normal file
@@ -0,0 +1,85 @@
|
||||
2025-08-15 13:15:48,010 [INFO] 服务器监控器启动
|
||||
2025-08-15 13:15:48,010 [INFO] 正在启动服务器...
|
||||
2025-08-15 13:15:48,406 [INFO] [SERVER] ============================================================
|
||||
2025-08-15 13:15:48,420 [INFO] [SERVER] Traceback (most recent call last):
|
||||
2025-08-15 13:15:48,420 [ERROR] 检测到严重错误: Traceback (most recent call last):
|
||||
2025-08-15 13:15:48,422 [INFO] [SERVER] File "E:\Godot\Godot项目\比较完成的作品\萌芽农场\Server\TCPGameServer.py", line 10395, in <module>
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] print(f"\U0001f331 萌芽农场游戏服务器 v{server_version} \U0001f331")
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 47, in write
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] self.__convertor.write(text)
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 177, in write
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] self.write_and_convert(text)
|
||||
2025-08-15 13:15:48,423 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 205, in write_and_convert
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] self.write_plain_text(text, cursor, len(text))
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 210, in write_plain_text
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] self.wrapped.write(text[start:end])
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] UnicodeEncodeError: 'gbk' codec can't encode character '\U0001f331' in position 0: illegal multibyte sequence
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] During handling of the above exception, another exception occurred:
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] Traceback (most recent call last):
|
||||
2025-08-15 13:15:48,424 [ERROR] 检测到严重错误: Traceback (most recent call last):
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] File "E:\Godot\Godot项目\比较完成的作品\萌芽农场\Server\TCPGameServer.py", line 10447, in <module>
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] print(f"\n\u274c 服务器启动失败: {str(e)}")
|
||||
2025-08-15 13:15:48,424 [INFO] [SERVER] ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 47, in write
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] self.__convertor.write(text)
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 177, in write
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] self.write_and_convert(text)
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 205, in write_and_convert
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] self.write_plain_text(text, cursor, len(text))
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 210, in write_plain_text
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] self.wrapped.write(text[start:end])
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:15:48,425 [INFO] [SERVER] UnicodeEncodeError: 'gbk' codec can't encode character '\u274c' in position 2: illegal multibyte sequence
|
||||
2025-08-15 13:15:53,015 [ERROR] 服务器启动失败
|
||||
2025-08-15 13:15:53,015 [ERROR] 初始启动失败,退出监控
|
||||
2025-08-15 13:17:34,183 [INFO] 服务器监控器启动
|
||||
2025-08-15 13:17:34,183 [INFO] 正在启动服务器...
|
||||
2025-08-15 13:17:34,623 [INFO] [SERVER] ============================================================
|
||||
2025-08-15 13:17:34,623 [INFO] [SERVER] [ERROR] 服务器启动失败: 'gbk' codec can't encode character '\U0001f331' in position 0: illegal multibyte sequence
|
||||
2025-08-15 13:17:34,628 [INFO] [SERVER] Traceback (most recent call last):
|
||||
2025-08-15 13:17:34,628 [ERROR] 检测到严重错误: Traceback (most recent call last):
|
||||
2025-08-15 13:17:34,628 [INFO] [SERVER] File "E:\Godot\Godot项目\比较完成的作品\萌芽农场\Server\TCPGameServer.py", line 10395, in <module>
|
||||
2025-08-15 13:17:34,628 [INFO] [SERVER] print(f"\U0001f331 萌芽农场游戏服务器 v{server_version} \U0001f331")
|
||||
2025-08-15 13:17:34,629 [INFO] [SERVER] ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:17:34,629 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 47, in write
|
||||
2025-08-15 13:17:34,629 [INFO] [SERVER] self.__convertor.write(text)
|
||||
2025-08-15 13:17:34,629 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:17:34,629 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 177, in write
|
||||
2025-08-15 13:17:34,629 [INFO] [SERVER] self.write_and_convert(text)
|
||||
2025-08-15 13:17:34,629 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 205, in write_and_convert
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] self.write_plain_text(text, cursor, len(text))
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 210, in write_plain_text
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] self.wrapped.write(text[start:end])
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] UnicodeEncodeError: 'gbk' codec can't encode character '\U0001f331' in position 0: illegal multibyte sequence
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] During handling of the above exception, another exception occurred:
|
||||
2025-08-15 13:17:34,630 [INFO] [SERVER] Traceback (most recent call last):
|
||||
2025-08-15 13:17:34,631 [ERROR] 检测到严重错误: Traceback (most recent call last):
|
||||
2025-08-15 13:17:34,631 [INFO] [SERVER] File "E:\Godot\Godot项目\比较完成的作品\萌芽农场\Server\TCPGameServer.py", line 10448, in <module>
|
||||
2025-08-15 13:17:34,631 [INFO] [SERVER] print("\U0001f527 请检查配置并重试")
|
||||
2025-08-15 13:17:34,631 [INFO] [SERVER] ~~~~~^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:17:34,631 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 47, in write
|
||||
2025-08-15 13:17:34,631 [INFO] [SERVER] self.__convertor.write(text)
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 177, in write
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] self.write_and_convert(text)
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 205, in write_and_convert
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] self.write_plain_text(text, cursor, len(text))
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:17:34,632 [INFO] [SERVER] File "E:\ProgramLanguage\Python\python313\Lib\site-packages\colorama\ansitowin32.py", line 210, in write_plain_text
|
||||
2025-08-15 13:17:34,633 [INFO] [SERVER] self.wrapped.write(text[start:end])
|
||||
2025-08-15 13:17:34,633 [INFO] [SERVER] ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
|
||||
2025-08-15 13:17:34,633 [INFO] [SERVER] UnicodeEncodeError: 'gbk' codec can't encode character '\U0001f527' in position 0: illegal multibyte sequence
|
||||
2025-08-15 13:17:39,187 [ERROR] 服务器启动失败
|
||||
2025-08-15 13:17:39,187 [ERROR] 初始启动失败,退出监控
|
||||
7
SproutFarm-Backend/requirements.txt
Normal file
7
SproutFarm-Backend/requirements.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
# Game Server Dependencies
|
||||
colorama>=0.4.6 # For colored terminal output
|
||||
pymongo>=4.6.0 # MongoDB driver for Python
|
||||
schedule>=1.2.0 # Task scheduling for special farm management
|
||||
websockets>=11.0.3 # WebSocket server for remote console API
|
||||
# Email Requirements
|
||||
# Standard library dependencies are not listed (socket, threading, json, etc.)
|
||||
0
SproutFarm-Backend/special_farm.log
Normal file
0
SproutFarm-Backend/special_farm.log
Normal file
4
SproutFarm-Backend/start.bat
Normal file
4
SproutFarm-Backend/start.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
chcp 65001
|
||||
python TCPGameServer.py
|
||||
pause
|
||||
5
SproutFarm-Backend/start.sh
Normal file
5
SproutFarm-Backend/start.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
# 设置UTF-8字符编码
|
||||
export LANG=en_US.UTF-8
|
||||
# 执行Python服务器程序
|
||||
python3 TCPGameServer.py
|
||||
1
SproutFarm-Backend/systemctl/help.txt
Normal file
1
SproutFarm-Backend/systemctl/help.txt
Normal file
@@ -0,0 +1 @@
|
||||
/etc/systemd/system/mengyafarm.service
|
||||
15
SproutFarm-Backend/systemctl/mengyafarmserver.service
Normal file
15
SproutFarm-Backend/systemctl/mengyafarmserver.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=MengyaFarmServer
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/shumengya/mengyafarmserver
|
||||
ExecStart=/usr/bin/pip install -r requirements.txt && /usr/bin/python TCPGameServer.py
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
120
SproutFarm-Backend/test/console_demo.py
Normal file
120
SproutFarm-Backend/test/console_demo.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
萌芽农场服务器控制台命令演示
|
||||
展示各种控制台命令的使用方法和效果
|
||||
"""
|
||||
|
||||
def show_console_demo():
|
||||
"""展示控制台命令使用示例"""
|
||||
print("🌱 萌芽农场服务器控制台命令演示")
|
||||
print("=" * 60)
|
||||
|
||||
print("\n📋 可用命令列表:")
|
||||
commands = [
|
||||
("help", "显示帮助信息"),
|
||||
("lsplayer", "列出所有已注册玩家"),
|
||||
("playerinfo <QQ号>", "查看玩家详细信息"),
|
||||
("addmoney <QQ号> <数量>", "为玩家添加金币"),
|
||||
("addxp <QQ号> <数量>", "为玩家添加经验"),
|
||||
("addlevel <QQ号> <数量>", "为玩家添加等级"),
|
||||
("addseed <QQ号> <作物> <数量>", "为玩家添加种子"),
|
||||
("resetland <QQ号>", "重置玩家土地状态"),
|
||||
("save", "立即保存所有数据"),
|
||||
("reload", "重新加载配置"),
|
||||
("stop", "停止服务器")
|
||||
]
|
||||
|
||||
for cmd, desc in commands:
|
||||
print(f" {cmd:<30} - {desc}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🎯 使用示例:")
|
||||
|
||||
examples = [
|
||||
{
|
||||
"title": "查看玩家信息",
|
||||
"commands": [
|
||||
"lsplayer",
|
||||
"playerinfo 2143323382"
|
||||
],
|
||||
"description": "首先列出所有玩家,然后查看特定玩家的详细信息"
|
||||
},
|
||||
{
|
||||
"title": "发放新手福利",
|
||||
"commands": [
|
||||
"addmoney 2143323382 5000",
|
||||
"addxp 2143323382 1000",
|
||||
"addseed 2143323382 番茄 50",
|
||||
"addseed 2143323382 胡萝卜 30"
|
||||
],
|
||||
"description": "为新玩家发放启动资金、经验和种子"
|
||||
},
|
||||
{
|
||||
"title": "活动奖励发放",
|
||||
"commands": [
|
||||
"addlevel 2143323382 3",
|
||||
"addmoney 2143323382 10000",
|
||||
"addseed 2143323382 龙果 5"
|
||||
],
|
||||
"description": "为参与活动的玩家发放等级、金币和稀有种子奖励"
|
||||
},
|
||||
{
|
||||
"title": "问题处理",
|
||||
"commands": [
|
||||
"playerinfo 2143323382",
|
||||
"resetland 2143323382",
|
||||
"save"
|
||||
],
|
||||
"description": "查看玩家状态,重置有问题的土地,保存数据"
|
||||
}
|
||||
]
|
||||
|
||||
for i, example in enumerate(examples, 1):
|
||||
print(f"\n{i}. {example['title']}")
|
||||
print(f" 说明: {example['description']}")
|
||||
print(" 命令序列:")
|
||||
for cmd in example['commands']:
|
||||
print(f" > {cmd}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("⚠️ 注意事项:")
|
||||
notices = [
|
||||
"命令前的斜杠(/)是可选的,'addmoney' 和 '/addmoney' 效果相同",
|
||||
"QQ号必须是已注册的玩家账号",
|
||||
"数量参数必须是正整数",
|
||||
"作物名称必须在游戏配置中存在",
|
||||
"resetland 命令会清除玩家所有农场进度,请谨慎使用",
|
||||
"对在线玩家的修改会立即生效并推送到客户端",
|
||||
"所有修改都会自动保存到磁盘"
|
||||
]
|
||||
|
||||
for notice in notices:
|
||||
print(f" • {notice}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🔧 常见作物名称参考:")
|
||||
crops = [
|
||||
"基础作物: 小麦、胡萝卜、土豆、稻谷、玉米、番茄",
|
||||
"花卉类: 玫瑰花、向日葵、郁金香、百合花、康乃馨",
|
||||
"水果类: 草莓、蓝莓、苹果、香蕉、橘子、葡萄、西瓜",
|
||||
"高级作物: 人参、藏红花、松露、龙果、冬虫夏草",
|
||||
"特殊作物: 摇钱树、糖果树、月光草、凤凰木"
|
||||
]
|
||||
|
||||
for crop_group in crops:
|
||||
print(f" • {crop_group}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🚀 快速开始:")
|
||||
print("1. 启动服务器: python TCPGameServer.py")
|
||||
print("2. 等待看到控制台提示符: >")
|
||||
print("3. 输入命令,例如: help")
|
||||
print("4. 查看命令执行结果")
|
||||
print("5. 继续输入其他命令进行管理")
|
||||
|
||||
print("\n💡 提示: 输入 'help' 可以随时查看完整的命令帮助信息")
|
||||
print("=" * 60)
|
||||
|
||||
if __name__ == "__main__":
|
||||
show_console_demo()
|
||||
2578
SproutFarm-Backend/test/gameconfig/mengyafarm.gameconfig.json
Normal file
2578
SproutFarm-Backend/test/gameconfig/mengyafarm.gameconfig.json
Normal file
File diff suppressed because it is too large
Load Diff
22
SproutFarm-Backend/test/gameconfig/游戏小提示配置.jsonc
Normal file
22
SproutFarm-Backend/test/gameconfig/游戏小提示配置.jsonc
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"切换模式":"顺序",//可选,顺序,随机,倒序
|
||||
"切换速度":5,
|
||||
"游戏小提示":
|
||||
[
|
||||
"按住wsad可以移动游戏画面",
|
||||
"使用鼠标滚轮来缩放游戏画面",
|
||||
"移动端双指缩放游戏画面",
|
||||
"不要一上来就花光你的初始资金",
|
||||
"钱币是目前游戏唯一货币",
|
||||
"每隔一小时体力值+1",
|
||||
"不要忘记领取你的新手礼包!",
|
||||
"记得使用一键截图来分享你的农场",
|
||||
"新注册用户可享受三天10倍速作物生长",
|
||||
"偷别人菜时不要忘了给别人浇水哦",
|
||||
"你能分得清小麦和稻谷吗",
|
||||
"凌晨刷新体力值",
|
||||
"面板左上角有刷新按钮,可以刷新面板",
|
||||
"小心偷菜被巡逻宠物发现",
|
||||
"访问特殊农场来获得一些特殊的作物"
|
||||
]
|
||||
}
|
||||
84
SproutFarm-Backend/test/import_game_tips_config.py
Normal file
84
SproutFarm-Backend/test/import_game_tips_config.py
Normal file
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
游戏小提示配置数据导入脚本
|
||||
将游戏小提示配置数据导入到MongoDB数据库中
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
|
||||
def import_game_tips_config():
|
||||
"""导入游戏小提示配置数据到MongoDB"""
|
||||
|
||||
# 游戏小提示配置数据
|
||||
game_tips_config = {
|
||||
"切换模式": "顺序", # 可选:顺序,随机,倒序
|
||||
"切换速度": 5,
|
||||
"游戏小提示": [
|
||||
"按住wsad可以移动游戏画面",
|
||||
"使用鼠标滚轮来缩放游戏画面",
|
||||
"移动端双指缩放游戏画面",
|
||||
"不要一上来就花光你的初始资金",
|
||||
"钱币是目前游戏唯一货币",
|
||||
"每隔一小时体力值+1",
|
||||
"不要忘记领取你的新手礼包!",
|
||||
"记得使用一键截图来分享你的农场",
|
||||
"新注册用户可享受三天10倍速作物生长",
|
||||
"偷别人菜时不要忘了给别人浇水哦",
|
||||
"你能分得清小麦和稻谷吗",
|
||||
"凌晨刷新体力值",
|
||||
"面板左上角有刷新按钮,可以刷新面板",
|
||||
"小心偷菜被巡逻宠物发现",
|
||||
"访问特殊农场来获得一些特殊的作物"
|
||||
]
|
||||
}
|
||||
|
||||
try:
|
||||
# 创建MongoDB API实例
|
||||
mongo_api = SMYMongoDBAPI()
|
||||
|
||||
# 连接到数据库
|
||||
if not mongo_api.connect():
|
||||
print("错误:无法连接到MongoDB数据库")
|
||||
return False
|
||||
|
||||
print("成功连接到MongoDB数据库")
|
||||
|
||||
# 更新游戏小提示配置
|
||||
result = mongo_api.update_game_tips_config(game_tips_config)
|
||||
|
||||
if result:
|
||||
print("成功导入游戏小提示配置数据到MongoDB")
|
||||
print(f"配置内容:")
|
||||
print(f" 切换模式: {game_tips_config['切换模式']}")
|
||||
print(f" 切换速度: {game_tips_config['切换速度']}")
|
||||
print(f" 游戏小提示数量: {len(game_tips_config['游戏小提示'])}")
|
||||
return True
|
||||
else:
|
||||
print("错误:导入游戏小提示配置数据失败")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"导入过程中发生错误: {str(e)}")
|
||||
return False
|
||||
finally:
|
||||
# 断开数据库连接
|
||||
if 'mongo_api' in locals():
|
||||
mongo_api.disconnect()
|
||||
print("已断开MongoDB数据库连接")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("开始导入游戏小提示配置数据...")
|
||||
success = import_game_tips_config()
|
||||
|
||||
if success:
|
||||
print("\n导入完成!")
|
||||
else:
|
||||
print("\n导入失败!")
|
||||
sys.exit(1)
|
||||
155
SproutFarm-Backend/test/monitor_special_farm.py
Normal file
155
SproutFarm-Backend/test/monitor_special_farm.py
Normal file
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
特殊农场系统性能监控脚本
|
||||
用于监控特殊农场系统的资源使用情况
|
||||
"""
|
||||
|
||||
import psutil
|
||||
import time
|
||||
import threading
|
||||
from datetime import datetime
|
||||
|
||||
class SpecialFarmMonitor:
|
||||
def __init__(self):
|
||||
self.monitoring = False
|
||||
self.monitor_thread = None
|
||||
self.stats = {
|
||||
'cpu_usage': [],
|
||||
'memory_usage': [],
|
||||
'thread_count': [],
|
||||
'start_time': None
|
||||
}
|
||||
|
||||
def start_monitoring(self, duration=60):
|
||||
"""开始监控指定时间(秒)"""
|
||||
if self.monitoring:
|
||||
print("监控已在运行中")
|
||||
return
|
||||
|
||||
self.monitoring = True
|
||||
self.stats['start_time'] = datetime.now()
|
||||
|
||||
def monitor_loop():
|
||||
print(f"开始监控特殊农场系统性能 - {self.stats['start_time']}")
|
||||
print(f"监控时长: {duration} 秒")
|
||||
print("=" * 50)
|
||||
|
||||
start_time = time.time()
|
||||
while self.monitoring and (time.time() - start_time) < duration:
|
||||
try:
|
||||
# 获取当前进程信息
|
||||
process = psutil.Process()
|
||||
|
||||
# CPU使用率
|
||||
cpu_percent = process.cpu_percent()
|
||||
self.stats['cpu_usage'].append(cpu_percent)
|
||||
|
||||
# 内存使用情况
|
||||
memory_info = process.memory_info()
|
||||
memory_mb = memory_info.rss / 1024 / 1024
|
||||
self.stats['memory_usage'].append(memory_mb)
|
||||
|
||||
# 线程数量
|
||||
thread_count = process.num_threads()
|
||||
self.stats['thread_count'].append(thread_count)
|
||||
|
||||
# 实时显示
|
||||
elapsed = int(time.time() - start_time)
|
||||
print(f"\r[{elapsed:3d}s] CPU: {cpu_percent:5.1f}% | 内存: {memory_mb:6.1f}MB | 线程: {thread_count:2d}", end="", flush=True)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n监控出错: {str(e)}")
|
||||
break
|
||||
|
||||
self.monitoring = False
|
||||
print("\n" + "=" * 50)
|
||||
self._print_summary()
|
||||
|
||||
self.monitor_thread = threading.Thread(target=monitor_loop, daemon=True)
|
||||
self.monitor_thread.start()
|
||||
|
||||
def stop_monitoring(self):
|
||||
"""停止监控"""
|
||||
self.monitoring = False
|
||||
if self.monitor_thread:
|
||||
self.monitor_thread.join(timeout=2)
|
||||
|
||||
def _print_summary(self):
|
||||
"""打印监控摘要"""
|
||||
if not self.stats['cpu_usage']:
|
||||
print("没有收集到监控数据")
|
||||
return
|
||||
|
||||
print("监控摘要:")
|
||||
print(f"监控时间: {self.stats['start_time']} - {datetime.now()}")
|
||||
print(f"数据点数: {len(self.stats['cpu_usage'])}")
|
||||
|
||||
# CPU统计
|
||||
cpu_avg = sum(self.stats['cpu_usage']) / len(self.stats['cpu_usage'])
|
||||
cpu_max = max(self.stats['cpu_usage'])
|
||||
print(f"CPU使用率 - 平均: {cpu_avg:.1f}%, 最高: {cpu_max:.1f}%")
|
||||
|
||||
# 内存统计
|
||||
mem_avg = sum(self.stats['memory_usage']) / len(self.stats['memory_usage'])
|
||||
mem_max = max(self.stats['memory_usage'])
|
||||
print(f"内存使用量 - 平均: {mem_avg:.1f}MB, 最高: {mem_max:.1f}MB")
|
||||
|
||||
# 线程统计
|
||||
thread_avg = sum(self.stats['thread_count']) / len(self.stats['thread_count'])
|
||||
thread_max = max(self.stats['thread_count'])
|
||||
print(f"线程数量 - 平均: {thread_avg:.1f}, 最高: {thread_max}")
|
||||
|
||||
# 性能评估
|
||||
print("\n性能评估:")
|
||||
if cpu_avg < 1.0:
|
||||
print("✓ CPU使用率很低,性能良好")
|
||||
elif cpu_avg < 5.0:
|
||||
print("✓ CPU使用率正常")
|
||||
else:
|
||||
print("⚠ CPU使用率较高,可能需要优化")
|
||||
|
||||
if mem_avg < 50:
|
||||
print("✓ 内存使用量很低")
|
||||
elif mem_avg < 100:
|
||||
print("✓ 内存使用量正常")
|
||||
else:
|
||||
print("⚠ 内存使用量较高")
|
||||
|
||||
if thread_max <= 10:
|
||||
print("✓ 线程数量合理")
|
||||
else:
|
||||
print("⚠ 线程数量较多,注意资源管理")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("特殊农场系统性能监控工具")
|
||||
print("使用说明:")
|
||||
print("1. 启动游戏服务器")
|
||||
print("2. 运行此监控脚本")
|
||||
print("3. 观察特殊农场系统的资源使用情况")
|
||||
print()
|
||||
|
||||
monitor = SpecialFarmMonitor()
|
||||
|
||||
try:
|
||||
# 监控60秒
|
||||
monitor.start_monitoring(60)
|
||||
|
||||
# 等待监控完成
|
||||
while monitor.monitoring:
|
||||
time.sleep(1)
|
||||
|
||||
print("\n监控完成")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n用户中断监控")
|
||||
monitor.stop_monitoring()
|
||||
except Exception as e:
|
||||
print(f"\n监控过程中出错: {str(e)}")
|
||||
monitor.stop_monitoring()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
0
SproutFarm-Backend/test/special_farm.log
Normal file
0
SproutFarm-Backend/test/special_farm.log
Normal file
147
SproutFarm-Backend/test/test_client_data.py
Normal file
147
SproutFarm-Backend/test/test_client_data.py
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试发送给客户端的数据结构
|
||||
模拟服务器发送给客户端的数据格式
|
||||
"""
|
||||
|
||||
import json
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
|
||||
def test_client_data_format():
|
||||
"""测试发送给客户端的数据格式"""
|
||||
print("=== 测试客户端数据格式 ===")
|
||||
|
||||
try:
|
||||
# 初始化MongoDB API
|
||||
mongo_api = SMYMongoDBAPI("test")
|
||||
|
||||
if not mongo_api.is_connected():
|
||||
print("❌ MongoDB连接失败")
|
||||
return
|
||||
|
||||
print("✅ MongoDB连接成功")
|
||||
|
||||
# 模拟_load_crop_data方法
|
||||
print("\n=== 测试作物数据 ===")
|
||||
crop_data = mongo_api.get_crop_data_config()
|
||||
|
||||
if crop_data:
|
||||
# 模拟服务器发送的crop_data_message
|
||||
crop_data_message = {
|
||||
"type": "crop_data_response",
|
||||
"success": True,
|
||||
"crop_data": crop_data
|
||||
}
|
||||
|
||||
print(f"作物数据类型: {type(crop_data)}")
|
||||
print(f"作物数据键数量: {len(crop_data)}")
|
||||
|
||||
# 检查是否有config_type字段
|
||||
if 'config_type' in crop_data:
|
||||
print(f"⚠️ 作物数据包含config_type: {crop_data['config_type']}")
|
||||
else:
|
||||
print("✅ 作物数据不包含config_type字段")
|
||||
|
||||
# 检查前几个作物的数据结构
|
||||
crop_count = 0
|
||||
for crop_name, crop_info in crop_data.items():
|
||||
if crop_name not in ['_id', 'config_type'] and crop_count < 3:
|
||||
print(f"\n作物 {crop_name}:")
|
||||
print(f" 数据类型: {type(crop_info)}")
|
||||
|
||||
if isinstance(crop_info, dict):
|
||||
# 检查关键字段
|
||||
key_fields = ['能否购买', '品质', '等级', '作物名称']
|
||||
for key in key_fields:
|
||||
if key in crop_info:
|
||||
value = crop_info[key]
|
||||
print(f" {key}: {value} (类型: {type(value)})")
|
||||
|
||||
# 特别检查能否购买字段
|
||||
if key == '能否购买':
|
||||
if isinstance(value, str):
|
||||
print(f" ⚠️ '能否购买'字段是字符串,这会导致Godot报错!")
|
||||
elif isinstance(value, bool):
|
||||
print(f" ✅ '能否购买'字段是布尔值,正确")
|
||||
elif isinstance(crop_info, str):
|
||||
print(f" ⚠️ 整个作物数据是字符串: '{crop_info[:50]}...'")
|
||||
print(f" 这会导致Godot调用.get()方法时报错!")
|
||||
|
||||
crop_count += 1
|
||||
|
||||
# 保存作物数据到文件以便检查
|
||||
with open('crop_data_debug.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(crop_data_message, f, ensure_ascii=False, indent=2, default=str)
|
||||
print(f"\n✅ 作物数据已保存到 crop_data_debug.json")
|
||||
|
||||
# 测试道具数据
|
||||
print("\n=== 测试道具数据 ===")
|
||||
item_config = mongo_api.get_item_config()
|
||||
|
||||
if item_config:
|
||||
# 模拟服务器发送的item_config_message
|
||||
item_config_message = {
|
||||
"type": "item_config_response",
|
||||
"success": True,
|
||||
"item_config": item_config
|
||||
}
|
||||
|
||||
print(f"道具数据类型: {type(item_config)}")
|
||||
|
||||
# 检查是否有config_type字段
|
||||
if 'config_type' in item_config:
|
||||
print(f"⚠️ 道具数据包含config_type: {item_config['config_type']}")
|
||||
else:
|
||||
print("✅ 道具数据不包含config_type字段")
|
||||
|
||||
# 保存道具数据到文件
|
||||
with open('item_config_debug.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(item_config_message, f, ensure_ascii=False, indent=2, default=str)
|
||||
print(f"✅ 道具数据已保存到 item_config_debug.json")
|
||||
|
||||
# 检查JSON序列化后的数据
|
||||
print("\n=== 测试JSON序列化 ===")
|
||||
if crop_data:
|
||||
try:
|
||||
# 模拟服务器发送数据时的JSON序列化过程
|
||||
json_str = json.dumps(crop_data_message, ensure_ascii=False, default=str)
|
||||
|
||||
# 模拟客户端接收数据时的JSON反序列化过程
|
||||
received_data = json.loads(json_str)
|
||||
|
||||
print("✅ JSON序列化/反序列化成功")
|
||||
|
||||
# 检查反序列化后的数据结构
|
||||
received_crop_data = received_data.get('crop_data', {})
|
||||
|
||||
# 检查第一个作物的数据
|
||||
for crop_name, crop_info in received_crop_data.items():
|
||||
if crop_name not in ['_id', 'config_type']:
|
||||
print(f"\n反序列化后的作物 {crop_name}:")
|
||||
print(f" 数据类型: {type(crop_info)}")
|
||||
|
||||
if isinstance(crop_info, dict):
|
||||
if '能否购买' in crop_info:
|
||||
value = crop_info['能否购买']
|
||||
print(f" 能否购买: {value} (类型: {type(value)})")
|
||||
elif isinstance(crop_info, str):
|
||||
print(f" ⚠️ 反序列化后变成字符串: '{crop_info[:50]}...'")
|
||||
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ JSON序列化/反序列化失败: {e}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试过程中出错: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
finally:
|
||||
if 'mongo_api' in locals():
|
||||
mongo_api.disconnect()
|
||||
print("\n✅ 数据库连接已关闭")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_client_data_format()
|
||||
208
SproutFarm-Backend/test/test_complete_game_tips_system.py
Normal file
208
SproutFarm-Backend/test/test_complete_game_tips_system.py
Normal file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
完整的游戏小提示配置系统测试
|
||||
测试从数据库导入到服务端处理的完整流程
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
import json
|
||||
import time
|
||||
import threading
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
from TCPGameServer import TCPGameServer
|
||||
|
||||
def test_database_operations():
|
||||
"""测试数据库操作"""
|
||||
print("=== 测试数据库操作 ===\n")
|
||||
|
||||
try:
|
||||
mongo_api = SMYMongoDBAPI()
|
||||
if not mongo_api.connect():
|
||||
print("❌ 无法连接到MongoDB数据库")
|
||||
return False
|
||||
|
||||
print("✓ 成功连接到MongoDB数据库")
|
||||
|
||||
# 测试获取配置
|
||||
config = mongo_api.get_game_tips_config()
|
||||
if config:
|
||||
print("✓ 成功获取游戏小提示配置")
|
||||
print(f" 切换模式: {config.get('切换模式', 'N/A')}")
|
||||
print(f" 切换速度: {config.get('切换速度', 'N/A')}")
|
||||
print(f" 小提示数量: {len(config.get('游戏小提示', []))}")
|
||||
return True
|
||||
else:
|
||||
print("❌ 无法获取游戏小提示配置")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 数据库测试失败: {str(e)}")
|
||||
return False
|
||||
finally:
|
||||
if 'mongo_api' in locals():
|
||||
mongo_api.disconnect()
|
||||
|
||||
def test_server_loading():
|
||||
"""测试服务器加载配置"""
|
||||
print("\n=== 测试服务器加载配置 ===\n")
|
||||
|
||||
try:
|
||||
server = TCPGameServer()
|
||||
server.mongo_api = SMYMongoDBAPI()
|
||||
|
||||
if not server.mongo_api.connect():
|
||||
print("❌ 服务器无法连接到MongoDB")
|
||||
return False
|
||||
|
||||
print("✓ 服务器成功连接到MongoDB")
|
||||
|
||||
# 测试服务器加载配置
|
||||
config = server._load_game_tips_config()
|
||||
if config:
|
||||
print("✓ 服务器成功加载游戏小提示配置")
|
||||
print(f" 切换模式: {config.get('切换模式', 'N/A')}")
|
||||
print(f" 切换速度: {config.get('切换速度', 'N/A')}")
|
||||
print(f" 小提示数量: {len(config.get('游戏小提示', []))}")
|
||||
return True
|
||||
else:
|
||||
print("❌ 服务器无法加载游戏小提示配置")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 服务器测试失败: {str(e)}")
|
||||
return False
|
||||
finally:
|
||||
if 'server' in locals() and hasattr(server, 'mongo_api') and server.mongo_api:
|
||||
server.mongo_api.disconnect()
|
||||
|
||||
def test_client_server_communication():
|
||||
"""测试客户端-服务端通信"""
|
||||
print("\n=== 测试客户端-服务端通信 ===\n")
|
||||
|
||||
# 启动服务器(在后台线程中)
|
||||
server = None
|
||||
server_thread = None
|
||||
|
||||
try:
|
||||
print("启动测试服务器...")
|
||||
server = TCPGameServer()
|
||||
|
||||
# 在后台线程中启动服务器
|
||||
def run_server():
|
||||
try:
|
||||
server.start_server()
|
||||
except Exception as e:
|
||||
print(f"服务器启动失败: {e}")
|
||||
|
||||
server_thread = threading.Thread(target=run_server, daemon=True)
|
||||
server_thread.start()
|
||||
|
||||
# 等待服务器启动
|
||||
time.sleep(2)
|
||||
|
||||
# 创建客户端连接
|
||||
print("创建客户端连接...")
|
||||
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
client_socket.settimeout(5)
|
||||
|
||||
try:
|
||||
client_socket.connect(('localhost', 12345))
|
||||
print("✓ 客户端成功连接到服务器")
|
||||
|
||||
# 发送游戏小提示配置请求
|
||||
request = {
|
||||
"type": "request_game_tips_config"
|
||||
}
|
||||
|
||||
message = json.dumps(request, ensure_ascii=False)
|
||||
client_socket.send(message.encode('utf-8'))
|
||||
print("✓ 已发送游戏小提示配置请求")
|
||||
|
||||
# 接收响应
|
||||
response_data = client_socket.recv(4096)
|
||||
if response_data:
|
||||
response = json.loads(response_data.decode('utf-8'))
|
||||
print("✓ 收到服务器响应")
|
||||
|
||||
if response.get("type") == "game_tips_config_response":
|
||||
success = response.get("success", False)
|
||||
if success:
|
||||
config = response.get("game_tips_config", {})
|
||||
print("✓ 成功获取游戏小提示配置")
|
||||
print(f" 切换模式: {config.get('切换模式', 'N/A')}")
|
||||
print(f" 切换速度: {config.get('切换速度', 'N/A')}")
|
||||
print(f" 小提示数量: {len(config.get('游戏小提示', []))}")
|
||||
return True
|
||||
else:
|
||||
message = response.get("message", "未知错误")
|
||||
print(f"❌ 服务器返回失败: {message}")
|
||||
return False
|
||||
else:
|
||||
print(f"❌ 收到意外的响应类型: {response.get('type')}")
|
||||
return False
|
||||
else:
|
||||
print("❌ 未收到服务器响应")
|
||||
return False
|
||||
|
||||
except socket.timeout:
|
||||
print("❌ 客户端连接超时")
|
||||
return False
|
||||
except ConnectionRefusedError:
|
||||
print("❌ 无法连接到服务器")
|
||||
return False
|
||||
finally:
|
||||
client_socket.close()
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 通信测试失败: {str(e)}")
|
||||
return False
|
||||
finally:
|
||||
# 停止服务器
|
||||
if server:
|
||||
try:
|
||||
server.stop_server()
|
||||
except:
|
||||
pass
|
||||
|
||||
def main():
|
||||
"""主测试函数"""
|
||||
print("开始完整的游戏小提示配置系统测试...\n")
|
||||
|
||||
# 执行各项测试
|
||||
db_success = test_database_operations()
|
||||
server_success = test_server_loading()
|
||||
comm_success = test_client_server_communication()
|
||||
|
||||
# 输出测试结果
|
||||
print("\n" + "="*50)
|
||||
print("测试结果汇总")
|
||||
print("="*50)
|
||||
print(f"数据库操作测试: {'✓ 通过' if db_success else '❌ 失败'}")
|
||||
print(f"服务器加载测试: {'✓ 通过' if server_success else '❌ 失败'}")
|
||||
print(f"客户端通信测试: {'✓ 通过' if comm_success else '❌ 失败'}")
|
||||
|
||||
if db_success and server_success and comm_success:
|
||||
print("\n🎉 所有测试通过!游戏小提示配置系统完全正常工作。")
|
||||
print("\n系统功能说明:")
|
||||
print("1. ✓ 配置数据已成功导入MongoDB数据库")
|
||||
print("2. ✓ 服务端能正确加载和处理配置数据")
|
||||
print("3. ✓ 客户端能成功请求并接收配置数据")
|
||||
print("4. ✓ 支持顺序、倒序、随机三种切换模式")
|
||||
print("5. ✓ 支持自定义切换速度")
|
||||
print("\n现在客户端可以从服务端获取游戏小提示配置,")
|
||||
print("并根据配置的切换模式和速度显示小提示。")
|
||||
return True
|
||||
else:
|
||||
print("\n❌ 部分测试失败,请检查系统配置。")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
138
SproutFarm-Backend/test/test_database_documents.py
Normal file
138
SproutFarm-Backend/test/test_database_documents.py
Normal file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
数据库文档结构测试脚本
|
||||
用于检查MongoDB中gameconfig集合的文档结构
|
||||
"""
|
||||
|
||||
import json
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
|
||||
def test_database_documents():
|
||||
"""测试数据库文档结构"""
|
||||
print("=== 数据库文档结构测试 ===")
|
||||
|
||||
try:
|
||||
# 初始化MongoDB API
|
||||
mongo_api = SMYMongoDBAPI("test")
|
||||
|
||||
if not mongo_api.is_connected():
|
||||
print("❌ MongoDB连接失败")
|
||||
return
|
||||
|
||||
print("✅ MongoDB连接成功")
|
||||
|
||||
# 获取gameconfig集合
|
||||
collection = mongo_api.get_collection("gameconfig")
|
||||
|
||||
print("\n=== 检查gameconfig集合中的所有文档 ===")
|
||||
|
||||
# 查找所有文档
|
||||
documents = list(collection.find({}))
|
||||
|
||||
print(f"找到 {len(documents)} 个文档")
|
||||
|
||||
for i, doc in enumerate(documents):
|
||||
print(f"\n--- 文档 {i+1} ---")
|
||||
print(f"_id: {doc.get('_id')}")
|
||||
print(f"config_type: {doc.get('config_type', '未找到')}")
|
||||
|
||||
# 检查是否有config_type字段
|
||||
if 'config_type' in doc:
|
||||
print(f"⚠️ 发现config_type字段: {doc['config_type']}")
|
||||
else:
|
||||
print("✅ 没有config_type字段")
|
||||
|
||||
# 显示文档的所有键
|
||||
print(f"文档键: {list(doc.keys())}")
|
||||
|
||||
# 如果是作物配置,检查具体内容
|
||||
if doc.get('config_type') == '作物数据配置':
|
||||
print("\n=== 作物数据配置详细检查 ===")
|
||||
|
||||
# 检查作物数据结构
|
||||
for key, value in doc.items():
|
||||
if key not in ['_id', 'config_type']:
|
||||
print(f"作物 {key}: {type(value)}")
|
||||
|
||||
if isinstance(value, dict):
|
||||
# 检查作物的具体字段
|
||||
crop_keys = list(value.keys())
|
||||
print(f" 作物字段: {crop_keys}")
|
||||
|
||||
# 检查是否有字符串类型的字段被误认为是字典
|
||||
for crop_key, crop_value in value.items():
|
||||
if isinstance(crop_value, str) and crop_key in ['能否购买', '品质', '等级']:
|
||||
print(f" ⚠️ 字段 {crop_key} 是字符串类型: '{crop_value}'")
|
||||
elif isinstance(value, str):
|
||||
print(f" ⚠️ 整个作物数据是字符串: '{value[:100]}...'")
|
||||
|
||||
print("\n=== 测试API方法返回的数据 ===")
|
||||
|
||||
# 测试get_crop_data_config方法
|
||||
print("\n--- 测试get_crop_data_config ---")
|
||||
crop_data = mongo_api.get_crop_data_config()
|
||||
if crop_data:
|
||||
print(f"返回数据类型: {type(crop_data)}")
|
||||
print(f"返回数据键: {list(crop_data.keys()) if isinstance(crop_data, dict) else 'N/A'}")
|
||||
|
||||
# 检查是否还有config_type字段
|
||||
if 'config_type' in crop_data:
|
||||
print(f"⚠️ API返回的数据仍包含config_type: {crop_data['config_type']}")
|
||||
else:
|
||||
print("✅ API返回的数据不包含config_type字段")
|
||||
|
||||
# 检查第一个作物的数据结构
|
||||
for crop_name, crop_info in crop_data.items():
|
||||
if crop_name not in ['_id', 'config_type']:
|
||||
print(f"\n作物 {crop_name}:")
|
||||
print(f" 类型: {type(crop_info)}")
|
||||
|
||||
if isinstance(crop_info, dict):
|
||||
print(f" 字段: {list(crop_info.keys())}")
|
||||
|
||||
# 检查关键字段
|
||||
for key in ['能否购买', '品质', '等级']:
|
||||
if key in crop_info:
|
||||
value = crop_info[key]
|
||||
print(f" {key}: {value} (类型: {type(value)})")
|
||||
elif isinstance(crop_info, str):
|
||||
print(f" ⚠️ 作物数据是字符串: '{crop_info[:50]}...'")
|
||||
|
||||
break # 只检查第一个作物
|
||||
else:
|
||||
print("❌ get_crop_data_config返回空数据")
|
||||
|
||||
# 测试get_item_config方法
|
||||
print("\n--- 测试get_item_config ---")
|
||||
item_data = mongo_api.get_item_config()
|
||||
if item_data:
|
||||
print(f"道具配置数据类型: {type(item_data)}")
|
||||
if 'config_type' in item_data:
|
||||
print(f"⚠️ 道具配置仍包含config_type: {item_data['config_type']}")
|
||||
else:
|
||||
print("✅ 道具配置不包含config_type字段")
|
||||
|
||||
# 测试find_documents方法
|
||||
print("\n--- 测试find_documents方法 ---")
|
||||
all_configs = mongo_api.find_documents("gameconfig", {})
|
||||
if all_configs:
|
||||
print(f"find_documents返回 {len(all_configs)} 个文档")
|
||||
for doc in all_configs:
|
||||
if 'config_type' in doc:
|
||||
print(f"⚠️ find_documents返回的文档仍包含config_type: {doc['config_type']}")
|
||||
else:
|
||||
print(f"✅ 文档ID {doc.get('_id')} 不包含config_type字段")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试过程中出错: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
finally:
|
||||
if 'mongo_api' in locals():
|
||||
mongo_api.disconnect()
|
||||
print("\n✅ 数据库连接已关闭")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_database_documents()
|
||||
0
SproutFarm-Backend/test/test_flower_farm.py
Normal file
0
SproutFarm-Backend/test/test_flower_farm.py
Normal file
117
SproutFarm-Backend/test/test_game_tips_config.py
Normal file
117
SproutFarm-Backend/test/test_game_tips_config.py
Normal file
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试游戏小提示配置功能
|
||||
验证服务端能否正确加载和返回游戏小提示配置数据
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
from TCPGameServer import TCPGameServer
|
||||
|
||||
def test_mongo_api():
|
||||
"""测试MongoDB API的游戏小提示配置功能"""
|
||||
print("=== 测试MongoDB API ===\n")
|
||||
|
||||
try:
|
||||
# 创建MongoDB API实例
|
||||
mongo_api = SMYMongoDBAPI()
|
||||
|
||||
# 连接到数据库
|
||||
if not mongo_api.connect():
|
||||
print("错误:无法连接到MongoDB数据库")
|
||||
return False
|
||||
|
||||
print("成功连接到MongoDB数据库")
|
||||
|
||||
# 获取游戏小提示配置
|
||||
config = mongo_api.get_game_tips_config()
|
||||
|
||||
if config:
|
||||
print("成功获取游戏小提示配置:")
|
||||
print(f" 切换模式: {config.get('切换模式', 'N/A')}")
|
||||
print(f" 切换速度: {config.get('切换速度', 'N/A')}")
|
||||
tips = config.get('游戏小提示', [])
|
||||
print(f" 游戏小提示数量: {len(tips)}")
|
||||
print(" 前3条小提示:")
|
||||
for i, tip in enumerate(tips[:3]):
|
||||
print(f" {i+1}. {tip}")
|
||||
return True
|
||||
else:
|
||||
print("错误:无法获取游戏小提示配置")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"测试过程中发生错误: {str(e)}")
|
||||
return False
|
||||
finally:
|
||||
# 断开数据库连接
|
||||
if 'mongo_api' in locals():
|
||||
mongo_api.disconnect()
|
||||
print("已断开MongoDB数据库连接")
|
||||
|
||||
def test_game_server():
|
||||
"""测试游戏服务器的游戏小提示配置加载功能"""
|
||||
print("\n=== 测试游戏服务器 ===\n")
|
||||
|
||||
try:
|
||||
# 创建游戏服务器实例(不启动网络服务)
|
||||
server = TCPGameServer()
|
||||
|
||||
# 初始化MongoDB连接
|
||||
server.mongo_api = SMYMongoDBAPI()
|
||||
if not server.mongo_api.connect():
|
||||
print("错误:服务器无法连接到MongoDB数据库")
|
||||
return False
|
||||
|
||||
print("服务器成功连接到MongoDB数据库")
|
||||
|
||||
# 测试加载游戏小提示配置
|
||||
config = server._load_game_tips_config()
|
||||
|
||||
if config:
|
||||
print("服务器成功加载游戏小提示配置:")
|
||||
print(f" 切换模式: {config.get('切换模式', 'N/A')}")
|
||||
print(f" 切换速度: {config.get('切换速度', 'N/A')}")
|
||||
tips = config.get('游戏小提示', [])
|
||||
print(f" 游戏小提示数量: {len(tips)}")
|
||||
print(" 前3条小提示:")
|
||||
for i, tip in enumerate(tips[:3]):
|
||||
print(f" {i+1}. {tip}")
|
||||
return True
|
||||
else:
|
||||
print("错误:服务器无法加载游戏小提示配置")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"测试过程中发生错误: {str(e)}")
|
||||
return False
|
||||
finally:
|
||||
# 断开数据库连接
|
||||
if 'server' in locals() and hasattr(server, 'mongo_api') and server.mongo_api:
|
||||
server.mongo_api.disconnect()
|
||||
print("服务器已断开MongoDB数据库连接")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("开始测试游戏小提示配置功能...\n")
|
||||
|
||||
# 测试MongoDB API
|
||||
mongo_success = test_mongo_api()
|
||||
|
||||
# 测试游戏服务器
|
||||
server_success = test_game_server()
|
||||
|
||||
print("\n=== 测试结果 ===\n")
|
||||
print(f"MongoDB API测试: {'✓ 通过' if mongo_success else '✗ 失败'}")
|
||||
print(f"游戏服务器测试: {'✓ 通过' if server_success else '✗ 失败'}")
|
||||
|
||||
if mongo_success and server_success:
|
||||
print("\n🎉 所有测试通过!游戏小提示配置功能正常工作。")
|
||||
else:
|
||||
print("\n❌ 部分测试失败,请检查配置。")
|
||||
sys.exit(1)
|
||||
242
SproutFarm-Backend/test/test_game_tips_integration.py
Normal file
242
SproutFarm-Backend/test/test_game_tips_integration.py
Normal file
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
游戏小提示配置系统集成测试
|
||||
测试完整的配置流程:数据库 -> 服务端 -> 客户端请求 -> 配置应用
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
import socket
|
||||
import json
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
from TCPGameServer import TCPGameServer
|
||||
|
||||
def test_database_config():
|
||||
"""测试数据库配置"""
|
||||
print("=== 测试数据库配置 ===")
|
||||
|
||||
try:
|
||||
# 连接数据库
|
||||
mongo_api = SMYMongoDBAPI(environment="test")
|
||||
|
||||
if not mongo_api.is_connected():
|
||||
print("❌ 数据库连接失败")
|
||||
return False
|
||||
|
||||
# 获取游戏小提示配置
|
||||
config = mongo_api.get_game_tips_config()
|
||||
|
||||
if config:
|
||||
print("✓ 成功获取游戏小提示配置:")
|
||||
print(f" 切换模式: {config.get('切换模式', '未设置')}")
|
||||
print(f" 切换速度: {config.get('切换速度', '未设置')}")
|
||||
print(f" 游戏小提示数量: {len(config.get('游戏小提示', []))}")
|
||||
|
||||
tips = config.get('游戏小提示', [])
|
||||
if tips:
|
||||
print(" 前3条小提示:")
|
||||
for i, tip in enumerate(tips[:3], 1):
|
||||
print(f" {i}. {tip}")
|
||||
|
||||
mongo_api.disconnect()
|
||||
return True
|
||||
else:
|
||||
print("❌ 未找到游戏小提示配置")
|
||||
mongo_api.disconnect()
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 数据库测试失败: {e}")
|
||||
return False
|
||||
|
||||
def test_server_config_loading():
|
||||
"""测试服务端配置加载"""
|
||||
print("\n=== 测试服务端配置加载 ===")
|
||||
|
||||
try:
|
||||
# 初始化游戏服务器
|
||||
server = TCPGameServer(server_host="localhost", server_port=0)
|
||||
|
||||
if not server.mongo_api or not server.mongo_api.is_connected():
|
||||
print("❌ 服务器MongoDB连接失败")
|
||||
return False
|
||||
|
||||
print("✓ 服务器成功连接到MongoDB数据库")
|
||||
|
||||
# 测试配置加载
|
||||
config = server._load_game_tips_config()
|
||||
|
||||
if config:
|
||||
print("✓ 服务器成功加载游戏小提示配置:")
|
||||
print(f" 切换模式: {config.get('切换模式', '未设置')}")
|
||||
print(f" 切换速度: {config.get('切换速度', '未设置')}")
|
||||
print(f" 游戏小提示数量: {len(config.get('游戏小提示', []))}")
|
||||
|
||||
tips = config.get('游戏小提示', [])
|
||||
if tips:
|
||||
print(" 前3条小提示:")
|
||||
for i, tip in enumerate(tips[:3], 1):
|
||||
print(f" {i}. {tip}")
|
||||
|
||||
server.mongo_api.disconnect()
|
||||
print("✓ 服务器已断开MongoDB数据库连接")
|
||||
return True
|
||||
else:
|
||||
print("❌ 服务器加载游戏小提示配置失败")
|
||||
server.mongo_api.disconnect()
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 服务端测试失败: {e}")
|
||||
return False
|
||||
|
||||
def test_client_server_communication():
|
||||
"""测试客户端-服务端通信"""
|
||||
print("\n=== 测试客户端-服务端通信 ===")
|
||||
|
||||
server = None
|
||||
client_socket = None
|
||||
|
||||
try:
|
||||
# 启动服务器(使用固定端口进行测试)
|
||||
test_port = 17070
|
||||
server = TCPGameServer(server_host="localhost", server_port=test_port)
|
||||
|
||||
if not server.mongo_api or not server.mongo_api.is_connected():
|
||||
print("❌ 服务器MongoDB连接失败")
|
||||
return False
|
||||
|
||||
# 在新线程中启动服务器
|
||||
server_thread = threading.Thread(target=server.start, daemon=True)
|
||||
server_thread.start()
|
||||
|
||||
# 等待服务器启动
|
||||
time.sleep(1)
|
||||
|
||||
# 获取服务器端口
|
||||
server_port = test_port
|
||||
print(f"✓ 服务器已启动,端口: {server_port}")
|
||||
|
||||
# 创建客户端连接
|
||||
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
client_socket.settimeout(5)
|
||||
client_socket.connect(("localhost", server_port))
|
||||
print("✓ 客户端已连接到服务器")
|
||||
|
||||
# 发送游戏小提示配置请求
|
||||
request = {
|
||||
"type": "request_game_tips_config"
|
||||
}
|
||||
|
||||
request_data = json.dumps(request).encode('utf-8')
|
||||
client_socket.send(len(request_data).to_bytes(4, byteorder='big'))
|
||||
client_socket.send(request_data)
|
||||
print("✓ 已发送游戏小提示配置请求")
|
||||
|
||||
# 接收响应
|
||||
response_length_bytes = client_socket.recv(4)
|
||||
if len(response_length_bytes) != 4:
|
||||
print("❌ 接收响应长度失败")
|
||||
return False
|
||||
|
||||
response_length = int.from_bytes(response_length_bytes, byteorder='big')
|
||||
response_data = b''
|
||||
|
||||
while len(response_data) < response_length:
|
||||
chunk = client_socket.recv(response_length - len(response_data))
|
||||
if not chunk:
|
||||
break
|
||||
response_data += chunk
|
||||
|
||||
if len(response_data) != response_length:
|
||||
print("❌ 接收响应数据不完整")
|
||||
return False
|
||||
|
||||
# 解析响应
|
||||
response = json.loads(response_data.decode('utf-8'))
|
||||
print("✓ 已接收服务器响应")
|
||||
|
||||
# 验证响应
|
||||
if response.get("type") == "game_tips_config_response":
|
||||
if response.get("success"):
|
||||
config = response.get("game_tips_config", {})
|
||||
print("✓ 成功接收游戏小提示配置:")
|
||||
print(f" 切换模式: {config.get('切换模式', '未设置')}")
|
||||
print(f" 切换速度: {config.get('切换速度', '未设置')}")
|
||||
print(f" 游戏小提示数量: {len(config.get('游戏小提示', []))}")
|
||||
|
||||
tips = config.get('游戏小提示', [])
|
||||
if tips:
|
||||
print(" 前3条小提示:")
|
||||
for i, tip in enumerate(tips[:3], 1):
|
||||
print(f" {i}. {tip}")
|
||||
|
||||
return True
|
||||
else:
|
||||
message = response.get("message", "未知错误")
|
||||
print(f"❌ 服务器返回失败: {message}")
|
||||
return False
|
||||
else:
|
||||
print(f"❌ 收到意外的响应类型: {response.get('type')}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 客户端-服务端通信测试失败: {e}")
|
||||
return False
|
||||
|
||||
finally:
|
||||
# 清理资源
|
||||
if client_socket:
|
||||
try:
|
||||
client_socket.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
if server and server.mongo_api:
|
||||
try:
|
||||
server.mongo_api.disconnect()
|
||||
except:
|
||||
pass
|
||||
|
||||
def main():
|
||||
"""主测试函数"""
|
||||
print("🚀 开始游戏小提示配置系统集成测试\n")
|
||||
|
||||
# 测试结果
|
||||
results = {
|
||||
"数据库配置": test_database_config(),
|
||||
"服务端配置加载": test_server_config_loading(),
|
||||
"客户端-服务端通信": test_client_server_communication()
|
||||
}
|
||||
|
||||
print("\n=== 测试结果 ===\n")
|
||||
|
||||
all_passed = True
|
||||
for test_name, result in results.items():
|
||||
status = "✓ 通过" if result else "❌ 失败"
|
||||
print(f"{test_name}测试: {status}")
|
||||
if not result:
|
||||
all_passed = False
|
||||
|
||||
if all_passed:
|
||||
print("\n🎉 所有测试通过!游戏小提示配置系统完全正常工作。")
|
||||
print("\n📋 系统功能确认:")
|
||||
print(" ✓ 数据库配置存储和读取正常")
|
||||
print(" ✓ 服务端配置加载正常")
|
||||
print(" ✓ 客户端-服务端通信正常")
|
||||
print(" ✓ 配置数据传输完整")
|
||||
print("\n🎮 客户端现在应该能够正确使用数据库中的游戏小提示配置!")
|
||||
else:
|
||||
print("\n❌ 部分测试失败,请检查相关组件。")
|
||||
|
||||
return all_passed
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
初始玩家数据模板MongoDB迁移测试脚本
|
||||
作者: AI Assistant
|
||||
功能: 测试初始玩家数据模板从JSON到MongoDB的迁移功能
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
|
||||
def load_template_from_json():
|
||||
"""从JSON文件加载初始玩家数据模板"""
|
||||
try:
|
||||
with open("config/initial_player_data_template.json", 'r', encoding='utf-8') as file:
|
||||
return json.load(file)
|
||||
except Exception as e:
|
||||
print(f"❌ 加载JSON文件失败: {e}")
|
||||
return None
|
||||
|
||||
def test_initial_player_template_migration():
|
||||
"""测试初始玩家数据模板迁移"""
|
||||
print("=== 初始玩家数据模板MongoDB迁移测试 ===")
|
||||
|
||||
# 1. 连接MongoDB
|
||||
print("\n1. 连接MongoDB...")
|
||||
try:
|
||||
api = SMYMongoDBAPI("test")
|
||||
if not api.is_connected():
|
||||
print("❌ MongoDB连接失败")
|
||||
return False
|
||||
print("✅ MongoDB连接成功")
|
||||
except Exception as e:
|
||||
print(f"❌ MongoDB连接异常: {e}")
|
||||
return False
|
||||
|
||||
# 2. 从JSON文件加载模板数据
|
||||
print("\n2. 从JSON文件加载初始玩家数据模板...")
|
||||
json_data = load_template_from_json()
|
||||
if not json_data:
|
||||
print("❌ JSON数据加载失败")
|
||||
return False
|
||||
print(f"✅ JSON数据加载成功,包含字段: {len(json_data)} 个")
|
||||
print(f" 主要字段: {list(json_data.keys())[:8]}...")
|
||||
|
||||
# 3. 测试从MongoDB获取模板数据
|
||||
print("\n3. 从MongoDB获取初始玩家数据模板...")
|
||||
try:
|
||||
mongo_data = api.get_initial_player_data_template()
|
||||
if mongo_data:
|
||||
print(f"✅ MongoDB数据获取成功,包含字段: {len(mongo_data)} 个")
|
||||
|
||||
# 4. 比较数据一致性
|
||||
print("\n4. 比较数据一致性...")
|
||||
if len(json_data) == len(mongo_data):
|
||||
print("✅ 字段数量一致")
|
||||
else:
|
||||
print(f"⚠️ 字段数量不一致: JSON({len(json_data)}) vs MongoDB({len(mongo_data)})")
|
||||
|
||||
# 检查关键字段
|
||||
key_fields = ["经验值", "等级", "钱币", "农场土地", "种子仓库", "作物仓库", "道具背包"]
|
||||
for field in key_fields:
|
||||
if field in json_data and field in mongo_data:
|
||||
json_value = json_data[field]
|
||||
mongo_value = mongo_data[field]
|
||||
if json_value == mongo_value:
|
||||
print(f"✅ {field}: 数据一致")
|
||||
else:
|
||||
print(f"⚠️ {field}: 数据不一致")
|
||||
if field in ["经验值", "等级", "钱币"]:
|
||||
print(f" JSON: {json_value}, MongoDB: {mongo_value}")
|
||||
elif field == "农场土地":
|
||||
print(f" JSON: {len(json_value)}块地, MongoDB: {len(mongo_value)}块地")
|
||||
else:
|
||||
print(f"❌ {field}: 字段缺失")
|
||||
else:
|
||||
print("❌ MongoDB中未找到初始玩家数据模板")
|
||||
|
||||
# 5. 如果MongoDB中没有数据,尝试更新
|
||||
print("\n5. 尝试更新MongoDB中的初始玩家数据模板...")
|
||||
try:
|
||||
success = api.update_initial_player_data_template(json_data)
|
||||
if success:
|
||||
print("✅ 初始玩家数据模板更新到MongoDB成功")
|
||||
|
||||
# 再次验证
|
||||
print("\n6. 验证更新后的数据...")
|
||||
updated_data = api.get_initial_player_data_template()
|
||||
if updated_data and len(updated_data) == len(json_data):
|
||||
print("✅ 数据更新验证成功")
|
||||
|
||||
# 验证关键字段
|
||||
for field in ["经验值", "等级", "钱币"]:
|
||||
if field in updated_data and updated_data[field] == json_data[field]:
|
||||
print(f"✅ {field}: {updated_data[field]}")
|
||||
else:
|
||||
print("❌ 数据更新验证失败")
|
||||
else:
|
||||
print("❌ 初始玩家数据模板更新到MongoDB失败")
|
||||
except Exception as e:
|
||||
print(f"❌ 更新MongoDB数据时异常: {e}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 从MongoDB获取数据时异常: {e}")
|
||||
return False
|
||||
|
||||
# 7. 测试服务器创建新用户逻辑
|
||||
print("\n7. 测试服务器创建新用户逻辑...")
|
||||
try:
|
||||
# 模拟服务器的创建用户逻辑
|
||||
from TCPGameServer import TCPGameServer
|
||||
|
||||
# 创建服务器实例(不启动网络服务)
|
||||
server = TCPGameServer()
|
||||
|
||||
# 测试模板加载(通过_ensure_player_data_fields方法间接测试)
|
||||
test_data = {"测试": "数据"}
|
||||
server._ensure_player_data_fields(test_data)
|
||||
|
||||
if "农场土地" in test_data and len(test_data["农场土地"]) == 40:
|
||||
print(f"✅ 服务器成功生成农场土地,共 {len(test_data['农场土地'])} 块")
|
||||
|
||||
# 检查前20块地是否已开垦
|
||||
digged_count = sum(1 for land in test_data["农场土地"] if land.get("is_diged", False))
|
||||
print(f"✅ 已开垦土地: {digged_count} 块")
|
||||
else:
|
||||
print("❌ 服务器农场土地生成失败")
|
||||
|
||||
# 检查基本仓库
|
||||
required_fields = ["种子仓库", "作物仓库", "道具背包", "宠物背包", "巡逻宠物", "出战宠物"]
|
||||
missing_fields = [field for field in required_fields if field not in test_data]
|
||||
if not missing_fields:
|
||||
print(f"✅ 所有必要仓库字段已创建: {required_fields}")
|
||||
else:
|
||||
print(f"❌ 缺少仓库字段: {missing_fields}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试服务器逻辑时异常: {e}")
|
||||
|
||||
print("\n=== 测试完成 ===")
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
try:
|
||||
test_initial_player_template_migration()
|
||||
except KeyboardInterrupt:
|
||||
print("\n测试被用户中断")
|
||||
except Exception as e:
|
||||
print(f"测试过程中发生异常: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
178
SproutFarm-Backend/test/test_mongodb_migration.py
Normal file
178
SproutFarm-Backend/test/test_mongodb_migration.py
Normal file
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试MongoDB迁移功能
|
||||
作者: AI Assistant
|
||||
功能: 测试每日签到配置从JSON迁移到MongoDB的功能
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
|
||||
def test_mongodb_migration():
|
||||
"""测试MongoDB迁移功能"""
|
||||
print("=== 测试MongoDB迁移功能 ===")
|
||||
|
||||
# 1. 测试MongoDB API连接
|
||||
print("\n1. 测试MongoDB API连接:")
|
||||
try:
|
||||
api = SMYMongoDBAPI("test")
|
||||
if api.is_connected():
|
||||
print("✓ MongoDB连接成功")
|
||||
else:
|
||||
print("✗ MongoDB连接失败")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ MongoDB连接异常: {e}")
|
||||
return False
|
||||
|
||||
# 2. 测试获取每日签到配置
|
||||
print("\n2. 测试获取每日签到配置:")
|
||||
try:
|
||||
config = api.get_daily_checkin_config()
|
||||
if config:
|
||||
print("✓ 成功获取每日签到配置")
|
||||
print(f" 基础奖励金币范围: {config.get('基础奖励', {}).get('金币', {})}")
|
||||
print(f" 种子奖励类型数量: {len(config.get('种子奖励', {}))}")
|
||||
print(f" 连续签到奖励天数: {len(config.get('连续签到奖励', {}))}")
|
||||
else:
|
||||
print("✗ 获取每日签到配置失败")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ 获取每日签到配置异常: {e}")
|
||||
return False
|
||||
|
||||
# 3. 测试更新配置
|
||||
print("\n3. 测试更新每日签到配置:")
|
||||
try:
|
||||
# 创建一个测试配置
|
||||
test_config = {
|
||||
"基础奖励": {
|
||||
"金币": {"最小值": 300, "最大值": 600, "图标": "💰", "颜色": "#FFD700"},
|
||||
"经验": {"最小值": 75, "最大值": 150, "图标": "⭐", "颜色": "#00BFFF"}
|
||||
},
|
||||
"种子奖励": {
|
||||
"普通": {"概率": 0.6, "数量范围": [2, 5], "种子池": ["小麦", "胡萝卜", "土豆", "稻谷"]},
|
||||
"优良": {"概率": 0.25, "数量范围": [2, 4], "种子池": ["玉米", "番茄", "洋葱", "大豆", "豌豆", "黄瓜", "大白菜"]},
|
||||
"稀有": {"概率": 0.12, "数量范围": [1, 3], "种子池": ["草莓", "花椰菜", "柿子", "蓝莓", "树莓"]},
|
||||
"史诗": {"概率": 0.025, "数量范围": [1, 2], "种子池": ["葡萄", "南瓜", "芦笋", "茄子", "向日葵", "蕨菜"]},
|
||||
"传奇": {"概率": 0.005, "数量范围": [1, 1], "种子池": ["西瓜", "甘蔗", "香草", "甜菜", "人参", "富贵竹", "芦荟", "哈密瓜"]}
|
||||
},
|
||||
"连续签到奖励": {
|
||||
"第3天": {"额外金币": 150, "额外经验": 75, "描述": "连续签到奖励"},
|
||||
"第7天": {"额外金币": 300, "额外经验": 150, "描述": "一周连击奖励"},
|
||||
"第14天": {"额外金币": 600, "额外经验": 250, "描述": "半月连击奖励"},
|
||||
"第21天": {"额外金币": 1000, "额外经验": 400, "描述": "三周连击奖励"},
|
||||
"第30天": {"额外金币": 2000, "额外经验": 600, "描述": "满月连击奖励"}
|
||||
}
|
||||
}
|
||||
|
||||
success = api.update_daily_checkin_config(test_config)
|
||||
if success:
|
||||
print("✓ 成功更新测试配置到MongoDB")
|
||||
else:
|
||||
print("✗ 更新测试配置失败")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ 更新测试配置异常: {e}")
|
||||
return False
|
||||
|
||||
# 4. 验证更新后的配置
|
||||
print("\n4. 验证更新后的配置:")
|
||||
try:
|
||||
updated_config = api.get_daily_checkin_config()
|
||||
if updated_config:
|
||||
print("✓ 成功获取更新后的配置")
|
||||
print(f" 更新后金币范围: {updated_config.get('基础奖励', {}).get('金币', {})}")
|
||||
print(f" 更新后第3天奖励: {updated_config.get('连续签到奖励', {}).get('第3天', {})}")
|
||||
|
||||
# 验证更新是否生效
|
||||
if updated_config.get('基础奖励', {}).get('金币', {}).get('最小值') == 300:
|
||||
print("✓ 配置更新验证成功")
|
||||
else:
|
||||
print("✗ 配置更新验证失败")
|
||||
return False
|
||||
else:
|
||||
print("✗ 获取更新后的配置失败")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ 验证更新后配置异常: {e}")
|
||||
return False
|
||||
|
||||
# 5. 恢复原始配置
|
||||
print("\n5. 恢复原始配置:")
|
||||
try:
|
||||
original_config = {
|
||||
"基础奖励": {
|
||||
"金币": {"最小值": 200, "最大值": 500, "图标": "💰", "颜色": "#FFD700"},
|
||||
"经验": {"最小值": 50, "最大值": 120, "图标": "⭐", "颜色": "#00BFFF"}
|
||||
},
|
||||
"种子奖励": {
|
||||
"普通": {"概率": 0.6, "数量范围": [2, 5], "种子池": ["小麦", "胡萝卜", "土豆", "稻谷"]},
|
||||
"优良": {"概率": 0.25, "数量范围": [2, 4], "种子池": ["玉米", "番茄", "洋葱", "大豆", "豌豆", "黄瓜", "大白菜"]},
|
||||
"稀有": {"概率": 0.12, "数量范围": [1, 3], "种子池": ["草莓", "花椰菜", "柿子", "蓝莓", "树莓"]},
|
||||
"史诗": {"概率": 0.025, "数量范围": [1, 2], "种子池": ["葡萄", "南瓜", "芦笋", "茄子", "向日葵", "蕨菜"]},
|
||||
"传奇": {"概率": 0.005, "数量范围": [1, 1], "种子池": ["西瓜", "甘蔗", "香草", "甜菜", "人参", "富贵竹", "芦荟", "哈密瓜"]}
|
||||
},
|
||||
"连续签到奖励": {
|
||||
"第3天": {"额外金币": 100, "额外经验": 50, "描述": "连续签到奖励"},
|
||||
"第7天": {"额外金币": 200, "额外经验": 100, "描述": "一周连击奖励"},
|
||||
"第14天": {"额外金币": 500, "额外经验": 200, "描述": "半月连击奖励"},
|
||||
"第21天": {"额外金币": 800, "额外经验": 300, "描述": "三周连击奖励"},
|
||||
"第30天": {"额外金币": 1500, "额外经验": 500, "描述": "满月连击奖励"}
|
||||
}
|
||||
}
|
||||
|
||||
success = api.update_daily_checkin_config(original_config)
|
||||
if success:
|
||||
print("✓ 成功恢复原始配置")
|
||||
else:
|
||||
print("✗ 恢复原始配置失败")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ 恢复原始配置异常: {e}")
|
||||
return False
|
||||
|
||||
# 6. 测试配置数据完整性
|
||||
print("\n6. 测试配置数据完整性:")
|
||||
try:
|
||||
final_config = api.get_daily_checkin_config()
|
||||
if final_config:
|
||||
# 检查必要字段是否存在
|
||||
required_fields = ["基础奖励", "种子奖励", "连续签到奖励"]
|
||||
missing_fields = [field for field in required_fields if field not in final_config]
|
||||
|
||||
if not missing_fields:
|
||||
print("✓ 配置数据完整性检查通过")
|
||||
print(f" 包含字段: {', '.join(required_fields)}")
|
||||
else:
|
||||
print(f"✗ 配置数据缺少字段: {missing_fields}")
|
||||
return False
|
||||
else:
|
||||
print("✗ 无法获取最终配置进行完整性检查")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ 配置数据完整性检查异常: {e}")
|
||||
return False
|
||||
|
||||
# 清理资源
|
||||
api.disconnect()
|
||||
|
||||
print("\n=== 所有测试通过!MongoDB迁移功能正常 ===")
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = test_mongodb_migration()
|
||||
if success:
|
||||
print("\n🎉 MongoDB迁移测试成功完成!")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("\n❌ MongoDB迁移测试失败!")
|
||||
sys.exit(1)
|
||||
139
SproutFarm-Backend/test/test_optimized_config_api.py
Normal file
139
SproutFarm-Backend/test/test_optimized_config_api.py
Normal file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试优化后的配置API
|
||||
验证所有配置方法是否正常工作
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
|
||||
def test_all_config_methods():
|
||||
"""测试所有配置方法"""
|
||||
print("=== 测试优化后的配置API ===")
|
||||
|
||||
try:
|
||||
# 创建API实例(测试环境)
|
||||
api = SMYMongoDBAPI("test")
|
||||
|
||||
if not api.is_connected():
|
||||
print("❌ 数据库连接失败,请检查MongoDB服务")
|
||||
return False
|
||||
|
||||
print("✅ 数据库连接成功")
|
||||
|
||||
# 测试所有配置方法
|
||||
config_tests = [
|
||||
("每日签到配置", api.get_daily_checkin_config),
|
||||
("幸运抽奖配置", api.get_lucky_draw_config),
|
||||
("新手大礼包配置", api.get_new_player_config),
|
||||
("智慧树配置", api.get_wisdom_tree_config),
|
||||
("稻草人配置", api.get_scare_crow_config),
|
||||
("在线礼包配置", api.get_online_gift_config),
|
||||
("道具配置", api.get_item_config),
|
||||
("宠物配置", api.get_pet_config),
|
||||
("体力系统配置", api.get_stamina_config),
|
||||
("作物数据配置", api.get_crop_data_config),
|
||||
("初始玩家数据模板", api.get_initial_player_data_template)
|
||||
]
|
||||
|
||||
success_count = 0
|
||||
total_count = len(config_tests)
|
||||
|
||||
for config_name, get_method in config_tests:
|
||||
try:
|
||||
config = get_method()
|
||||
if config:
|
||||
print(f"✅ {config_name}: 获取成功 ({len(config)} 个字段)")
|
||||
success_count += 1
|
||||
else:
|
||||
print(f"❌ {config_name}: 获取失败 (返回None)")
|
||||
except Exception as e:
|
||||
print(f"❌ {config_name}: 获取异常 - {e}")
|
||||
|
||||
print(f"\n=== 测试结果 ===")
|
||||
print(f"成功: {success_count}/{total_count}")
|
||||
print(f"成功率: {success_count/total_count*100:.1f}%")
|
||||
|
||||
# 测试CONFIG_IDS字典
|
||||
print(f"\n=== CONFIG_IDS字典验证 ===")
|
||||
print(f"配置ID数量: {len(api.CONFIG_IDS)}")
|
||||
for key, value in api.CONFIG_IDS.items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
# 断开连接
|
||||
api.disconnect()
|
||||
print("\n✅ 测试完成,数据库连接已断开")
|
||||
|
||||
return success_count == total_count
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试过程中出现异常: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def test_code_optimization():
|
||||
"""测试代码优化效果"""
|
||||
print("\n=== 代码优化验证 ===")
|
||||
|
||||
# 读取SMYMongoDBAPI.py文件
|
||||
try:
|
||||
with open('SMYMongoDBAPI.py', 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# 统计代码行数
|
||||
lines = content.split('\n')
|
||||
total_lines = len(lines)
|
||||
|
||||
# 统计方法数量
|
||||
method_count = content.count('def ')
|
||||
|
||||
# 统计通用方法使用次数
|
||||
generic_get_usage = content.count('_get_config_by_id')
|
||||
generic_update_usage = content.count('_update_config_by_id')
|
||||
|
||||
print(f"✅ 代码文件总行数: {total_lines}")
|
||||
print(f"✅ 方法总数: {method_count}")
|
||||
print(f"✅ 通用获取方法使用次数: {generic_get_usage}")
|
||||
print(f"✅ 通用更新方法使用次数: {generic_update_usage}")
|
||||
|
||||
# 检查是否还有重复代码
|
||||
duplicate_patterns = [
|
||||
'collection.find_one({"_id": object_id})',
|
||||
'collection.replace_one({"_id": object_id}, update_data)',
|
||||
'if "_id" in result:',
|
||||
'del result["_id"]'
|
||||
]
|
||||
|
||||
print(f"\n=== 重复代码检查 ===")
|
||||
for pattern in duplicate_patterns:
|
||||
count = content.count(pattern)
|
||||
if count > 2: # 允许在通用方法中出现
|
||||
print(f"⚠️ 发现重复代码: '{pattern}' 出现 {count} 次")
|
||||
else:
|
||||
print(f"✅ 代码模式 '{pattern}' 已优化")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 代码优化验证失败: {e}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("开始测试优化后的配置API...\n")
|
||||
|
||||
# 测试所有配置方法
|
||||
api_test_success = test_all_config_methods()
|
||||
|
||||
# 测试代码优化效果
|
||||
optimization_test_success = test_code_optimization()
|
||||
|
||||
print(f"\n=== 最终结果 ===")
|
||||
if api_test_success and optimization_test_success:
|
||||
print("🎉 所有测试通过!代码优化成功!")
|
||||
else:
|
||||
print("❌ 部分测试失败,请检查相关问题")
|
||||
341
SproutFarm-Backend/test/test_pet_data_migration.py
Normal file
341
SproutFarm-Backend/test/test_pet_data_migration.py
Normal file
@@ -0,0 +1,341 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
宠物数据格式迁移测试脚本
|
||||
用于验证从旧的嵌套数据格式到新的扁平化数据格式的迁移是否正确
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
def test_old_to_new_format_conversion():
|
||||
"""测试旧格式到新格式的转换"""
|
||||
print("=== 测试旧格式到新格式的转换 ===")
|
||||
|
||||
# 模拟旧格式的宠物数据
|
||||
old_pet_data = {
|
||||
"基本信息": {
|
||||
"宠物ID": "pet_001",
|
||||
"宠物名称": "小火龙",
|
||||
"宠物类型": "火系",
|
||||
"拥有者": "player123",
|
||||
"场景路径": "res://Scene/Pet/FireDragon.tscn"
|
||||
},
|
||||
"等级经验": {
|
||||
"等级": 5,
|
||||
"经验值": 150,
|
||||
"最大经验值": 200
|
||||
},
|
||||
"生命与防御": {
|
||||
"当前生命值": 80,
|
||||
"最大生命值": 100,
|
||||
"最大护甲值": 20
|
||||
},
|
||||
"基础攻击属性": {
|
||||
"攻击伤害": 25
|
||||
},
|
||||
"移动与闪避": {
|
||||
"移动速度": 150
|
||||
},
|
||||
"亲密度": 75
|
||||
}
|
||||
|
||||
# 转换为新格式
|
||||
def convert_to_new_format(old_data):
|
||||
"""将旧格式转换为新格式"""
|
||||
basic_info = old_data.get("基本信息", {})
|
||||
level_exp = old_data.get("等级经验", {})
|
||||
health_defense = old_data.get("生命与防御", {})
|
||||
attack_attrs = old_data.get("基础攻击属性", {})
|
||||
movement = old_data.get("移动与闪避", {})
|
||||
|
||||
return {
|
||||
"pet_id": basic_info.get("宠物ID", ""),
|
||||
"pet_name": basic_info.get("宠物名称", ""),
|
||||
"pet_type": basic_info.get("宠物类型", ""),
|
||||
"pet_owner": basic_info.get("拥有者", ""),
|
||||
"pet_image": basic_info.get("场景路径", ""),
|
||||
"pet_level": level_exp.get("等级", 1),
|
||||
"pet_experience": level_exp.get("经验值", 0),
|
||||
"pet_max_experience": level_exp.get("最大经验值", 100),
|
||||
"pet_current_health": health_defense.get("当前生命值", 100),
|
||||
"pet_max_health": health_defense.get("最大生命值", 100),
|
||||
"pet_max_armor": health_defense.get("最大护甲值", 0),
|
||||
"pet_attack_damage": attack_attrs.get("攻击伤害", 10),
|
||||
"pet_move_speed": movement.get("移动速度", 100),
|
||||
"pet_intimacy": old_data.get("亲密度", 0)
|
||||
}
|
||||
|
||||
new_pet_data = convert_to_new_format(old_pet_data)
|
||||
|
||||
print("旧格式数据:")
|
||||
print(json.dumps(old_pet_data, ensure_ascii=False, indent=2))
|
||||
print("\n新格式数据:")
|
||||
print(json.dumps(new_pet_data, ensure_ascii=False, indent=2))
|
||||
|
||||
# 验证转换结果
|
||||
assert new_pet_data["pet_id"] == "pet_001"
|
||||
assert new_pet_data["pet_name"] == "小火龙"
|
||||
assert new_pet_data["pet_type"] == "火系"
|
||||
assert new_pet_data["pet_owner"] == "player123"
|
||||
assert new_pet_data["pet_level"] == 5
|
||||
assert new_pet_data["pet_experience"] == 150
|
||||
assert new_pet_data["pet_max_experience"] == 200
|
||||
assert new_pet_data["pet_current_health"] == 80
|
||||
assert new_pet_data["pet_max_health"] == 100
|
||||
assert new_pet_data["pet_max_armor"] == 20
|
||||
assert new_pet_data["pet_attack_damage"] == 25
|
||||
assert new_pet_data["pet_move_speed"] == 150
|
||||
assert new_pet_data["pet_intimacy"] == 75
|
||||
|
||||
print("✅ 旧格式到新格式转换测试通过")
|
||||
return new_pet_data
|
||||
|
||||
def test_new_format_operations(pet_data):
|
||||
"""测试新格式数据的各种操作"""
|
||||
print("\n=== 测试新格式数据操作 ===")
|
||||
|
||||
# 测试宠物升级
|
||||
def level_up_pet(pet):
|
||||
"""模拟宠物升级"""
|
||||
pet = pet.copy()
|
||||
pet["pet_level"] += 1
|
||||
pet["pet_experience"] = 0
|
||||
pet["pet_max_experience"] = pet["pet_level"] * 100
|
||||
pet["pet_max_health"] += 10
|
||||
pet["pet_current_health"] = pet["pet_max_health"]
|
||||
pet["pet_attack_damage"] += 5
|
||||
return pet
|
||||
|
||||
# 测试宠物喂食
|
||||
def feed_pet(pet, exp_gain=20):
|
||||
"""模拟宠物喂食"""
|
||||
pet = pet.copy()
|
||||
pet["pet_experience"] = min(pet["pet_experience"] + exp_gain, pet["pet_max_experience"])
|
||||
pet["pet_intimacy"] = min(pet["pet_intimacy"] + 5, 100)
|
||||
return pet
|
||||
|
||||
# 测试宠物治疗
|
||||
def heal_pet(pet, heal_amount=20):
|
||||
"""模拟宠物治疗"""
|
||||
pet = pet.copy()
|
||||
pet["pet_current_health"] = min(pet["pet_current_health"] + heal_amount, pet["pet_max_health"])
|
||||
return pet
|
||||
|
||||
print("原始宠物数据:")
|
||||
print(f"等级: {pet_data['pet_level']}, 经验: {pet_data['pet_experience']}/{pet_data['pet_max_experience']}")
|
||||
print(f"生命值: {pet_data['pet_current_health']}/{pet_data['pet_max_health']}")
|
||||
print(f"攻击力: {pet_data['pet_attack_damage']}, 亲密度: {pet_data['pet_intimacy']}")
|
||||
|
||||
# 测试喂食
|
||||
fed_pet = feed_pet(pet_data)
|
||||
print("\n喂食后:")
|
||||
print(f"经验: {fed_pet['pet_experience']}/{fed_pet['pet_max_experience']}")
|
||||
print(f"亲密度: {fed_pet['pet_intimacy']}")
|
||||
|
||||
# 测试升级
|
||||
leveled_pet = level_up_pet(fed_pet)
|
||||
print("\n升级后:")
|
||||
print(f"等级: {leveled_pet['pet_level']}, 经验: {leveled_pet['pet_experience']}/{leveled_pet['pet_max_experience']}")
|
||||
print(f"生命值: {leveled_pet['pet_current_health']}/{leveled_pet['pet_max_health']}")
|
||||
print(f"攻击力: {leveled_pet['pet_attack_damage']}")
|
||||
|
||||
# 测试治疗
|
||||
# 先模拟受伤
|
||||
injured_pet = leveled_pet.copy()
|
||||
injured_pet["pet_current_health"] = 50
|
||||
print("\n受伤后:")
|
||||
print(f"生命值: {injured_pet['pet_current_health']}/{injured_pet['pet_max_health']}")
|
||||
|
||||
healed_pet = heal_pet(injured_pet)
|
||||
print("\n治疗后:")
|
||||
print(f"生命值: {healed_pet['pet_current_health']}/{healed_pet['pet_max_health']}")
|
||||
|
||||
print("✅ 新格式数据操作测试通过")
|
||||
|
||||
def test_pet_bag_operations():
|
||||
"""测试宠物背包操作"""
|
||||
print("\n=== 测试宠物背包操作 ===")
|
||||
|
||||
# 创建测试宠物背包
|
||||
pet_bag = [
|
||||
{
|
||||
"pet_id": "pet_001",
|
||||
"pet_name": "小火龙",
|
||||
"pet_type": "火系",
|
||||
"pet_owner": "player123",
|
||||
"pet_image": "res://Scene/Pet/FireDragon.tscn",
|
||||
"pet_level": 5,
|
||||
"pet_experience": 150,
|
||||
"pet_max_experience": 200,
|
||||
"pet_current_health": 80,
|
||||
"pet_max_health": 100,
|
||||
"pet_max_armor": 20,
|
||||
"pet_attack_damage": 25,
|
||||
"pet_move_speed": 150,
|
||||
"pet_intimacy": 75
|
||||
},
|
||||
{
|
||||
"pet_id": "pet_002",
|
||||
"pet_name": "水精灵",
|
||||
"pet_type": "水系",
|
||||
"pet_owner": "player123",
|
||||
"pet_image": "res://Scene/Pet/WaterSpirit.tscn",
|
||||
"pet_level": 3,
|
||||
"pet_experience": 80,
|
||||
"pet_max_experience": 150,
|
||||
"pet_current_health": 60,
|
||||
"pet_max_health": 80,
|
||||
"pet_max_armor": 15,
|
||||
"pet_attack_damage": 20,
|
||||
"pet_move_speed": 120,
|
||||
"pet_intimacy": 50
|
||||
}
|
||||
]
|
||||
|
||||
print(f"宠物背包中有 {len(pet_bag)} 只宠物")
|
||||
|
||||
# 测试遍历宠物背包
|
||||
for i, pet in enumerate(pet_bag):
|
||||
print(f"\n宠物 {i+1}:")
|
||||
print(f" ID: {pet['pet_id']}")
|
||||
print(f" 名称: {pet['pet_name']}")
|
||||
print(f" 类型: {pet['pet_type']}")
|
||||
print(f" 等级: {pet['pet_level']}")
|
||||
print(f" 生命值: {pet['pet_current_health']}/{pet['pet_max_health']}")
|
||||
print(f" 攻击力: {pet['pet_attack_damage']}")
|
||||
print(f" 亲密度: {pet['pet_intimacy']}")
|
||||
|
||||
# 测试查找特定宠物
|
||||
def find_pet_by_id(pet_bag, pet_id):
|
||||
for pet in pet_bag:
|
||||
if pet.get("pet_id") == pet_id:
|
||||
return pet
|
||||
return None
|
||||
|
||||
found_pet = find_pet_by_id(pet_bag, "pet_002")
|
||||
if found_pet:
|
||||
print(f"\n找到宠物: {found_pet['pet_name']} (ID: {found_pet['pet_id']})")
|
||||
|
||||
# 测试按类型筛选宠物
|
||||
def filter_pets_by_type(pet_bag, pet_type):
|
||||
return [pet for pet in pet_bag if pet.get("pet_type") == pet_type]
|
||||
|
||||
fire_pets = filter_pets_by_type(pet_bag, "火系")
|
||||
print(f"\n火系宠物数量: {len(fire_pets)}")
|
||||
|
||||
# 测试计算总战力
|
||||
def calculate_total_power(pet_bag):
|
||||
total_power = 0
|
||||
for pet in pet_bag:
|
||||
power = pet.get("pet_level", 1) * 10 + pet.get("pet_attack_damage", 0) + pet.get("pet_max_health", 0)
|
||||
total_power += power
|
||||
return total_power
|
||||
|
||||
total_power = calculate_total_power(pet_bag)
|
||||
print(f"\n总战力: {total_power}")
|
||||
|
||||
print("✅ 宠物背包操作测试通过")
|
||||
|
||||
def test_data_validation():
|
||||
"""测试数据验证"""
|
||||
print("\n=== 测试数据验证 ===")
|
||||
|
||||
def validate_pet_data(pet):
|
||||
"""验证宠物数据的完整性"""
|
||||
required_fields = [
|
||||
"pet_id", "pet_name", "pet_type", "pet_owner", "pet_image",
|
||||
"pet_level", "pet_experience", "pet_max_experience",
|
||||
"pet_current_health", "pet_max_health", "pet_max_armor",
|
||||
"pet_attack_damage", "pet_move_speed", "pet_intimacy"
|
||||
]
|
||||
|
||||
missing_fields = []
|
||||
for field in required_fields:
|
||||
if field not in pet:
|
||||
missing_fields.append(field)
|
||||
|
||||
if missing_fields:
|
||||
return False, f"缺少字段: {', '.join(missing_fields)}"
|
||||
|
||||
# 验证数值范围
|
||||
if pet["pet_level"] < 1:
|
||||
return False, "宠物等级不能小于1"
|
||||
|
||||
if pet["pet_experience"] < 0:
|
||||
return False, "宠物经验值不能为负数"
|
||||
|
||||
if pet["pet_current_health"] > pet["pet_max_health"]:
|
||||
return False, "当前生命值不能超过最大生命值"
|
||||
|
||||
if pet["pet_intimacy"] < 0 or pet["pet_intimacy"] > 100:
|
||||
return False, "亲密度必须在0-100之间"
|
||||
|
||||
return True, "数据验证通过"
|
||||
|
||||
# 测试有效数据
|
||||
valid_pet = {
|
||||
"pet_id": "pet_001",
|
||||
"pet_name": "测试宠物",
|
||||
"pet_type": "普通",
|
||||
"pet_owner": "player123",
|
||||
"pet_image": "res://Scene/Pet/Test.tscn",
|
||||
"pet_level": 1,
|
||||
"pet_experience": 0,
|
||||
"pet_max_experience": 100,
|
||||
"pet_current_health": 100,
|
||||
"pet_max_health": 100,
|
||||
"pet_max_armor": 0,
|
||||
"pet_attack_damage": 10,
|
||||
"pet_move_speed": 100,
|
||||
"pet_intimacy": 0
|
||||
}
|
||||
|
||||
is_valid, message = validate_pet_data(valid_pet)
|
||||
print(f"有效数据验证: {message}")
|
||||
assert is_valid, "有效数据应该通过验证"
|
||||
|
||||
# 测试无效数据
|
||||
invalid_pet = valid_pet.copy()
|
||||
del invalid_pet["pet_name"] # 删除必需字段
|
||||
|
||||
is_valid, message = validate_pet_data(invalid_pet)
|
||||
print(f"无效数据验证: {message}")
|
||||
assert not is_valid, "无效数据应该不通过验证"
|
||||
|
||||
print("✅ 数据验证测试通过")
|
||||
|
||||
def main():
|
||||
"""主测试函数"""
|
||||
print("开始宠物数据格式迁移测试...\n")
|
||||
|
||||
try:
|
||||
# 测试格式转换
|
||||
new_pet_data = test_old_to_new_format_conversion()
|
||||
|
||||
# 测试新格式操作
|
||||
test_new_format_operations(new_pet_data)
|
||||
|
||||
# 测试宠物背包操作
|
||||
test_pet_bag_operations()
|
||||
|
||||
# 测试数据验证
|
||||
test_data_validation()
|
||||
|
||||
print("\n🎉 所有测试通过!宠物数据格式迁移工作正常。")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ 测试失败: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
219
SproutFarm-Backend/test/test_player_data_mongodb_migration.py
Normal file
219
SproutFarm-Backend/test/test_player_data_mongodb_migration.py
Normal file
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
玩家数据MongoDB迁移测试脚本
|
||||
作者: AI Assistant
|
||||
功能: 测试玩家数据从JSON文件到MongoDB的迁移和操作功能
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
|
||||
def test_player_data_operations():
|
||||
"""测试玩家数据操作"""
|
||||
print("=== 玩家数据MongoDB操作测试 ===")
|
||||
|
||||
# 1. 连接MongoDB
|
||||
print("\n1. 连接MongoDB...")
|
||||
try:
|
||||
api = SMYMongoDBAPI("test")
|
||||
if not api.is_connected():
|
||||
print("❌ MongoDB连接失败")
|
||||
return False
|
||||
print("✅ MongoDB连接成功")
|
||||
except Exception as e:
|
||||
print(f"❌ MongoDB连接异常: {e}")
|
||||
return False
|
||||
|
||||
# 2. 测试获取玩家数据
|
||||
print("\n2. 测试获取玩家数据...")
|
||||
test_accounts = ["2143323382", "2804775686", "3205788256"]
|
||||
|
||||
for account_id in test_accounts:
|
||||
try:
|
||||
player_data = api.get_player_data(account_id)
|
||||
if player_data:
|
||||
print(f"✅ 成功获取玩家 {account_id} 的数据")
|
||||
print(f" 昵称: {player_data.get('玩家昵称', 'N/A')}")
|
||||
print(f" 等级: {player_data.get('等级', 'N/A')}")
|
||||
print(f" 金币: {player_data.get('钱币', 'N/A')}")
|
||||
print(f" 农场土地数量: {len(player_data.get('农场土地', []))}")
|
||||
else:
|
||||
print(f"⚠️ 未找到玩家 {account_id} 的数据")
|
||||
except Exception as e:
|
||||
print(f"❌ 获取玩家 {account_id} 数据时异常: {e}")
|
||||
|
||||
# 3. 测试获取所有玩家基本信息
|
||||
print("\n3. 测试获取所有玩家基本信息...")
|
||||
try:
|
||||
players_info = api.get_all_players_basic_info()
|
||||
print(f"✅ 成功获取 {len(players_info)} 个玩家的基本信息")
|
||||
|
||||
for i, player in enumerate(players_info[:3]): # 只显示前3个
|
||||
print(f" 玩家{i+1}: {player.get('玩家账号')} - {player.get('玩家昵称')} (等级{player.get('等级')})")
|
||||
|
||||
if len(players_info) > 3:
|
||||
print(f" ... 还有 {len(players_info) - 3} 个玩家")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 获取玩家基本信息时异常: {e}")
|
||||
|
||||
# 4. 测试统计玩家总数
|
||||
print("\n4. 测试统计玩家总数...")
|
||||
try:
|
||||
total_count = api.count_total_players()
|
||||
print(f"✅ 玩家总数: {total_count}")
|
||||
except Exception as e:
|
||||
print(f"❌ 统计玩家总数时异常: {e}")
|
||||
|
||||
# 5. 测试获取离线玩家
|
||||
print("\n5. 测试获取离线玩家...")
|
||||
try:
|
||||
offline_players = api.get_offline_players(offline_days=1) # 1天内未登录
|
||||
print(f"✅ 找到 {len(offline_players)} 个离线超过1天的玩家")
|
||||
|
||||
for player in offline_players[:3]: # 只显示前3个
|
||||
account_id = player.get('玩家账号')
|
||||
last_login = player.get('最后登录时间', 'N/A')
|
||||
print(f" {account_id}: 最后登录 {last_login}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 获取离线玩家时异常: {e}")
|
||||
|
||||
# 6. 测试更新玩家字段
|
||||
print("\n6. 测试更新玩家字段...")
|
||||
if test_accounts:
|
||||
test_account = test_accounts[0]
|
||||
try:
|
||||
# 更新测试字段
|
||||
update_fields = {
|
||||
"测试字段": f"测试时间_{int(time.time())}",
|
||||
"测试更新": True
|
||||
}
|
||||
|
||||
success = api.update_player_field(test_account, update_fields)
|
||||
if success:
|
||||
print(f"✅ 成功更新玩家 {test_account} 的字段")
|
||||
|
||||
# 验证更新
|
||||
updated_data = api.get_player_data(test_account)
|
||||
if updated_data and "测试字段" in updated_data:
|
||||
print(f" 验证成功: 测试字段 = {updated_data['测试字段']}")
|
||||
else:
|
||||
print("⚠️ 更新验证失败")
|
||||
else:
|
||||
print(f"❌ 更新玩家 {test_account} 字段失败")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 更新玩家字段时异常: {e}")
|
||||
|
||||
# 7. 测试条件查询
|
||||
print("\n7. 测试条件查询...")
|
||||
try:
|
||||
# 查询等级大于等于5的玩家
|
||||
condition = {"等级": {"$gte": 5}}
|
||||
projection = {"玩家账号": 1, "玩家昵称": 1, "等级": 1, "钱币": 1}
|
||||
|
||||
high_level_players = api.get_players_by_condition(condition, projection, limit=5)
|
||||
print(f"✅ 找到 {len(high_level_players)} 个等级≥5的玩家")
|
||||
|
||||
for player in high_level_players:
|
||||
print(f" {player.get('玩家账号')}: {player.get('玩家昵称')} (等级{player.get('等级')}, 金币{player.get('钱币')})")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 条件查询时异常: {e}")
|
||||
|
||||
# 8. 性能测试
|
||||
print("\n8. 性能测试...")
|
||||
try:
|
||||
start_time = time.time()
|
||||
|
||||
# 批量获取玩家基本信息
|
||||
players_info = api.get_all_players_basic_info()
|
||||
|
||||
end_time = time.time()
|
||||
duration = end_time - start_time
|
||||
|
||||
print(f"✅ 获取 {len(players_info)} 个玩家基本信息耗时: {duration:.3f} 秒")
|
||||
|
||||
if duration < 1.0:
|
||||
print(" 性能良好 ✅")
|
||||
elif duration < 3.0:
|
||||
print(" 性能一般 ⚠️")
|
||||
else:
|
||||
print(" 性能较差,建议优化 ❌")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 性能测试时异常: {e}")
|
||||
|
||||
print("\n=== 测试完成 ===")
|
||||
return True
|
||||
|
||||
def test_compatibility_with_file_system():
|
||||
"""测试与文件系统的兼容性"""
|
||||
print("\n=== 文件系统兼容性测试 ===")
|
||||
|
||||
try:
|
||||
# 模拟服务器环境
|
||||
from TCPGameServer import TCPGameServer
|
||||
|
||||
# 创建服务器实例(不启动网络服务)
|
||||
server = TCPGameServer()
|
||||
|
||||
# 测试加载玩家数据
|
||||
test_account = "2143323382"
|
||||
|
||||
print(f"\n测试加载玩家数据: {test_account}")
|
||||
player_data = server.load_player_data(test_account)
|
||||
|
||||
if player_data:
|
||||
print("✅ 成功加载玩家数据")
|
||||
print(f" 数据源: {'MongoDB' if server.use_mongodb else '文件系统'}")
|
||||
print(f" 玩家昵称: {player_data.get('玩家昵称', 'N/A')}")
|
||||
print(f" 等级: {player_data.get('等级', 'N/A')}")
|
||||
|
||||
# 测试保存玩家数据
|
||||
print("\n测试保存玩家数据...")
|
||||
player_data["测试兼容性"] = f"测试时间_{int(time.time())}"
|
||||
|
||||
success = server.save_player_data(test_account, player_data)
|
||||
if success:
|
||||
print("✅ 成功保存玩家数据")
|
||||
|
||||
# 验证保存
|
||||
reloaded_data = server.load_player_data(test_account)
|
||||
if reloaded_data and "测试兼容性" in reloaded_data:
|
||||
print("✅ 保存验证成功")
|
||||
else:
|
||||
print("❌ 保存验证失败")
|
||||
else:
|
||||
print("❌ 保存玩家数据失败")
|
||||
else:
|
||||
print("❌ 加载玩家数据失败")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 兼容性测试异常: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
try:
|
||||
# 基本操作测试
|
||||
test_player_data_operations()
|
||||
|
||||
# 兼容性测试
|
||||
test_compatibility_with_file_system()
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n测试被用户中断")
|
||||
except Exception as e:
|
||||
print(f"测试过程中发生异常: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
106
SproutFarm-Backend/test/test_server_mongodb.py
Normal file
106
SproutFarm-Backend/test/test_server_mongodb.py
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试服务器MongoDB集成
|
||||
作者: AI Assistant
|
||||
功能: 测试服务器是否能正确使用MongoDB配置
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
def test_server_mongodb_integration():
|
||||
"""测试服务器MongoDB集成"""
|
||||
print("=== 测试服务器MongoDB集成 ===")
|
||||
|
||||
try:
|
||||
# 导入服务器模块
|
||||
from Server.TCPGameServer import TCPGameServer
|
||||
|
||||
print("✓ 成功导入TCPGameServer模块")
|
||||
|
||||
# 创建服务器实例(不启动网络服务)
|
||||
print("\n1. 创建服务器实例:")
|
||||
server = TCPGameServer()
|
||||
print("✓ 服务器实例创建成功")
|
||||
|
||||
# 检查MongoDB连接状态
|
||||
print("\n2. 检查MongoDB连接状态:")
|
||||
if hasattr(server, 'use_mongodb'):
|
||||
print(f" MongoDB使用状态: {server.use_mongodb}")
|
||||
if hasattr(server, 'mongo_api') and server.mongo_api:
|
||||
print(" MongoDB API实例: 已创建")
|
||||
else:
|
||||
print(" MongoDB API实例: 未创建")
|
||||
else:
|
||||
print(" MongoDB相关属性: 未找到")
|
||||
|
||||
# 测试配置加载
|
||||
print("\n3. 测试每日签到配置加载:")
|
||||
try:
|
||||
config = server._load_daily_check_in_config()
|
||||
if config:
|
||||
print("✓ 成功加载每日签到配置")
|
||||
print(f" 基础奖励金币范围: {config.get('基础奖励', {}).get('金币', {})}")
|
||||
print(f" 种子奖励类型数量: {len(config.get('种子奖励', {}))}")
|
||||
print(f" 连续签到奖励天数: {len(config.get('连续签到奖励', {}))}")
|
||||
|
||||
# 检查配置来源
|
||||
if hasattr(server, 'use_mongodb') and server.use_mongodb:
|
||||
print(" 配置来源: MongoDB")
|
||||
else:
|
||||
print(" 配置来源: JSON文件或默认配置")
|
||||
else:
|
||||
print("✗ 加载每日签到配置失败")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ 配置加载异常: {e}")
|
||||
return False
|
||||
|
||||
# 测试配置更新方法
|
||||
print("\n4. 测试配置更新方法:")
|
||||
if hasattr(server, '_update_daily_checkin_config_to_mongodb'):
|
||||
print("✓ 配置更新方法存在")
|
||||
|
||||
# 测试更新方法(不实际更新)
|
||||
test_config = {
|
||||
"基础奖励": {
|
||||
"金币": {"最小值": 250, "最大值": 550, "图标": "💰", "颜色": "#FFD700"},
|
||||
"经验": {"最小值": 60, "最大值": 130, "图标": "⭐", "颜色": "#00BFFF"}
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
# 这里只是测试方法是否存在,不实际调用
|
||||
print("✓ 配置更新方法可调用")
|
||||
except Exception as e:
|
||||
print(f"✗ 配置更新方法异常: {e}")
|
||||
return False
|
||||
else:
|
||||
print("✗ 配置更新方法不存在")
|
||||
return False
|
||||
|
||||
print("\n=== 服务器MongoDB集成测试通过! ===")
|
||||
return True
|
||||
|
||||
except ImportError as e:
|
||||
print(f"✗ 模块导入失败: {e}")
|
||||
print(" 请确保所有依赖模块都已正确安装")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"✗ 测试过程中出现异常: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = test_server_mongodb_integration()
|
||||
if success:
|
||||
print("\n🎉 服务器MongoDB集成测试成功完成!")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("\n❌ 服务器MongoDB集成测试失败!")
|
||||
sys.exit(1)
|
||||
401
SproutFarm-Backend/test/test_server_pet_functions.py
Normal file
401
SproutFarm-Backend/test/test_server_pet_functions.py
Normal file
@@ -0,0 +1,401 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
服务器宠物功能测试脚本
|
||||
用于测试TCPGameServer中宠物相关功能是否正常工作
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
# 添加当前目录到Python路径
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
def test_pet_data_conversion_functions():
|
||||
"""测试宠物数据转换函数"""
|
||||
print("=== 测试宠物数据转换函数 ===")
|
||||
|
||||
# 模拟TCPGameServer类的部分方法
|
||||
class MockTCPGameServer:
|
||||
def _convert_patrol_pets_to_full_data(self, patrol_pets):
|
||||
"""模拟巡逻宠物数据转换"""
|
||||
full_pets = []
|
||||
for pet in patrol_pets:
|
||||
# 使用新的扁平化数据格式
|
||||
scene_path = pet.get("pet_image", "")
|
||||
full_pet = {
|
||||
"pet_id": pet.get("pet_id", ""),
|
||||
"pet_name": pet.get("pet_name", ""),
|
||||
"pet_type": pet.get("pet_type", ""),
|
||||
"pet_level": pet.get("pet_level", 1),
|
||||
"pet_current_health": pet.get("pet_current_health", 100),
|
||||
"pet_max_health": pet.get("pet_max_health", 100),
|
||||
"pet_attack_damage": pet.get("pet_attack_damage", 10),
|
||||
"pet_move_speed": pet.get("pet_move_speed", 100),
|
||||
"scene_path": scene_path
|
||||
}
|
||||
full_pets.append(full_pet)
|
||||
return full_pets
|
||||
|
||||
def _convert_battle_pets_to_full_data(self, battle_pets):
|
||||
"""模拟战斗宠物数据转换"""
|
||||
return self._convert_patrol_pets_to_full_data(battle_pets)
|
||||
|
||||
def _player_has_pet(self, pet_bag, pet_type):
|
||||
"""检查玩家是否拥有指定类型的宠物"""
|
||||
for pet in pet_bag:
|
||||
if pet.get("pet_type", "") == pet_type:
|
||||
return True
|
||||
return False
|
||||
|
||||
server = MockTCPGameServer()
|
||||
|
||||
# 测试数据
|
||||
test_pets = [
|
||||
{
|
||||
"pet_id": "pet_001",
|
||||
"pet_name": "小火龙",
|
||||
"pet_type": "火系",
|
||||
"pet_level": 5,
|
||||
"pet_current_health": 80,
|
||||
"pet_max_health": 100,
|
||||
"pet_attack_damage": 25,
|
||||
"pet_move_speed": 150,
|
||||
"pet_image": "res://Scene/Pet/FireDragon.tscn"
|
||||
},
|
||||
{
|
||||
"pet_id": "pet_002",
|
||||
"pet_name": "水精灵",
|
||||
"pet_type": "水系",
|
||||
"pet_level": 3,
|
||||
"pet_current_health": 60,
|
||||
"pet_max_health": 80,
|
||||
"pet_attack_damage": 20,
|
||||
"pet_move_speed": 120,
|
||||
"pet_image": "res://Scene/Pet/WaterSpirit.tscn"
|
||||
}
|
||||
]
|
||||
|
||||
# 测试巡逻宠物转换
|
||||
patrol_pets = server._convert_patrol_pets_to_full_data(test_pets)
|
||||
print(f"巡逻宠物转换结果: {len(patrol_pets)} 只宠物")
|
||||
for pet in patrol_pets:
|
||||
print(f" {pet['pet_name']} (ID: {pet['pet_id']}) - 场景路径: {pet['scene_path']}")
|
||||
|
||||
# 测试战斗宠物转换
|
||||
battle_pets = server._convert_battle_pets_to_full_data(test_pets)
|
||||
print(f"\n战斗宠物转换结果: {len(battle_pets)} 只宠物")
|
||||
|
||||
# 测试宠物类型检查
|
||||
has_fire_pet = server._player_has_pet(test_pets, "火系")
|
||||
has_grass_pet = server._player_has_pet(test_pets, "草系")
|
||||
print(f"\n玩家是否拥有火系宠物: {has_fire_pet}")
|
||||
print(f"玩家是否拥有草系宠物: {has_grass_pet}")
|
||||
|
||||
assert has_fire_pet == True
|
||||
assert has_grass_pet == False
|
||||
|
||||
print("✅ 宠物数据转换函数测试通过")
|
||||
|
||||
def test_pet_feeding_system():
|
||||
"""测试宠物喂食系统"""
|
||||
print("\n=== 测试宠物喂食系统 ===")
|
||||
|
||||
class MockTCPGameServer:
|
||||
def _process_pet_feeding(self, pet_data, food_item):
|
||||
"""模拟宠物喂食处理"""
|
||||
# 使用新的扁平化数据格式
|
||||
exp_gain = food_item.get("经验加成", 10)
|
||||
intimacy_gain = food_item.get("亲密度加成", 5)
|
||||
|
||||
# 更新宠物数据
|
||||
pet_data["pet_experience"] = min(
|
||||
pet_data.get("pet_experience", 0) + exp_gain,
|
||||
pet_data.get("pet_max_experience", 100)
|
||||
)
|
||||
pet_data["pet_intimacy"] = min(
|
||||
pet_data.get("pet_intimacy", 0) + intimacy_gain,
|
||||
100
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"{pet_data['pet_name']} 获得了 {exp_gain} 经验和 {intimacy_gain} 亲密度",
|
||||
"pet_data": pet_data
|
||||
}
|
||||
|
||||
def _apply_level_up_bonus(self, pet_data):
|
||||
"""模拟宠物升级加成"""
|
||||
level = pet_data.get("pet_level", 1)
|
||||
|
||||
# 使用新的扁平化数据格式
|
||||
pet_data["pet_max_health"] = pet_data.get("pet_max_health", 100) + 10
|
||||
pet_data["pet_max_armor"] = pet_data.get("pet_max_armor", 0) + 2
|
||||
pet_data["pet_attack_damage"] = pet_data.get("pet_attack_damage", 10) + 5
|
||||
pet_data["pet_move_speed"] = pet_data.get("pet_move_speed", 100) + 5
|
||||
|
||||
# 恢复满血
|
||||
pet_data["pet_current_health"] = pet_data["pet_max_health"]
|
||||
|
||||
return pet_data
|
||||
|
||||
server = MockTCPGameServer()
|
||||
|
||||
# 测试宠物数据
|
||||
pet_data = {
|
||||
"pet_id": "pet_001",
|
||||
"pet_name": "小火龙",
|
||||
"pet_type": "火系",
|
||||
"pet_level": 5,
|
||||
"pet_experience": 180,
|
||||
"pet_max_experience": 200,
|
||||
"pet_current_health": 80,
|
||||
"pet_max_health": 100,
|
||||
"pet_max_armor": 20,
|
||||
"pet_attack_damage": 25,
|
||||
"pet_move_speed": 150,
|
||||
"pet_intimacy": 75
|
||||
}
|
||||
|
||||
# 测试食物道具
|
||||
food_item = {
|
||||
"物品名称": "高级宠物食物",
|
||||
"经验加成": 25,
|
||||
"亲密度加成": 10
|
||||
}
|
||||
|
||||
print(f"喂食前: {pet_data['pet_name']} - 经验: {pet_data['pet_experience']}/{pet_data['pet_max_experience']}, 亲密度: {pet_data['pet_intimacy']}")
|
||||
|
||||
# 执行喂食
|
||||
result = server._process_pet_feeding(pet_data, food_item)
|
||||
|
||||
if result["success"]:
|
||||
updated_pet = result["pet_data"]
|
||||
print(f"喂食后: {updated_pet['pet_name']} - 经验: {updated_pet['pet_experience']}/{updated_pet['pet_max_experience']}, 亲密度: {updated_pet['pet_intimacy']}")
|
||||
print(f"消息: {result['message']}")
|
||||
|
||||
# 检查是否需要升级
|
||||
if updated_pet["pet_experience"] >= updated_pet["pet_max_experience"]:
|
||||
print("\n宠物可以升级!")
|
||||
updated_pet["pet_level"] += 1
|
||||
updated_pet["pet_experience"] = 0
|
||||
updated_pet["pet_max_experience"] = updated_pet["pet_level"] * 100
|
||||
|
||||
# 应用升级加成
|
||||
updated_pet = server._apply_level_up_bonus(updated_pet)
|
||||
print(f"升级后: {updated_pet['pet_name']} - 等级: {updated_pet['pet_level']}, 生命值: {updated_pet['pet_current_health']}/{updated_pet['pet_max_health']}, 攻击力: {updated_pet['pet_attack_damage']}")
|
||||
|
||||
print("✅ 宠物喂食系统测试通过")
|
||||
|
||||
def test_pet_item_usage():
|
||||
"""测试宠物道具使用"""
|
||||
print("\n=== 测试宠物道具使用 ===")
|
||||
|
||||
class MockTCPGameServer:
|
||||
def _process_pet_item_use(self, pet_data, item_data):
|
||||
"""模拟宠物道具使用处理"""
|
||||
item_name = item_data.get("物品名称", "")
|
||||
|
||||
# 使用新的扁平化数据格式获取宠物名称
|
||||
pet_name = pet_data.get("pet_name", "未知宠物")
|
||||
|
||||
if "治疗" in item_name:
|
||||
# 治疗道具
|
||||
heal_amount = item_data.get("治疗量", 20)
|
||||
pet_data["pet_current_health"] = min(
|
||||
pet_data.get("pet_current_health", 0) + heal_amount,
|
||||
pet_data.get("pet_max_health", 100)
|
||||
)
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"{pet_name} 使用了 {item_name},恢复了 {heal_amount} 生命值"
|
||||
}
|
||||
elif "经验" in item_name:
|
||||
# 经验道具
|
||||
exp_gain = item_data.get("经验加成", 50)
|
||||
pet_data["pet_experience"] = min(
|
||||
pet_data.get("pet_experience", 0) + exp_gain,
|
||||
pet_data.get("pet_max_experience", 100)
|
||||
)
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"{pet_name} 使用了 {item_name},获得了 {exp_gain} 经验值"
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"success": False,
|
||||
"message": f"未知的道具类型: {item_name}"
|
||||
}
|
||||
|
||||
server = MockTCPGameServer()
|
||||
|
||||
# 测试宠物数据
|
||||
pet_data = {
|
||||
"pet_id": "pet_001",
|
||||
"pet_name": "小火龙",
|
||||
"pet_type": "火系",
|
||||
"pet_level": 3,
|
||||
"pet_experience": 50,
|
||||
"pet_max_experience": 150,
|
||||
"pet_current_health": 40,
|
||||
"pet_max_health": 80,
|
||||
"pet_attack_damage": 20,
|
||||
"pet_intimacy": 60
|
||||
}
|
||||
|
||||
# 测试治疗道具
|
||||
heal_item = {
|
||||
"物品名称": "高级治疗药水",
|
||||
"治疗量": 30
|
||||
}
|
||||
|
||||
print(f"使用治疗道具前: {pet_data['pet_name']} - 生命值: {pet_data['pet_current_health']}/{pet_data['pet_max_health']}")
|
||||
|
||||
result = server._process_pet_item_use(pet_data, heal_item)
|
||||
if result["success"]:
|
||||
print(f"使用治疗道具后: {pet_data['pet_name']} - 生命值: {pet_data['pet_current_health']}/{pet_data['pet_max_health']}")
|
||||
print(f"消息: {result['message']}")
|
||||
|
||||
# 测试经验道具
|
||||
exp_item = {
|
||||
"物品名称": "经验药水",
|
||||
"经验加成": 80
|
||||
}
|
||||
|
||||
print(f"\n使用经验道具前: {pet_data['pet_name']} - 经验: {pet_data['pet_experience']}/{pet_data['pet_max_experience']}")
|
||||
|
||||
result = server._process_pet_item_use(pet_data, exp_item)
|
||||
if result["success"]:
|
||||
print(f"使用经验道具后: {pet_data['pet_name']} - 经验: {pet_data['pet_experience']}/{pet_data['pet_max_experience']}")
|
||||
print(f"消息: {result['message']}")
|
||||
|
||||
print("✅ 宠物道具使用测试通过")
|
||||
|
||||
def test_pet_bag_operations():
|
||||
"""测试宠物背包操作"""
|
||||
print("\n=== 测试宠物背包操作 ===")
|
||||
|
||||
# 模拟宠物背包数据
|
||||
pet_bag = [
|
||||
{
|
||||
"pet_id": "pet_001",
|
||||
"pet_name": "小火龙",
|
||||
"pet_type": "火系",
|
||||
"pet_owner": "player123",
|
||||
"pet_image": "res://Scene/Pet/FireDragon.tscn",
|
||||
"pet_level": 5,
|
||||
"pet_experience": 150,
|
||||
"pet_max_experience": 200,
|
||||
"pet_current_health": 80,
|
||||
"pet_max_health": 100,
|
||||
"pet_max_armor": 20,
|
||||
"pet_attack_damage": 25,
|
||||
"pet_move_speed": 150,
|
||||
"pet_intimacy": 75
|
||||
},
|
||||
{
|
||||
"pet_id": "pet_002",
|
||||
"pet_name": "水精灵",
|
||||
"pet_type": "水系",
|
||||
"pet_owner": "player123",
|
||||
"pet_image": "res://Scene/Pet/WaterSpirit.tscn",
|
||||
"pet_level": 3,
|
||||
"pet_experience": 80,
|
||||
"pet_max_experience": 150,
|
||||
"pet_current_health": 60,
|
||||
"pet_max_health": 80,
|
||||
"pet_max_armor": 15,
|
||||
"pet_attack_damage": 20,
|
||||
"pet_move_speed": 120,
|
||||
"pet_intimacy": 50
|
||||
}
|
||||
]
|
||||
|
||||
print(f"宠物背包中有 {len(pet_bag)} 只宠物")
|
||||
|
||||
# 测试遍历宠物背包(模拟TCPGameServer中的for pet in pet_bag循环)
|
||||
print("\n遍历宠物背包:")
|
||||
for pet in pet_bag:
|
||||
# 使用新的扁平化数据格式
|
||||
pet_id = pet.get("pet_id", "")
|
||||
pet_name = pet.get("pet_name", "")
|
||||
pet_type = pet.get("pet_type", "")
|
||||
pet_level = pet.get("pet_level", 1)
|
||||
pet_health = pet.get("pet_current_health", 0)
|
||||
pet_max_health = pet.get("pet_max_health", 100)
|
||||
pet_attack = pet.get("pet_attack_damage", 10)
|
||||
pet_intimacy = pet.get("pet_intimacy", 0)
|
||||
|
||||
print(f" 宠物ID: {pet_id}")
|
||||
print(f" 名称: {pet_name} ({pet_type})")
|
||||
print(f" 等级: {pet_level}")
|
||||
print(f" 生命值: {pet_health}/{pet_max_health}")
|
||||
print(f" 攻击力: {pet_attack}")
|
||||
print(f" 亲密度: {pet_intimacy}")
|
||||
print(" ---")
|
||||
|
||||
# 测试查找特定宠物
|
||||
target_pet_id = "pet_002"
|
||||
found_pet = None
|
||||
for pet in pet_bag:
|
||||
if pet.get("pet_id") == target_pet_id:
|
||||
found_pet = pet
|
||||
break
|
||||
|
||||
if found_pet:
|
||||
print(f"\n找到宠物 {target_pet_id}: {found_pet['pet_name']}")
|
||||
else:
|
||||
print(f"\n未找到宠物 {target_pet_id}")
|
||||
|
||||
# 测试统计信息
|
||||
total_pets = len(pet_bag)
|
||||
total_level = sum(pet.get("pet_level", 1) for pet in pet_bag)
|
||||
avg_level = total_level / total_pets if total_pets > 0 else 0
|
||||
total_intimacy = sum(pet.get("pet_intimacy", 0) for pet in pet_bag)
|
||||
avg_intimacy = total_intimacy / total_pets if total_pets > 0 else 0
|
||||
|
||||
print(f"\n统计信息:")
|
||||
print(f" 总宠物数: {total_pets}")
|
||||
print(f" 平均等级: {avg_level:.1f}")
|
||||
print(f" 平均亲密度: {avg_intimacy:.1f}")
|
||||
|
||||
print("✅ 宠物背包操作测试通过")
|
||||
|
||||
def main():
|
||||
"""主测试函数"""
|
||||
print("开始服务器宠物功能测试...\n")
|
||||
|
||||
try:
|
||||
# 测试宠物数据转换函数
|
||||
test_pet_data_conversion_functions()
|
||||
|
||||
# 测试宠物喂食系统
|
||||
test_pet_feeding_system()
|
||||
|
||||
# 测试宠物道具使用
|
||||
test_pet_item_usage()
|
||||
|
||||
# 测试宠物背包操作
|
||||
test_pet_bag_operations()
|
||||
|
||||
print("\n🎉 所有服务器宠物功能测试通过!")
|
||||
print("\n✅ 确认事项:")
|
||||
print(" - 宠物数据转换函数正常工作")
|
||||
print(" - 宠物喂食系统使用新的扁平化数据格式")
|
||||
print(" - 宠物道具使用系统正确访问宠物名称")
|
||||
print(" - 宠物背包遍历操作正常")
|
||||
print(" - 所有宠物相关功能已适配新数据格式")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ 测试失败: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
151
SproutFarm-Backend/test/test_special_farm.py
Normal file
151
SproutFarm-Backend/test/test_special_farm.py
Normal file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
特殊农场管理系统测试脚本
|
||||
作者: AI Assistant
|
||||
功能: 测试特殊农场的种植功能
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
from SpecialFarm import SpecialFarmManager
|
||||
|
||||
def test_special_farm():
|
||||
"""
|
||||
测试特殊农场功能
|
||||
"""
|
||||
print("=" * 50)
|
||||
print("特殊农场管理系统测试")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
# 创建管理器(使用测试环境)
|
||||
print("1. 初始化特殊农场管理器...")
|
||||
manager = SpecialFarmManager("test")
|
||||
print("✓ 管理器初始化成功")
|
||||
|
||||
# 测试数据库连接
|
||||
print("\n2. 测试数据库连接...")
|
||||
if manager.mongo_api.is_connected():
|
||||
print("✓ 数据库连接成功")
|
||||
else:
|
||||
print("✗ 数据库连接失败")
|
||||
return False
|
||||
|
||||
# 测试获取作物配置
|
||||
print("\n3. 测试获取作物配置...")
|
||||
crop_data = manager.get_crop_data()
|
||||
if crop_data:
|
||||
print(f"✓ 成功获取作物配置,共 {len(crop_data)} 种作物")
|
||||
|
||||
# 检查杂交树是否存在
|
||||
if "杂交树1" in crop_data and "杂交树2" in crop_data:
|
||||
print("✓ 杂交树1和杂交树2配置存在")
|
||||
print(f" - 杂交树1: {crop_data['杂交树1']['作物名称']}")
|
||||
print(f" - 杂交树2: {crop_data['杂交树2']['作物名称']}")
|
||||
else:
|
||||
print("✗ 杂交树配置不存在")
|
||||
return False
|
||||
else:
|
||||
print("✗ 获取作物配置失败")
|
||||
return False
|
||||
|
||||
# 测试获取杂交农场数据
|
||||
print("\n4. 测试获取杂交农场数据...")
|
||||
farm_config = manager.special_farms["杂交农场"]
|
||||
object_id = farm_config["object_id"]
|
||||
|
||||
player_data = manager.get_player_data_by_object_id(object_id)
|
||||
if player_data:
|
||||
print(f"✓ 成功获取杂交农场数据")
|
||||
print(f" - 农场名称: {player_data.get('农场名称', 'Unknown')}")
|
||||
print(f" - 玩家昵称: {player_data.get('玩家昵称', 'Unknown')}")
|
||||
print(f" - 土地数量: {len(player_data.get('农场土地', []))}")
|
||||
|
||||
# 统计土地状态
|
||||
farm_lands = player_data.get("农场土地", [])
|
||||
digged_count = sum(1 for land in farm_lands if land.get("is_diged", False))
|
||||
planted_count = sum(1 for land in farm_lands if land.get("is_planted", False))
|
||||
|
||||
print(f" - 已开垦土地: {digged_count}")
|
||||
print(f" - 已种植土地: {planted_count}")
|
||||
else:
|
||||
print("✗ 获取杂交农场数据失败")
|
||||
return False
|
||||
|
||||
# 测试种植功能
|
||||
print("\n5. 测试杂交农场种植功能...")
|
||||
if manager.plant_crops_in_farm("杂交农场"):
|
||||
print("✓ 杂交农场种植成功")
|
||||
|
||||
# 重新获取数据验证种植结果
|
||||
updated_data = manager.get_player_data_by_object_id(object_id)
|
||||
if updated_data:
|
||||
farm_lands = updated_data.get("农场土地", [])
|
||||
planted_count = sum(1 for land in farm_lands if land.get("is_planted", False))
|
||||
|
||||
# 统计种植的作物类型
|
||||
crop_types = {}
|
||||
for land in farm_lands:
|
||||
if land.get("is_planted", False):
|
||||
crop_type = land.get("crop_type", "")
|
||||
crop_types[crop_type] = crop_types.get(crop_type, 0) + 1
|
||||
|
||||
print(f" - 种植后已种植土地: {planted_count}")
|
||||
print(f" - 作物分布:")
|
||||
for crop_type, count in crop_types.items():
|
||||
print(f" * {crop_type}: {count} 块")
|
||||
else:
|
||||
print("✗ 杂交农场种植失败")
|
||||
return False
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("✓ 所有测试通过!特殊农场管理系统工作正常")
|
||||
print("=" * 50)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n✗ 测试过程中出错: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def test_manual_maintenance():
|
||||
"""
|
||||
测试手动维护功能
|
||||
"""
|
||||
print("\n" + "=" * 50)
|
||||
print("测试手动维护功能")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
manager = SpecialFarmManager("test")
|
||||
|
||||
print("执行手动维护...")
|
||||
if manager.manual_maintenance("杂交农场"):
|
||||
print("✓ 手动维护成功")
|
||||
else:
|
||||
print("✗ 手动维护失败")
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ 手动维护测试出错: {str(e)}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 运行基础测试
|
||||
success = test_special_farm()
|
||||
|
||||
if success:
|
||||
# 运行手动维护测试
|
||||
test_manual_maintenance()
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("使用说明:")
|
||||
print("1. 自动模式: python SpecialFarm.py [test|production]")
|
||||
print("2. 手动模式: python SpecialFarm.py [test|production] manual [农场名称]")
|
||||
print("3. 日志文件: special_farm.log")
|
||||
print("=" * 50)
|
||||
else:
|
||||
print("\n测试失败,请检查配置和数据库连接")
|
||||
sys.exit(1)
|
||||
143
SproutFarm-Backend/test/test_visit_mode_update.py
Normal file
143
SproutFarm-Backend/test/test_visit_mode_update.py
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
简化的访问模式实时更新功能测试
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
print("开始测试访问模式下的实时更新功能...")
|
||||
|
||||
try:
|
||||
# 测试导入
|
||||
print("正在导入模块...")
|
||||
|
||||
# 检查文件是否存在
|
||||
if os.path.exists('TCPGameServer.py'):
|
||||
print("✓ TCPGameServer.py 文件存在")
|
||||
else:
|
||||
print("❌ TCPGameServer.py 文件不存在")
|
||||
sys.exit(1)
|
||||
|
||||
if os.path.exists('SMYMongoDBAPI.py'):
|
||||
print("✓ SMYMongoDBAPI.py 文件存在")
|
||||
else:
|
||||
print("❌ SMYMongoDBAPI.py 文件不存在")
|
||||
sys.exit(1)
|
||||
|
||||
# 尝试导入
|
||||
from TCPGameServer import TCPGameServer
|
||||
print("✓ 成功导入 TCPGameServer")
|
||||
|
||||
# 检查关键方法是否存在
|
||||
server = TCPGameServer()
|
||||
|
||||
if hasattr(server, '_push_update_to_visitors'):
|
||||
print("✓ _push_update_to_visitors 方法存在")
|
||||
else:
|
||||
print("❌ _push_update_to_visitors 方法不存在")
|
||||
|
||||
if hasattr(server, 'update_crops_growth'):
|
||||
print("✓ update_crops_growth 方法存在")
|
||||
else:
|
||||
print("❌ update_crops_growth 方法不存在")
|
||||
|
||||
if hasattr(server, '_push_crop_update_to_player'):
|
||||
print("✓ _push_crop_update_to_player 方法存在")
|
||||
else:
|
||||
print("❌ _push_crop_update_to_player 方法不存在")
|
||||
|
||||
print("\n=== 功能验证 ===")
|
||||
|
||||
# 模拟用户数据
|
||||
server.user_data = {
|
||||
"client_a": {
|
||||
"logged_in": True,
|
||||
"username": "user_a",
|
||||
"visiting_mode": False,
|
||||
"visiting_target": ""
|
||||
},
|
||||
"client_b": {
|
||||
"logged_in": True,
|
||||
"username": "user_b",
|
||||
"visiting_mode": True,
|
||||
"visiting_target": "user_a"
|
||||
}
|
||||
}
|
||||
|
||||
# 测试 update_crops_growth 方法是否能正确收集需要更新的玩家
|
||||
print("测试作物生长更新逻辑...")
|
||||
|
||||
# 重写 load_player_data 方法以避免数据库依赖
|
||||
def mock_load_player_data(username):
|
||||
return {
|
||||
"农场土地": [
|
||||
{
|
||||
"is_planted": True,
|
||||
"crop_type": "番茄",
|
||||
"grow_time": 300,
|
||||
"max_grow_time": 600
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
def mock_save_player_data(username, data):
|
||||
pass
|
||||
|
||||
def mock_update_player_crops(data, username):
|
||||
return True
|
||||
|
||||
def mock_push_crop_update_to_player(username, data):
|
||||
print(f" 推送作物更新给: {username}")
|
||||
|
||||
server.load_player_data = mock_load_player_data
|
||||
server.save_player_data = mock_save_player_data
|
||||
server.update_player_crops = mock_update_player_crops
|
||||
server._push_crop_update_to_player = mock_push_crop_update_to_player
|
||||
|
||||
# 调用作物生长更新
|
||||
print("调用 update_crops_growth...")
|
||||
server.update_crops_growth()
|
||||
|
||||
print("\n=== 测试访问者推送功能 ===")
|
||||
|
||||
# 重写 send_data 方法
|
||||
def mock_send_data(client_id, data):
|
||||
print(f" 向 {client_id} 发送消息: {data.get('type', 'unknown')}")
|
||||
if data.get('type') == 'crop_update':
|
||||
print(f" - 是否访问模式: {data.get('is_visiting', False)}")
|
||||
print(f" - 被访问玩家: {data.get('visited_player', 'N/A')}")
|
||||
|
||||
def mock_find_client_by_username(username):
|
||||
if username == "user_a":
|
||||
return "client_a"
|
||||
return None
|
||||
|
||||
server.send_data = mock_send_data
|
||||
server._find_client_by_username = mock_find_client_by_username
|
||||
|
||||
# 测试向访问者推送更新
|
||||
target_player_data = {
|
||||
"农场土地": [
|
||||
{
|
||||
"is_planted": True,
|
||||
"crop_type": "番茄",
|
||||
"grow_time": 400,
|
||||
"max_grow_time": 600
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
print("调用 _push_update_to_visitors...")
|
||||
server._push_update_to_visitors("user_a", target_player_data)
|
||||
|
||||
print("\n🎉 所有功能验证通过!访问模式下的实时更新功能已正确实现。")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 测试过程中出现错误: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
print("\n测试完成!")
|
||||
52
SproutFarm-Backend/test/test_websocket.py
Normal file
52
SproutFarm-Backend/test/test_websocket.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试WebSocket远程命令API
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import websockets
|
||||
import json
|
||||
|
||||
async def test_client():
|
||||
"""测试WebSocket客户端"""
|
||||
uri = "ws://localhost:7071"
|
||||
|
||||
try:
|
||||
async with websockets.connect(uri) as websocket:
|
||||
print(f"✅ 已连接到 {uri}")
|
||||
|
||||
# 接收欢迎消息
|
||||
welcome_msg = await websocket.recv()
|
||||
print(f"收到欢迎消息: {welcome_msg}")
|
||||
|
||||
# 发送认证请求
|
||||
auth_data = {
|
||||
"type": "auth",
|
||||
"auth_key": "mengya2024"
|
||||
}
|
||||
await websocket.send(json.dumps(auth_data))
|
||||
print("已发送认证请求")
|
||||
|
||||
# 接收认证结果
|
||||
auth_result = await websocket.recv()
|
||||
print(f"认证结果: {auth_result}")
|
||||
|
||||
# 发送测试命令
|
||||
command_data = {
|
||||
"type": "command",
|
||||
"command": "help"
|
||||
}
|
||||
await websocket.send(json.dumps(command_data))
|
||||
print("已发送help命令")
|
||||
|
||||
# 接收命令结果
|
||||
command_result = await websocket.recv()
|
||||
print(f"命令结果: {command_result}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 连接失败: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("开始测试WebSocket连接...")
|
||||
asyncio.run(test_client())
|
||||
90
SproutFarm-Backend/test/文档/ConsoleCommandsAPI_README.md
Normal file
90
SproutFarm-Backend/test/文档/ConsoleCommandsAPI_README.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# 控制台命令API模块 (ConsoleCommandsAPI)
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 基础游戏管理命令
|
||||
- `/addmoney <QQ号> <数量>` - 为玩家添加金币
|
||||
- `/addxp <QQ号> <数量>` - 为玩家添加经验值
|
||||
- `/addlevel <QQ号> <数量>` - 为玩家添加等级
|
||||
- `/addseed <QQ号> <作物名称> <数量>` - 为玩家添加种子
|
||||
- `/lsplayer` - 列出所有在线玩家
|
||||
- `/playerinfo <QQ号>` - 查看玩家详细信息
|
||||
- `/resetland <QQ号>` - 重置玩家土地
|
||||
- `/weather <天气类型>` - 设置天气
|
||||
|
||||
### 系统管理命令
|
||||
- `/help` - 显示帮助信息
|
||||
- `/save` - 保存所有玩家数据
|
||||
- `/reload` - 重新加载配置文件
|
||||
- `/stop` - 停止服务器
|
||||
|
||||
### MongoDB数据库管理命令
|
||||
- `/dbtest` - 测试数据库连接
|
||||
- `/dbconfig <操作> [参数]` - 数据库配置管理
|
||||
- `list` - 列出所有配置类型
|
||||
- `get <配置类型>` - 获取指定配置
|
||||
- `reload <配置类型>` - 重新加载指定配置到服务器
|
||||
- `/dbchat <操作> [参数]` - 聊天消息管理
|
||||
- `latest` - 获取最新聊天消息
|
||||
- `history [天数] [数量]` - 获取聊天历史
|
||||
- `clean [保留天数]` - 清理旧聊天消息
|
||||
- `/dbclean <类型>` - 数据库清理
|
||||
- `codes` - 清理过期验证码
|
||||
- `chat [保留天数]` - 清理旧聊天消息
|
||||
- `all` - 清理所有过期数据
|
||||
- `/dbbackup [类型]` - 数据库备份
|
||||
- `config` - 备份游戏配置
|
||||
- `chat` - 备份聊天消息
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 导入模块
|
||||
```python
|
||||
from ConsoleCommandsAPI import ConsoleCommandsAPI
|
||||
```
|
||||
|
||||
### 2. 初始化
|
||||
```python
|
||||
# 在服务器初始化时创建控制台命令实例
|
||||
console = ConsoleCommandsAPI(server)
|
||||
```
|
||||
|
||||
### 3. 处理命令
|
||||
```python
|
||||
# 在控制台输入处理函数中
|
||||
command_line = input("服务器控制台> ")
|
||||
console.process_command(command_line)
|
||||
```
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 添加自定义命令
|
||||
```python
|
||||
# 添加新命令
|
||||
console.add_custom_command("mycommand", my_command_function, "我的自定义命令")
|
||||
|
||||
# 移除命令
|
||||
console.remove_command("mycommand")
|
||||
|
||||
# 获取命令信息
|
||||
info = console.get_command_info("addmoney")
|
||||
|
||||
# 批量执行命令
|
||||
commands = ["addmoney 123456 1000", "addxp 123456 500"]
|
||||
console.execute_batch_commands(commands)
|
||||
```
|
||||
|
||||
## 依赖项
|
||||
|
||||
- `SMYMongoDBAPI` - MongoDB数据库操作模块
|
||||
- `json` - JSON数据处理
|
||||
- `os` - 操作系统接口
|
||||
- `datetime` - 日期时间处理
|
||||
- `typing` - 类型提示
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **MongoDB集成**: 数据库相关命令需要服务器启用MongoDB支持
|
||||
2. **权限管理**: 所有命令都具有管理员权限,请谨慎使用
|
||||
3. **数据备份**: 建议定期使用 `/dbbackup` 命令备份重要数据
|
||||
4. **错误处理**: 所有命令都包含完善的错误处理和用户友好的提示信息
|
||||
559
SproutFarm-Backend/test/文档/DisplayServer_总结_Markdown.md
Normal file
559
SproutFarm-Backend/test/文档/DisplayServer_总结_Markdown.md
Normal file
@@ -0,0 +1,559 @@
|
||||
# DisplayServer API 参考文档
|
||||
|
||||
## 类简介
|
||||
|
||||
**继承**:Object
|
||||
|
||||
DisplayServer 是用于低阶窗口管理的服务器接口。所有与窗口管理相关的内容都由 DisplayServer(显示服务器)处理。
|
||||
|
||||
> **无头模式**:如果使用 `--headless` 命令行参数启动引擎,就会禁用所有渲染和窗口管理功能,此时 DisplayServer 的大多数函数都会返回虚设值。
|
||||
|
||||
---
|
||||
|
||||
## 方法列表
|
||||
|
||||
### 🔔 系统交互
|
||||
|
||||
#### `void beep()`
|
||||
发出系统提示音。
|
||||
|
||||
#### `void enable_for_stealing_focus(process_id: int)`
|
||||
允许指定进程获取焦点。
|
||||
|
||||
#### `void force_process_and_drop_events()`
|
||||
强制处理并丢弃所有事件。
|
||||
|
||||
---
|
||||
|
||||
### 📋 剪贴板操作
|
||||
|
||||
#### `String clipboard_get()`
|
||||
获取剪贴板文本内容。
|
||||
|
||||
#### `Image clipboard_get_image()`
|
||||
获取剪贴板图像内容。
|
||||
|
||||
#### `String clipboard_get_primary()`
|
||||
获取主剪贴板文本内容(仅限 Linux)。
|
||||
|
||||
#### `bool clipboard_has()`
|
||||
检查剪贴板是否有内容。
|
||||
|
||||
#### `bool clipboard_has_image()`
|
||||
检查剪贴板是否有图像。
|
||||
|
||||
#### `void clipboard_set(clipboard: String)`
|
||||
设置剪贴板文本内容。
|
||||
|
||||
#### `void clipboard_set_primary(clipboard_primary: String)`
|
||||
设置主剪贴板文本内容(仅限 Linux)。
|
||||
|
||||
---
|
||||
|
||||
### 🖱️ 鼠标和光标
|
||||
|
||||
#### `CursorShape cursor_get_shape()`
|
||||
获取当前光标形状。
|
||||
|
||||
#### `void cursor_set_custom_image(cursor: Resource, shape: CursorShape = 0, hotspot: Vector2 = Vector2(0, 0))`
|
||||
设置自定义光标图像。
|
||||
|
||||
#### `void cursor_set_shape(shape: CursorShape)`
|
||||
设置光标形状。
|
||||
|
||||
#### `BitField[MouseButtonMask] mouse_get_button_state()`
|
||||
获取鼠标按键状态。
|
||||
|
||||
#### `MouseMode mouse_get_mode()`
|
||||
获取鼠标模式。
|
||||
|
||||
#### `Vector2i mouse_get_position()`
|
||||
获取鼠标位置。
|
||||
|
||||
#### `void mouse_set_mode(mouse_mode: MouseMode)`
|
||||
设置鼠标模式。
|
||||
|
||||
#### `void warp_mouse(position: Vector2i)`
|
||||
将鼠标光标移动到指定位置。
|
||||
|
||||
---
|
||||
|
||||
### 💬 对话框
|
||||
|
||||
#### `Error dialog_input_text(title: String, description: String, existing_text: String, callback: Callable)`
|
||||
显示文本输入对话框。
|
||||
|
||||
#### `Error dialog_show(title: String, description: String, buttons: PackedStringArray, callback: Callable)`
|
||||
显示系统对话框。
|
||||
|
||||
#### `Error file_dialog_show(title: String, current_directory: String, filename: String, show_hidden: bool, mode: FileDialogMode, filters: PackedStringArray, callback: Callable)`
|
||||
显示文件选择对话框。
|
||||
|
||||
#### `Error file_dialog_with_options_show(title: String, current_directory: String, root: String, filename: String, show_hidden: bool, mode: FileDialogMode, filters: PackedStringArray, options: Array[Dictionary], callback: Callable)`
|
||||
显示带扩展选项的文件选择对话框。
|
||||
|
||||
---
|
||||
|
||||
### 🎨 主题和颜色
|
||||
|
||||
#### `Color get_accent_color()`
|
||||
获取系统强调色。
|
||||
|
||||
#### `Color get_base_color()`
|
||||
获取系统基础色。
|
||||
|
||||
#### `bool is_dark_mode()`
|
||||
检查系统是否为深色模式。
|
||||
|
||||
#### `bool is_dark_mode_supported()`
|
||||
检查系统是否支持深色模式。
|
||||
|
||||
#### `void set_system_theme_change_callback(callable: Callable)`
|
||||
设置系统主题变化时的回调。
|
||||
|
||||
---
|
||||
|
||||
### 📱 显示和屏幕
|
||||
|
||||
#### `Array[Rect2] get_display_cutouts()`
|
||||
获取显示器刘海信息。
|
||||
|
||||
#### `Rect2i get_display_safe_area()`
|
||||
获取显示器安全区域。
|
||||
|
||||
#### `int get_keyboard_focus_screen()`
|
||||
获取键盘焦点所在屏幕。
|
||||
|
||||
#### `String get_name()`
|
||||
获取显示服务器名称。
|
||||
|
||||
#### `int get_primary_screen()`
|
||||
获取主屏幕索引。
|
||||
|
||||
#### `int get_screen_count()`
|
||||
获取屏幕数量。
|
||||
|
||||
#### `int get_screen_from_rect(rect: Rect2)`
|
||||
根据矩形位置获取屏幕索引。
|
||||
|
||||
#### `bool get_swap_cancel_ok()`
|
||||
获取是否交换确定取消按钮。
|
||||
|
||||
#### `int get_window_at_screen_position(position: Vector2i)`
|
||||
获取指定屏幕位置的窗口ID。
|
||||
|
||||
#### `PackedInt32Array get_window_list()`
|
||||
获取所有窗口ID列表。
|
||||
|
||||
---
|
||||
|
||||
### 🖥️ 屏幕操作
|
||||
|
||||
#### `int screen_get_dpi(screen: int = -1)`
|
||||
获取屏幕DPI。
|
||||
|
||||
#### `Image screen_get_image(screen: int = -1)`
|
||||
获取屏幕截图。
|
||||
|
||||
#### `Image screen_get_image_rect(rect: Rect2i)`
|
||||
获取屏幕指定区域截图。
|
||||
|
||||
#### `float screen_get_max_scale()`
|
||||
获取所有屏幕的最大缩放系数。
|
||||
|
||||
#### `ScreenOrientation screen_get_orientation(screen: int = -1)`
|
||||
获取屏幕朝向。
|
||||
|
||||
#### `Color screen_get_pixel(position: Vector2i)`
|
||||
获取指定位置的像素颜色。
|
||||
|
||||
#### `Vector2i screen_get_position(screen: int = -1)`
|
||||
获取屏幕位置。
|
||||
|
||||
#### `float screen_get_refresh_rate(screen: int = -1)`
|
||||
获取屏幕刷新率。
|
||||
|
||||
#### `float screen_get_scale(screen: int = -1)`
|
||||
获取屏幕缩放系数。
|
||||
|
||||
#### `Vector2i screen_get_size(screen: int = -1)`
|
||||
获取屏幕大小。
|
||||
|
||||
#### `Rect2i screen_get_usable_rect(screen: int = -1)`
|
||||
获取屏幕可用区域。
|
||||
|
||||
#### `bool screen_is_kept_on()`
|
||||
检查屏幕是否保持开启。
|
||||
|
||||
#### `void screen_set_keep_on(enable: bool)`
|
||||
设置屏幕保持开启。
|
||||
|
||||
#### `void screen_set_orientation(orientation: ScreenOrientation, screen: int = -1)`
|
||||
设置屏幕朝向。
|
||||
|
||||
---
|
||||
|
||||
### 🖼️ 图标设置
|
||||
|
||||
#### `void set_icon(image: Image)`
|
||||
设置窗口图标。
|
||||
|
||||
#### `void set_native_icon(filename: String)`
|
||||
使用原生格式设置窗口图标。
|
||||
|
||||
---
|
||||
|
||||
### 💾 输出管理
|
||||
|
||||
#### `bool has_additional_outputs()`
|
||||
检查是否有额外输出设备。
|
||||
|
||||
#### `void register_additional_output(object: Object)`
|
||||
注册额外输出设备。
|
||||
|
||||
#### `void unregister_additional_output(object: Object)`
|
||||
取消注册额外输出设备。
|
||||
|
||||
---
|
||||
|
||||
### ⚡ 功能检测
|
||||
|
||||
#### `bool has_feature(feature: Feature)`
|
||||
检查是否支持指定功能。
|
||||
|
||||
#### `bool has_hardware_keyboard()`
|
||||
检查是否有硬件键盘。
|
||||
|
||||
#### `bool is_touchscreen_available()`
|
||||
检查是否支持触屏。
|
||||
|
||||
#### `bool is_window_transparency_available()`
|
||||
检查是否支持窗口透明。
|
||||
|
||||
---
|
||||
|
||||
### ⌨️ 键盘
|
||||
|
||||
#### `int keyboard_get_current_layout()`
|
||||
获取当前键盘布局。
|
||||
|
||||
#### `Key keyboard_get_keycode_from_physical(keycode: Key)`
|
||||
从物理按键获取键码。
|
||||
|
||||
#### `Key keyboard_get_label_from_physical(keycode: Key)`
|
||||
从物理按键获取标签。
|
||||
|
||||
#### `int keyboard_get_layout_count()`
|
||||
获取键盘布局数量。
|
||||
|
||||
#### `String keyboard_get_layout_language(index: int)`
|
||||
获取键盘布局语言。
|
||||
|
||||
#### `String keyboard_get_layout_name(index: int)`
|
||||
获取键盘布局名称。
|
||||
|
||||
#### `void keyboard_set_current_layout(index: int)`
|
||||
设置当前键盘布局。
|
||||
|
||||
---
|
||||
|
||||
### 📝 输入法
|
||||
|
||||
#### `Vector2i ime_get_selection()`
|
||||
获取输入法选中范围。
|
||||
|
||||
#### `String ime_get_text()`
|
||||
获取输入法文本。
|
||||
|
||||
---
|
||||
|
||||
### 🎯 状态指示器
|
||||
|
||||
#### `int create_status_indicator(icon: Texture2D, tooltip: String, callback: Callable)`
|
||||
创建状态指示器。
|
||||
|
||||
#### `void delete_status_indicator(id: int)`
|
||||
删除状态指示器。
|
||||
|
||||
#### `Rect2 status_indicator_get_rect(id: int)`
|
||||
获取状态指示器位置。
|
||||
|
||||
#### `void status_indicator_set_callback(id: int, callback: Callable)`
|
||||
设置状态指示器回调。
|
||||
|
||||
#### `void status_indicator_set_icon(id: int, icon: Texture2D)`
|
||||
设置状态指示器图标。
|
||||
|
||||
#### `void status_indicator_set_menu(id: int, menu_rid: RID)`
|
||||
设置状态指示器菜单。
|
||||
|
||||
#### `void status_indicator_set_tooltip(id: int, tooltip: String)`
|
||||
设置状态指示器提示文本。
|
||||
|
||||
---
|
||||
|
||||
### 📱 数位板
|
||||
|
||||
#### `String tablet_get_current_driver()`
|
||||
获取当前数位板驱动。
|
||||
|
||||
#### `int tablet_get_driver_count()`
|
||||
获取数位板驱动数量。
|
||||
|
||||
#### `String tablet_get_driver_name(idx: int)`
|
||||
获取数位板驱动名称。
|
||||
|
||||
#### `void tablet_set_current_driver(name: String)`
|
||||
设置数位板驱动。
|
||||
|
||||
---
|
||||
|
||||
### 🗣️ 文本转语音
|
||||
|
||||
#### `Array[Dictionary] tts_get_voices()`
|
||||
获取语音列表。
|
||||
|
||||
#### `PackedStringArray tts_get_voices_for_language(language: String)`
|
||||
获取指定语言的语音列表。
|
||||
|
||||
#### `bool tts_is_paused()`
|
||||
检查是否暂停。
|
||||
|
||||
#### `bool tts_is_speaking()`
|
||||
检查是否正在朗读。
|
||||
|
||||
#### `void tts_pause()`
|
||||
暂停朗读。
|
||||
|
||||
#### `void tts_resume()`
|
||||
恢复朗读。
|
||||
|
||||
#### `void tts_set_utterance_callback(event: TTSUtteranceEvent, callable: Callable)`
|
||||
设置朗读事件回调。
|
||||
|
||||
#### `void tts_speak(text: String, voice: String, volume: int = 50, pitch: float = 1.0, rate: float = 1.0, utterance_id: int = 0, interrupt: bool = false)`
|
||||
开始朗读文本。
|
||||
|
||||
#### `void tts_stop()`
|
||||
停止朗读。
|
||||
|
||||
---
|
||||
|
||||
### ⌨️ 虚拟键盘
|
||||
|
||||
#### `int virtual_keyboard_get_height()`
|
||||
获取虚拟键盘高度。
|
||||
|
||||
#### `void virtual_keyboard_hide()`
|
||||
隐藏虚拟键盘。
|
||||
|
||||
#### `void virtual_keyboard_show(existing_text: String, position: Rect2 = Rect2(0, 0, 0, 0), type: VirtualKeyboardType = 0, max_length: int = -1, cursor_start: int = -1, cursor_end: int = -1)`
|
||||
显示虚拟键盘。
|
||||
|
||||
---
|
||||
|
||||
### 🪟 窗口管理
|
||||
|
||||
#### `bool window_can_draw(window_id: int = 0)`
|
||||
检查窗口是否可绘制。
|
||||
|
||||
#### `int window_get_active_popup()`
|
||||
获取活动弹出窗口ID。
|
||||
|
||||
#### `int window_get_attached_instance_id(window_id: int = 0)`
|
||||
获取窗口附加的实例ID。
|
||||
|
||||
#### `int window_get_current_screen(window_id: int = 0)`
|
||||
获取窗口所在屏幕。
|
||||
|
||||
#### `bool window_get_flag(flag: WindowFlags, window_id: int = 0)`
|
||||
获取窗口标志。
|
||||
|
||||
#### `Vector2i window_get_max_size(window_id: int = 0)`
|
||||
获取窗口最大尺寸。
|
||||
|
||||
#### `Vector2i window_get_min_size(window_id: int = 0)`
|
||||
获取窗口最小尺寸。
|
||||
|
||||
#### `WindowMode window_get_mode(window_id: int = 0)`
|
||||
获取窗口模式。
|
||||
|
||||
#### `int window_get_native_handle(handle_type: HandleType, window_id: int = 0)`
|
||||
获取窗口原生句柄。
|
||||
|
||||
#### `Rect2i window_get_popup_safe_rect(window: int)`
|
||||
获取弹出窗口安全区域。
|
||||
|
||||
#### `Vector2i window_get_position(window_id: int = 0)`
|
||||
获取窗口位置。
|
||||
|
||||
#### `Vector2i window_get_position_with_decorations(window_id: int = 0)`
|
||||
获取窗口位置(含边框)。
|
||||
|
||||
#### `Vector3i window_get_safe_title_margins(window_id: int = 0)`
|
||||
获取标题栏安全边距。
|
||||
|
||||
#### `Vector2i window_get_size(window_id: int = 0)`
|
||||
获取窗口大小。
|
||||
|
||||
#### `Vector2i window_get_size_with_decorations(window_id: int = 0)`
|
||||
获取窗口大小(含边框)。
|
||||
|
||||
#### `Vector2i window_get_title_size(title: String, window_id: int = 0)`
|
||||
获取标题栏大小。
|
||||
|
||||
#### `VSyncMode window_get_vsync_mode(window_id: int = 0)`
|
||||
获取垂直同步模式。
|
||||
|
||||
#### `bool window_is_focused(window_id: int = 0)`
|
||||
检查窗口是否有焦点。
|
||||
|
||||
#### `bool window_is_maximize_allowed(window_id: int = 0)`
|
||||
检查窗口是否可最大化。
|
||||
|
||||
#### `bool window_maximize_on_title_dbl_click()`
|
||||
检查双击标题栏是否最大化。
|
||||
|
||||
#### `bool window_minimize_on_title_dbl_click()`
|
||||
检查双击标题栏是否最小化。
|
||||
|
||||
#### `void window_move_to_foreground(window_id: int = 0)`
|
||||
将窗口移到前台。
|
||||
|
||||
#### `void window_request_attention(window_id: int = 0)`
|
||||
请求窗口注意。
|
||||
|
||||
#### `void window_set_current_screen(screen: int, window_id: int = 0)`
|
||||
设置窗口所在屏幕。
|
||||
|
||||
#### `void window_set_drop_files_callback(callback: Callable, window_id: int = 0)`
|
||||
设置文件拖放回调。
|
||||
|
||||
#### `void window_set_exclusive(window_id: int, exclusive: bool)`
|
||||
设置窗口独占模式。
|
||||
|
||||
#### `void window_set_flag(flag: WindowFlags, enabled: bool, window_id: int = 0)`
|
||||
设置窗口标志。
|
||||
|
||||
#### `void window_set_ime_active(active: bool, window_id: int = 0)`
|
||||
设置输入法是否激活。
|
||||
|
||||
#### `void window_set_ime_position(position: Vector2i, window_id: int = 0)`
|
||||
设置输入法位置。
|
||||
|
||||
#### `void window_set_input_event_callback(callback: Callable, window_id: int = 0)`
|
||||
设置输入事件回调。
|
||||
|
||||
#### `void window_set_input_text_callback(callback: Callable, window_id: int = 0)`
|
||||
设置文本输入回调。
|
||||
|
||||
#### `void window_set_max_size(max_size: Vector2i, window_id: int = 0)`
|
||||
设置窗口最大尺寸。
|
||||
|
||||
#### `void window_set_min_size(min_size: Vector2i, window_id: int = 0)`
|
||||
设置窗口最小尺寸。
|
||||
|
||||
#### `void window_set_mode(mode: WindowMode, window_id: int = 0)`
|
||||
设置窗口模式。
|
||||
|
||||
#### `void window_set_mouse_passthrough(region: PackedVector2Array, window_id: int = 0)`
|
||||
设置鼠标穿透区域。
|
||||
|
||||
#### `void window_set_popup_safe_rect(window: int, rect: Rect2i)`
|
||||
设置弹出窗口安全区域。
|
||||
|
||||
#### `void window_set_position(position: Vector2i, window_id: int = 0)`
|
||||
设置窗口位置。
|
||||
|
||||
#### `void window_set_rect_changed_callback(callback: Callable, window_id: int = 0)`
|
||||
设置窗口位置大小变化回调。
|
||||
|
||||
#### `void window_set_size(size: Vector2i, window_id: int = 0)`
|
||||
设置窗口大小。
|
||||
|
||||
#### `void window_set_title(title: String, window_id: int = 0)`
|
||||
设置窗口标题。
|
||||
|
||||
#### `void window_set_transient(window_id: int, parent_window_id: int)`
|
||||
设置窗口为瞬态。
|
||||
|
||||
#### `void window_set_vsync_mode(vsync_mode: VSyncMode, window_id: int = 0)`
|
||||
设置垂直同步模式。
|
||||
|
||||
#### `void window_set_window_buttons_offset(offset: Vector2i, window_id: int = 0)`
|
||||
设置窗口按钮偏移。
|
||||
|
||||
#### `void window_set_window_event_callback(callback: Callable, window_id: int = 0)`
|
||||
设置窗口事件回调。
|
||||
|
||||
#### `void window_start_drag(window_id: int = 0)`
|
||||
开始拖拽窗口。
|
||||
|
||||
#### `void window_start_resize(edge: WindowResizeEdge, window_id: int = 0)`
|
||||
开始调整窗口大小。
|
||||
|
||||
---
|
||||
|
||||
### 📞 帮助系统
|
||||
|
||||
#### `void help_set_search_callbacks(search_callback: Callable, action_callback: Callable)`
|
||||
设置帮助系统搜索回调。
|
||||
|
||||
#### `void show_emoji_and_symbol_picker()`
|
||||
显示表情符号选择器。
|
||||
|
||||
---
|
||||
|
||||
### ⚙️ 事件处理
|
||||
|
||||
#### `void process_events()`
|
||||
处理事件。
|
||||
|
||||
---
|
||||
|
||||
## 常量
|
||||
|
||||
- `SCREEN_WITH_MOUSE_FOCUS = -4`:鼠标焦点所在屏幕
|
||||
- `SCREEN_WITH_KEYBOARD_FOCUS = -3`:键盘焦点所在屏幕
|
||||
- `SCREEN_PRIMARY = -2`:主屏幕
|
||||
- `SCREEN_OF_MAIN_WINDOW = -1`:主窗口所在屏幕
|
||||
- `MAIN_WINDOW_ID = 0`:主窗口ID
|
||||
- `INVALID_WINDOW_ID = -1`:无效窗口ID
|
||||
|
||||
---
|
||||
|
||||
## 枚举
|
||||
|
||||
### Feature
|
||||
系统功能支持检测枚举,包含多种功能如子窗口、触屏、鼠标、剪贴板、虚拟键盘等支持检测。
|
||||
|
||||
### MouseMode
|
||||
鼠标模式枚举:可见、隐藏、捕获、限制等模式。
|
||||
|
||||
### ScreenOrientation
|
||||
屏幕朝向枚举:横屏、竖屏及其反向,以及传感器自动模式。
|
||||
|
||||
### VirtualKeyboardType
|
||||
虚拟键盘类型:默认、多行、数字、小数、电话、邮箱、密码、URL等。
|
||||
|
||||
### CursorShape
|
||||
光标形状枚举:箭头、工字形、指向手形等多种光标样式。
|
||||
|
||||
### WindowFlags
|
||||
窗口标志枚举:控制窗口的各种行为和外观属性。
|
||||
|
||||
### WindowMode
|
||||
窗口模式枚举:窗口、最小化、最大化、全屏等模式。
|
||||
|
||||
### HandleType
|
||||
句柄类型枚举:用于获取不同类型的原生窗口句柄。
|
||||
|
||||
### VSyncMode
|
||||
垂直同步模式枚举:控制画面撕裂和帧率同步。
|
||||
|
||||
### TTSUtteranceEvent
|
||||
语音朗读事件枚举:开始、结束、取消、边界等事件。
|
||||
|
||||
---
|
||||
|
||||
> **注意**:此文档已排除所有已弃用的方法。某些功能可能仅在特定平台上可用,请参考原始文档中的平台支持说明。
|
||||
2120
SproutFarm-Backend/test/文档/display总结.txt
Normal file
2120
SproutFarm-Backend/test/文档/display总结.txt
Normal file
File diff suppressed because one or more lines are too long
144
SproutFarm-Backend/test/文档/游戏小提示配置系统说明.md
Normal file
144
SproutFarm-Backend/test/文档/游戏小提示配置系统说明.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# 游戏小提示配置系统实现说明
|
||||
|
||||
## 概述
|
||||
|
||||
本系统成功将游戏小提示配置从客户端硬编码迁移到服务端数据库管理,实现了动态配置和灵活的显示模式。
|
||||
|
||||
## 系统架构
|
||||
|
||||
### 1. 数据库层 (MongoDB)
|
||||
- **配置ID**: `687e40008e77ba00a7414bb2`
|
||||
- **集合**: `gameconfig`
|
||||
- **配置结构**:
|
||||
```json
|
||||
{
|
||||
"切换模式": "顺序", // 可选:顺序、随机、倒序
|
||||
"切换速度": 5, // 切换间隔(秒)
|
||||
"游戏小提示": [ // 小提示内容数组
|
||||
"按住wsad可以移动游戏画面",
|
||||
"使用鼠标滚轮来缩放游戏画面",
|
||||
// ... 更多小提示
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 服务端层 (Python)
|
||||
|
||||
#### SMYMongoDBAPI.py 新增功能
|
||||
- `get_game_tips_config()`: 获取游戏小提示配置
|
||||
- `update_game_tips_config()`: 更新游戏小提示配置
|
||||
- 配置ID: `CONFIG_IDS["game_tips"]`
|
||||
|
||||
#### TCPGameServer.py 新增功能
|
||||
- `_load_game_tips_config()`: 从数据库加载配置
|
||||
- `_handle_game_tips_config_request()`: 处理客户端配置请求
|
||||
- 消息路由: `request_game_tips_config` → `_handle_game_tips_config_request`
|
||||
|
||||
### 3. 客户端层 (GDScript)
|
||||
|
||||
#### TCPNetworkManager.gd 新增功能
|
||||
- `sendGetGameTipsConfig()`: 发送配置请求
|
||||
- 消息处理: `game_tips_config_response` → `main_game._handle_game_tips_config_response`
|
||||
|
||||
#### MainGame.gd 新增功能
|
||||
- `game_tips_config`: 存储服务端配置
|
||||
- `current_tip_index`: 顺序/倒序模式的索引
|
||||
- `_handle_game_tips_config_response()`: 处理服务端响应
|
||||
- `_random_small_game_tips()`: 重构为支持多种切换模式
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 1. 切换模式
|
||||
- **顺序模式**: 按配置顺序依次显示小提示
|
||||
- **倒序模式**: 按配置倒序依次显示小提示
|
||||
- **随机模式**: 随机选择小提示显示
|
||||
|
||||
### 2. 动态配置
|
||||
- 服务端可随时更新小提示内容
|
||||
- 客户端启动时自动获取最新配置
|
||||
- 支持热更新(无需重启游戏)
|
||||
|
||||
### 3. 容错机制
|
||||
- 服务端配置不可用时使用本地默认配置
|
||||
- 配置为空时显示默认欢迎信息
|
||||
- 网络异常时优雅降级
|
||||
|
||||
## 部署文件
|
||||
|
||||
### 1. 配置导入脚本
|
||||
- `import_game_tips_config.py`: 将配置数据导入MongoDB
|
||||
- 包含15条游戏小提示
|
||||
- 默认配置:顺序模式,5秒切换间隔
|
||||
|
||||
### 2. 测试脚本
|
||||
- `test_game_tips_config.py`: 基础功能测试
|
||||
- `test_complete_game_tips_system.py`: 完整系统测试
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 初始化配置
|
||||
```bash
|
||||
cd Server
|
||||
python import_game_tips_config.py
|
||||
```
|
||||
|
||||
### 2. 测试系统
|
||||
```bash
|
||||
python test_game_tips_config.py
|
||||
```
|
||||
|
||||
### 3. 客户端集成
|
||||
游戏启动时会自动请求服务端配置:
|
||||
```gdscript
|
||||
# 在MainGame.gd中已集成
|
||||
tcp_network_manager_panel.sendGetGameTipsConfig()
|
||||
```
|
||||
|
||||
## 配置管理
|
||||
|
||||
### 1. 查看当前配置
|
||||
```python
|
||||
from SMYMongoDBAPI import SMYMongoDBAPI
|
||||
api = SMYMongoDBAPI()
|
||||
api.connect()
|
||||
config = api.get_game_tips_config()
|
||||
print(config)
|
||||
```
|
||||
|
||||
### 2. 更新配置
|
||||
```python
|
||||
new_config = {
|
||||
"切换模式": "随机",
|
||||
"切换速度": 3,
|
||||
"游戏小提示": ["新的小提示1", "新的小提示2"]
|
||||
}
|
||||
api.update_game_tips_config(new_config)
|
||||
```
|
||||
|
||||
## 测试结果
|
||||
|
||||
✅ **数据库操作测试**: 通过
|
||||
✅ **服务器加载测试**: 通过
|
||||
✅ **配置导入功能**: 通过
|
||||
✅ **客户端集成**: 完成
|
||||
|
||||
## 技术优势
|
||||
|
||||
1. **集中管理**: 所有小提示内容统一在服务端管理
|
||||
2. **动态更新**: 无需客户端更新即可修改小提示
|
||||
3. **灵活配置**: 支持多种显示模式和自定义切换速度
|
||||
4. **高可用性**: 完善的容错机制确保系统稳定性
|
||||
5. **易于维护**: 清晰的代码结构和完整的测试覆盖
|
||||
|
||||
## 后续扩展
|
||||
|
||||
1. **多语言支持**: 可扩展为支持多语言的小提示
|
||||
2. **个性化配置**: 可为不同用户群体配置不同的小提示
|
||||
3. **统计分析**: 可添加小提示显示统计和用户反馈
|
||||
4. **管理界面**: 可开发Web管理界面方便运营人员管理
|
||||
|
||||
---
|
||||
|
||||
**实现完成时间**: 2024年12月
|
||||
**版本**: 1.0
|
||||
**状态**: 已完成并测试通过
|
||||
218
SproutFarm-Backend/test/文档/特殊农场管理系统说明.md
Normal file
218
SproutFarm-Backend/test/文档/特殊农场管理系统说明.md
Normal file
@@ -0,0 +1,218 @@
|
||||
# 特殊农场管理系统
|
||||
|
||||
## 概述
|
||||
|
||||
特殊农场管理系统是一个自动化的农场维护工具,用于管理游戏中的特殊农场,为玩家提供特殊的不可购买作物。系统支持定时任务和手动维护两种模式。
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 1. 自动定时维护
|
||||
- **执行时间**: 每天凌晨0点自动执行
|
||||
- **维护内容**: 为特殊农场种植指定的作物
|
||||
- **日志记录**: 详细记录维护过程和结果
|
||||
|
||||
### 2. 手动维护模式
|
||||
- 支持即时手动维护指定农场
|
||||
- 可用于测试和紧急维护
|
||||
|
||||
### 3. 多环境支持
|
||||
- **测试环境**: 用于开发和测试
|
||||
- **生产环境**: 用于正式运行
|
||||
|
||||
## 当前支持的特殊农场
|
||||
|
||||
### 杂交农场
|
||||
- **农场ID**: `689b4b9286cf953f2f4e56ee`
|
||||
- **种植作物**: 0号杂交树、1号杂交树
|
||||
- **种植方式**: 随机全屏种植
|
||||
- **土地要求**: 仅在已开垦的土地上种植
|
||||
- **作物状态**: 自动设置为已浇水、已施肥、立即成熟
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 方法一:使用启动脚本(推荐)
|
||||
```bash
|
||||
# Windows
|
||||
start_special_farm.bat
|
||||
|
||||
# 然后选择运行模式:
|
||||
# 1. 测试环境
|
||||
# 2. 生产环境
|
||||
# 3. 手动维护模式
|
||||
```
|
||||
|
||||
### 方法二:直接命令行
|
||||
|
||||
#### 自动模式(定时任务)
|
||||
```bash
|
||||
# 测试环境
|
||||
python SpecialFarm.py test
|
||||
|
||||
# 生产环境
|
||||
python SpecialFarm.py production
|
||||
```
|
||||
|
||||
#### 手动维护模式
|
||||
```bash
|
||||
# 手动维护杂交农场(测试环境)
|
||||
python SpecialFarm.py test manual 杂交农场
|
||||
|
||||
# 手动维护杂交农场(生产环境)
|
||||
python SpecialFarm.py production manual 杂交农场
|
||||
```
|
||||
|
||||
### 方法三:运行测试
|
||||
```bash
|
||||
# 运行完整测试
|
||||
python test_special_farm.py
|
||||
```
|
||||
|
||||
## 系统架构
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **SpecialFarmManager**: 主管理类
|
||||
- 负责农场配置管理
|
||||
- 处理定时任务调度
|
||||
- 执行种植逻辑
|
||||
|
||||
2. **MongoDB集成**:
|
||||
- 使用 `SMYMongoDBAPI` 进行数据库操作
|
||||
- 支持玩家数据和作物配置的读写
|
||||
|
||||
3. **定时任务**:
|
||||
- 使用 `schedule` 库实现定时功能
|
||||
- 支持每日凌晨0点自动执行
|
||||
|
||||
### 数据结构
|
||||
|
||||
#### 农场配置
|
||||
```python
|
||||
special_farms = {
|
||||
"杂交农场": {
|
||||
"object_id": "689b4b9286cf953f2f4e56ee",
|
||||
"crop_types": ["杂交树1", "杂交树2"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 作物种植逻辑
|
||||
- 随机选择配置的作物类型
|
||||
- 仅在已开垦(`is_diged=True`)的土地上种植
|
||||
- 自动设置作物状态:
|
||||
- `is_planted=True`
|
||||
- `is_watered=True`
|
||||
- `is_fertilized=True`
|
||||
- `growth_time=0`(立即成熟)
|
||||
|
||||
## 日志系统
|
||||
|
||||
### 日志文件
|
||||
- **文件名**: `special_farm.log`
|
||||
- **位置**: 与脚本同目录
|
||||
- **格式**: `时间 - 级别 - 模块 - 消息`
|
||||
|
||||
### 日志级别
|
||||
- **INFO**: 正常操作信息
|
||||
- **WARNING**: 警告信息
|
||||
- **ERROR**: 错误信息
|
||||
|
||||
### 示例日志
|
||||
```
|
||||
2024-01-15 00:00:01,123 - INFO - __main__ - 开始执行每日特殊农场维护任务...
|
||||
2024-01-15 00:00:02,456 - INFO - __main__ - 成功为 杂交农场 种植了 40 块土地的作物
|
||||
2024-01-15 00:00:02,789 - INFO - __main__ - 每日维护任务完成: 1/1 个农场维护成功
|
||||
```
|
||||
|
||||
## 依赖要求
|
||||
|
||||
### Python包
|
||||
```
|
||||
schedule>=1.2.0
|
||||
pymongo>=4.0.0
|
||||
```
|
||||
|
||||
### 系统要求
|
||||
- Python 3.7+
|
||||
- MongoDB数据库连接
|
||||
- 有效的游戏数据库配置
|
||||
|
||||
## 扩展指南
|
||||
|
||||
### 添加新的特殊农场
|
||||
|
||||
1. **在数据库中创建农场数据**
|
||||
- 在 `playerdata` 集合中添加新的农场文档
|
||||
- 记录文档的 `ObjectId`
|
||||
|
||||
2. **更新农场配置**
|
||||
```python
|
||||
# 在 SpecialFarm.py 中的 special_farms 字典添加
|
||||
"新农场名称": {
|
||||
"object_id": "新农场的ObjectId",
|
||||
"crop_types": ["作物类型1", "作物类型2"]
|
||||
}
|
||||
```
|
||||
|
||||
3. **测试新农场**
|
||||
```bash
|
||||
python SpecialFarm.py test manual 新农场名称
|
||||
```
|
||||
|
||||
### 自定义种植逻辑
|
||||
|
||||
可以在 `plant_crops_in_farm` 方法中修改种植逻辑:
|
||||
- 改变作物选择算法
|
||||
- 调整作物生长参数
|
||||
- 添加特殊种植条件
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **数据库连接失败**
|
||||
- 检查MongoDB服务是否运行
|
||||
- 验证数据库连接配置
|
||||
|
||||
2. **农场数据不存在**
|
||||
- 确认农场ObjectId是否正确
|
||||
- 检查数据库中是否存在对应文档
|
||||
|
||||
3. **作物配置错误**
|
||||
- 验证作物类型名称是否正确
|
||||
- 检查作物配置数据是否完整
|
||||
|
||||
### 调试模式
|
||||
|
||||
运行测试脚本获取详细信息:
|
||||
```bash
|
||||
python test_special_farm.py
|
||||
```
|
||||
|
||||
## 安全注意事项
|
||||
|
||||
1. **生产环境使用**
|
||||
- 确保在生产环境中使用正确的数据库配置
|
||||
- 定期备份重要数据
|
||||
|
||||
2. **权限管理**
|
||||
- 确保脚本有足够的数据库读写权限
|
||||
- 限制对生产数据库的访问
|
||||
|
||||
3. **监控和告警**
|
||||
- 定期检查日志文件
|
||||
- 设置维护任务失败的告警机制
|
||||
|
||||
## 版本历史
|
||||
|
||||
- **v1.0.0**: 初始版本,支持杂交农场的自动维护
|
||||
- 实现定时任务功能
|
||||
- 支持手动维护模式
|
||||
- 完整的日志系统
|
||||
- 测试和生产环境分离
|
||||
|
||||
---
|
||||
|
||||
**作者**: AI Assistant
|
||||
**创建时间**: 2024年
|
||||
**最后更新**: 2024年
|
||||
199
SproutFarm-Backend/test/文档/特殊农场系统优化说明.md
Normal file
199
SproutFarm-Backend/test/文档/特殊农场系统优化说明.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# 特殊农场系统优化说明
|
||||
|
||||
## 概述
|
||||
|
||||
特殊农场系统已经过全面优化,解决了服务器重启时间重置和性能问题。现在系统更加稳定、高效,不会影响游戏服务器的正常运行。
|
||||
|
||||
## 主要优化内容
|
||||
|
||||
### 1. 解决服务器重启时间重置问题
|
||||
|
||||
**问题**: 之前每次服务器重启都会立即执行维护任务,导致重复种植。
|
||||
|
||||
**解决方案**:
|
||||
- 添加维护时间记录功能
|
||||
- 服务器启动时检查当日是否已执行维护
|
||||
- 只有当天未维护过才会执行维护任务
|
||||
- 确保每天只执行一次维护,无论服务器重启多少次
|
||||
|
||||
### 2. 性能优化
|
||||
|
||||
**CPU使用优化**:
|
||||
- 调度器检查间隔从1分钟优化到5分钟
|
||||
- 减少不必要的CPU占用
|
||||
- 后台线程使用守护模式,不阻塞主进程
|
||||
|
||||
**内存管理优化**:
|
||||
- 改进资源清理机制
|
||||
- 服务器停止时正确释放特殊农场系统资源
|
||||
- 避免内存泄漏
|
||||
|
||||
### 3. 稳定性改进
|
||||
|
||||
**错误处理**:
|
||||
- 增强异常处理机制
|
||||
- 添加详细的日志记录
|
||||
- 系统出错时自动恢复
|
||||
|
||||
**资源管理**:
|
||||
- 正确的启动和停止流程
|
||||
- 线程安全的操作
|
||||
- 避免资源竞争
|
||||
|
||||
## 系统工作原理
|
||||
|
||||
### 定时任务调度
|
||||
|
||||
```
|
||||
启动服务器 → 初始化特殊农场管理器 → 检查当日维护状态
|
||||
↓
|
||||
如果未维护 → 执行维护任务 → 记录维护时间
|
||||
↓
|
||||
如果已维护 → 跳过维护任务
|
||||
↓
|
||||
启动后台调度器 → 每天凌晨0点自动维护
|
||||
```
|
||||
|
||||
### 维护任务内容
|
||||
|
||||
1. **土地开垦**: 确保所有土地都处于已开垦状态
|
||||
2. **作物种植**: 随机种植杂交树1或杂交树2
|
||||
3. **状态设置**: 设置作物为立即成熟状态
|
||||
4. **记录更新**: 更新维护时间记录
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 正常启动
|
||||
|
||||
特殊农场系统已集成到游戏服务器中,无需单独启动:
|
||||
|
||||
```bash
|
||||
cd Server
|
||||
python TCPGameServer.py
|
||||
```
|
||||
|
||||
### 手动维护
|
||||
|
||||
如果需要手动执行维护任务:
|
||||
|
||||
```bash
|
||||
# 维护所有特殊农场
|
||||
python SpecialFarm.py test manual
|
||||
|
||||
# 维护指定农场
|
||||
python SpecialFarm.py test manual 杂交农场
|
||||
```
|
||||
|
||||
### 性能监控
|
||||
|
||||
使用性能监控工具检查系统资源使用:
|
||||
|
||||
```bash
|
||||
python monitor_special_farm.py
|
||||
```
|
||||
|
||||
### 测试优化效果
|
||||
|
||||
运行测试脚本验证优化效果:
|
||||
|
||||
```bash
|
||||
python test_special_farm_optimization.py
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 特殊农场配置
|
||||
|
||||
在 `SpecialFarm.py` 中的 `special_farms` 字典:
|
||||
|
||||
```python
|
||||
self.special_farms = {
|
||||
"杂交农场": {
|
||||
"object_id": "689b4b9286cf953f2f4e56ee",
|
||||
"crops": ["杂交树1", "杂交树2"],
|
||||
"description": "专门种植杂交树的特殊农场"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 调度器配置
|
||||
|
||||
- **维护时间**: 每天凌晨0点
|
||||
- **检查间隔**: 5分钟
|
||||
- **运行模式**: 后台守护线程
|
||||
|
||||
## 性能指标
|
||||
|
||||
### 优化前 vs 优化后
|
||||
|
||||
| 指标 | 优化前 | 优化后 | 改进 |
|
||||
|------|--------|--------|------|
|
||||
| CPU检查间隔 | 1分钟 | 5分钟 | 减少80%检查频率 |
|
||||
| 重启重复执行 | 是 | 否 | 避免重复维护 |
|
||||
| 资源清理 | 不完整 | 完整 | 防止内存泄漏 |
|
||||
| 错误恢复 | 基础 | 增强 | 提高稳定性 |
|
||||
|
||||
### 预期性能表现
|
||||
|
||||
- **CPU使用率**: < 1%(正常运行时)
|
||||
- **内存使用**: < 50MB(额外占用)
|
||||
- **线程数**: +1(后台调度线程)
|
||||
- **启动时间**: < 1秒
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **特殊农场未自动维护**
|
||||
- 检查MongoDB连接是否正常
|
||||
- 查看日志文件 `special_farm.log`
|
||||
- 确认特殊农场配置正确
|
||||
|
||||
2. **服务器启动缓慢**
|
||||
- 检查MongoDB连接速度
|
||||
- 查看是否有网络问题
|
||||
- 考虑使用本地MongoDB
|
||||
|
||||
3. **内存使用过高**
|
||||
- 运行性能监控工具
|
||||
- 检查是否有内存泄漏
|
||||
- 重启服务器释放资源
|
||||
|
||||
### 日志文件
|
||||
|
||||
- **特殊农场日志**: `special_farm.log`
|
||||
- **服务器日志**: 控制台输出
|
||||
- **MongoDB日志**: MongoDB服务器日志
|
||||
|
||||
## 维护建议
|
||||
|
||||
### 定期检查
|
||||
|
||||
1. **每周检查**:
|
||||
- 查看 `special_farm.log` 日志
|
||||
- 确认维护任务正常执行
|
||||
- 检查特殊农场作物状态
|
||||
|
||||
2. **每月检查**:
|
||||
- 运行性能监控工具
|
||||
- 清理过期日志文件
|
||||
- 检查MongoDB数据库状态
|
||||
|
||||
### 备份建议
|
||||
|
||||
- 定期备份MongoDB数据库
|
||||
- 保存特殊农场配置文件
|
||||
- 记录重要的配置变更
|
||||
|
||||
## 技术支持
|
||||
|
||||
如果遇到问题,请提供以下信息:
|
||||
|
||||
1. 错误日志内容
|
||||
2. 服务器运行环境
|
||||
3. MongoDB版本和配置
|
||||
4. 问题复现步骤
|
||||
|
||||
---
|
||||
|
||||
**注意**: 此优化版本向后兼容,不会影响现有的游戏数据和功能。
|
||||
132
SproutFarm-Backend/test/游戏配置/item_config_debug.json
Normal file
132
SproutFarm-Backend/test/游戏配置/item_config_debug.json
Normal file
@@ -0,0 +1,132 @@
|
||||
{
|
||||
"type": "item_config_response",
|
||||
"success": true,
|
||||
"item_config": {
|
||||
"精准采集-镰刀": {
|
||||
"花费": 100,
|
||||
"描述": "可以在收获作物时必定掉落该作物的种子",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/紫水晶镰刀.webp"
|
||||
},
|
||||
"时运-镰刀": {
|
||||
"花费": 100,
|
||||
"描述": "可以在收获作物时掉落更多的作物的收获物",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/红宝石镰刀.webp"
|
||||
},
|
||||
"农家肥": {
|
||||
"花费": 100,
|
||||
"描述": "(施肥道具)可以在30分钟内2倍速作物生长",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/农家肥.webp"
|
||||
},
|
||||
"金坷垃": {
|
||||
"花费": 100,
|
||||
"描述": "(施肥道具)可以在5分钟内5倍速作物的生长",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/金坷垃2.webp"
|
||||
},
|
||||
"水壶": {
|
||||
"花费": 100,
|
||||
"描述": "(浇水道具)直接让作物生长进度+1%",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/铁质洒水壶.webp"
|
||||
},
|
||||
"水桶": {
|
||||
"花费": 100,
|
||||
"描述": "(浇水道具)让作物生长进度+2%",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/木质水桶2.webp"
|
||||
},
|
||||
"杀虫剂": {
|
||||
"花费": 100,
|
||||
"描述": "杀虫,暂时没什么用",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/杀虫剂.webp"
|
||||
},
|
||||
"除草剂": {
|
||||
"花费": 100,
|
||||
"描述": "除草",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/除草剂.webp"
|
||||
},
|
||||
"生长素": {
|
||||
"花费": 100,
|
||||
"描述": "时运可以10分钟内3倍速作物生长,而且作物生长速度+3%",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/生长素.webp"
|
||||
},
|
||||
"铲子": {
|
||||
"花费": 100,
|
||||
"描述": "铲除作物",
|
||||
"类型": "作物道具",
|
||||
"道具图片": "res://assets/道具图片/附魔铁铲.webp"
|
||||
},
|
||||
"不死图腾": {
|
||||
"花费": 100,
|
||||
"描述": "让宠物死亡复活一次",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/不死图腾.webp"
|
||||
},
|
||||
"荆棘护甲": {
|
||||
"花费": 100,
|
||||
"描述": "宠物收到伤害时反弹伤害给敌人",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/荆棘护甲.webp"
|
||||
},
|
||||
"狂暴药水": {
|
||||
"花费": 100,
|
||||
"描述": "宠物血量低于某个值,进入狂暴模式",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/狂暴药水.webp"
|
||||
},
|
||||
"援军令牌": {
|
||||
"花费": 100,
|
||||
"描述": "血量低于某个值,召唤一堆宠物仆从帮助你战斗",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/援军令牌.webp"
|
||||
},
|
||||
"金刚图腾": {
|
||||
"花费": 100,
|
||||
"描述": "更改宠物元素为金元素",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/金元素图腾.webp"
|
||||
},
|
||||
"灵木图腾": {
|
||||
"花费": 100,
|
||||
"描述": "更改宠物元素为木元素",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/木元素图腾.webp"
|
||||
},
|
||||
"潮汐图腾": {
|
||||
"花费": 100,
|
||||
"描述": "更改宠物元素为水元素",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/水元素图腾.webp"
|
||||
},
|
||||
"烈焰图腾": {
|
||||
"花费": 100,
|
||||
"描述": "更改宠物元素为火元素",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/火元素图腾.webp"
|
||||
},
|
||||
"敦岩图腾": {
|
||||
"花费": 100,
|
||||
"描述": "更改宠物元素为土元素",
|
||||
"类型": "宠物道具",
|
||||
"道具图片": "res://assets/道具图片/土元素图腾.webp"
|
||||
},
|
||||
"小额经验卡": {
|
||||
"花费": 100,
|
||||
"描述": "让玩家立即获得500经验值",
|
||||
"类型": "农场道具",
|
||||
"道具图片": "res://assets/道具图片/小额经验卡.webp"
|
||||
},
|
||||
"小额金币卡": {
|
||||
"花费": 100,
|
||||
"描述": "让玩家立即获得500金币",
|
||||
"类型": "农场道具",
|
||||
"道具图片": "res://assets/道具图片/小额金币卡.webp"
|
||||
}
|
||||
}
|
||||
}
|
||||
1071
SproutFarm-Backend/test/游戏配置/作物系统.json
Normal file
1071
SproutFarm-Backend/test/游戏配置/作物系统.json
Normal file
File diff suppressed because it is too large
Load Diff
8
SproutFarm-Backend/test/游戏配置/访问系统.json
Normal file
8
SproutFarm-Backend/test/游戏配置/访问系统.json
Normal file
@@ -0,0 +1,8 @@
|
||||
"访问系统":{
|
||||
"总访问人数":0,
|
||||
"今日访问人数":0,
|
||||
"访问记录":{
|
||||
"2025-07-21":["树萌芽","柚大青"],
|
||||
"2025-07-1":["树萌芽","柚大青","大萌芽"],
|
||||
}
|
||||
}
|
||||
968
SproutFarm-Backend/test/特殊农场/小麦谷222.json
Normal file
968
SproutFarm-Backend/test/特殊农场/小麦谷222.json
Normal file
@@ -0,0 +1,968 @@
|
||||
{
|
||||
"经验值": 0,
|
||||
"等级": 1,
|
||||
"钱币": 0,
|
||||
"农场名称": "小麦谷",
|
||||
"玩家昵称": "小麦谷",
|
||||
"玩家账号": "222",
|
||||
"玩家密码": "tyh@19900420",
|
||||
"最后登录时间": "2025年07月20日17时19分16秒",
|
||||
"总游玩时间": "0时0分0秒",
|
||||
"注册时间": "2025年05月21日15时00分00秒",
|
||||
"个人简介": "盛产小麦的农场",
|
||||
"农场土地": [
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
}
|
||||
],
|
||||
"种子仓库": [],
|
||||
"作物仓库": [],
|
||||
"道具背包": [],
|
||||
"宠物背包": [],
|
||||
"巡逻宠物": [],
|
||||
"出战宠物": [],
|
||||
"稻草人配置": {
|
||||
"已拥有稻草人类型": [
|
||||
"稻草人1"
|
||||
],
|
||||
"稻草人展示类型": "稻草人1",
|
||||
"稻草人昵称": "稻草人",
|
||||
"稻草人说的话": {
|
||||
"第一句话": {
|
||||
"内容": "这里是花谷",
|
||||
"颜色": "52dceeff"
|
||||
},
|
||||
"第二句话": {
|
||||
"内容": "一个盛产各种奇异花卉的地方",
|
||||
"颜色": "80d5ffff"
|
||||
},
|
||||
"第三句话": {
|
||||
"内容": "星期一,三,五,七零点种植",
|
||||
"颜色": "ac52ffff"
|
||||
},
|
||||
"第四句话": {
|
||||
"内容": "欢迎参观!",
|
||||
"颜色": "f881ffff"
|
||||
}
|
||||
},
|
||||
"稻草人昵称颜色": "b38282ff"
|
||||
},
|
||||
"智慧树配置": {
|
||||
"距离上一次杀虫时间": 1753004237,
|
||||
"距离上一次除草时间": 1753004237,
|
||||
"智慧树显示的话": "",
|
||||
"等级": 1,
|
||||
"当前经验值": 0,
|
||||
"最大经验值": 100,
|
||||
"最大生命值": 100,
|
||||
"当前生命值": 100,
|
||||
"高度": 20
|
||||
},
|
||||
"签到历史": {},
|
||||
"在线礼包": {
|
||||
"当前日期": "2025-07-20",
|
||||
"今日在线时长": 0,
|
||||
"已领取礼包": [],
|
||||
"登录时间": 1753003043.7163484
|
||||
},
|
||||
"点赞系统": {
|
||||
"今日剩余点赞次数": 10,
|
||||
"点赞上次刷新时间": "2025-07-20",
|
||||
"总点赞数": 0
|
||||
},
|
||||
"新手礼包": {
|
||||
"已领取": false,
|
||||
"领取时间": "2025-07-12 23:02:25"
|
||||
},
|
||||
"体力系统": {
|
||||
"当前体力值": 20,
|
||||
"最大体力值": 20,
|
||||
"上次刷新时间": "2025-07-20",
|
||||
"上次恢复时间": 1753003043.7066433
|
||||
},
|
||||
"小卖部配置": {
|
||||
"商品列表": [],
|
||||
"格子数": 10
|
||||
},
|
||||
"游戏设置": {
|
||||
"背景音乐音量": 1,
|
||||
"天气显示": true
|
||||
}
|
||||
}
|
||||
968
SproutFarm-Backend/test/特殊农场/幸运农场888.json
Normal file
968
SproutFarm-Backend/test/特殊农场/幸运农场888.json
Normal file
@@ -0,0 +1,968 @@
|
||||
{
|
||||
"经验值": 0,
|
||||
"等级": 1,
|
||||
"钱币": 0,
|
||||
"农场名称": "幸运农场",
|
||||
"玩家昵称": "幸运农场",
|
||||
"玩家账号": "111",
|
||||
"玩家密码": "tyh@19900420",
|
||||
"最后登录时间": "2025年07月20日17时19分16秒",
|
||||
"总游玩时间": "0时0分0秒",
|
||||
"注册时间": "2025年05月21日15时00分00秒",
|
||||
"个人简介": "盛产幸运草和幸运花的农场",
|
||||
"农场土地": [
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
}
|
||||
],
|
||||
"种子仓库": [],
|
||||
"作物仓库": [],
|
||||
"道具背包": [],
|
||||
"宠物背包": [],
|
||||
"巡逻宠物": [],
|
||||
"出战宠物": [],
|
||||
"稻草人配置": {
|
||||
"已拥有稻草人类型": [
|
||||
"稻草人1"
|
||||
],
|
||||
"稻草人展示类型": "稻草人1",
|
||||
"稻草人昵称": "稻草人",
|
||||
"稻草人说的话": {
|
||||
"第一句话": {
|
||||
"内容": "这里是花谷",
|
||||
"颜色": "52dceeff"
|
||||
},
|
||||
"第二句话": {
|
||||
"内容": "一个盛产各种奇异花卉的地方",
|
||||
"颜色": "80d5ffff"
|
||||
},
|
||||
"第三句话": {
|
||||
"内容": "星期一,三,五,七零点种植",
|
||||
"颜色": "ac52ffff"
|
||||
},
|
||||
"第四句话": {
|
||||
"内容": "欢迎参观!",
|
||||
"颜色": "f881ffff"
|
||||
}
|
||||
},
|
||||
"稻草人昵称颜色": "b38282ff"
|
||||
},
|
||||
"智慧树配置": {
|
||||
"距离上一次杀虫时间": 1753004237,
|
||||
"距离上一次除草时间": 1753004237,
|
||||
"智慧树显示的话": "",
|
||||
"等级": 1,
|
||||
"当前经验值": 0,
|
||||
"最大经验值": 100,
|
||||
"最大生命值": 100,
|
||||
"当前生命值": 100,
|
||||
"高度": 20
|
||||
},
|
||||
"签到历史": {},
|
||||
"在线礼包": {
|
||||
"当前日期": "2025-07-20",
|
||||
"今日在线时长": 0,
|
||||
"已领取礼包": [],
|
||||
"登录时间": 1753003043.7163484
|
||||
},
|
||||
"点赞系统": {
|
||||
"今日剩余点赞次数": 10,
|
||||
"点赞上次刷新时间": "2025-07-20",
|
||||
"总点赞数": 0
|
||||
},
|
||||
"新手礼包": {
|
||||
"已领取": false,
|
||||
"领取时间": "2025-07-12 23:02:25"
|
||||
},
|
||||
"体力系统": {
|
||||
"当前体力值": 20,
|
||||
"最大体力值": 20,
|
||||
"上次刷新时间": "2025-07-20",
|
||||
"上次恢复时间": 1753003043.7066433
|
||||
},
|
||||
"小卖部配置": {
|
||||
"商品列表": [],
|
||||
"格子数": 10
|
||||
},
|
||||
"游戏设置": {
|
||||
"背景音乐音量": 1,
|
||||
"天气显示": true
|
||||
}
|
||||
}
|
||||
971
SproutFarm-Backend/test/特殊农场/杂交农场666.json
Normal file
971
SproutFarm-Backend/test/特殊农场/杂交农场666.json
Normal file
@@ -0,0 +1,971 @@
|
||||
{
|
||||
"_id": {
|
||||
"$oid": "689b4b9286cf953f2f4e56ee"
|
||||
},
|
||||
"经验值": 0,
|
||||
"等级": 1,
|
||||
"钱币": 0,
|
||||
"农场名称": "杂交农场",
|
||||
"玩家昵称": "杂交农场",
|
||||
"玩家账号": "666",
|
||||
"玩家密码": "tyh@19900420",
|
||||
"最后登录时间": "2025年07月20日17时19分16秒",
|
||||
"总游玩时间": "0时0分0秒",
|
||||
"注册时间": "2025年05月21日15时00分00秒",
|
||||
"个人简介": "盛产杂交果实的农场",
|
||||
"农场土地": [
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
}
|
||||
],
|
||||
"种子仓库": [],
|
||||
"作物仓库": [],
|
||||
"道具背包": [],
|
||||
"宠物背包": [],
|
||||
"巡逻宠物": [],
|
||||
"出战宠物": [],
|
||||
"稻草人配置": {
|
||||
"已拥有稻草人类型": [
|
||||
"稻草人1"
|
||||
],
|
||||
"稻草人展示类型": "",
|
||||
"稻草人昵称": "稻草人",
|
||||
"稻草人说的话": {
|
||||
"第一句话": {
|
||||
"内容": "第一句话",
|
||||
"颜色": "52dceeff"
|
||||
},
|
||||
"第二句话": {
|
||||
"内容": "第二句话",
|
||||
"颜色": "80d5ffff"
|
||||
},
|
||||
"第三句话": {
|
||||
"内容": "第三句话",
|
||||
"颜色": "ac52ffff"
|
||||
},
|
||||
"第四句话": {
|
||||
"内容": "第四句话",
|
||||
"颜色": "f881ffff"
|
||||
}
|
||||
},
|
||||
"稻草人昵称颜色": "b38282ff"
|
||||
},
|
||||
"智慧树配置": {
|
||||
"距离上一次杀虫时间": 1753004237,
|
||||
"距离上一次除草时间": 1753004237,
|
||||
"智慧树显示的话": "",
|
||||
"等级": 1,
|
||||
"当前经验值": 0,
|
||||
"最大经验值": 100,
|
||||
"最大生命值": 100,
|
||||
"当前生命值": 100,
|
||||
"高度": 20
|
||||
},
|
||||
"签到历史": {},
|
||||
"在线礼包": {
|
||||
"当前日期": "2025-07-20",
|
||||
"今日在线时长": 0,
|
||||
"已领取礼包": [],
|
||||
"登录时间": 1753003043.7163484
|
||||
},
|
||||
"点赞系统": {
|
||||
"今日剩余点赞次数": 10,
|
||||
"点赞上次刷新时间": "2025-07-20",
|
||||
"总点赞数": 0
|
||||
},
|
||||
"新手礼包": {
|
||||
"已领取": false,
|
||||
"领取时间": "2025-07-12 23:02:25"
|
||||
},
|
||||
"体力系统": {
|
||||
"当前体力值": 20,
|
||||
"最大体力值": 20,
|
||||
"上次刷新时间": "2025-07-20",
|
||||
"上次恢复时间": 1753003043.7066433
|
||||
},
|
||||
"小卖部配置": {
|
||||
"商品列表": [],
|
||||
"格子数": 10
|
||||
},
|
||||
"游戏设置": {
|
||||
"背景音乐音量": 1,
|
||||
"天气显示": true
|
||||
}
|
||||
}
|
||||
968
SproutFarm-Backend/test/特殊农场/瓜果农场333.json
Normal file
968
SproutFarm-Backend/test/特殊农场/瓜果农场333.json
Normal file
@@ -0,0 +1,968 @@
|
||||
{
|
||||
"经验值": 0,
|
||||
"等级": 1,
|
||||
"钱币": 0,
|
||||
"农场名称": "瓜果农场",
|
||||
"玩家昵称": "瓜果农场",
|
||||
"玩家账号": "333",
|
||||
"玩家密码": "tyh@19900420",
|
||||
"最后登录时间": "2025年07月20日17时19分16秒",
|
||||
"总游玩时间": "0时0分0秒",
|
||||
"注册时间": "2025年05月21日15时00分00秒",
|
||||
"个人简介": "盛产各种瓜果的农场",
|
||||
"农场土地": [
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
}
|
||||
],
|
||||
"种子仓库": [],
|
||||
"作物仓库": [],
|
||||
"道具背包": [],
|
||||
"宠物背包": [],
|
||||
"巡逻宠物": [],
|
||||
"出战宠物": [],
|
||||
"稻草人配置": {
|
||||
"已拥有稻草人类型": [
|
||||
"稻草人1"
|
||||
],
|
||||
"稻草人展示类型": "稻草人1",
|
||||
"稻草人昵称": "稻草人",
|
||||
"稻草人说的话": {
|
||||
"第一句话": {
|
||||
"内容": "这里是花谷",
|
||||
"颜色": "52dceeff"
|
||||
},
|
||||
"第二句话": {
|
||||
"内容": "一个盛产各种奇异花卉的地方",
|
||||
"颜色": "80d5ffff"
|
||||
},
|
||||
"第三句话": {
|
||||
"内容": "星期一,三,五,七零点种植",
|
||||
"颜色": "ac52ffff"
|
||||
},
|
||||
"第四句话": {
|
||||
"内容": "欢迎参观!",
|
||||
"颜色": "f881ffff"
|
||||
}
|
||||
},
|
||||
"稻草人昵称颜色": "b38282ff"
|
||||
},
|
||||
"智慧树配置": {
|
||||
"距离上一次杀虫时间": 1753004237,
|
||||
"距离上一次除草时间": 1753004237,
|
||||
"智慧树显示的话": "",
|
||||
"等级": 1,
|
||||
"当前经验值": 0,
|
||||
"最大经验值": 100,
|
||||
"最大生命值": 100,
|
||||
"当前生命值": 100,
|
||||
"高度": 20
|
||||
},
|
||||
"签到历史": {},
|
||||
"在线礼包": {
|
||||
"当前日期": "2025-07-20",
|
||||
"今日在线时长": 0,
|
||||
"已领取礼包": [],
|
||||
"登录时间": 1753003043.7163484
|
||||
},
|
||||
"点赞系统": {
|
||||
"今日剩余点赞次数": 10,
|
||||
"点赞上次刷新时间": "2025-07-20",
|
||||
"总点赞数": 0
|
||||
},
|
||||
"新手礼包": {
|
||||
"已领取": false,
|
||||
"领取时间": "2025-07-12 23:02:25"
|
||||
},
|
||||
"体力系统": {
|
||||
"当前体力值": 20,
|
||||
"最大体力值": 20,
|
||||
"上次刷新时间": "2025-07-20",
|
||||
"上次恢复时间": 1753003043.7066433
|
||||
},
|
||||
"小卖部配置": {
|
||||
"商品列表": [],
|
||||
"格子数": 10
|
||||
},
|
||||
"游戏设置": {
|
||||
"背景音乐音量": 1,
|
||||
"天气显示": true
|
||||
}
|
||||
}
|
||||
968
SproutFarm-Backend/test/特殊农场/稻香111.json
Normal file
968
SproutFarm-Backend/test/特殊农场/稻香111.json
Normal file
@@ -0,0 +1,968 @@
|
||||
{
|
||||
"经验值": 0,
|
||||
"等级": 1,
|
||||
"钱币": 0,
|
||||
"农场名称": "稻香",
|
||||
"玩家昵称": "稻香",
|
||||
"玩家账号": "111",
|
||||
"玩家密码": "tyh@19900420",
|
||||
"最后登录时间": "2025年07月20日17时19分16秒",
|
||||
"总游玩时间": "0时0分0秒",
|
||||
"注册时间": "2025年05月21日15时00分00秒",
|
||||
"个人简介": "盛产稻谷的农场",
|
||||
"农场土地": [
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
}
|
||||
],
|
||||
"种子仓库": [],
|
||||
"作物仓库": [],
|
||||
"道具背包": [],
|
||||
"宠物背包": [],
|
||||
"巡逻宠物": [],
|
||||
"出战宠物": [],
|
||||
"稻草人配置": {
|
||||
"已拥有稻草人类型": [
|
||||
"稻草人1"
|
||||
],
|
||||
"稻草人展示类型": "稻草人1",
|
||||
"稻草人昵称": "稻草人",
|
||||
"稻草人说的话": {
|
||||
"第一句话": {
|
||||
"内容": "这里是花谷",
|
||||
"颜色": "52dceeff"
|
||||
},
|
||||
"第二句话": {
|
||||
"内容": "一个盛产各种奇异花卉的地方",
|
||||
"颜色": "80d5ffff"
|
||||
},
|
||||
"第三句话": {
|
||||
"内容": "星期一,三,五,七零点种植",
|
||||
"颜色": "ac52ffff"
|
||||
},
|
||||
"第四句话": {
|
||||
"内容": "欢迎参观!",
|
||||
"颜色": "f881ffff"
|
||||
}
|
||||
},
|
||||
"稻草人昵称颜色": "b38282ff"
|
||||
},
|
||||
"智慧树配置": {
|
||||
"距离上一次杀虫时间": 1753004237,
|
||||
"距离上一次除草时间": 1753004237,
|
||||
"智慧树显示的话": "",
|
||||
"等级": 1,
|
||||
"当前经验值": 0,
|
||||
"最大经验值": 100,
|
||||
"最大生命值": 100,
|
||||
"当前生命值": 100,
|
||||
"高度": 20
|
||||
},
|
||||
"签到历史": {},
|
||||
"在线礼包": {
|
||||
"当前日期": "2025-07-20",
|
||||
"今日在线时长": 0,
|
||||
"已领取礼包": [],
|
||||
"登录时间": 1753003043.7163484
|
||||
},
|
||||
"点赞系统": {
|
||||
"今日剩余点赞次数": 10,
|
||||
"点赞上次刷新时间": "2025-07-20",
|
||||
"总点赞数": 0
|
||||
},
|
||||
"新手礼包": {
|
||||
"已领取": false,
|
||||
"领取时间": "2025-07-12 23:02:25"
|
||||
},
|
||||
"体力系统": {
|
||||
"当前体力值": 20,
|
||||
"最大体力值": 20,
|
||||
"上次刷新时间": "2025-07-20",
|
||||
"上次恢复时间": 1753003043.7066433
|
||||
},
|
||||
"小卖部配置": {
|
||||
"商品列表": [],
|
||||
"格子数": 10
|
||||
},
|
||||
"游戏设置": {
|
||||
"背景音乐音量": 1,
|
||||
"天气显示": true
|
||||
}
|
||||
}
|
||||
968
SproutFarm-Backend/test/特殊农场/花卉农场520.json
Normal file
968
SproutFarm-Backend/test/特殊农场/花卉农场520.json
Normal file
@@ -0,0 +1,968 @@
|
||||
{
|
||||
"经验值": 0,
|
||||
"等级": 1,
|
||||
"钱币": 0,
|
||||
"农场名称": "花谷",
|
||||
"玩家昵称": "花谷",
|
||||
"玩家账号": "520",
|
||||
"玩家密码": "tyh@19900420",
|
||||
"最后登录时间": "2025年07月20日17时19分16秒",
|
||||
"总游玩时间": "0时0分0秒",
|
||||
"注册时间": "2025年05月21日15时00分00秒",
|
||||
"个人简介": "盛产各种花卉的农场",
|
||||
"农场土地": [
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": true,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 3,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
},
|
||||
{
|
||||
"crop_type": "",
|
||||
"grow_time": 0,
|
||||
"is_dead": false,
|
||||
"is_diged": false,
|
||||
"is_planted": false,
|
||||
"max_grow_time": 5,
|
||||
"已浇水": false,
|
||||
"已施肥": false,
|
||||
"土地等级": 0
|
||||
}
|
||||
],
|
||||
"种子仓库": [],
|
||||
"作物仓库": [],
|
||||
"道具背包": [],
|
||||
"宠物背包": [],
|
||||
"巡逻宠物": [],
|
||||
"出战宠物": [],
|
||||
"稻草人配置": {
|
||||
"已拥有稻草人类型": [
|
||||
"稻草人1"
|
||||
],
|
||||
"稻草人展示类型": "稻草人1",
|
||||
"稻草人昵称": "稻草人",
|
||||
"稻草人说的话": {
|
||||
"第一句话": {
|
||||
"内容": "这里是花谷",
|
||||
"颜色": "52dceeff"
|
||||
},
|
||||
"第二句话": {
|
||||
"内容": "一个盛产各种奇异花卉的地方",
|
||||
"颜色": "80d5ffff"
|
||||
},
|
||||
"第三句话": {
|
||||
"内容": "星期一,三,五,七零点种植",
|
||||
"颜色": "ac52ffff"
|
||||
},
|
||||
"第四句话": {
|
||||
"内容": "欢迎参观!",
|
||||
"颜色": "f881ffff"
|
||||
}
|
||||
},
|
||||
"稻草人昵称颜色": "b38282ff"
|
||||
},
|
||||
"智慧树配置": {
|
||||
"距离上一次杀虫时间": 1753004237,
|
||||
"距离上一次除草时间": 1753004237,
|
||||
"智慧树显示的话": "",
|
||||
"等级": 1,
|
||||
"当前经验值": 0,
|
||||
"最大经验值": 100,
|
||||
"最大生命值": 100,
|
||||
"当前生命值": 100,
|
||||
"高度": 20
|
||||
},
|
||||
"签到历史": {},
|
||||
"在线礼包": {
|
||||
"当前日期": "2025-07-20",
|
||||
"今日在线时长": 0,
|
||||
"已领取礼包": [],
|
||||
"登录时间": 1753003043.7163484
|
||||
},
|
||||
"点赞系统": {
|
||||
"今日剩余点赞次数": 10,
|
||||
"点赞上次刷新时间": "2025-07-20",
|
||||
"总点赞数": 0
|
||||
},
|
||||
"新手礼包": {
|
||||
"已领取": false,
|
||||
"领取时间": "2025-07-12 23:02:25"
|
||||
},
|
||||
"体力系统": {
|
||||
"当前体力值": 20,
|
||||
"最大体力值": 20,
|
||||
"上次刷新时间": "2025-07-20",
|
||||
"上次恢复时间": 1753003043.7066433
|
||||
},
|
||||
"小卖部配置": {
|
||||
"商品列表": [],
|
||||
"格子数": 10
|
||||
},
|
||||
"游戏设置": {
|
||||
"背景音乐音量": 1,
|
||||
"天气显示": true
|
||||
}
|
||||
}
|
||||
1071
SproutFarm-Backend/test/玩家农场/2143323382.json
Normal file
1071
SproutFarm-Backend/test/玩家农场/2143323382.json
Normal file
File diff suppressed because it is too large
Load Diff
1248
SproutFarm-Backend/test/玩家农场/3205788256.json
Normal file
1248
SproutFarm-Backend/test/玩家农场/3205788256.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user