XIUNOX 更新记录贴 202600712

管理

2026-07-12 更新日志

  • [XSS风险] 修复 xnx_fields 插件 hook 文件 json_encode 缺少 JSON_HEX_TAG 安全标志

    • 文件: plugin/xnx_fields/hook/post_ref_thread_after.htm (window.FIELDS_LANG)

    • 文件: plugin/xnx_fields/hook/thread_js.htm (window.XNX_FIELDS)

    • 与同插件 admin 模板(json_encode + JSON_HEX_TAG|JSON_HEX_AMP|...)保持一致

    • 必测: 发帖页自定义字段渲染 + 帖子详情页付费查看按钮

  • [变量未定义] 修复 admin_hidden.php 中 post[subject] 未定义键报错(3 处统一加 ?? 空合并)

    • 必测: admin/?xnx_hidden-list.htm / admin/?xnx_hidden-logs.htm / admin/?xnx_hidden-purchases.htm

  • [逻辑错误] 调整 xnx_hidden admin tab 顺序:设置放第一个(原为最后)

    • 同步修改: hidden_admin.htm + setting.htm

  • [CSRF防护缺失] 修复 xnx_fields 后台版块绑定/分类删除/字段删除 AJAX 请求未传 csrf_token 导致 CSRF 校验失败

    • 根因: ajaxPost 函数中用普通 object 传参的 3 处调用(单行版块绑定/分类删除/字段删除)未注入 csrf_token,而 admin/index.inc.php 对所有 POST 请求做中央化 CSRF 校验

    • 修复: 在 ajaxPost 函数中统一注入 csrf_token(从页面 form 的 csrf_token 字段获取),FormData 传参的调用已由表单 CsrfService::input() 包含无需额外处理

    • 必测: admin/?xnx_fields-forum.htm (选择绑定分类) / admin/?xnx_fields-category.htm (删除分类) / admin/?xnx_fields-field-{id}.htm (删除字段)

    • 回归: admin/?xnx_fields-category.htm (保存分类) / admin/?xnx_fields-field-{id}.htm (保存字段+拖拽排序)

  • [逻辑错误] 修复 xnx_tag 话题帖子列表未过滤已软删除帖子

    • 根因: tag.php 用 db_find 直接查询 thread 表,绕过了核心 thread__find() 自动添加 is_deleted=0 的过滤逻辑;且 onThreadDelete 钩子只挂在物理删除(thread_delete),软删除(thread_soft_delete)不清理话题关联

    • 修复: 查询条件加 is_deleted=>0,与核心 thread_find_by_tids 做法一致

    • 必测: 软删除一个带话题的帖子后访问 topic-{tagid}.htm,确认该帖子不再出现在话题列表

  • [逻辑错误] 个人信息区块积分显示改为按配置类型显示

    • 首页/我的页面:credits 替换为 golds,label 从后台 golds_name 获取

    • 必测: 首页右侧栏登录用户卡片、我的页面用户卡片

    • xnx_invite 侧边栏「获得积分」按 inviter_credits_type 动态显示 label 和对应 reward 字段

    • 必测: 邀请中心侧边栏(配置 inviter_credits_type=credits/golds 分别验证)

    • xnx_dice 侧边栏 label 三元判断补全 rmbs 分支(原 rmbs 回退显示「积分」)

    • 必测: 摇骰子页(配置 credits_type=rmbs 验证 label 显示「人民币」)

    • xnx_invite setting.php creditsTypes 改用系统配置名称(credits_name/golds_name),未补 rmbs(后端日志统计/表结构不支持)

    • 回归: 后台邀请插件设置页积分类型下拉显示名称

  • [GET表单路由丢失] 修复 xnx_lottery 后台筛选搜索 404(GET 表单提交覆盖路由 query,改为 JS 构建 URL 跳转)

    • 必测: admin/?plugin-setting-xnx_lottery.htm 各 tab 的筛选搜索

  • [组件混用] xnx_lottery 后台 tab 结构重组:5 个平级 tab 改为 3 主 tab + 子 tab

    • 主Tab1: 基本设置

    • 主Tab2: 侧边栏抽奖管理(子tab: 奖品管理+抽奖记录)

    • 主Tab3: 帖子管理(子tab: 抽奖活动+中奖记录)

    • 必测: admin/?plugin-setting-xnx_lottery.htm#tab-sidebar / #tab-thread

    • 回归: 各子 tab 切换、搜索后自动回到对应子 tab

  • [语言包不同步] 同步 zh-cn/zh-tw/en-us 三语言包 xnx_lottery_admin_tab_thread 文案

  • [组件混用] 统一全部插件翻页样式为全局右对齐样式(27个文件、37处翻页)

    • 统一为: nav.m-2[aria-label=lang(page_navigation)] > ul.pagination.pagination-boxed.justify-content-end.flex-wrap

    • C类(手写翻页重构为pagination()函数): xnx_magic/history.php+magic_history.htm、xnx_report/setting.php+setting.htm

    • A-2类(裸echo/div补nav/ul包裹): xnx_hidden(3处)、xnx_duel(5文件)、xnx_attach_access、xnx_tag(2文件)

    • A-1类(仅改nav/ul class): xnx_lottery(3处)、xnx_appcenter、xnx_checkin(2文件)、xnx_medal(3文件)、xnx_verify(2文件)、xnx_dice、xnx_invite(2处)、xnx_ai_reply、xnx_friendlink(2处)、xnx_ad_selfbuy、xnx_oauth、xnx_tag/tags_all

    • 修复 xnx_oauth 外层 d-flex.justify-content-center 与 ul 右对齐冲突(移除外层div)

    • 修复 xnx_tag/tags_all 外层 div.mt-3 多余间距(移除外层div)

    • 同步补充 page_navigation 语言键到 zh-cn/zh-tw/en-us/bbs_common.php(核心 pagination.inc.htm 也引用此键但原未定义)

    • 必测: 各插件前台/后台翻页页面(xnx_magic/history-1、xnx_report/setting-list-pending-1、xnx_checkin/rank、xnx_medal/setting 等)

    • 回归: 核心翻页 view/htm/pagination.inc.htm 未改动

  • [安全合规] 批量修复 27 个 xnx_ 插件安全合规问题(3 严重 + 10 中等 + 6 轻微)

    • 严重: xnx_edgeone 敏感配置(secret_id/secret_key/auth_key) param() 未传 FALSE 关闭 htmlspecialchars,密钥特殊字符被转义导致 API 鉴权失败

    • 严重: xnx_medal/uninstall.php 遗漏 DROP xnx_forum_medal 表,卸载后残留孤儿表

    • 严重: xnx_hidden/uninstall.php 遗漏 DROP xnx_hidden_log 表 + setting_delete(xnx_hidden),卸载后残留审计表和配置

    • 中等: xnx_checkin/setting.php+admin.php 补管理员权限校验(gid != 1 && gid != 2)

    • 中等: xnx_status/route/admin_status.php 补管理员权限校验

    • 中等: xnx_friendlink/setting.php 移除 html_entity_decode 反转义 param() 默认 htmlspecialchars(view 端已有 esc_html 二次转义,此层反转义多余且不规范)

    • 中等: xnx_magic/magic_history.htm keyword/interpretation/lucky_tip 补 esc_html(管理员词库数据未转义存储,输出需转义防 XSS)

    • 中等: xnx_attach_access/AttachAccessService.php purchase 方法补 credits_type 白名单校验(credits/golds/rmbs)

    • 中等: xnx_edgeone/setting.htm JS 中 zoneName/Target 拼接 innerHTML 补 eoEscapeHtml 转义防 XSS(数据来自腾讯云 API 返回)

    • 中等: xnx_edgeone/hook/footer_end.htm+header_start.htm htmlspecialchars 替换为 esc_html/esc_attr

    • 中等: xnx_edgeone/install.php + xnx_demo_data/install.php 末尾补清理 model.min.php 编译缓存

    • 轻微: xnx_oauth/my_oauth.htm 4 处 htmlspecialchars 替换为 esc_html/esc_attr

    • 轻微: xnx_hidden/hook/model_post_format_end.php 删除 DEBUG 诊断块(会向访客泄露 hidden_id/权限类型/购买数等内部信息)

    • 轻微: xnx_maintenance/setting.php custom_css param() 传 FALSE 关闭 htmlspecialchars(CSS 中 > < & 不应被转义,会导致选择器失效)

    • 轻微: xnx_duel/DuelService.php + xnx_tag/install.php 补「保留 db_sql_find」注释

    • 必测: 后台各插件设置页保存功能、xnx_edgeone API 连接测试、xnx_magic 历史记录页、xnx_hidden 隐藏内容渲染

  • [状态不同步] 修复插件开发手册 docs/ 与当前源码不一致(40+ 处问题)

    • 删除 07-example-nx_tag.md(整篇基于虚构 nx_tag,实际为 xnx_tag)

    • README.md: 去掉 07 导航,nx_tag→xnx_tag 命名前缀示例

    • 01-architecture.md: 修正 6 处行号/依赖版本比较(实际有语义化版本)/install 流程补并发锁+扫描器/补 plugin_hook 运行时分发/upgrade 机制/protected_paths 白名单/模板安全检测/bbs_plugin.version 字段

    • 02-plugin-structure.md: plugin_read_by_dir 行号/补 capabilities 字段/修正 hooks_rank 排序方向(降序值大先跑)/nx_tag→xnx_tag 真实文件清单/minimal 示例字段类型

    • 03-hooks-catalog.md: 源码扫描重建 607 个 hook,删除虚构 header_theme_/body_end/theme_ 与 nxn_hook 引用,补录 model_route_table_end.php/post_list_inc_*(22个)/forum/sidebar/post/my/user_create 等遗漏 hook

    • 04-api-cheatsheet.md: 补 CacheHelper 完整 API(remember/pluginKey/pluginDeletePrefix)/http_location 第二参数/forum_create/setting_delete/cache_truncate flushdb 警告/esc_js 实现/CSRF token 存 cookie 非 session

    • 05-frontend-security.md: anime.js 从 CSS 移到 JS/bbs.js 路径修正/补 flash toast+cron_run/xiuno-modern.js 行数 679→816/CSRF 服务端读取来源澄清

    • 06-ai-collaboration.md: 扫描器规则重写为 5 级(Fatal 11 条)/bbs_version 阈值 1.0.2 非 4.5 且为 error 非 fatal/补 protected_paths/plugin_hook 运行时分发/模板安全检测/upgrade.php 机制

  • [配置不同步] 实施插件版本号规范:version 三位制 + bbs_version 两位制

    • 扫描器逻辑(lib/PluginScanner.php):bbs_version 必须两位制 X.Y 且 <= 核心主次版本(XIUNOX_VERSION 取前两段),version 必须三位制 X.Y.Z

    • 扫描规则(lib/PluginScannerRules.php):新增 plugin_version_format(warning 级),更新 conf_version 描述

    • 核心默认值(model/plugin.func.php:569-570):version 默认 1.0→1.0.0,bbs_version 默认 4.0→1.0

    • 批量更新 30 个插件 conf.json:bbs_version 统一改 1.0(匹配当前核心 1.0.9),version 统一改三位制

    • 文档更新:docs/02-plugin-structure.md(conf.json 字段表+示例),docs/06-ai-collaboration.md(扫描器规则)

    • 必测: 后台插件列表扫描、新插件安装时扫描拦截、现有插件重新启用

    • 回归: admin/?plugin-list.htm、admin/?plugin-read-*.htm

  • [逻辑错误] xnx_checkin 右侧栏「今日排名」原显示「1天」无意义,改为显示签到时间 HH:MM

    • 必测: ?xnx_checkin(切到「今日排名」tab,确认显示时:分;切「连续/累计签到」仍显示 N 天)

    • 数据来源: getTodayCheckinUsers 已返回 checkin_time 字段,前端未取用

    • 根因: today 分支 map 时硬编码 days=1 未保留 checkin_time,渲染未按 tab 区分

  • [逻辑错误] 修复 xnx_tag 话题详情页帖子数统计未过滤未审核帖子

    • 根因: totaldbcount(′xnxthreadtag′)仅数关联表,未JOINthread表过滤isdeletedauditstatus;话题卡片显示的tag['threads'] 是 xnx_tag 表缓存计数,发帖 +1 时不考虑审核状态

    • 修复: total改为JOINthread表实时计数,按权限过滤(管理员看所有/普通用户auditstatus=1OR自己的/游客仅auditstatus=1),与列表显示逻辑一致;tag['threads'] 覆盖为 $total(不写库),话题卡片显示数 + SEO description 同步生效

    • 必测: topic-{tagid}.htm(管理员/普通用户/游客分别验证显示数与列表数一致;待审帖子作者能在话题页看到自己的帖子且总数包含)

  • [配置不同步] 修复 xnx_lottery/install.php 末尾缺少 model.min.php 缓存清理(违反插件 install.php 必须清理编译缓存硬约束)

    • 根因: upgrade.php 有 plugin_clear_tmp_dir() 但 install.php 末尾完全没有清理逻辑,新装用户在生产环境 model.min.php 合并加载下 install 后未重新启用时旧缓存不含本插件 Service 类会白屏

    • 修复: 末尾添加 @xn_unlink($conf[\x27tmp_path\x27].\x27model.min.php\x27) 与 xnx_duel/xnx_icon/xnx_status 三个插件保持一致

    • 必测: 生产环境(model.min.php 存在时)全新安装 xnx_lottery 后访问帖子抽奖/侧边栏抽奖不白屏

    • 回归: 已升级用户重新禁用启用插件、后台插件列表扫描

  • [配置不同步] 检查 4 个含 upgrade.php 的 xnx 插件 install/upgrade 一致性(xnx_duel/xnx_icon/xnx_status 一致,xnx_lottery 已修复)

  • [变量未定义] 修复 xnx_dice 投注提示余额不足(800金币投10金币被前端拦下)

    • 根因: dice.js getBalance() 通过 getElementById("dice-balance") 获取余额元素,但 dice_index.htm 模板中无此 id 的元素(该 id 仅在投注成功后由后端 OOB swap 输出),首次进入页面时 balanceEl=null → getBalance() 返回 0 → betAmount(10) > 0 为 true → 前端拦下并 toast 余额不足

    • 修复: dice_index.htm 投注档位信息行加 <span id="dice-balance"> 显示初始余额;后端 OOB swap 输出带 class=fw-bold text-body 保持替换后样式一致

    • 必测: ?dice 页面投注(余额充足时不再误报余额不足;投注后余额实时刷新)

  • [组件混用] xnx_dice 骰子点数从 CSS radial-gradient 改为 Tabler Icons 图标

    • 每个 dice-face 内加 <i class="ti ti-dice-N">(N=16),移除 face-16 的 background-image radial-gradient 点数绘制

    • CSS 改为 flex 居中 + font-size 控制图标大小(桌面 48px / 移动 36px),保留 3D 立方体翻滚动画

    • 必测: ?dice 页面骰子显示图标 + 摇骰子翻滚动画 + 定格到结果面

  • [HTMX事件冲突] 修复 xnx_dice 骰子摇不完(结果已显示但骰子永不停止)

    • 根因: htmx 4 移除了 evt.detail.target(改用 evt.detail.ctx),dice.js 4 个事件监听器(htmx:after:swap/response:error/after:request)都依赖 evt.detail.target 判断是否为 #dice-result,htmx 4 中该字段为 undefined → 每次都 return → stopRolling() 永远不被调用

    • 修复: 移除对 evt.detail.target 的依赖,改为检查 state.isAnimating + DOM 中 #dice-result 是否有 data-dice1 属性;htmx:after:request 的 failed 检查增加 ctx.failed 回退

    • 必测: ?dice 投注后骰子翻滚动画在 ~1.2s 后停止并定格到结果面

  • [组件混用] xnx_dice 骰子点数改回 radial-gradient(回退上一版 Tabler Icons 图标方案),同步优化 UI

    • 恢复: 移除 <i class="ti ti-dice-N"> 标签,恢复 face-1~6 的 background-image radial-gradient 点数绘制

    • UI 优化: 骰子面圆角 12→14px、内阴影增强、点数 10→11px、定格过渡用弹性曲线 cubic-bezier(0.34,1.56,0.64,1)、perspective 1000→1200 视角上移

    • UI 优化: 押大小按钮加 py-2 增大触控区、投注信息条用 bg-body-tertiary 包裹分列布局、档位按钮选中态抬升+阴影、摇骰子按钮 hover 抬升+阴影、历史记录项圆角

    • 必测: ?dice 页面骰子点数显示 + 翻滚动画 + 押大小按钮 + 档位按钮选中态

  • [新功能] xnx_dice 庄家操控:大额投注按概率强制让用户输(管理员豁免)

    • 后台基本设置 Tab 加「庄家操控」区块:开关 + 阈值 + 概率(0-100%)

    • DiceService::shouldManipulate() 判断逻辑:开启 && 非管理员(gid=1,2) && 投注≥阈值 && random_int(1,100)≤概率

    • DiceService::generateLosingDice() 生成必输骰子组合:押大→小或豹子、押小→大或豹子、押单字N→不含N

    • play() 方法加 $gid 参数,route/dice.php 调用时传入

    • 默认关闭(house_edge_enabled=0),需后台手动开启

    • 必测: 后台设置页保存操控配置 + 普通用户大额投注输了 + 管理员大额投注不受影响

  • [新功能] xnx_dice 右侧栏加盈亏排行榜

    • DiceService::getTopPlayers(10) 聚合 SUM(profit) 降序,缓存 5 分钟,批量查用户名避免 N+1

    • dice_index.htm 右侧栏用户卡下方加排行榜卡,Top3 显示奖牌图标,盈亏正数绿色负数红色

    • 必测: ?dice 右侧栏显示排行榜 + 投注后排行榜更新(缓存 5 分钟延迟)

  • [优化] xnx_dice 输赢反馈体验增强

    • 中奖:骰子舞台绿色光晕脉冲 1.5s + 浮动 +N 数字飞出 + 余额高亮 + 移动端长振

    • 输了:骰子舞台红色闪烁 0.8s + 浮动 -N 数字飞出 + 余额高亮 + 移动端短振

    • 必测: ?dice 投注后观察舞台光效 + 浮动数字 + 余额变化动画

  • [逻辑错误] 优化 cache_debug 日志:只记录缓存未命中(MISS),不再记录 HIT/SET

    • 根因: CacheHelper.php:366 DEBUG>1 时记录每次缓存 HIT/MISS/SET,首页一次请求产生几十条日志,cache_debug.php 一天 1.6MB/1073 行,99% 是无价值的 HIT/SET 噪声

    • 修复: 增加 $type === 'miss' 条件,只记录 MISS(未命中需回源查询的事件),HIT/SET 是正常行为不记录

    • 预期: 日志量从 1073 行/天 降到约 50 行/天(仅首次缓存未命中),减少 95%+

    • 必测: 首页/话题页/帖子详情页访问后查看 log/202607/cache_debug.php,确认只有 MISS 无 HIT/SET

  • [UI优化] xnx_dice 结果区重构:从按钮下方 alert 改为骰子正下方大号结果组件

    • 移动: #dice-result 从摇骰子按钮下方移到骰子舞台正下方,不再覆盖押注区域

    • 重构: 后端返回的 alert-secondary 改为专属 .dice-outcome 组件(大号状态图标3rem + 大号盈亏数字2.2rem + 点数和 + 左边框颜色条 + 渐变背景)

    • 视觉: 中奖绿色渐变+奖杯图标+加号金额、输了红色渐变+悲伤图标+减号金额、错误橙色边框

    • 动画: 结果出现时弹性放大 cubic-bezier(0.34,1.56,0.64,1),移动端字号缩小

    • 必测: ?dice 投注后骰子正下方弹出大号结果组件,押注区域不被覆盖

  • [信息泄露] 删除 message() 函数遗留的调试 error_log,清理 PHP errors.log 噪声

    • 根因: model/misc.func.php:289-294 有一段调试代码,每次 message() 被调用都 error_log 一条请求头信息到 PHP 全局 errors.log。message() 是 Xiuno 提示消息函数(登录/发帖/回复/点赞等都调用),导致 ServBay 的 /Applications/ServBay/logs/php/8.5/errors.log 膨胀到 3.9MB,最近 100 行全是 "[message()] is_htmx= HX-Request=(none) X-Requested-With=XMLHttpRequest HX-Boosted=(none) code=0" 这种无调试价值的噪声,真正的 PHP 错误被淹没

    • 修复: 删除 if(DEBUG){error_log(...)} 整段调试代码块

    • 清缓存: tmp/model_misc.func.php(misc.func.php 通过 _include() 加载,有编译缓存)

    • 必测: 任意触发 message() 的操作(登录/发帖/回复),确认 errors.log 不再新增 "[message()]" 行

  • [bug修复] xnx_dice 结果区显示太快:after:swap 时先隐藏 #dice-result(visibility:hidden),骰子停止后才显示

  • [bug修复] xnx_dice 今日盈亏显示为0:sidebar_stats value 传带+前缀字符串被 intval 变0,改为传纯数字;去掉无效的 #dice-stats/#dice-today-profit OOB(sidebar 用 data-key 非 id),改为 data-* 属性 + JS 更新 sidebar [data-key=today_count/today_profit]

  • [bug修复] xnx_dice 排行榜头像不显示:user_find_by_uids 返回的 avatar 是原始数字非 URL,改用 avatar_component($uid, sm) 生成头像

  • [优化] xnx_dice 排行榜加总投注次数显示 + 标题旁加「每5分钟更新」提示

  • [优化] xnx_dice 玩法说明去掉押单字相关内容(保留大/小/豹子),后台设置去掉 odds_number_1/2/3 赔率配置

    • 必测: ?dice 投注后骰子先停再显示结果 + 今日盈亏正确更新 + 排行榜头像正常 + 玩法说明无押单字

    • 必测: 后台插件设置页赔率只显示押大小一项

  • [bug修复] xnx_dice play action 中 $today_count 未定义错误:统计计算在 echo 之后,提前到 echo 之前

  • [bug修复] xnx_dice 今日盈亏显示:JS 更新用纯数字+class 控制颜色,与 sidebar 模板 intval 输出一致

最新回复

请先登录后再回复 登录

uid:1 管理
关注
随遇而安,随缘而行
发帖 84
评论 346
粉丝 11
关注 1
发新帖
目录
XIUNOX 更新记录贴 202600712