总时长:
0
@@ -1263,13 +1295,15 @@
const ADJUSTMENT_THROTTLE = 100; // 100ms节流
let currentExcludeText = ''; // 保存当前的排除文本
- // 在全局变量区域添加拾取效率相关变量
let currentPickEfficiencyItem = null; // 当前计算的拾取物
let isPickEfficiencyMode = false; // 是否处于拾取效率模式
let picksSortByCount = true; // true: 按数量排序, false: 按拾取顺序
let currentSortState = 0; // 0:读取顺序, 1:时间排序, 2:耗时升序, 3:耗时降序
+ let isTimeFilterMode = false; // 时间筛选模式
+ let timeFilterStart = null; // 筛选开始时间
+ let timeFilterEnd = null; // 筛选结束时间
// 自定义确认对话框
function showCustomConfirm(title, message) {
@@ -1433,13 +1467,47 @@
allGroups: []
};
+ // 取得URL参数(大小寫兼容)
+ function getValue(varname) {
+ const url = window.location.href;
+ const urlObj = new URL(url);
+ const params = new URLSearchParams(urlObj.search);
+
+ // 1. 首先嘗試原始大小寫
+ let value = params.get(varname);
+ if (value !== null) {
+ return value;
+ }
+
+ // 2. 如果沒有找到,嘗試小寫
+ const paramNames = Array.from(params.keys());
+ const matchedName = paramNames.find(name =>
+ name.toLowerCase() === varname.toLowerCase()
+ );
+
+ // 返回匹配的參數值,如果找不到則返回空字符串
+ return matchedName ? params.get(matchedName) : "";
+ }
+
// 页面加载时显示帮助提示
window.onload = function () {
- const now = new Date();
- const currentHour = now.getHours();
- const minutes = now.getMinutes();
- if ((currentHour < 6) || (currentHour === 6 && minutes <= 30)) {
+ // 首先读取URL参数
+ const themeParam = getValue("C");
+ const boxParam = getValue("LBox");
+
+ // 1. 设置主题(参数优先级最高)
+ if (themeParam === "1") {
document.body.classList.add('dark-theme');
+ } else if (themeParam === "0") {
+ document.body.classList.remove('dark-theme');
+ } else {
+ // 如果没有主题参数,使用原来的时间判断逻辑
+ const now = new Date();
+ const currentHour = now.getHours();
+ const minutes = now.getMinutes();
+ if ((currentHour < 6) || (currentHour === 6 && minutes <= 30)) {
+ document.body.classList.add('dark-theme');
+ }
}
// 显示帮助提示
@@ -1468,8 +1536,14 @@
document.body.classList.add('mobile-device');
document.getElementById('fileUploadContainer').classList.add('visible');
} else {
- // 电脑设备保持隐藏状态
- document.getElementById('fileUploadContainer').classList.remove('visible');
+ // 电脑设备:如果参数指定显示,则显示;否则保持隐藏
+ if (boxParam === "true") {
+ document.getElementById('fileUploadContainer').classList.add('visible');
+ uploadContainerVisible = true; // 根据参数设置显示,变量设为true
+ } else {
+ document.getElementById('fileUploadContainer').classList.remove('visible');
+ uploadContainerVisible = false; // 根据参数设置隐藏,变量设为false
+ }
}
// 初始化功能按钮状态
@@ -1496,11 +1570,12 @@
84: timeColumnsVisible, // 时间列
89: statsColumnsVisible, // 统计列
73: picksColumnsVisible, // 拾取物列
- // 79: isPickEfficiencyMode, // 拾取效率模式(新增)
+ // 79: isPickEfficiencyMode, // 拾取效率模式
80: isStaticMode, // 导出模式
74: hideZeroStatsTasks, // 异常任务
72: isFilterMode, // 任務篩選
- 77: false // 统计拾取物(新增)
+ 77: false, // 统计拾取物
+ 100: isTimeFilterMode // 时间筛选模式
};
// 更新按钮显示状态
@@ -1560,9 +1635,12 @@
// case 85: // 表格格式切换
// isActive = useLegacyFormat;
// break;
- case 77: // 统计拾取物(新增)- 始终为false,只是占位符
+ case 77: // 统计拾取物- 始终为false,只是占位符
isActive = false;
break;
+ case 100: // 数字键盘4 - 时间筛选
+ isActive = isTimeFilterMode;
+ break;
}
// 更新按钮状态
@@ -1585,104 +1663,6 @@
}
}
- // 处理文件选择事件
- async function handleFileSelect(e) {
- const files = Array.from(e.target.files)
- .filter(f => f.name.startsWith('better-genshin-impact'))
- .sort((a, b) => parseDateFromFileName(a.name) - parseDateFromFileName(b.name));
-
- if (files.length === 0) {
- alert('请选择BetterGI日志文件(文件名以better-genshin-impact开头)');
- return;
- }
-
- parsingContext.activeGroups.clear();
- parsingContext.activeTasks.clear();
- parsingContext.allGroups = [];
-
- try {
- resetTimeTracker();
- document.getElementById('dropZone').innerHTML = '
解析中...
';
- document.getElementById('dropZone').className = 'has-content';
-
- for (const file of files) {
- const content = await readFileAsText(file);
- parseLog(content, parseDateFromFileName(file.name));
- }
-
- const result = finalizeParsing();
- document.getElementById('dropZone').innerHTML = generateHTML(result);
- setupCoordPopups();
- document.querySelectorAll('.group-header').forEach((el, i) => {
- el.onclick = (e) => {
- const arrow = el.querySelector('.arrow');
- const content = document.getElementById(`group-${i}`);
- const container = el.closest('.group-container');
-
- // 获取配置组标题和内容的位置信息
- const headerRect = el.getBoundingClientRect();
- const containerRect = container.getBoundingClientRect();
-
- // 判断标题是否在可视区域顶部(考虑固定定位)
- const isStickyAtTop = headerRect.top <= 15 && headerRect.top >= -10;
-
- if (isStickyAtTop) {
- // 计算需要滚动到的位置
- // 让配置组标题滚动到距离顶部30px的位置
- const targetPosition = container.offsetTop - 40;
- const currentPosition = dropZone.scrollTop;
- const scrollDistance = Math.abs(targetPosition - currentPosition);
-
- // 计算滚动时间:根据距离,但不小于300ms,不大于2000ms,然后加上500ms的额外时间
- const scrollDuration = Math.min(2000, Math.max(200, scrollDistance)) + 50;
-
- // 使用平滑滚动
- dropZone.scrollTo({
- top: targetPosition,
- behavior: 'smooth'
- });
-
- // 在滚动完成后再折叠,使用计算出的时间
- setTimeout(() => {
- toggleCollapseState(el, content, arrow);
- }, scrollDuration);
-
- } else {
- // 已经在顶部,直接折叠
- toggleCollapseState(el, content, arrow);
- }
- };
- });
-
- // 应用初始显示状态
- updateTimeColumnsVisibility();
- updateStatsColumnsVisibility();
- updateTableFormat();
- setupRowHighlight();
-
- // 使用防抖版本
- setTimeout(() => {
- debouncedAdjustTableHeader();
- }, 150);
- // 标记已有日志数据
- hasLogData = true;
- showQuickNavToggle();
- } catch (e) {
- document.getElementById('dropZone').innerHTML = `
解析失败:${e.message}
`;
- hideQuickNavToggle();
- }
- }
-
- // 读取文件内容为文本
- function readFileAsText(file) {
- return new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onload = e => resolve(e.target.result);
- reader.onerror = e => reject(e);
- reader.readAsText(file);
- });
- }
-
// 任務篩選功能
function toggleTaskFilter() {
if (isFilterMode) {
@@ -1726,15 +1706,15 @@
if (hideZeroStatsTasks) {
toggleZeroStatsTasksInFilterMode();
}
-
+ // 更新任務數量
+ updateTaskCounts();
// 顯示篩選提示
showFilterIndicator();
-
// 更新按鈕狀態
updateButtonState(72);
}
- // 修改退出筛选模式的函数,确保正确处理零统计状态
+ // 退出筛选模式的函数,确保正确处理零统计状态
function exitFilterMode() {
isFilterMode = false;
currentFilterKeywords = [];
@@ -1773,7 +1753,7 @@
updateButtonState(72);
}
- // 修改 applyTaskFilter 函数,在筛选模式下隐藏所有拾取物
+ // 在筛选模式下隐藏所有拾取物
function applyTaskFilter() {
const tables = document.querySelectorAll('table');
@@ -1937,6 +1917,7 @@
// 筛选后调整表头位置
setTimeout(() => {
adjustTableHeaderPosition();
+ updateTaskCounts(); // 更新任务数量显示
refreshQuickNav();
}, 50);
}
@@ -1953,7 +1934,7 @@
teamRolesRow.style.display = '';
}
- // 显示所有行,但根据拾取效率模式状态处理拾取物行
+ // 显示所有行,但根据模式状态处理拾取物行
const rows = table.querySelectorAll('tr');
rows.forEach(row => {
if (!row.querySelector('th')) {
@@ -1977,6 +1958,7 @@
// 重新调整表头位置
setTimeout(() => {
adjustTableHeaderPosition();
+ updateTaskCounts(); // 更新任务数量显示
refreshQuickNav();
}, 50);
}
@@ -2015,15 +1997,34 @@
dropZone.classList.remove('dragover');
});
+ // 處理拖放事件
dropZone.addEventListener('drop', async e => {
e.preventDefault();
dropZone.style.backgroundColor = '';
- const files = Array.from(e.dataTransfer.files)
+ const success = await processFiles(e.dataTransfer.files);
+ if (!success) {
+ alert('请拖入BetterGI日志文件(文件名以better-genshin-impact开头)');
+ }
+ });
+
+ // 處理文件選擇事件
+ async function handleFileSelect(e) {
+ const success = await processFiles(e.target.files);
+ if (!success) {
+ alert('请选择BetterGI日志文件(文件名以better-genshin-impact开头)');
+ }
+ }
+
+ //處理文件列表的通用函數
+ async function processFiles(fileList) {
+ const files = Array.from(fileList)
.filter(f => f.name.startsWith('better-genshin-impact'))
.sort((a, b) => parseDateFromFileName(a.name) - parseDateFromFileName(b.name));
- if (files.length === 0) return;
+ if (files.length === 0) {
+ return false;
+ }
parsingContext.activeGroups.clear();
parsingContext.activeTasks.clear();
@@ -2032,6 +2033,7 @@
try {
resetTimeTracker();
dropZone.innerHTML = '
解析中...
';
+ dropZone.className = 'has-content';
for (const file of files) {
const content = await file.text();
@@ -2039,10 +2041,10 @@
}
const result = finalizeParsing();
- dropZone.className = 'has-content';
dropZone.innerHTML = generateHTML(result);
setupCoordPopups();
- // 修改折叠功能事件处理
+
+ // 折叠功能事件处理
document.querySelectorAll('.group-header').forEach((el, i) => {
el.onclick = (e) => {
const arrow = el.querySelector('.arrow');
@@ -2090,22 +2092,28 @@
updateStatsColumnsVisibility();
// 应用初始表格格式
updateTableFormat();
-
// 设置行高亮效果
setupRowHighlight();
+ // 使用防抖版本調整表頭
+ setTimeout(() => {
+ debouncedAdjustTableHeader();
+ }, 150);
+
// 第二次讀檔時保留各功能状态
- if (hasLogData = true) {
+ if (hasLogData) {
refreshHTML();
}
// 标记已有日志数据
hasLogData = true;
showQuickNavToggle();
+ return true;
} catch (e) {
dropZone.innerHTML = `
解析失败:${e.message}
`;
hideQuickNavToggle();
+ return false;
}
- });
+ }
function setupSortButtons() {
// 时间排序按钮
@@ -2346,7 +2354,7 @@
});
}
- // 修改坐标弹窗事件处理函数
+ // 坐标弹窗事件处理函数
function setupCoordPopups() {
const coordsCells = document.querySelectorAll('.coords-cell');
const battleCells = document.querySelectorAll('.has-battle-events');
@@ -2807,13 +2815,13 @@
SURVIVAL_AFTER_SKILL: 20, // 生存位技能后的切换 +20
NORMAL_SWITCH: 1, // 一般成功切换角色 +1
COLLECTION_SWITCH: -100, // 采集相关切换 -100(确保排除)
- MOVEMENT_CONTEXT: 5 // 新增:移动上下文权重 +8
+ MOVEMENT_CONTEXT: 5 // 移动上下文权重 +8
};
// 任务级别的角色统计
let survivalWeights = new Map(); // 生存位权重
let walkWeights = new Map(); // 行走位权重
- let dashWeights = new Map(); // 新增:赶路位权重
+ let dashWeights = new Map(); // 赶路位权重
let lastSwitchedRole = null; // 记录最近切换的角色
let pendingSurvivalAction = false; // 标记有生存位动作待处理
let nahidaCollect = false; // 纳西妲采集标记
@@ -2844,7 +2852,7 @@
pendingSurvivalAction = true;
}
- // 新增:检测赶路位指令
+ // 检测赶路位指令
if (line.includes('自动赶路:"') && line.includes('赶路')) {
const dashMatch = line.match(/自动赶路:"(.+?)" 赶路/);
if (dashMatch && currentGroup && currentTask) {
@@ -2874,7 +2882,7 @@
let survivalWeightToAdd = 0;
let walkWeightToAdd = 0;
- // 新增:检查最近是否有赶路操作
+ // 检查最近是否有赶路操作
const hasRecentDash = currentTask.recentDashRole === roleName;
// 采集相关的切换 - 给负权重确保排除
@@ -2895,7 +2903,7 @@
walkWeightToAdd = WEIGHTS.NORMAL_SWITCH * 10;
}
- // 新增:移动上下文权重判断
+ // 移动上下文权重判断
if (prevLine.includes('到达路径点附近') ||
prevLine.includes('执行 "简易策略脚本"') ||
prevLine.includes('粗略接近途经点') ||
@@ -2903,7 +2911,7 @@
walkWeightToAdd += WEIGHTS.MOVEMENT_CONTEXT;
}
- // 新增:交互或拾取后的切换权重 +8
+ // 交互或拾取后的切换权重 +8
if (prevLine.includes('交互或拾取:"')) {
walkWeightToAdd += 8;
}
@@ -2939,8 +2947,8 @@
teamRoles: new Set(),
survivalRoles: [], // 生存位
walkRoles: [], // 行走位
- dashRoles: [], // 新增:赶路位
- hasRotationTargeting: false // 新增:旋转索敌标记
+ dashRoles: [], // 赶路位
+ hasRotationTargeting: false // 旋转索敌标记
};
group.lastActive = parseTime(prevLine, fileDate);
parsingContext.activeGroups.set(groupName, group);
@@ -2983,7 +2991,7 @@
// 汇总配置组的角色信息
const groupSurvivalRoles = new Map();
const groupWalkRoles = new Map();
- const groupDashRoles = new Map(); // 新增:赶路位汇总
+ const groupDashRoles = new Map(); // 赶路位汇总
group.tasks.forEach(task => {
// 汇总生存位 - 只取每个任务的主要生存位
@@ -3085,15 +3093,15 @@
timeout: 0
},
picks: new Map(),
- reviveEvents: [], // 新增:复活事件
- timeoutEvents: [], // 新增:超时事件
+ reviveEvents: [], // 复活事件
+ timeoutEvents: [], // 超时事件
maxBattleCount: 0, // 记录最大战斗次数
- specialAlerts: new Map(), // 修改:使用Map而不是数组,用于计数特殊事件
- survivalRoles: [], // 新增:生存位角色
- walkRoles: [], // 新增:行走位角色
- dashRoles: [], // 新增:赶路位角色
- recentDashRole: null, // 新增:最近的赶路角色,用于排除行走位权重
- skipped: false // 新增跳过标记
+ specialAlerts: new Map(), // 用于计数特殊事件
+ survivalRoles: [], // 生存位角色
+ walkRoles: [], // 行走位角色
+ dashRoles: [], // 赶路位角色
+ recentDashRole: null, // 最近的赶路角色,用于排除行走位权重
+ skipped: false // 跳过标记
};
currentGroup.tasks.push(task);
parsingContext.activeTasks.set(task.name, task);
@@ -3161,7 +3169,7 @@
// 保存到任务
task.survivalRoles = finalSurvivalRole ? [finalSurvivalRole] : [];
task.walkRoles = finalWalkRole ? [finalWalkRole] : [];
- task.dashRoles = finalDashRole ? [finalDashRole] : []; // 新增:保存赶路位
+ task.dashRoles = finalDashRole ? [finalDashRole] : [];
// 调试输出
// console.log(`任务 ${task.name} 生存位权重:`, Array.from(survivalWeights.entries()));
@@ -3257,10 +3265,15 @@
}
}
// if (line.includes("距离过远,跳过路径点")) currentTask.faults.too_far_skip++;
- if (line.includes("距离过远") && /\(\d+\.?\d*,\d+\.?\d*\)->\(\d+\.?\d*,\d+\.?\d*\)=\d+\.?\d*,跳过路径点/)
+ // 0.56.后不傳回极大的坐标
+ if (
+ (line.includes("距离过远") && /\(\d+\.?\d*,\d+\.?\d*\)->\(\d+\.?\d*,\d+\.?\d*\)=\d+\.?\d*,跳过路径点/) ||
+ line.includes("未识别到当前位置")
+ ) {
currentTask.faults.too_far_skip++;
+ }
- if (line.includes(",重试多次后仍然失败,放弃此路径点!")) {
+ if (line.includes(",重试多次后仍然失败,放弃此路径点!") || line.includes("执行超时,放弃此次追踪")) {
const message = '路径识别失败,放弃路径';
const type = 'abnormal-alert';
if (currentTask.specialAlerts.has(message)) {
@@ -3383,7 +3396,10 @@
}
// 6. 战斗脚本设置错误
- if (line.includes('执行脚本时发生异常: "未匹配到任何战斗脚本"') || line.includes('执行地图追踪时候发生错误: "未匹配到任何战斗脚本"')) {
+ if (
+ line.includes('执行脚本时发生异常: "未匹配到任何战斗脚本"')
+ || line.includes('执行地图追踪时候发生错误: "未匹配到任何战斗脚本"')
+ || line.includes('执行地图追踪时候发生错误: "战斗策略文件不存在"')) {
const message = '未匹配到任何战斗脚本';
const type = 'combat-script-error';
if (currentTask.specialAlerts.has(message)) {
@@ -3668,8 +3684,14 @@
}
// 27.鋤地一條龍(坐标获取异常,不记录运行数据)
- if (line.includes('坐标获取异常,不记录运行数据') ||
- (line.includes('出现异常') && line.includes('不记录cd'))) {
+ if (
+ line.includes('坐标获取异常,不记录运行数据') || // 鋤地2.0.2前日志
+ line.includes('路线未正常完成、坐标获取异常或不处于主界面,不记录运行数据') || // 鋤地2.0.3日志
+ line.includes('距离异常,不记录数据') || // 采集cd管理
+ (line.includes('出现异常') && line.includes('不记录cd')) ||
+ line.includes('出发点与终点过于接近,不记录运行数据') ||
+ line.includes('位置几乎未变化,不更新刷新时间')
+ ) {
const message = '终点坐标异常,不记录';
const type = 'abnormal-alert';
currentTask.faults.too_far_skip++;
@@ -3814,7 +3836,7 @@
currentTask.picks.set(pickItemName, (currentTask.picks.get(pickItemName) || 0) + 1);
currentGroup.picks.set(pickItemName, (currentGroup.picks.get(pickItemName) || 0) + 1);
- // 新增:記錄拾取順序
+ // 記錄拾取順序
if (!currentTask.pickSequence) {
currentTask.pickSequence = [];
}
@@ -3839,7 +3861,7 @@
return nameWithoutExt;
}
- // 新增函数:检查任务是否有实际执行内容
+ // 检查任务是否有实际执行内容
function hasTaskActualContent(task) {
// 如果有任何统计信息不为0,说明有实际执行
if (task.faults.revive > 0 ||
@@ -3934,14 +3956,14 @@
return result.join('') || "0秒";
}
- // 新增耗时计算函数
+ // 耗时计算函数
function calculateDuration(start, end) {
if (!start || !end) return '进行中';
const diff = (end.getTime() - start.getTime()) / 1000;
return formatDuration(diff);
}
- // 新增配置组耗时计算
+ // 配置组耗时计算
function calculateGroupDuration(group) {
if (!group.startTime || !group.endTime) return '进行中';
const diff = (group.endTime.getTime() - group.startTime.getTime()) / 1000;
@@ -4106,7 +4128,7 @@
}
}
- // 檢查赶路位(新增)- 改为模糊匹配
+ // 檢查赶路位 - 改为模糊匹配
if (group.dashRoles && group.dashRoles.length > 0) {
const dashRoleNames = roleStr.split(',').map(r => r.trim());
const foundDashRoles = group.dashRoles.filter(dashRole =>
@@ -4136,10 +4158,12 @@
`;
}
- // 修改表头,在拾取物列添加效率按钮
html += `