版本:v1.0(2026-11-01) 目标源码:
D:\phpstudy_pro\WWW\KXFarm(Java Swing 单机版,310 文件 / 10.8 MB) 依据规范:docs/插件开发规范.md(v1.8,核心 V1.3.2) 插件标识:目录plugins/kx_farm/,命名空间Plugin\KxFarm,显示名「开心农场」
一、现状盘点(KXFarm)
1.1 技术形态
| 项 | 结论 |
|---|---|
| 技术栈 | Java SE + Swing 桌面 GUI(.classpath/.project 为 Eclipse 工程) |
| 入口 | src/main/APP.java → view/user/LoginJFrame(自带注册/登录窗口) |
| 数据 | 本地文件存档:`user/{userID}/user.txt |
| 多人 | 无网络层;「好友农场」FriendFarm 直接读同机其他用户目录,属本地伪多人 |
| 状态推进 | javax.swing.Timer + System.currentTimeMillis() 客户端计时 |
| 主窗口 | view/farm/JtFarm.java(491 行,金币/经验/等级刷新与交互总控) |
结论:GUI、登录注册、存档、计时全部不可复用,可复用部分为数值规则 + 美术资源。
1.2 核心数据模型(源码字段)
UserBean:userID / userName / nick / passWord / pic / money(double) / exp / level / notice / userSignLandData:landID / cronid(作物ID) / startTime(epoch ms) / nowStage / stealCountCropBean(image/crops/cropN/crop.txt):cropId / name / pic / unitTime / stageCount / buyLevel / sellMoney / seedMoney
1.3 作物数值表(原版,共 15 种)
阶段时长规则:第 k 阶段耗时
k * unitTime秒;总成熟时间 =unitTime * n(n+1)/2秒。 收获产量:随机 10–30;偷摘产量:随机 1–3(每块地全站仅一次)。
| ID | 作物 | 阶段数 | 单阶段基数(秒) | 原版总时长 | 买价 | 卖价 | 解锁等级 |
|---|---|---|---|---|---|---|---|
| 1 | 草莓 | 5 | 10 | 150s | 10 | 20 | 1 |
| 2 | 玉米 | 5 | 12 | 180s | 15 | 30 | 1 |
| 3 | 白萝卜 | 4 | 15 | 150s | 18 | 35 | 1 |
| 4 | 胡萝卜 | 4 | 16 | 160s | 19 | 37 | 1 |
| 5 | 地瓜 | 5 | 18 | 270s | 20 | 40 | 2 |
| 6 | 茄子 | 5 | 19 | 285s | 22 | 42 | 2 |
| 7 | 西红柿 | 5 | 20 | 300s | 24 | 44 | 2 |
| 8 | 绿豆 | 5 | 22 | 330s | 26 | 46 | 3 |
| 9 | 辣椒 | 5 | 24 | 360s | 28 | 48 | 3 |
| 10 | 南瓜 | 5 | 26 | 390s | 30 | 50 | 4 |
| 11 | 苹果 | 6 | 28 | 588s | 33 | 55 | 4 |
| 12 | 西瓜 | 5 | 30 | 450s | 35 | 57 | 5 |
| 13 | 香蕉 | 6 | 32 | 672s | 37 | 60 | 5 |
| 14 | 桃子 | 5 | 34 | 510s | 38 | 62 | 6 |
| 15 | 菠萝 | 6 | 36 | 756s | 39 | 64 | 6 |
1.4 原版玩法规则(需在 Web 版保留)
- 播种消耗背包种子,经验 +5;收获经验 +1;铲地经验 +3;出售经验 +1(按次)。
- 升级公式:
升级所需经验 = level * (level + 1) * 100(原版((level+1)*level/2)*200),只升 1 级。 - 收获进「仓库」,出售按
产量 × sellMoney计入金币。 - 偷摘:仅可偷成熟且未被偷过的地块,偷后该地块
stealCount > 0,其他访客不能再偷。 - 默认 6 块地(存档
land.txt为 6 行:地号,作物ID,开始时间)。
1.5 美术资源盘点
| 目录 | 文件数 | 体积 | 可用性 |
|---|---|---|---|
image/background | 4 PNG 1024×768 | 3.17 MB | ✅ 选 1 张作农场场景底图(需压成 JPEG/WebP) |
image/background背景图片 | 4 PNG | 3.17 MB | ❌ 与上者完全重复,丢弃 |
image/crops(15 组) | 121 PNG + 15 txt | 1.48 MB | ✅ 核心素材:每阶段一张 201×103 整块地贴图 + seed.png(48×48) + cron_start/cron_end |
image/soil土地图片 | 5 PNG 201×103 | 0.16 MB | ✅ 空地/翻地状态 |
image/guiRes | 35(32 PNG/2 GIF/1 JPG) | 1.96 MB | ⚠️ 选留(招牌 paizi、角色、tilled、成功动效),其余裁掉 |
image/face | 20 GIF | 0.03 MB | ❌ 站点已有头像,不用 |
image/topbutton (18)(19).png | 2 PNG | 0.02 MB | ❌ 桌面顶栏按钮,不用 |
bin/、user/、.settings/ | — | ~3 MB | ❌ 编译产物与桌面存档,不入包 |
关键约束:插件商店单包上限默认 5120 KB(规范 §11.35),当前可用图片约 6.8 MB → 必须做资源压缩,目标整包 < 4 MB。
二、改造总体思路
- 只移植「规则 + 美术」,不移植 UI:Java Swing 窗口、登录注册、本地存档、Timer 全部丢弃。
- 单机 → 在线多人:
- 账号体系接入 FlintHub 登录(
Auth),不再自带注册/登录; - 存档从
user/*.txt迁到插件独立 SQLite; - 计时改为服务端时间判定(
planted_at+ 阶段时长),客户端只负责倒计时展示 → 天然防改时间作弊; - 「好友农场」升级为「访问任意站点用户农场 + 偷摘」,并记录偷摘日志。
- 账号体系接入 FlintHub 登录(
- 两套经济不混用:金币/经验/等级存插件库,不直接写站内积分;后台可选开启「升级奖励站内积分」(调用
Points::award)。 - 渲染方案:每块地是一张 201×103 的整块贴图,Web 端用 CSS Grid +
background-image即可,不需要 Canvas 引擎;空地/生长/成熟直接换图,成熟期加 CSS 浮动动效。 - 按插件规范落地:
plugins/kx_farm/标准目录、三语语言包、后台固定结构、CSRF/原子更新/事务、9 项打包门禁。
三、功能范围
3.1 MVP(首个可上线版本)
- 前台
/farm:农场网格(初始 6 块、可扩至 12)、作物状态倒计时、快捷操作(播种/收获/铲地/浇水)、金币/经验/等级条、背包与仓库抽屉、商店弹层。 - 作物时长按
unitTime × 60(后台可调倍率)、买种子、卖作物、自动进仓库、收获随机产量、经验与升级(金币体系独立于站内积分)。 - 访问他人农场
/farm/visit/{uid}+ 偷摘(每块地全站一次,可后台关闭)。 - 排行榜
/farm/rank(按等级/经验或金币,Top 20)。 - 后台
/admin/kx-farm:概览、玩家列表(金币/经验/封禁/补发/重置)、作物数值编辑、全局设置(时间倍率/土地上限/偷菜开关/每日限额)、操作日志。 - 入口:顶部导航
nav_plugin_links+ 首页右栏home_sidebar_bottom+ 个人主页profile_user_card_after三个入口。
3.2 P1(迭代)
- 每日任务(播种/收获/出售/偷菜各 N 次 → 金币奖励)。
- 道具:化肥(缩短当前阶段 50%)、浇水(缩短 10%,一次性)。
- 成就与徽章、收获/升级飘字、访问动态(谁偷了我的菜)。
- 金币 ↔ 站内积分兑换(后台开关 + 汇率)。
3.3 明确不做
- 桌面版登录/注册/改密码/换头像窗口(交由站点账号体系)。
- 桌面本地存档导入(如需老存档迁移,仅后台提供 CLI 一次性导入,默认不做)。
- 桌面摇奖/商店外的 GUI 装饰功能。
四、数据库设计(插件独立 SQLite:plugins/kx_farm/data/kx_farm.sqlite)
kf_users (
user_id INTEGER PRIMARY KEY, -- 站点 users.id
coins INTEGER NOT NULL DEFAULT 200, -- 金币(新用户初始 200)
exp INTEGER NOT NULL DEFAULT 0,
level INTEGER NOT NULL DEFAULT 1,
lands INTEGER NOT NULL DEFAULT 6, -- 已解锁地块数(≤12)
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
)
kf_lands (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
slot INTEGER NOT NULL, -- 0..11
crop_id INTEGER NOT NULL DEFAULT 0, -- 0 = 空地
planted_at INTEGER NOT NULL DEFAULT 0, -- unix 秒
watered INTEGER NOT NULL DEFAULT 0, -- 已浇水(一次性)
fertilized INTEGER NOT NULL DEFAULT 0, -- 施肥次数
steal_count INTEGER NOT NULL DEFAULT 0, -- 0=未被偷;1=已偷
steal_by INTEGER NOT NULL DEFAULT 0,
cleared_at INTEGER NOT NULL DEFAULT 0, -- 成熟后未铲地的标记
UNIQUE(user_id, slot)
)
kf_bag (user_id INTEGER, crop_id INTEGER, qty INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(user_id, crop_id))
kf_store (user_id INTEGER, crop_id INTEGER, qty INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(user_id, crop_id))
kf_crops (
crop_id INTEGER PRIMARY KEY, name_key TEXT NOT NULL, stage_count INTEGER NOT NULL,
unit_time INTEGER NOT NULL, seed_price INTEGER NOT NULL, sell_price INTEGER NOT NULL,
buy_level INTEGER NOT NULL, enabled INTEGER NOT NULL DEFAULT 1, sort INTEGER NOT NULL DEFAULT 0
)
kf_config (key TEXT PRIMARY KEY, value TEXT NOT NULL) -- 时间倍率/土地上限/开关/限额
kf_daily (user_id INTEGER, day TEXT, sell_qty INT, steal_cnt INT, harvest_cnt INT, planted_cnt INT,
PRIMARY KEY(user_id, day))
kf_logs (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INT, action TEXT, detail TEXT, created_at TEXT)
索引:kf_lands(user_id)、kf_store(user_id)、kf_bag(user_id)、kf_logs(user_id, created_at)、kf_daily(user_id, day)。
并发/防作弊要点
- 播种:先原子扣种子
UPDATE kf_bag SET qty=qty-1 WHERE user_id=:u AND crop_id=:c AND qty>0(rowCount()==0→ 拒绝),再UPDATE kf_lands ... WHERE crop_id=0抢占地块;任一失败整体回滚。 - 收获:
UPDATE kf_lands SET crop_id=0, cleared_at=:t WHERE user_id=:u AND slot=:s AND crop_id=:c AND planted_at=:p(CAS),rowCount()!=1视为重复收获 → 拒绝;产量在事务内随机并写入仓库。 - 偷摘:
UPDATE kf_lands SET steal_count=steal_count+1, steal_by=:thief WHERE user_id=:owner AND slot=:s AND steal_count=0 AND crop_id=:c AND planted_at<=成熟阈值,rowCount()==1才算成功。 - 成熟判断全部服务端计算:
elapsed = time() - planted_at,与客户端无关。 - 每用户每类操作每日上限(
kf_daily,可后台关)。 Plugin::db()已带ERRMODE_EXCEPTION+busy_timeout=5000,插件不覆盖任何 PDO 属性(红线 7)。
五、路由与接口清单
5.1 前台页面(route_register)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /farm | 我的农场(需登录,未登录 requireLogin()) |
| GET | /farm/visit/{uid} | 访问他人农场(公开可看,偷菜需登录) |
| GET | /farm/rank | 排行榜(等级/金币 Top 20) |
5.2 前台接口(全部 JSON,/api/kx_farm/*)
| 方法 | 路径 | 参数 | 说明 |
|---|---|---|---|
| GET | /api/kx_farm/state | — | 一次返回:用户数值、地块(含服务端计算的阶段/剩余秒)、商店、背包、仓库、今日限额 |
| GET | /api/kx_farm/visit | uid | 他人地块只返回阶段与是否可偷,不暴露精确时间 |
| POST | /api/kx_farm/plant | slot, crop_id | 播种(扣种子 + 经验 +5) |
| POST | /api/kx_farm/harvest | slot | 收获(随机 10–30,进仓库,经验 +1) |
| POST | /api/kx_farm/shovel | slot | 铲地(仅成熟/枯萎,经验 +3) |
| POST | /api/kx_farm/buy | crop_id, qty | 买种子(金币扣减原子校验余额) |
| POST | /api/kx_farm/sell | crop_id, qty | 卖作物(仓库扣减 + 金币增加,经验 +1) |
| POST | /api/kx_farm/steal | uid, slot | 偷摘(1–3,写日志) |
| POST | /api/kx_farm/expand | — | 扩地(等级 + 金币门槛) |
统一约定:所有 POST 先 ajaxUser()(登录)→ Csrf::verifyOrDie() → 业务;失败一律 {ok:false,msg};写操作返回最新数值,前端不自行改余额,以服务端回包为准。
5.3 后台(admin_route_register,实际前缀 /admin)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /admin/kx-farm | 管理首页(Tab:概览 / 玩家 / 作物 / 设置 / 日志) |
| POST | /admin/kx-farm/save | 保存全局设置(写 kf_config) |
| POST | /admin/kx-farm/crop-save | 编辑作物数值(价格/时长/解锁等级/上下架) |
| POST | /admin/kx-farm/player | 玩家操作:补发金币、重置农场、封禁农场 |
| GET | /admin/kx-farm/logs | 日志分页查询 |
全局设置存插件库
kf_config,不写站内全局 Settings →permissions仅需["route:admin"]。
六、视图与前端实现
6.1 页面骨架
views/farm/index.php 我的农场(.kf-wrap 内层容器,1080px)
views/farm/visit.php 他人农场
views/farm/rank.php 排行榜
views/farm/_topbar.php 金币/经验/等级/今日额度(三页复用)
views/admin.php 后台固定结构(admin-container + admin/_sidebar + main.admin-content + admin-header)
- 前台沿用核心样式变量
--mn-*,不自造配色;按钮统一mn-btn / mn-btn-primary,输入用mn-input; - 路由地址一律
$this->url()/Url::to();静态资源才BASE_PATH;JS 不拼 URL(全部由data-*注入); - 零内联:无
<script>逻辑块、无on*、无style=。
6.2 农场网格渲染
- 布局:
grid-template-columns: repeat(3, minmax(0, 1fr)),每格aspect-ratio: 201/103; - 每格
background-image指向当前阶段贴图(assets/img/crops/{crop}/{stage}.webp),成熟加.is-mature浮动动画; - 场景底图 1024×768 作为外层背景,整体在 1080px 容器内等比缩放,860px 断点切 2 列;
- 倒计时:页面拿到
planted_at、unit_time、stage_count后由 JS 本地推进显示,仅展示,所有判定以接口返回的stage/remaining为准; - 定时刷新:页面可见时每 30s 拉一次
/api/kx_farm/state(不可见时暂停,visibilitychange)。
6.3 交互弹层
商店 / 背包 / 仓库统一用页面内 DOM 弹层(非原生 alert),复用一个 .kf-modal;操作结果统一 toast,禁止 alert()。
6.4 语言包(三语,键集合与键序必须完全一致——门禁 #1)
- 前缀
plugin.kx_farm.*:导航、标题、按钮、提示、错误码、后台表单、作物名(15 个crop_1..15)、日志动作名; - 作物名走语言包(不写死中文),数值进
kf_crops(后台可调)。
七、资源改造计划
| 步骤 | 内容 | 目标 |
|---|---|---|
| 1 | 复制 15 组作物贴图(201×103 ×121 张)+ cron_start/cron_end + seed.png | 保留原画风 |
| 2 | 统一转 WebP q85(保透明),命名 assets/img/crops/{cropId}/{stage}.webp、seed.webp | 1.48 MB → ≈0.6 MB |
| 3 | 背景:4 选 1(推荐 background/1.png),转 JPEG q80(或 WebP q80),可选提供 2 套皮肤 | 0.7–0.9 MB → ≈0.15–0.25 MB |
| 4 | soil 5 张转 WebP,用作空地/未解锁 | 0.16 → 0.06 MB |
| 5 | guiRes 只留 paizi.png / tilled.png / success.gif / congrats.gif → WebP/压缩 GIF | 1.96 → ≈0.3 MB |
| 6 | 丢弃重复 background背景图片、face、topbutton、bin、user、.settings | −4 MB 以上 |
| 7 | 图片统一懒加载 + loading=lazy(弹层内素材),首屏只加载场景底图 + 6 格 | 首屏 ≤ 400 KB |
合计目标:插件包 < 4 MB(留足商店 5120 KB 余量),并在 改动说明.md 注明素材来源。
八、规范落地清单(逐项对照)
- 目录:
plugin.json / Plugin.php / FrontController.php / AdminController.php / hook/ / views/ / assets/ / lang/ / data/。 - plugin.json:
name=开心农场、version=1.0.0、min_core=1.3.2、category=entertainment、icon=seedling(已核实存在于TemplateCompiler::$map)、admin_url=/admin/kx-farm、permissions=["route:admin"]、hooks见下。 - 钩子:
init_after(幂等建表 + 种子数据)、route_register、admin_route_register、nav_plugin_links(双触发守卫 + 16px 图标)、home_sidebar_bottom(侧栏入口卡片)、profile_user_card_after("去 TA 的农场"按钮)。 - 独立库:
Plugin::db()+ensureSchema();DDL 幂等;事务只包本库写,发积分等跨库动作放事务外。 - 安全:
ajaxUser()→Csrf::verifyOrDie()顺序;原子 UPDATE +rowCount();IN查询强转占位符;输出e();禁unserialize/eval/DOCUMENT_ROOT;上传(若 P1 加自定义头像)走Upload::file()。 - i18n:三语 100+ 键,键序一致;
lang/自动合并,无需钩子。 - 后台:固定侧栏结构、表格/分页/提示按核心后台写法(
alert-error而非alert-danger、form-input仅限.admin-content作用域)。 - 打包:
php cli/release_build.php --type=plugin --name=kx_farm --version=1.0.0 --dry-run,9 项门禁通过后正式出包并重建release/plugins/index.json。
九、实施阶段与验收
M0 骨架与资源(先行)
- 建插件目录、
plugin.json、三语空壳、SQLite 建表、种子 15 作物; - 资源流水线:裁剪/转码/命名/体积统计。
- 验收:
php -l全绿;包体积 < 4MB;kf_crops15 条与上表逐条一致。
M1 数据层 + 核心循环(无 UI)
Plugin.php:state() / plant() / harvest() / shovel() / buy() / sell()纯业务方法(可被控制器与 CLI 复用);- 服务端阶段计算、经验/升级、原子更新与事务。
- 验收:脚本/接口模拟「买→种→等→收→卖」闭环;重复收获/重复播种被拒;余额不会为负。
M2 前台主页面
/farm页面 +state接口 + 网格渲染 + 弹层(商店/背包/仓库)+ 顶部数值条。- 验收:登录可见 6 块地;操作后数值/贴图即时正确;刷新后状态一致;移动端 2 列不溢出。
M3 社交玩法
/farm/visit/{uid}、偷摘、排行榜、profile_user_card_after入口、侧栏卡片。- 验收:A 偷 B 的菜只能成功一次;B 地块显示"已被偷";日志可查;未登录访问只读。
M4 后台
- 概览/玩家/作物/设置/日志 5 个 Tab,CSRF 全覆盖,分页与筛选。
- 验收:改作物价格后前台立即生效;封禁玩家后其接口返回 403;重置农场清空地块但保留账号数值。
M5 合规、性能、打包
- i18n 三语比对、零内联扫描、URL 双模式(伪静态开/关)回归、并发脚本(10 并发重复收获)、9 项门禁、正式出包。
- 验收:门禁全 PASS(签名 WARN 可接受);
/farm首屏 < 500ms(本地);商店包可安装并激活。
十、风险与对策
| 风险 | 影响 | 对策 |
|---|---|---|
| 图片 6.8MB 超商店 5MB | 无法上架 | M0 阶段先做转码与裁剪,整包 < 4MB;必要时降背景分辨率到 1280×720 |
| 原版数值通胀(1 次收获 10–30 个) | 金币贬值、排行榜失真 | 保留原味同时加「每日出售/偷摘上限」,后台可调;首版不上积分兑换 |
| 客户端改时间作弊 | 数值失衡 | 阶段/成熟/偷菜判定 100% 服务端;客户端只做展示 |
| SQLite 并发写 | 高并发下锁等待 | 单事务短小、只写必要列、busy_timeout=5000、避免在事务内做非 DB 操作 |
| 桌面版存档迁移 | 老玩家数据丢失 | 首版不迁移;如需,后台提供一次性 CLI 导入(Properties → SQLite),默认关闭 |
| 素材版权/来源 | 上架审核风险 | 在 改动说明.md 与后台说明中标明素材来源于用户提供的 KXFarm 工程 |
路由 /farm 冲突 | 404/覆盖 | 已检索核心 app/ 无 /farm 路由;实现前再对 plugins/*/hook/route_register.php 做一次全量冲突扫描 |
十一、交付文件清单
plugins/kx_farm/
├── plugin.json
├── Plugin.php # db/ensureSchema/种子/业务方法(state,plant,harvest,...)
├── FrontController.php # /farm、/farm/visit、/farm/rank、/api/kx_farm/*
├── AdminController.php # /admin/kx-farm 及 POST 动作
├── hook/
│ ├── init_after.php
│ ├── route_register.php
│ ├── admin_route_register.php
│ ├── nav_plugin_links.php
│ ├── home_sidebar_bottom.php
│ └── profile_user_card_after.php
├── views/
│ ├── farm/index.php
│ ├── farm/visit.php
│ ├── farm/rank.php
│ ├── farm/_topbar.php
│ └── admin.php
├── assets/
│ ├── style.css
│ ├── game.js
│ └── img/ (crops/ soil/ bg/ gui/,压缩后 < 3.5MB)
├── lang/ (zh.php / en.php / zh_tw.php)
└── data/ (运行期自动创建 sqlite + .htaccess + web.config)
十二、已确认决策(2026-11-01 用户拍板)
| # | 决策项 | 结论 | 落地影响 |
|---|---|---|---|
| 1 | 经济体系 | 独立金币(金币/经验/等级存插件库) | 不读写站内积分;Points::award 仅用于 P1 可选的「升级奖励」 |
| 2 | 时间倍率 | ×60(1 游戏秒 = 1 现实分钟) | 草莓 150s→2.5h,菠萝 756s→12.6h;后台 time_scale 可调 |
| 3 | 偷菜 | 保留 | 每块地全站仅 1 次、偷 1–3 个,需登录且等级 ≥3,后台可关 |
| 4 | 土地 | 6 块起、可扩到 12 | kf_users.lands 默认 6;扩地需等级 + 金币门槛 |
| 5 | 资源取舍 | 默认按 体积优先(整包 < 4MB) | 背景单套 1024×768 转 JPEG/WebP,crops/soil 转 WebP |
以上结论已同步到第三 / 四 / 五 / 七章的默认参数,开发时直接按此实现,无需再确认。