-- ============================================ -- 坐标记录器(后台常驻版) -- 首次启动输入文件名,文件保存在 /storage/emulated/0/胡桃/ -- 点击GG悬浮窗弹出菜单,显示保存路径 -- ============================================ pcall(function() gg.setVisible(false) end) pcall(function() if luajava and luajava.setFloatingWindowHide then luajava.setFloatingWindowHide(true) end end) local COORD_DIR = "/storage/emulated/0/胡桃" local FILE_NAME = "坐标合集" local COORD_FILE = COORD_DIR .. "/" .. FILE_NAME .. ".txt" -- ========== 尝试创建文件夹 ========== pcall(function() if file and file.mkdir then file.mkdir(COORD_DIR) else os.execute('mkdir -p "' .. COORD_DIR .. '" 2>/dev/null') end end) -- ========== 首次启动:让用户输入文件名 ========== local first_run = true if first_run then local prompt = gg.prompt({ "请输入坐标文件名(不含后缀,默认:坐标合集)" }, {"坐标合集"}, {"text"}) if prompt and prompt[1] and prompt[1] ~= "" then FILE_NAME = prompt[1] end first_run = false end COORD_FILE = COORD_DIR .. "/" .. FILE_NAME .. ".txt" -- ========== 提示用户文件保存位置 ========== gg.alert( "📍 坐标记录器已启动\n\n" .. "坐标文件将保存到:\n" .. COORD_FILE .. "\n\n" .. "点击「确定」开始后台运行\n" .. "之后点击 GG 悬浮窗弹出菜单操作" ) -- ========== 获取坐标(使用新链) ========== function get_world_coords() local ranges = gg.getRangesList('libyuanshen.so:bss') if not ranges or #ranges == 0 then ranges = gg.getRangesList('libyuanshen.so') if not ranges then return nil end for _, r in ipairs(ranges) do if r.state == "Cb" then ranges = {r} break end end if not ranges or #ranges == 0 then return nil end end local bss = ranges[1] -- 新链:libyuanshen.so:bss[1]+0x309100+0x800 local ptr_addr = bss.start + 0x309100 local val = gg.getValues({{address = ptr_addr, flags = gg.TYPE_QWORD}}) if not val or not val[1] or val[1].value == 0 then return nil end local ptr = val[1].value + 0x800 -- ptr 指向 Y 轴 local vals = gg.getValues({ {address = ptr - 4, flags = gg.TYPE_FLOAT}, -- X {address = ptr, flags = gg.TYPE_FLOAT}, -- Y {address = ptr + 4, flags = gg.TYPE_FLOAT} -- Z }) if not vals or #vals < 3 then return nil end return {x = vals[1].value, y = vals[2].value, z = vals[3].value} end -- ========== 获取已有点数 ========== function get_point_count() local f = io.open(COORD_FILE, "r") if not f then return 0 end local count = 0 for _ in f:lines() do count = count + 1 end f:close() return count end -- ========== 保存坐标 ========== function save_coord(x, y, z) local count = get_point_count() + 1 local name = "点" .. count local line = string.format('{"description":"","name":"%s","position":[%.10f,%.10f,%.10f]}', name, x, y, z) local f = io.open(COORD_FILE, "a") if f then f:write(line .. "\n") f:close() return true, count else gg.toast("❌ 无法写入文件: " .. COORD_FILE) return false, nil end end -- ========== 记录动作 ========== function do_record() local coords = get_world_coords() if not coords then gg.toast("❌ 获取坐标失败,确认角色在大世界") return end local ok, num = save_coord(coords.x, coords.y, coords.z) if ok then gg.toast(string.format("✅ 已记录 点%d (%.1f, %.1f, %.1f)", num, coords.x, coords.y, coords.z)) else gg.toast("❌ 保存失败") end end -- ========== 显示菜单 ========== function show_menu() local coords = get_world_coords() local count = get_point_count() local menu_title = string.format("📁 %s 已记录 %d 个点", FILE_NAME, count) if coords then menu_title = menu_title .. string.format("\n%.1f %.1f %.1f", coords.x, coords.y, coords.z) else menu_title = menu_title .. "\n未获取到坐标" end menu_title = menu_title .. "\n📂 " .. COORD_FILE local choice = gg.choice({ "📝 记录坐标", "📊 查看点数", "📂 查看保存路径", "🚪 退出脚本" }, menu_title, "取消") if choice == 1 then do_record() elseif choice == 2 then gg.toast("📊 已记录 " .. count .. " 个坐标点") elseif choice == 3 then gg.alert("坐标文件保存在:\n" .. COORD_FILE .. "\n\n您可以通过文件管理器查看") elseif choice == 4 then gg.toast("📍 已退出") os.exit() end end -- ========== 主循环(后台常驻) ========== gg.toast("📍 坐标记录器已启动,点击GG悬浮窗操作") local trigger = 0 while true do if gg.isVisible(true) then trigger = 1 gg.setVisible(false) end if trigger == 1 then show_menu() trigger = 0 end gg.sleep(100) end