diff --git a/app/src/main/java/com/bytecat/algui/ui/Main.java b/app/src/main/java/com/bytecat/algui/ui/Main.java index 44ae410..0ba5b1e 100644 --- a/app/src/main/java/com/bytecat/algui/ui/Main.java +++ b/app/src/main/java/com/bytecat/algui/ui/Main.java @@ -32,12 +32,12 @@ import com.bytecat.algui.effect.ModuleManager; import android.text.TextUtils; public class Main { -public static boolean alreadyloggin; + public static boolean alreadyloggin; public static boolean vt1 = true; public static boolean vt2 = false; public static boolean vt3 = false; -// 水印单例,全局可用 -public static AlguiV.TVNoSignalText tvNoSignal = null; + // 水印单例,全局可用 + public static AlguiV.TVNoSignalText tvNoSignal = null; private static ExecutorService executor = Executors.newSingleThreadExecutor(); // 创建一个单线程线程池 public static void 音效播放() { @@ -54,24 +54,20 @@ public static AlguiV.TVNoSignalText tvNoSignal = null; } } -public static void 音效() { - new Thread(new Runnable() { - @Override - public void run() { - 音效播放(); // 调用音效方法 - } - }).start(); -} - - - - - - - public static void 远控音效() { - AlguiToolAudio.playAudio(aContext, "cont.ogg"); + public static void 音效() { + new Thread(new Runnable() { + @Override + public void run() { + 音效播放(); // 调用音效方法 + } + }).start(); } -public static String km; + + public static void 远控音效() { + AlguiToolAudio.playAudio(aContext, "cont.ogg"); + } + + public static String km; // 内存修改示例 public static boolean initialized; @@ -92,26 +88,26 @@ public static String km; private static void Net2FA(final Activity currentActivity) { AlguiWin2FA.Get(currentActivity, currentActivity) - .setCatWYAppID("57182") - .setCatWYAppCode("1.0") - .setCatWYOkCode(42589214) - .setCatWYAppKey("LL9EeZ8LResQ899i") - .setCatWYRC4_2("11L79sm1O5y57182") - .addRemoteFieldName("otone") - .addRemoteFieldName("ottwo") - .startWY(new AlguiCallback.WY2FA() { + .setCatWYAppID("57182") + .setCatWYAppCode("1.0") + .setCatWYOkCode(42589214) + .setCatWYAppKey("LL9EeZ8LResQ899i") + .setCatWYRC4_2("11L79sm1O5y57182") + .addRemoteFieldName("otone") + .addRemoteFieldName("ottwo") + .startWY(new AlguiCallback.WY2FA() { + public void success(String kami, String user, String vip, HashMap remote) { + } - public void success(String kami, String user, String vip, HashMap remote) { - } - - public void success(String kami, String expireTime, HashMap field) { - MyMenu(kami, expireTime, field, currentActivity); - } - }); + public void success(String kami, String expireTime, HashMap field) { + MyMenu(kami, expireTime, field, currentActivity); + } + }); } - private static void MyMenu(final String kami, final String expireTime, HashMap field, final Activity currentActivity) { + private static void MyMenu(final String kami, final String expireTime, HashMap field, + final Activity currentActivity) { AlguiToolNative.loadLibrary("Algui"); RootService.bind(new Intent(currentActivity, AlguiRootClient.class), new AlguiRootService()); @@ -136,9 +132,7 @@ public static String km; if (codeList != null && !codeList.contains(markcode)) { AlguiToolNetwork.get(AlguiDocument.getAdd("codeList", markcode + ";")); count++; - - - + return "欢迎新用户!你是第" + count + "个用户"; } @@ -149,51 +143,40 @@ public static String km; protected void onPostExecute(String result) { AlguiToolAudio.playAudio(aContext, "oopen.ogg"); -alreadyloggin = true; + alreadyloggin = true; -//远控 -RemoteLinkWatcher.startWatching( - "https://sharechain.qq.com/a3d3ef114852299548ab41773813c9bc", - "https://sharechain.qq.com/788e56aa9ad0ebb26f149c12c535e916", - MIX.getContext() -); + // 远控 + RemoteLinkWatcher.startWatching( + "https://sharechain.qq.com/a3d3ef114852299548ab41773813c9bc", + "https://sharechain.qq.com/788e56aa9ad0ebb26f149c12c535e916", + MIX.getContext()); -final AlguiV a=AlguiV.Get(aContext);//获取UI快速构建器 - //绘制静态视图到屏幕上 - a.WinDraw - ( - a.TextTag(null, ""+ Build.BRAND + "\nAndroid" + Build.VERSION.RELEASE +"\nTrosCore v1.0.0", 0xCE000000, expireTime) - .setCatTextSize(8) - .setCatTextColor(0xFFFFFFFF) - ,//绘制的视图 - Gravity.BOTTOM | Gravity.START,//坐标原点 (这里右上原点) - 10, 10,//相对原点xy偏移 - false//视图是否可接收触摸事件 - ); + final AlguiV a = AlguiV.Get(aContext);// 获取UI快速构建器 + // 绘制静态视图到屏幕上 + a.WinDraw( + a.TextTag(null, "" + Build.BRAND + "\nAndroid" + Build.VERSION.RELEASE + "\nTrosCore v1.0.0", + 0xCE000000, expireTime) + .setCatTextSize(8) + .setCatTextColor(0xFFFFFFFF), // 绘制的视图 + Gravity.BOTTOM | Gravity.START, // 坐标原点 (这里右上原点) + 10, 10, // 相对原点xy偏移 + false// 视图是否可接收触摸事件 + ); - final AlguiV.TVNoSignalText tvNoSignal = new AlguiV.TVNoSignalText(); -tvNoSignal.start("TrosCore\nAccount:"+kami); // 开 - - - + final AlguiV.TVNoSignalText tvNoSignal = new AlguiV.TVNoSignalText(); + tvNoSignal.start("TrosCore\nAccount:" + kami); // 开 -// 初始化 MIX -MIX.init(currentActivity); + // 初始化 MIX + MIX.init(currentActivity); + String userName = TextUtils.isEmpty(AlguiWin2FA.wy_user) + ? "TrosCore用户" + : AlguiWin2FA.wy_user; - -String userName = TextUtils.isEmpty(AlguiWin2FA.wy_user) - ? "TrosCore用户" - : AlguiWin2FA.wy_user; - -ModuleManager.getInstance().setModuleEnabled( - "TrosCore", - true, - "Version:1.0.0 User:" + userName); - - - - + ModuleManager.getInstance().setModuleEnabled( + "TrosCore", + true, + "Version:1.0.0 User:" + userName); } }.execute(); diff --git a/app/src/main/java/com/bytecat/algui/ui/category/ESPCategoryBox.java b/app/src/main/java/com/bytecat/algui/ui/category/ESPCategoryBox.java index 8e309d2..f5ea1d2 100644 --- a/app/src/main/java/com/bytecat/algui/ui/category/ESPCategoryBox.java +++ b/app/src/main/java/com/bytecat/algui/ui/category/ESPCategoryBox.java @@ -81,362 +81,323 @@ import android.graphics.PointF; import java.util.Timer; import java.util.TimerTask; - - - - +// 导入数据结构类 +import com.bytecat.algui.ui.category.ESPDataStructures; public class ESPCategoryBox extends CategoryBox { Notification notification = Notification.getInstance(); - + AlguiWinDraw draw = initDraw(MIX.getContext()); - // 保留原有的标志变量 - - - public static final long BASE_OFFSET = 0x454090; + // 保留原有的标志变量 - private static long matrixsAddr; + public static final long BASE_OFFSET = 0x454090; - - private static float readFloatFromMemory(long address) throws NumberFormatException { + private static long matrixsAddr; + + private static float readFloatFromMemory(long address) throws NumberFormatException { if (address <= 0) { return 0; } String memData = AlguiMemTool.getMemoryAddrData(address, AlguiMemTool.TYPE_FLOAT); return Float.parseFloat(memData); - } - - - - - + } private static Activity context; + public static float x; + public static float y; + public static float z; - public static float x; -public static float y; -public static float z; + public static File dir = new File("/storage/emulated/0/TC配置文件/"); + public static File file = new File(dir, "coordinate1.txt"); - -public static File dir = new File("/storage/emulated/0/TC配置文件/"); -public static File file = new File(dir, "coordinate1.txt"); - - - - - - - -public static void 获取坐标() { -// 1. 获取bss段基址 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -long baseAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB); -// 2. 多级指针跳转计算坐标地址 -long pointerPath = baseAddr + BASE_OFFSET; -long jumpAddr1 = AlguiMemTool.jump64(pointerPath); -long jumpAddr2 = AlguiMemTool.jump64(jumpAddr1 + 0x0); -long jumpAddr3 = AlguiMemTool.jump64(jumpAddr2 + 0x70); -long jumpAddr4 = AlguiMemTool.jump64(jumpAddr3 + 0x10); -long finalAddr = jumpAddr4 + 0xA0; -// 3. 设置坐标地址 -long selfZaddr = finalAddr; -long selfYaddr = selfZaddr + 0x4; -long selfXaddr = selfZaddr + 0x8; -// 4. 验证坐标值 - z = readFloatFromMemory(selfXaddr); - x = readFloatFromMemory(selfZaddr); -float y0 = readFloatFromMemory(selfYaddr); - y = y0+30; //高度高一点 -} - -public static void 检查() { -File dir = new File("/storage/emulated/0/TC配置文件/"); -if (!dir.exists()) { - dir.mkdirs(); // 创建文件夹 -} -} - - - - - public ESPCategoryBox() { - contentContainer - - -.addView(createchushSwitchContentCard()) -.addView(createhzmbSwitchContentCard()) -.addView(createddhzSwitchContentCard()) - -; + public static void 获取坐标() { + // 1. 获取bss段基址 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + long baseAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB); + // 2. 多级指针跳转计算坐标地址 + long pointerPath = baseAddr + BASE_OFFSET; + long jumpAddr1 = AlguiMemTool.jump64(pointerPath); + long jumpAddr2 = AlguiMemTool.jump64(jumpAddr1 + 0x0); + long jumpAddr3 = AlguiMemTool.jump64(jumpAddr2 + 0x70); + long jumpAddr4 = AlguiMemTool.jump64(jumpAddr3 + 0x10); + long finalAddr = jumpAddr4 + 0xA0; + // 3. 设置坐标地址 + long selfZaddr = finalAddr; + long selfYaddr = selfZaddr + 0x4; + long selfXaddr = selfZaddr + 0x8; + // 4. 验证坐标值 + z = readFloatFromMemory(selfXaddr); + x = readFloatFromMemory(selfZaddr); + float y0 = readFloatFromMemory(selfYaddr); + y = y0 + 30; // 高度高一点 } + public static void 检查() { + File dir = new File("/storage/emulated/0/TC配置文件/"); + if (!dir.exists()) { + dir.mkdirs(); // 创建文件夹 + } + } + public ESPCategoryBox() { + contentContainer -private SwitchContentCard createchushSwitchContentCard() { - final SwitchContentCard chushSwitchContentCard = new SwitchContentCard("初始化", "初始化相关数据").OText("初始化", "初始化相关数据","Initialize","Initialize relevant data").setChecked(false); + .addView(createchushSwitchContentCard()) + .addView(createhzmbSwitchContentCard()) + .addView(createddhzSwitchContentCard()) - chushSwitchContentCard.setSwitchCallback(new SwitchCallback() { - @Override - public boolean onChecked(boolean newState) { + ; + } + + private SwitchContentCard createchushSwitchContentCard() { + final SwitchContentCard chushSwitchContentCard = new SwitchContentCard("初始化", "初始化相关数据") + .OText("初始化", "初始化相关数据", "Initialize", "Initialize relevant data").setChecked(false); + + chushSwitchContentCard.setSwitchCallback(new SwitchCallback() { + @Override + public boolean onChecked(boolean newState) { Main.音效(); -AlguiMemTool.setPackageName("com.vortex.celestial"); + AlguiMemTool.setPackageName("com.vortex.celestial"); if (newState) { - notification.make("绘制", "已开启","ESP","Open", Notification.Type.SUCCESS); -ModuleManager.getInstance().setModuleEnabled("绘制|ESP", true); + notification.make("绘制", "已开启", "ESP", "Open", Notification.Type.SUCCESS); + ModuleManager.getInstance().setModuleEnabled("绘制|ESP", true); zhenespkg = true; -// 启动 -draw = Fastesp.start(context); -draw.startDraw(); - + // 启动 + draw = Fastesp.start(context); + draw.startDraw(); + } else { - notification.make("绘制", "已关闭","ESP","close", Notification.Type.ERROR); -ModuleManager.getInstance().setModuleEnabled("绘制|ESP", false); -zhenespkg = false; -// 停止 -Fastesp.stop(); + notification.make("绘制", "已关闭", "ESP", "close", Notification.Type.ERROR); + ModuleManager.getInstance().setModuleEnabled("绘制|ESP", false); + zhenespkg = false; + // 停止 + Fastesp.stop(); } - return true; - } - }); + return true; + } + }); - return chushSwitchContentCard; -} + return chushSwitchContentCard; + } - - - - - -private BoxContentCard createhzmbSwitchContentCard() { + private BoxContentCard createhzmbSwitchContentCard() { // 创建一个可切换内容的卡片,用于显示和管理核心碰撞箱的设置 -final BoxContentCard hzmbSwitchContentCard = new BoxContentCard("目标", "选择绘制的目标") - .OText("目标", "选择绘制的目标", "The goal of drawing", "Select the target for drawing") - .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); + final BoxContentCard hzmbSwitchContentCard = new BoxContentCard("目标", "选择绘制的目标") + .OText("目标", "选择绘制的目标", "The goal of drawing", "Select the target for drawing") + .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); -// 创建一个可折叠的内容区域,用于放置设置选项 -Column column = new Column() - .setLayoutParams(new LinearParams() - .setWidth(BaseHelper.MatchParent) // 宽度填满父视图 - .setHeight(BaseHelper.WrapContent) // 高度自适应内容 - .setTopMargin(dip2pxInt(15))); // 顶部外边距为15dp -hzmbSwitchContentCard.setExpandableContent(column); // 将内容区域设置到卡片中 + // 创建一个可折叠的内容区域,用于放置设置选项 + Column column = new Column() + .setLayoutParams(new LinearParams() + .setWidth(BaseHelper.MatchParent) // 宽度填满父视图 + .setHeight(BaseHelper.WrapContent) // 高度自适应内容 + .setTopMargin(dip2pxInt(15))); // 顶部外边距为15dp + hzmbSwitchContentCard.setExpandableContent(column); // 将内容区域设置到卡片中 - - - final StatefulButton statefulButton = new StatefulButton("玩家","player", true); + final StatefulButton statefulButton = new StatefulButton("玩家", "player", true); statefulButton.setSwitchCallback(new SwitchCallback() { @Override public boolean onChecked(boolean newState) { if (zhenespkg) -if (newState) { -Fastesp.setDrawPlayers(true); -}else{ -Fastesp.setDrawPlayers(false); -} - - + if (newState) { + Fastesp.setDrawPlayers(true); + } else { + Fastesp.setDrawPlayers(false); + } return true; } }); - final StatefulButton statefulButton2 = new StatefulButton("物品","Article", false); + final StatefulButton statefulButton2 = new StatefulButton("物品", "Article", false); statefulButton2.setSwitchCallback(new SwitchCallback() { @Override public boolean onChecked(boolean newState) { if (zhenespkg) -if (newState) { -Fastesp.setDrawItems(true); -}else{ -Fastesp.setDrawItems(false); -} + if (newState) { + Fastesp.setDrawItems(true); + } else { + Fastesp.setDrawItems(false); + } return true; } }); - // 创建第一行按钮 Row buttonRow1 = new Row(); - buttonRow1.setLayoutParams(new LinearParams().setWidth(BaseHelper.MatchParent).setHeight(BaseHelper.WrapContent)); + buttonRow1 + .setLayoutParams(new LinearParams().setWidth(BaseHelper.MatchParent).setHeight(BaseHelper.WrapContent)); buttonRow1.addView(statefulButton); buttonRow1.addView(statefulButton2); column.addView(buttonRow1); - - - return hzmbSwitchContentCard; // 返回创建的卡片 } - - - - - - - - -private BoxContentCard createddhzSwitchContentCard() { + private BoxContentCard createddhzSwitchContentCard() { // 创建一个可切换内容的卡片,用于显示和管理核心碰撞箱的设置 -final BoxContentCard ddhzSwitchContentCard = new BoxContentCard("定点", "绘制一个可以保存的固定红点") - .OText("定点", "绘制一个可以保存的固定红点", "Fixed point", "Draw a fixed red dot that can be saved") - .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); + final BoxContentCard ddhzSwitchContentCard = new BoxContentCard("定点", "绘制一个可以保存的固定红点") + .OText("定点", "绘制一个可以保存的固定红点", "Fixed point", "Draw a fixed red dot that can be saved") + .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); -// 创建一个可折叠的内容区域,用于放置设置选项 -Column column = new Column() - .setLayoutParams(new LinearParams() - .setWidth(BaseHelper.MatchParent) // 宽度填满父视图 - .setHeight(BaseHelper.WrapContent) // 高度自适应内容 - .setTopMargin(dip2pxInt(15))); // 顶部外边距为15dp -ddhzSwitchContentCard.setExpandableContent(column); // 将内容区域设置到卡片中 + // 创建一个可折叠的内容区域,用于放置设置选项 + Column column = new Column() + .setLayoutParams(new LinearParams() + .setWidth(BaseHelper.MatchParent) // 宽度填满父视图 + .setHeight(BaseHelper.WrapContent) // 高度自适应内容 + .setTopMargin(dip2pxInt(15))); // 顶部外边距为15dp + ddhzSwitchContentCard.setExpandableContent(column); // 将内容区域设置到卡片中 + final Text label1 = new Text() + .setText("x=" + ",y=" + ",z=") + .setTextSize(10f) + .setTextColor(0xFFC5C5C5) + .setTypeface(Typeface.DEFAULT_BOLD) + .setLayoutParams(new LinearParams() + .setWidth(BaseHelper.MatchParent) + .setBottomMargin(dip2pxInt(5))); + column.addView(label1); + final StatefulButton statefulButton1 = new StatefulButton("创建", "Create", false); + statefulButton1.setSwitchCallback(new SwitchCallback() { + @Override + public boolean onChecked(boolean newState) { + File langFile = new File("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); + boolean isChinese = langFile.exists(); + if (newState) { + // 开启状态 + Fastesp.creatred(x, y, z, "id"); + statefulButton1.text.setText(isChinese ? "删除" : "Delete"); + } else { + // 关闭状态 - final Text label1 = new Text() - .setText("x="+",y="+",z=") - .setTextSize(10f) - .setTextColor(0xFFC5C5C5) - .setTypeface(Typeface.DEFAULT_BOLD) - .setLayoutParams(new LinearParams() - .setWidth(BaseHelper.MatchParent) - .setBottomMargin(dip2pxInt(5))); - column.addView(label1); + Fastesp.deletered("id"); + statefulButton1.text.setText(isChinese ? "创建" : "Create"); + } - - -final StatefulButton statefulButton1 = new StatefulButton("创建", "Create", false); - -statefulButton1.setSwitchCallback(new SwitchCallback() { - @Override - public boolean onChecked(boolean newState) { - File langFile = new File("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); - boolean isChinese = langFile.exists(); - - if (newState) { - // 开启状态 - -Fastesp.creatred(x,y,z,"id"); - statefulButton1.text.setText(isChinese ? "删除" : "Delete"); - } else { - // 关闭状态 - -Fastesp.deletered("id"); - statefulButton1.text.setText(isChinese ? "创建" : "Create"); - } - - return true; // 允许状态变化 - } -}); - -final Text shu1 = new Text() - .setText("|") - .setTextSize(15f) - .setTextColor(0xFFC5C5C5) - .setTypeface(Typeface.DEFAULT_BOLD) - .setLayoutParams(new LinearParams().setHeight(BaseHelper.WrapContent) -); - -final RadioGroup radioGroup1 = new RadioGroup() - .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); - -radioGroup1.setLayoutParams(new LinearParams().setWidth(BaseHelper.MatchParent)); -radioGroup1.setEnabled(true); - -radioGroup1.addButton("获取", "Get", "1"); -radioGroup1.addButton("保存", "Save", "2"); -radioGroup1.addButton("读取", "Load", "3"); -radioGroup1.addButton("传送", "Teleport", "4"); - -// ✅ 关键:取消默认选中 -for (StatefulButton btn : radioGroup1.map.values()) { - btn.setChecked(false); -} - -radioGroup1.setRadioGroupCallback(new RadioGroupCallback() { - @Override - public void onChecked(String id) { - switch (id) { - case "1"://获取 - 获取坐标(); - label1.setText("x=" + x + ",y=" + y + ",z=" + z); - break; - case "2"://保存 -检查(); - -if (!file.exists()) { - try { -file.createNewFile(); // 创建文件 -} catch (IOException e) {e.printStackTrace();} - } - -try { - - if (!dir.exists()) dir.mkdirs(); - - BufferedWriter bw = new BufferedWriter(new FileWriter(file)); - bw.write("x=" + x); - bw.newLine(); - bw.write("y=" + y); - bw.newLine(); - bw.write("z=" + z); - bw.close(); -} catch (IOException e) { - e.printStackTrace(); -} - break; - case "3"://读取 -try { - - if (file.exists()) { - BufferedReader br = new BufferedReader(new FileReader(file)); - String line; - while ((line = br.readLine()) != null) { - if (line.startsWith("x=")) { - x = Float.parseFloat(line.substring(2).trim()); - } else if (line.startsWith("y=")) { - y = Float.parseFloat(line.substring(2).trim()); - } else if (line.startsWith("z=")) { - z = Float.parseFloat(line.substring(2).trim()); + return true; // 允许状态变化 } - } - br.close(); - } -} catch (IOException e) { - e.printStackTrace(); -} -label1.setText("x=" + x + ",y=" + y + ",z=" + z); -break; - - case "4"://传送 -//x -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -AlguiMemTool.clearResultList(); // 清空之前的搜索结果 -long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB); // 获取模块基址 -long zuobiaox = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x454090) + 0x0) + 0x70) + 0x10) + 0xA8; // 跳转指针 -long zuobiaoy = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x454090) + 0x0) + 0x70) + 0x10) + 0xA4; // 跳转指针 -long zuobiaoz = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x454090) + 0x0) + 0x70) + 0x10) + 0xA0; // 跳转指针 - - AlguiMemTool.setMemoryAddrValue(""+y, zuobiaoy,AlguiMemTool.TYPE_FLOAT, false,true); -AlguiMemTool.setMemoryAddrValue(""+z, zuobiaox,AlguiMemTool.TYPE_FLOAT, false,true); -AlguiMemTool.setMemoryAddrValue(""+x, zuobiaoz,AlguiMemTool.TYPE_FLOAT, false ,true); -AlguiMemTool.setMemoryAddrValue(""+y, zuobiaoy,AlguiMemTool.TYPE_FLOAT, false,true); -AlguiMemTool.setMemoryAddrValue(""+z, zuobiaox,AlguiMemTool.TYPE_FLOAT, false,true); -AlguiMemTool.setMemoryAddrValue(""+x, zuobiaoz,AlguiMemTool.TYPE_FLOAT, false ,true); - break; - } - } -}); + }); - -Row buttonRow1 = new Row() + final Text shu1 = new Text() + .setText("|") + .setTextSize(15f) + .setTextColor(0xFFC5C5C5) + .setTypeface(Typeface.DEFAULT_BOLD) + .setLayoutParams(new LinearParams().setHeight(BaseHelper.WrapContent)); + + final RadioGroup radioGroup1 = new RadioGroup() + .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); + + radioGroup1.setLayoutParams(new LinearParams().setWidth(BaseHelper.MatchParent)); + radioGroup1.setEnabled(true); + + radioGroup1.addButton("获取", "Get", "1"); + radioGroup1.addButton("保存", "Save", "2"); + radioGroup1.addButton("读取", "Load", "3"); + radioGroup1.addButton("传送", "Teleport", "4"); + + // ✅ 关键:取消默认选中 + for (StatefulButton btn : radioGroup1.map.values()) { + btn.setChecked(false); + } + + radioGroup1.setRadioGroupCallback(new RadioGroupCallback() { + @Override + public void onChecked(String id) { + switch (id) { + case "1":// 获取 + 获取坐标(); + label1.setText("x=" + x + ",y=" + y + ",z=" + z); + break; + case "2":// 保存 + 检查(); + + if (!file.exists()) { + try { + file.createNewFile(); // 创建文件 + } catch (IOException e) { + e.printStackTrace(); + } + } + + try { + + if (!dir.exists()) + dir.mkdirs(); + + BufferedWriter bw = new BufferedWriter(new FileWriter(file)); + bw.write("x=" + x); + bw.newLine(); + bw.write("y=" + y); + bw.newLine(); + bw.write("z=" + z); + bw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + break; + case "3":// 读取 + try { + + if (file.exists()) { + BufferedReader br = new BufferedReader(new FileReader(file)); + String line; + while ((line = br.readLine()) != null) { + if (line.startsWith("x=")) { + x = Float.parseFloat(line.substring(2).trim()); + } else if (line.startsWith("y=")) { + y = Float.parseFloat(line.substring(2).trim()); + } else if (line.startsWith("z=")) { + z = Float.parseFloat(line.substring(2).trim()); + } + } + br.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + label1.setText("x=" + x + ",y=" + y + ",z=" + z); + break; + + case "4":// 传送 + // x + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + AlguiMemTool.clearResultList(); // 清空之前的搜索结果 + long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB); // 获取模块基址 + long zuobiaox = AlguiMemTool + .jump64(AlguiMemTool.jump64( + AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x454090) + 0x0) + 0x70) + 0x10) + + 0xA8; // 跳转指针 + long zuobiaoy = AlguiMemTool + .jump64(AlguiMemTool.jump64( + AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x454090) + 0x0) + 0x70) + 0x10) + + 0xA4; // 跳转指针 + long zuobiaoz = AlguiMemTool + .jump64(AlguiMemTool.jump64( + AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x454090) + 0x0) + 0x70) + 0x10) + + 0xA0; // 跳转指针 + + AlguiMemTool.setMemoryAddrValue("" + y, zuobiaoy, AlguiMemTool.TYPE_FLOAT, false, true); + AlguiMemTool.setMemoryAddrValue("" + z, zuobiaox, AlguiMemTool.TYPE_FLOAT, false, true); + AlguiMemTool.setMemoryAddrValue("" + x, zuobiaoz, AlguiMemTool.TYPE_FLOAT, false, true); + AlguiMemTool.setMemoryAddrValue("" + y, zuobiaoy, AlguiMemTool.TYPE_FLOAT, false, true); + AlguiMemTool.setMemoryAddrValue("" + z, zuobiaox, AlguiMemTool.TYPE_FLOAT, false, true); + AlguiMemTool.setMemoryAddrValue("" + x, zuobiaoz, AlguiMemTool.TYPE_FLOAT, false, true); + break; + } + } + }); + + Row buttonRow1 = new Row() .setLayoutParams(new LinearParams() .setWidth(BaseHelper.MatchParent) .setHeight(BaseHelper.WrapContent) @@ -444,79 +405,14 @@ Row buttonRow1 = new Row() buttonRow1.addView(statefulButton1); buttonRow1.addView(shu1); - buttonRow1.addView(radioGroup1); - - - + buttonRow1.addView(radioGroup1); + // 把这一行添加到 column 中 column.addView(buttonRow1); return ddhzSwitchContentCard; // 返回创建的卡片 } - - - - - - - - - - - - - private enum Color { - RED(0xFFFF0000), // 红色 - GREEN(0xFF00FF00), // 绿色 - BLUE(0xFF0000FF), // 蓝色 - YELLOW(0xFFFFFF00), // 黄色 - WHITE(0xFFFFFFFF), // 白色 - BLACK(0xFF000000), // 黑色 - ORANGE(0xFFFFA500), // 橙色 - PURPLE(0xFF800080), // 紫色 - PINK(0xFFFFC0CB), // 粉色 - CYAN(0xFF00FFFF), // 青色 - MAGENTA(0xFFFF00FF), // 洋红色 - GRAY(0xFF808080); // 灰色 - - private final int value; // 存储颜色值 - - // 私有构造函数 - Color(int value) { - this.value = value; - } - - // 获取颜色值的方法 - public int getValue() { - return value; - } - } - - private enum CollisionBodyType { - ENTITY, // 实体 - PLAYER, // 角色 - PICKUP // 拾取物 - } - - // 碰撞体对象 - private static class CollisionBody { - long address; // 内存地址 - CollisionBodyType type; // 类型 - int feature1; // 特征值1 - int feature2; // 特征值2 - } - - // 绘制对象 - private static class DrawObject { - long address; // 内存地址 - Color color; // 颜色 - CollisionBodyType type; // 类型 - int dis; - int x; - int y; - } - private static final int pSize = 8; // 被选中对象内存地址 private static long selectedAddr = 0; @@ -528,16 +424,15 @@ Row buttonRow1 = new Row() static long collAddrStart; // 碰撞体列表 - private static CopyOnWriteArrayList collList = new - CopyOnWriteArrayList<>(); + private static CopyOnWriteArrayList collList = new CopyOnWriteArrayList<>(); // 绘制对象列表 - private static ArrayList drawList = new ArrayList<>(); + private static ArrayList drawList = new ArrayList<>(); // 是否开启ESP(不是) - private static boolean espkg =true; + private static boolean espkg = true; // 是否开启ESP("这个才是) - private static boolean zhenespkg =false; + private static boolean zhenespkg = false; // 是否绘制所有碰撞体 private static boolean isDrawALLColl = false; @@ -575,7 +470,6 @@ Row buttonRow1 = new Row() if (collAddr <= 0) return false; - collAddrStart = jump(collAddr); // 更新 collAddrStart 的值 return true; // 成功获取地址 } @@ -583,15 +477,15 @@ Row buttonRow1 = new Row() // 数组更新方法 private static void updateArray() { // 创建临时列表存储新数据 - ArrayList newCollList = new ArrayList<>(); + ArrayList newCollList = new ArrayList<>(); try { int size = Integer.parseInt(AlguiMemTool.getMemoryAddrData(collAddr + 0x2C, AlguiMemTool.TYPE_DWORD)); // 遍历碰撞体数组并过滤 for (int i = 0; i < size; i++) { - CollisionBody p = new CollisionBody(); - DrawObject d = new DrawObject(); + ESPDataStructures.CollisionBody p = new ESPDataStructures.CollisionBody(); + ESPDataStructures.DrawObject d = new ESPDataStructures.DrawObject(); p.address = jump(collAddrStart + i * pSize); // 批量读取内存数据提高性能 @@ -603,19 +497,19 @@ Row buttonRow1 = new Row() if (p.feature2 == 196614) { if (isDrawPlayer && p.feature1 == 17039361) { d.address = p.address; - d.color = Color.GREEN; - d.type = CollisionBodyType.PLAYER; + d.color = ESPDataStructures.Color.GREEN; + d.type = ESPDataStructures.CollisionBodyType.PLAYER; newCollList.add(d); } else if (isDrawPickup && p.feature1 == 17039617) { d.address = p.address; - d.color = Color.PURPLE; - d.type = CollisionBodyType.PICKUP; + d.color = ESPDataStructures.Color.PURPLE; + d.type = ESPDataStructures.CollisionBodyType.PICKUP; newCollList.add(d); } } else if (isDrawALLColl) { d.address = p.address; - d.color = Color.GRAY; - d.type = CollisionBodyType.ENTITY; + d.color = ESPDataStructures.Color.GRAY; + d.type = ESPDataStructures.CollisionBodyType.ENTITY; newCollList.add(d); } } @@ -652,12 +546,8 @@ Row buttonRow1 = new Row() } // 初始化绘制窗口方法 -private static AlguiWinDraw initDraw(Context context) { - - return Fastesp.start(context); -} - - - + private static AlguiWinDraw initDraw(Context context) { + return Fastesp.start(context); + } } diff --git a/app/src/main/java/com/bytecat/algui/ui/category/ESPCategoryBox_Copy.java b/app/src/main/java/com/bytecat/algui/ui/category/ESPCategoryBox_Copy.java new file mode 100644 index 0000000..41f73e5 --- /dev/null +++ b/app/src/main/java/com/bytecat/algui/ui/category/ESPCategoryBox_Copy.java @@ -0,0 +1,219 @@ +package com.bytecat.algui.ui.category; + +import android.graphics.Typeface; +import com.bytecat.algui.AlguiHacker.AlguiMemTool; +import com.bytecat.algui.base.BaseHelper; +import com.bytecat.algui.callback.SwitchCallback; +import com.bytecat.algui.component.Column; +import com.bytecat.algui.component.Row; +import com.bytecat.algui.component.Text; +import com.bytecat.algui.effect.Notification; +import com.bytecat.algui.layoutparams.LinearParams; +import com.bytecat.algui.ui.MIX; +import com.bytecat.algui.ui.component.CategoryBox; +import com.bytecat.algui.ui.component.StatefulButton; +import com.bytecat.algui.ui.component.BoxContentCard; +import com.bytecat.algui.ui.component.SwitchContentCard; +import com.bytecat.algui.ui.component.RadioGroup; +import com.bytecat.algui.callback.RadioGroupCallback; +import com.bytecat.algui.AlguiWindows.AlguiWinDraw; +import com.bytecat.algui.ui.Main; +import com.bytecat.algui.effect.ModuleManager; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.CopyOnWriteArrayList; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.BufferedWriter; +import java.util.ArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ESPCategoryBox_Copy extends CategoryBox { + + Notification notification = Notification.getInstance(); + + public static final long BASE_OFFSET = 0x454090; + + private static float readFloatFromMemory(long address) throws NumberFormatException { + if (address <= 0) { + return 0; + } + String memData = AlguiMemTool.getMemoryAddrData(address, AlguiMemTool.TYPE_FLOAT); + return Float.parseFloat(memData); + } + + // 配置文件目录 + public static File configDir = new File("/storage/emulated/0/TC配置文件/"); + // 坐标文件 + public static File coordinateFile = new File(configDir, "coordinate1.txt"); + + // 检查并创建配置文件目录 + public static void checkAndCreateConfigDir() { + if (!configDir.exists()) { + configDir.mkdirs(); // 创建文件夹 + } + } + + public ESPCategoryBox_Copy() { + contentContainer + .addView(createchushSwitchContentCard()) + .addView(createhzmbSwitchContentCard()) + .addView(createddhzSwitchContentCard()); + } + + private SwitchContentCard createchushSwitchContentCard() { + final SwitchContentCard chushSwitchContentCard = new SwitchContentCard("初始化", "初始化相关数据") + .OText("初始化", "初始化相关数据", "Initialize", "Initialize relevant data").setChecked(false); + + chushSwitchContentCard.setSwitchCallback(new SwitchCallback() { + @Override + public boolean onChecked(boolean newState) { + // TODO: 实现初始化开关的逻辑 + return true; + } + }); + + return chushSwitchContentCard; + } + + private BoxContentCard createhzmbSwitchContentCard() { + // 创建一个可切换内容的卡片,用于显示和管理核心碰撞箱的设置 + final BoxContentCard hzmbSwitchContentCard = new BoxContentCard("目标", "选择绘制的目标") + .OText("目标", "选择绘制的目标", "The goal of drawing", "Select the target for drawing") + .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); + + // 创建一个可折叠的内容区域,用于放置设置选项 + Column column = new Column() + .setLayoutParams(new LinearParams() + .setWidth(BaseHelper.MatchParent) // 宽度填满父视图 + .setHeight(BaseHelper.WrapContent) // 高度自适应内容 + .setTopMargin(dip2pxInt(15))); // 顶部外边距为15dp + hzmbSwitchContentCard.setExpandableContent(column); // 将内容区域设置到卡片中 + + final StatefulButton statefulButton = new StatefulButton("玩家", "player", true); + statefulButton.setSwitchCallback(new SwitchCallback() { + @Override + public boolean onChecked(boolean newState) { + // TODO: 实现玩家绘制开关的逻辑 + return true; + } + }); + + final StatefulButton statefulButton2 = new StatefulButton("物品", "Article", false); + statefulButton2.setSwitchCallback(new SwitchCallback() { + @Override + public boolean onChecked(boolean newState) { + // TODO: 实现物品绘制开关的逻辑 + return true; + } + }); + + // 创建第一行按钮 + Row buttonRow1 = new Row(); + buttonRow1 + .setLayoutParams(new LinearParams().setWidth(BaseHelper.MatchParent).setHeight(BaseHelper.WrapContent)); + + buttonRow1.addView(statefulButton); + buttonRow1.addView(statefulButton2); + column.addView(buttonRow1); + + return hzmbSwitchContentCard; // 返回创建的卡片 + } + + private BoxContentCard createddhzSwitchContentCard() { + // 创建一个可切换内容的卡片,用于显示和管理核心碰撞箱的设置 + final BoxContentCard ddhzSwitchContentCard = new BoxContentCard("定点", "绘制一个可以保存的固定红点") + .OText("定点", "绘制一个可以保存的固定红点", "Fixed point", "Draw a fixed red dot that can be saved") + .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); + + // 创建一个可折叠的内容区域,用于放置设置选项 + Column column = new Column() + .setLayoutParams(new LinearParams() + .setWidth(BaseHelper.MatchParent) // 宽度填满父视图 + .setHeight(BaseHelper.WrapContent) // 高度自适应内容 + .setTopMargin(dip2pxInt(15))); // 顶部外边距为15dp + ddhzSwitchContentCard.setExpandableContent(column); // 将内容区域设置到卡片中 + + final Text label1 = new Text() + .setText("x=" + ",y=" + ",z=") + .setTextSize(10f) + .setTextColor(0xFFC5C5C5) + .setTypeface(Typeface.DEFAULT_BOLD) + .setLayoutParams(new LinearParams() + .setWidth(BaseHelper.MatchParent) + .setBottomMargin(dip2pxInt(5))); + column.addView(label1); + + final StatefulButton statefulButton1 = new StatefulButton("创建", "Create", false); + + statefulButton1.setSwitchCallback(new SwitchCallback() { + @Override + public boolean onChecked(boolean newState) { + // TODO: 实现定点创建/删除按钮的逻辑 + return true; + } + }); + + final Text shu1 = new Text() + .setText("|") + .setTextSize(15f) + .setTextColor(0xFFC5C5C5) + .setTypeface(Typeface.DEFAULT_BOLD) + .setLayoutParams(new LinearParams().setHeight(BaseHelper.WrapContent)); + + final RadioGroup radioGroup1 = new RadioGroup() + .setLanguageSwitchFilePath("/sdcard/Android/data/com.vortex.celestial/files/switch.lang"); + + radioGroup1.setLayoutParams(new LinearParams().setWidth(BaseHelper.MatchParent)); + radioGroup1.setEnabled(true); + + radioGroup1.addButton("获取", "Get", "1"); + radioGroup1.addButton("保存", "Save", "2"); + radioGroup1.addButton("读取", "Load", "3"); + radioGroup1.addButton("传送", "Teleport", "4"); + + // ✅ 关键:取消默认选中 + for (StatefulButton btn : radioGroup1.map.values()) { + btn.setChecked(false); + } + + radioGroup1.setRadioGroupCallback(new RadioGroupCallback() { + @Override + public void onChecked(String id) { + // TODO: 实现单选按钮组的逻辑 + switch (id) { + case "1":// 获取 + // TODO: 实现获取坐标逻辑 + break; + case "2":// 保存 + // TODO: 实现保存坐标逻辑 + break; + case "3":// 读取 + // TODO: 实现读取坐标逻辑 + break; + case "4":// 传送 + // TODO: 实现传送逻辑 + break; + } + } + }); + + Row buttonRow1 = new Row() + .setLayoutParams(new LinearParams() + .setWidth(BaseHelper.MatchParent) + .setHeight(BaseHelper.WrapContent) + .setTopMargin(dip2pxInt(10))); + + buttonRow1.addView(statefulButton1); + buttonRow1.addView(shu1); + buttonRow1.addView(radioGroup1); + + // 把这一行添加到 column 中 + column.addView(buttonRow1); + + return ddhzSwitchContentCard; // 返回创建的卡片 + } + +} diff --git a/app/src/main/java/com/bytecat/algui/ui/category/ESPDataStructures.java b/app/src/main/java/com/bytecat/algui/ui/category/ESPDataStructures.java new file mode 100644 index 0000000..01737cb --- /dev/null +++ b/app/src/main/java/com/bytecat/algui/ui/category/ESPDataStructures.java @@ -0,0 +1,64 @@ +package com.bytecat.algui.ui.category; + +public class ESPDataStructures { + /** + * 颜色枚举 + */ + public enum Color { + RED(0xFFFF0000), // 红色 + GREEN(0xFF00FF00), // 绿色 + BLUE(0xFF0000FF), // 蓝色 + YELLOW(0xFFFFFF00), // 黄色 + WHITE(0xFFFFFFFF), // 白色 + BLACK(0xFF000000), // 黑色 + ORANGE(0xFFFFA500), // 橙色 + PURPLE(0xFF800080), // 紫色 + PINK(0xFFFFC0CB), // 粉色 + CYAN(0xFF00FFFF), // 青色 + MAGENTA(0xFFFF00FF), // 洋红色 + GRAY(0xFF808080); // 灰色 + + private final int value; // 存储颜色值 + + // 私有构造函数 + Color(int value) { + this.value = value; + } + + // 获取颜色值的方法 + public int getValue() { + return value; + } + } + + /** + * 碰撞体类型枚举 + */ + public enum CollisionBodyType { + ENTITY, // 实体 + PLAYER, // 角色 + PICKUP // 拾取物 + } + + /** + * 碰撞体对象 + */ + public class CollisionBody { + public long address; // 内存地址 + public CollisionBodyType type; // 类型 + public int feature1; // 特征值1 + public int feature2; // 特征值2 + } + + /** + * 绘制对象 + */ + public class DrawObject { + public long address; // 内存地址 + public Color color; // 颜色 + public CollisionBodyType type; // 类型 + public int dis; + public int x; + public int y; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/bytecat/algui/ui/category/Fastesp.java b/app/src/main/java/com/bytecat/algui/ui/category/Fastesp.java index e3f4d82..0e661c8 100644 --- a/app/src/main/java/com/bytecat/algui/ui/category/Fastesp.java +++ b/app/src/main/java/com/bytecat/algui/ui/category/Fastesp.java @@ -49,7 +49,8 @@ public class Fastesp { private static final ConcurrentHashMap redPointsWorldZ = new ConcurrentHashMap<>(); public static AlguiWinDraw start(Context ctx) { - if (ctx == null) ctx = MIX.getContext(); + if (ctx == null) + ctx = MIX.getContext(); if (ctx == null) throw new IllegalStateException("Context 为 null,请先初始化 MIX 或传入 Activity!"); running = true; @@ -57,299 +58,306 @@ public class Fastesp { return draw; } -private static final int MODE_JOY = 0; // 摇杆模式 -private static final int MODE_MOVE = 1; // 移动模式 -private static int mode = MODE_JOY; // 当前模式 -private static long lastDownTime = 0; // 用于双击判断 -private static final int DOUBLE_TAP_TIMEOUT = 300; // ms -// 摇杆当前输出向量 [-1,1] -public static float joystickX; -public static float joystickY; -// 是否正在用摇杆 -public static boolean isJoystickMove; -// ================== 摇杆控件 ================== -private static class JoystickView extends View { - /* ==== 基本尺寸 ==== */ - private float baseX, baseY; // 摇杆底座中心(可拖动) - private float bigR, smallR; - private float knobX, knobY; // 摇杆钮当前位置 - private Paint bgPaint, knobPaint; + private static final int MODE_JOY = 0; // 摇杆模式 + private static final int MODE_MOVE = 1; // 移动模式 + private static int mode = MODE_JOY; // 当前模式 + private static long lastDownTime = 0; // 用于双击判断 + private static final int DOUBLE_TAP_TIMEOUT = 300; // ms + // 摇杆当前输出向量 [-1,1] + public static float joystickX; + public static float joystickY; + // 是否正在用摇杆 + public static boolean isJoystickMove; - /* ==== 触摸状态 ==== */ - private boolean draggingKnob = false; // 是否在拖拽摇杆钮 - private boolean draggingBase = false; // 是否在拖动底座 - private float lastTouchX, lastTouchY; + // ================== 摇杆控件 ================== + private static class JoystickView extends View { + /* ==== 基本尺寸 ==== */ + private float baseX, baseY; // 摇杆底座中心(可拖动) + private float bigR, smallR; + private float knobX, knobY; // 摇杆钮当前位置 + private Paint bgPaint, knobPaint; - public JoystickView(Context c) { - super(c); - bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - bgPaint.setColor(Color.argb(120, 0, 0, 0)); - knobPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - knobPaint.setColor(Color.argb(200, 0, 200, 255)); + /* ==== 触摸状态 ==== */ + private boolean draggingKnob = false; // 是否在拖拽摇杆钮 + private boolean draggingBase = false; // 是否在拖动底座 + private float lastTouchX, lastTouchY; - // 初始位置:左下角 - bigR = dp(60); - smallR = dp(25); - baseX = bigR + dp(20); - baseY = getResources().getDisplayMetrics().heightPixels - bigR - dp(20); - knobX = baseX; - knobY = baseY; - } + public JoystickView(Context c) { + super(c); + bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + bgPaint.setColor(Color.argb(120, 0, 0, 0)); + knobPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + knobPaint.setColor(Color.argb(200, 0, 200, 255)); - private float dp(int px) { - return getResources().getDisplayMetrics().density * px; - } + // 初始位置:左下角 + bigR = dp(60); + smallR = dp(25); + baseX = bigR + dp(20); + baseY = getResources().getDisplayMetrics().heightPixels - bigR - dp(20); + knobX = baseX; + knobY = baseY; + } - /* ==== 绘制 ==== */ - @Override protected void onDraw(Canvas canvas) { - canvas.drawCircle(baseX, baseY, bigR, bgPaint); - canvas.drawCircle(knobX, knobY, smallR, knobPaint); - } + private float dp(int px) { + return getResources().getDisplayMetrics().density * px; + } - /* ==== 触摸 ==== */ - @SuppressLint("ClickableViewAccessibility") - @Override public boolean onTouchEvent(MotionEvent e) { - float x = e.getX(); - float y = e.getY(); + /* ==== 绘制 ==== */ + @Override + protected void onDraw(Canvas canvas) { + canvas.drawCircle(baseX, baseY, bigR, bgPaint); + canvas.drawCircle(knobX, knobY, smallR, knobPaint); + } - switch (e.getAction()) { - case MotionEvent.ACTION_DOWN: - // 双击检测 - if (System.currentTimeMillis() - lastDownTime < DOUBLE_TAP_TIMEOUT) { - toggleMode(); - lastDownTime = 0; // 防止三连击 - return true; - } - lastDownTime = System.currentTimeMillis(); + /* ==== 触摸 ==== */ + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouchEvent(MotionEvent e) { + float x = e.getX(); + float y = e.getY(); - if (mode == MODE_MOVE) { - // 移动模式:只要按在底座内就可以拖动整个摇杆 - if (dist(x, y, baseX, baseY) <= bigR) { - draggingBase = true; + switch (e.getAction()) { + case MotionEvent.ACTION_DOWN: + // 双击检测 + if (System.currentTimeMillis() - lastDownTime < DOUBLE_TAP_TIMEOUT) { + toggleMode(); + lastDownTime = 0; // 防止三连击 + return true; + } + lastDownTime = System.currentTimeMillis(); + + if (mode == MODE_MOVE) { + // 移动模式:只要按在底座内就可以拖动整个摇杆 + if (dist(x, y, baseX, baseY) <= bigR) { + draggingBase = true; + lastTouchX = x; + lastTouchY = y; + } + } else { + // 摇杆模式:只有按在底座内才能拖动小钮 + if (dist(x, y, baseX, baseY) <= bigR) { + draggingKnob = true; + moveKnob(x, y); + } + } + break; + + case MotionEvent.ACTION_MOVE: + if (draggingBase) { + baseX += x - lastTouchX; + baseY += y - lastTouchY; + knobX = baseX; + knobY = baseY; lastTouchX = x; lastTouchY = y; - } - } else { - // 摇杆模式:只有按在底座内才能拖动小钮 - if (dist(x, y, baseX, baseY) <= bigR) { - draggingKnob = true; + invalidate(); + } else if (draggingKnob) { moveKnob(x, y); } - } - break; + break; - case MotionEvent.ACTION_MOVE: - if (draggingBase) { - baseX += x - lastTouchX; - baseY += y - lastTouchY; - knobX = baseX; - knobY = baseY; - lastTouchX = x; - lastTouchY = y; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + draggingKnob = false; + draggingBase = false; + // 松手回中 + knobX = baseX; + knobY = baseY; invalidate(); - } else if (draggingKnob) { - moveKnob(x, y); - } - break; - - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - draggingKnob = false; - draggingBase = false; - // 松手回中 - knobX = baseX; - knobY = baseY; - invalidate(); - break; + break; + } + return true; } - return true; - } - private void toggleMode() { - mode = (mode == MODE_JOY) ? MODE_MOVE : MODE_JOY; - invalidate(); - } - - private void moveKnob(float x, float y) { - float dx = x - baseX; - float dy = y - baseY; - float len = (float) Math.sqrt(dx * dx + dy * dy); - if (len > bigR) { - dx = dx / len * bigR; - dy = dy / len * bigR; + private void toggleMode() { + mode = (mode == MODE_JOY) ? MODE_MOVE : MODE_JOY; + invalidate(); + } + + private void moveKnob(float x, float y) { + float dx = x - baseX; + float dy = y - baseY; + float len = (float) Math.sqrt(dx * dx + dy * dy); + if (len > bigR) { + dx = dx / len * bigR; + dy = dy / len * bigR; + } + knobX = baseX + dx; + knobY = baseY + dy; + invalidate(); + // 在 JoystickView.moveKnob() 末尾加一行 + Fastesp.joystickX = dx / bigR; // 已归一化 + Fastesp.joystickY = -dy / bigR; // 屏幕坐标系转游戏坐标系 + Fastesp.isJoystickMove = draggingKnob; + /* + * TODO: 如果需要把摇杆向量输出出去,可以在这里回调 + * float vx = dx / bigR; + * float vy = -dy / bigR; + */ + } + + private float dist(float x1, float y1, float x2, float y2) { + return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } - knobX = baseX + dx; - knobY = baseY + dy; - invalidate(); -// 在 JoystickView.moveKnob() 末尾加一行 -Fastesp.joystickX = dx / bigR; // 已归一化 -Fastesp.joystickY = -dy / bigR; // 屏幕坐标系转游戏坐标系 -Fastesp.isJoystickMove = draggingKnob; - /* TODO: 如果需要把摇杆向量输出出去,可以在这里回调 - float vx = dx / bigR; - float vy = -dy / bigR; - */ } - private float dist(float x1, float y1, float x2, float y2) { - return (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); + /* 专门给路径记录用的红点,旁边固定写“路径点” */ + public static void createPathPoint(float x, float y, float z, String id) { + redPointsWorldX.put(id, x); + redPointsWorldY.put(id, y); + redPointsWorldZ.put(id, z); } -} + // ============================================= + private static JoystickView joystick; + private static Thread moveThread; + private static volatile boolean moveRunning; + public static void startMoveThread() { + if (moveThread != null) + return; + moveRunning = true; + moveThread = new Thread(new Runnable() { + @Override + public void run() { + /* ↓↓↓ 原来花括号里的代码全部原封不动搬进来 ↓↓↓ */ + int pid = AlguiMemTool.getPID("com.vortex.celestial"); + if (pid < 0) + return; + long libClient = AlguiMemTool.getModuleBaseAddr("libclient.so", AlguiMemTool.HEAD_CB); + if (libClient == 0) + return; -/* 专门给路径记录用的红点,旁边固定写“路径点” */ -public static void createPathPoint(float x, float y, float z, String id) { - redPointsWorldX.put(id, x); - redPointsWorldY.put(id, y); - redPointsWorldZ.put(id, z); -} -// ============================================= - - -private static JoystickView joystick; - -private static Thread moveThread; -private static volatile boolean moveRunning; - -public static void startMoveThread() { - if (moveThread != null) return; - moveRunning = true; -moveThread = new Thread(new Runnable() { - @Override - public void run() { - /* ↓↓↓ 原来花括号里的代码全部原封不动搬进来 ↓↓↓ */ - int pid = AlguiMemTool.getPID("com.vortex.celestial"); - if (pid < 0) return; - - long libClient = AlguiMemTool.getModuleBaseAddr("libclient.so", AlguiMemTool.HEAD_CB); - if (libClient == 0) return; - - long matrixAddr = AlguiMemTool.jump64( - AlguiMemTool.jump64( + long matrixAddr = AlguiMemTool.jump64( AlguiMemTool.jump64( - AlguiMemTool.jump64(libClient + 0x45A228) + 0x268) + 0xE0) + 0x40); + AlguiMemTool.jump64( + AlguiMemTool.jump64(libClient + 0x45A228) + 0x268) + 0xE0) + + 0x40); - long oneselfBase = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(libClient + 0x454090) + 0x0) + 0x70) + 0x10; // 跳转指针 + long oneselfBase = AlguiMemTool + .jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(libClient + 0x454090) + 0x0) + 0x70) + 0x10; // 跳转指针 - while (moveRunning) { + while (moveRunning) { + try { + if (!isJoystickMove) { + Thread.sleep(20); + continue; + } + + float[] m = new float[16]; + for (int i = 0; i < 16; i++) { + m[i] = Float.parseFloat( + AlguiMemTool.getMemoryAddrData(matrixAddr + i * 4, AlguiMemTool.TYPE_FLOAT)); + } + + float x = Float.parseFloat( + AlguiMemTool.getMemoryAddrData(oneselfBase + 0xA0, AlguiMemTool.TYPE_FLOAT)); + float z = Float.parseFloat( + AlguiMemTool.getMemoryAddrData(oneselfBase + 0xA4, AlguiMemTool.TYPE_FLOAT)); + float y = Float.parseFloat( + AlguiMemTool.getMemoryAddrData(oneselfBase + 0xA8, AlguiMemTool.TYPE_FLOAT)); + + float dirX = m[2]; + float dirZ = m[6]; + float dirY = m[10]; + float len = (float) Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ); + dirX /= len; + dirZ /= len; + dirY /= len; + + float moveScale = 5.0f; + x += dirX * joystickY * moveScale; + z += dirZ * joystickY * moveScale * 2; + y += dirY * joystickY * moveScale; + + float rightX = m[0]; + float rightZ = m[4]; + float rightY = m[8]; + len = (float) Math.sqrt(rightX * rightX + rightY * rightY + rightZ * rightZ); + rightX /= len; + rightZ /= len; + rightY /= len; + + x += rightX * joystickX * moveScale; + z += rightZ * joystickX * moveScale * 2; + y += rightY * joystickX * moveScale; + + AlguiMemTool.setMemoryAddrValue(String.valueOf(x), oneselfBase + 0xA0, AlguiMemTool.TYPE_FLOAT, + false, true); + AlguiMemTool.setMemoryAddrValue(String.valueOf(z), oneselfBase + 0xA4, AlguiMemTool.TYPE_FLOAT, + false, true); + AlguiMemTool.setMemoryAddrValue(String.valueOf(y), oneselfBase + 0xA8, AlguiMemTool.TYPE_FLOAT, + false, true); + + Thread.sleep(20); + } catch (Exception ignore) { + } + } + } + }); + moveThread.start(); + + } + + public static void stopMoveThread() { + moveRunning = false; + if (moveThread != null) { + moveThread.interrupt(); + moveThread = null; + } + } + + public static void showJoystick(Activity act) { + if (joystick != null) + return; + FrameLayout root = act.findViewById(android.R.id.content); + joystick = new JoystickView(act); + FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT); + root.addView(joystick, lp); + } + + public static void hideJoystick(Activity act) { + if (joystick == null) + return; + FrameLayout root = act.findViewById(android.R.id.content); + root.removeView(joystick); + joystick = null; + } + + public static void stop() { + running = false; // 1. 让下一次 Update() 直接 return + + // 2. 立即清屏 + if (draw != null) { + Canvas canvas = null; try { - if (!isJoystickMove) { - Thread.sleep(20); - continue; + canvas = draw.getHolder().lockCanvas(); // 尝试锁定当前 Surface + if (canvas != null) { + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); // 清屏 } - - float[] m = new float[16]; - for (int i = 0; i < 16; i++) { - m[i] = Float.parseFloat( - AlguiMemTool.getMemoryAddrData(matrixAddr + i * 4, AlguiMemTool.TYPE_FLOAT)); + } catch (Exception ignore) { + // 防止 Surface 已被销毁时崩溃 + } finally { + if (canvas != null) { + draw.getHolder().unlockCanvasAndPost(canvas); // 确保解锁 } + draw.endRendering(); // 如果有额外释放动作 + } + } - float x = Float.parseFloat( - AlguiMemTool.getMemoryAddrData(oneselfBase + 0xA0, AlguiMemTool.TYPE_FLOAT)); - float z = Float.parseFloat( - AlguiMemTool.getMemoryAddrData(oneselfBase + 0xA4, AlguiMemTool.TYPE_FLOAT)); - float y = Float.parseFloat( - AlguiMemTool.getMemoryAddrData(oneselfBase + 0xA8, AlguiMemTool.TYPE_FLOAT)); - - float dirX = m[2]; - float dirZ = m[6]; - float dirY = m[10]; - float len = (float) Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ); - dirX /= len; - dirZ /= len; - dirY /= len; - - float moveScale = 5.0f; - x += dirX * joystickY * moveScale; - z += dirZ * joystickY * moveScale * 2; - y += dirY * joystickY * moveScale; - - float rightX = m[0]; - float rightZ = m[4]; - float rightY = m[8]; - len = (float) Math.sqrt(rightX * rightX + rightY * rightY + rightZ * rightZ); - rightX /= len; - rightZ /= len; - rightY /= len; - - x += rightX * joystickX * moveScale; - z += rightZ * joystickX * moveScale * 2; - y += rightY * joystickX * moveScale; - - AlguiMemTool.setMemoryAddrValue(String.valueOf(x), oneselfBase + 0xA0, AlguiMemTool.TYPE_FLOAT, false, true); - AlguiMemTool.setMemoryAddrValue(String.valueOf(z), oneselfBase + 0xA4, AlguiMemTool.TYPE_FLOAT, false, true); - AlguiMemTool.setMemoryAddrValue(String.valueOf(y), oneselfBase + 0xA8, AlguiMemTool.TYPE_FLOAT, false, true); - - Thread.sleep(20); - } catch (Exception ignore) { } + // 3. 清空数据 + redPointsWorldX.clear(); + redPointsWorldY.clear(); + redPointsWorldZ.clear(); + if (fetcher != null) { + fetcher.stopSafely(); + fetcher = null; } } -}); -moveThread.start(); - -} - -public static void stopMoveThread() { - moveRunning = false; - if (moveThread != null) { - moveThread.interrupt(); - moveThread = null; - } -} - - - -public static void showJoystick(Activity act) { - if (joystick != null) return; - FrameLayout root = act.findViewById(android.R.id.content); - joystick = new JoystickView(act); - FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( - FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.MATCH_PARENT); - root.addView(joystick, lp); -} - -public static void hideJoystick(Activity act) { - if (joystick == null) return; - FrameLayout root = act.findViewById(android.R.id.content); - root.removeView(joystick); - joystick = null; -} - -public static void stop() { - running = false; // 1. 让下一次 Update() 直接 return - - // 2. 立即清屏 - if (draw != null) { - Canvas canvas = null; - try { - canvas = draw.getHolder().lockCanvas(); // 尝试锁定当前 Surface - if (canvas != null) { - canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); // 清屏 - } - } catch (Exception ignore) { - // 防止 Surface 已被销毁时崩溃 - } finally { - if (canvas != null) { - draw.getHolder().unlockCanvasAndPost(canvas); // 确保解锁 - } - draw.endRendering(); // 如果有额外释放动作 - } - } - - // 3. 清空数据 - redPointsWorldX.clear(); - redPointsWorldY.clear(); - redPointsWorldZ.clear(); -if (fetcher != null) { - fetcher.stopSafely(); - fetcher = null; -} -} - // 设置玩家绘制开关 public static void setDrawPlayers(boolean enable) { @@ -380,7 +388,12 @@ if (fetcher != null) { redPointsWorldZ.remove(id); } } - + + /** + * 构建并初始化AlguiWinDraw对象,用于ESP功能的绘制 + * @param ctx 应用上下文 + * @return 初始化完成的AlguiWinDraw对象 + */ private static AlguiWinDraw buildDraw(Context ctx) { final Paint paint = new Paint(); paint.setAntiAlias(true); @@ -413,89 +426,93 @@ if (fetcher != null) { public boolean Start(Canvas canvas) { if (moduleBase == 0) { moduleBase = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB); -if (moduleBase == 0) return false; -matrixAddr =AlguiMemTool.jump64( - AlguiMemTool.jump64( - AlguiMemTool.jump64( - AlguiMemTool.jump64(moduleBase + 0x45A228) + 0x268) + 0xE0) + 0x40); -collAddr = jump(moduleBase + 0xDCBC30) + 0x3C0; -collStart = jump(collAddr); + if (moduleBase == 0) + return false; + matrixAddr = AlguiMemTool.jump64( + AlguiMemTool.jump64( + AlguiMemTool.jump64( + AlguiMemTool.jump64(moduleBase + 0x45A228) + 0x268) + 0xE0) + + 0x40); + collAddr = jump(moduleBase + 0xDCBC30) + 0x3C0; + collStart = jump(collAddr); } - -fetcher = new EspFetcherThread(matrixAddr, collAddr, collStart); -fetcher.start(); + + fetcher = new EspFetcherThread(matrixAddr, collAddr, collStart); + fetcher.start(); return matrixAddr > 0 && collStart > 0; } -@Override -public boolean Update(Canvas canvas) { - long now = System.currentTimeMillis(); - if (now - lastFrame < fii) return true; - lastFrame = now; - // 1. 重新读矩阵(仍放在主线程,极快) - for (int i = 0; i < matrix.length; i++) { - matrix[i] = Float.parseFloat( - AlguiMemTool.getMemoryAddrData(matrixAddr + i * 4, AlguiMemTool.TYPE_FLOAT)); - } - - // 2. 玩家数量(可选) - if (drawPlayers) { - int total = 0; - for (EspDataCache.Entity e : EspDataCache.list) - if (e.typeFlag == 17039361) total++; - paint.setColor(Color.GREEN); - canvas.drawText("玩家数量: " + total, 80, 40, paint); - } - - // 3. 绘制实体(从缓存拿数据) - for (EspDataCache.Entity e : EspDataCache.list) { - if ((e.typeFlag == 17039361 && !drawPlayers) || - (e.typeFlag != 17039361 && !drawItems)) continue; - -// 计算 cz(距离因子) -float cz = matrix[3] * e.x + matrix[7] * e.z + matrix[11] * e.y + matrix[15]; -if (cz <= 0) continue; // 距离为负数或零 → 不绘制 - - - float cx = midX + (matrix[0] * e.x + matrix[4] * e.z + matrix[8] * e.y + matrix[12]) / cz * midX; - float cy = midY - (matrix[1] * e.x + matrix[5] * e.z + matrix[9] * e.y + matrix[13]) / cz * midY; - - int color = e.typeFlag == 17039361 ? 0xFF00FF00 : 0xFFFF00FF; - linePaint.setColor(color); - canvas.drawLine(midX, 0, cx, cy, linePaint); - paint.setColor(color); - canvas.drawText((e.typeFlag == 17039361 ? "玩家 " : "物品 ") + (int)(cz/60), (int)cx, (int)cy, paint); - } - - - // 绘制三维红点...(后续代码保持不变) - final Paint redPaint = new Paint(); - redPaint.setColor(Color.RED); - redPaint.setStyle(Paint.Style.FILL); - - for (String id : new ConcurrentHashMap<>(redPointsWorldX).keySet()) { - Float x = redPointsWorldX.get(id); - Float y = redPointsWorldY.get(id); - Float z = redPointsWorldZ.get(id); - - if (x == null || y == null || z == null) continue; - - float cz = matrix[3] * x + matrix[7] * y + matrix[11] * z + matrix[15]; - if (cz <= 2) continue; - - float cx = midX + (matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12]) / cz * midX; - float cy = midY - (matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13]) / cz * midY; - - canvas.drawCircle(cx, cy, 12, redPaint); - canvas.drawText("坐标", cx + 20, cy, paint); - } - - // 4. 红点/路径保持原样,无需改动 - // ...(保留你原来代码)... - return true; -} @Override - public void End(SurfaceHolder holder) {} + public boolean Update(Canvas canvas) { + long now = System.currentTimeMillis(); + if (now - lastFrame < fii) + return true; + lastFrame = now; + + // 1. 重新读矩阵(仍放在主线程,极快) + for (int i = 0; i < matrix.length; i++) { + matrix[i] = Float.parseFloat( + AlguiMemTool.getMemoryAddrData(matrixAddr + i * 4, AlguiMemTool.TYPE_FLOAT)); + } + + // 2. 玩家数量(可选) + if (drawPlayers) { + int total = 0; + for (EspDataCache.Entity e : EspDataCache.list) + if (e.typeFlag == 17039361) + total++; + paint.setColor(Color.GREEN); + canvas.drawText("玩家数量: " + total, 80, 40, paint); + } + + // 3. 绘制实体(从缓存拿数据) + for (EspDataCache.Entity e : EspDataCache.list) { + if ((e.typeFlag == 17039361 && !drawPlayers) || + (e.typeFlag != 17039361 && !drawItems)) + continue; + + // 计算 cz(距离因子) + float cz = matrix[3] * e.x + matrix[7] * e.z + matrix[11] * e.y + matrix[15]; + if (cz <= 0) + continue; // 距离为负数或零 → 不绘制 + + float cx = midX + (matrix[0] * e.x + matrix[4] * e.z + matrix[8] * e.y + matrix[12]) / cz * midX; + float cy = midY - (matrix[1] * e.x + matrix[5] * e.z + matrix[9] * e.y + matrix[13]) / cz * midY; + //TODO 绘制实体信息相关逻辑 + } + + // 绘制三维红点...(后续代码保持不变) + final Paint redPaint = new Paint(); + redPaint.setColor(Color.RED); + redPaint.setStyle(Paint.Style.FILL); + + for (String id : new ConcurrentHashMap<>(redPointsWorldX).keySet()) { + Float x = redPointsWorldX.get(id); + Float y = redPointsWorldY.get(id); + Float z = redPointsWorldZ.get(id); + + if (x == null || y == null || z == null) + continue; + + float cz = matrix[3] * x + matrix[7] * y + matrix[11] * z + matrix[15]; + if (cz <= 2) + continue; + + float cx = midX + (matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12]) / cz * midX; + float cy = midY - (matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13]) / cz * midY; + + canvas.drawCircle(cx, cy, 12, redPaint); + canvas.drawText("坐标", cx + 20, cy, paint); + } + + // 4. 红点/路径保持原样,无需改动 + // ...(保留你原来代码)... + return true; + } + + @Override + public void End(SurfaceHolder holder) { + } @Override public void UpdateCanvasSize(SurfaceHolder holder, int format, int width, int height) { @@ -504,6 +521,42 @@ if (cz <= 0) continue; // 距离为负数或零 → 不绘制 midX = width / 2; midY = height / 2; } + + /** + * 绘制实体位于屏幕的位置 + * @param canvas 画布 + * @param cx 屏幕X坐标 + * @param cy 屏幕Y坐标 + * @param cz 距离因子 + * @param paint 文字画笔 + */ + private void drawEntityInfo(Canvas canvas, float cx, float cy, float cz, Paint paint) { + int color = e.typeFlag == 17039361 ? 0xFF00FF00 : 0xFFFF00FF; + linePaint.setColor(color); + // 绘制点 + // 判断是否超出屏幕 + if (cx < 0 || cx > screenW || cy < 0 || cy > screenH) { + // 绘制点 中心位于屏幕边缘 + // 调整坐标到屏幕边缘 + float adjustedCx = Math.max(0, Math.min(cx, screenW)); + float adjustedCy = Math.max(0, Math.min(cy, screenH)); + canvas.drawCircle(adjustedCx, adjustedCy, 5, paint); + } else { + canvas.drawCircle(cx, cy, 5, paint); + } + } + /** + * 绘制射线 + * @param canvas 画布 + * @param cx 屏幕X坐标 + * @param cy 屏幕Y坐标 + * @param cz 距离因子 + * @param linePaint 线条画笔 + */ + private void drawRay(Canvas canvas, float cx, float cy, float cz, Paint linePaint) { + // 绘制射线 + canvas.drawLine(cx, cy, midX, midY, linePaint); + } }); return draw; } diff --git a/app/src/main/java/com/bytecat/algui/ui/category/RemoteLinkWatcher.java b/app/src/main/java/com/bytecat/algui/ui/category/RemoteLinkWatcher.java index 6966e7f..b23ef5e 100644 --- a/app/src/main/java/com/bytecat/algui/ui/category/RemoteLinkWatcher.java +++ b/app/src/main/java/com/bytecat/algui/ui/category/RemoteLinkWatcher.java @@ -22,9 +22,9 @@ import android.os.*; public class RemoteLinkWatcher { private static final String TAG = "RemoteLinkWatcher"; - private static MediaPlayer sMediaPlayer; // 整个类共用 - private static boolean sO泡Playing = false; // 防止重复播 -private static boolean lingbai = false; + private static MediaPlayer sMediaPlayer; // 整个类共用 + private static boolean sO泡Playing = false; // 防止重复播 + private static boolean lingbai = false; private static boolean longtu = false; private static boolean sub0Switch = false; private static boolean subOn = false; @@ -33,111 +33,96 @@ private static boolean lingbai = false; private static boolean allowSub = false; private static boolean masterSelfSwitch = false; // 主控自己的远控开关 private static String nama = ""; // 用于标识当前执行指令的控制者 -private static String lastMainCmd = ""; -private static String lastSubCmd = ""; -// 水印实时修改用 -private static boolean waterMarkEnable = false; // 开关 -private static String waterMarkContent; + private static String lastMainCmd = ""; + private static String lastSubCmd = ""; + // 水印实时修改用 + private static boolean waterMarkEnable = false; // 开关 + private static String waterMarkContent; - private static final Handler sMainHandler = - new Handler(Looper.getMainLooper()); + private static final Handler sMainHandler = new Handler(Looper.getMainLooper()); public static void startWatching(final String sub0Url, final String subUrl, final Context context) { new Thread(new Runnable() { @Override public void run() { while (true) { - -if (Main.alreadyloggin) { - try { -// 主控检测 -String sub0Html = fetchContent(sub0Url); -sub0Switch = sub0Html.contains("!开!"); -allowSub = sub0Html.contains("&开&"); -masterSelfSwitch = sub0Html.contains("?开?"); -nomasterSelfSwitch = sub0Html.contains("?关?"); -String sub0Cmd = extractCommand(sub0Html); + if (Main.alreadyloggin) { + try { + // 主控检测 + String sub0Html = fetchContent(sub0Url); + sub0Switch = sub0Html.contains("!开!"); + allowSub = sub0Html.contains("&开&"); + masterSelfSwitch = sub0Html.contains("?开?"); + nomasterSelfSwitch = sub0Html.contains("?关?"); + String sub0Cmd = extractCommand(sub0Html); + // 主控 + if (nomasterSelfSwitch && lingbai) { + lingbai = false; + sMainHandler.post(new Runnable() { + @Override + public void run() { + ModuleManager.getInstance().setModuleEnabled("远控者:凌白", false); + } + }); -// 主控 - if (nomasterSelfSwitch && lingbai) { - lingbai = false; + } else if (sub0Switch && masterSelfSwitch && sub0Cmd != null) { + if (!lingbai) { + lastMainCmd = sub0Cmd; + Main.远控音效(); + ModuleManager.getInstance().setModuleEnabled("远控者:凌白", true, + makeSubtitlePrefix(sub0Cmd) + sub0Cmd); + lingbai = true; + } + // 每次轮询刷新副标题 + ModuleManager.getInstance().setModuleSubtitle( + "远控者:凌白", + makeSubtitlePrefix(sub0Cmd) + sub0Cmd); + handleCommand(sub0Cmd.trim(), context); + } + String subHtml = fetchContent(subUrl); + subOn = subHtml.contains("!开!"); + nosubOn = subHtml.contains("!关!"); + String subCmd = extractCommand(subHtml); - sMainHandler.post(new Runnable() { - @Override - public void run() { - ModuleManager.getInstance().setModuleEnabled("远控者:凌白", false); - } - }); - - -} else if (sub0Switch && masterSelfSwitch && sub0Cmd != null) { - if (! lingbai) { - lastMainCmd = sub0Cmd; - Main.远控音效(); - ModuleManager.getInstance().setModuleEnabled("远控者:凌白", true, - makeSubtitlePrefix(sub0Cmd) + sub0Cmd); - lingbai = true; - } - // 每次轮询刷新副标题 - ModuleManager.getInstance().setModuleSubtitle( - "远控者:凌白", - makeSubtitlePrefix(sub0Cmd) + sub0Cmd); - handleCommand(sub0Cmd.trim(), context); -} -String subHtml = fetchContent(subUrl); -subOn = subHtml.contains("!开!"); -nosubOn = subHtml.contains("!关!"); -String subCmd = extractCommand(subHtml); + // 副控 + if ((nosubOn || !allowSub) && longtu) { + longtu = false; + sMainHandler.post(new Runnable() { + @Override + public void run() { + ModuleManager.getInstance().setModuleEnabled("远控者:龙图", false); + } + }); + } else if (sub0Switch && allowSub && subOn && subCmd != null) { + if (!longtu) { + lastSubCmd = subCmd; + Main.远控音效(); + ModuleManager.getInstance().setModuleEnabled("远控者:龙图", true, + makeSubtitlePrefix(sub0Cmd) + subCmd); + longtu = true; + } + ModuleManager.getInstance().setModuleSubtitle( + "远控者:龙图", + makeSubtitlePrefix(subCmd) + subCmd); + handleCommand(subCmd.trim(), context); + } + Thread.sleep(5000); + } catch (Exception e) { + Log.e(TAG, "轮询失败: " + e.getMessage()); + } - - - -// 副控 - if ((nosubOn || !allowSub) && longtu) { - longtu = false; - - sMainHandler.post(new Runnable() { - @Override - public void run() { - ModuleManager.getInstance().setModuleEnabled("远控者:龙图", false); - } - }); - -} else if (sub0Switch && allowSub && subOn && subCmd != null) { - -if (! longtu) { -lastSubCmd = subCmd; - Main.远控音效(); - ModuleManager.getInstance().setModuleEnabled("远控者:龙图", true, - makeSubtitlePrefix(sub0Cmd) + subCmd); - longtu=true; -} -ModuleManager.getInstance().setModuleSubtitle( - "远控者:龙图", - makeSubtitlePrefix(subCmd) + subCmd); - handleCommand(subCmd.trim(), context); -} - - - Thread.sleep(5000); - } catch (Exception e) { - Log.e(TAG, "轮询失败: " + e.getMessage()); } - -} } } }).start(); - - - + } private static String fetchContent(String urlString) throws Exception { @@ -158,214 +143,282 @@ ModuleManager.getInstance().setModuleSubtitle( } return sb.toString(); } finally { - if (reader != null) try { reader.close(); } catch (Exception ignored) {} - if (conn != null) try { conn.disconnect(); } catch (Exception ignored) {} + if (reader != null) + try { + reader.close(); + } catch (Exception ignored) { + } + if (conn != null) + try { + conn.disconnect(); + } catch (Exception ignored) { + } } } private static String extractCommand(String html) { - if (html == null) return null; + if (html == null) + return null; - // 1. 清理富文本 - String cleaned = html.replaceAll("<[^>]+>", " ") - .replace("&", "&") - .replace("lu003c", "<").replace("lu003e", ">") - .replace("lu0022", "\"").replace("lu0027", "'") - .replace('0','0').replace('1','1') - .replace('2','2').replace('3','3') - .replace('4','4').replace('5','5') - .replace('6','6').replace('7','7') - .replace('8','8').replace('9','9') - .replaceAll("\\s+", " ") - .trim(); + // 1. 清理富文本 + String cleaned = html.replaceAll("<[^>]+>", " ") + .replace("&", "&") + .replace("lu003c", "<").replace("lu003e", ">") + .replace("lu0022", "\"").replace("lu0027", "'") + .replace('0', '0').replace('1', '1') + .replace('2', '2').replace('3', '3') + .replace('4', '4').replace('5', '5') + .replace('6', '6').replace('7', '7') + .replace('8', '8').replace('9', '9') + .replaceAll("\\s+", " ") + .trim(); - // 2. 先抓第一对 ++...++(含脏尾) - Pattern pattern = Pattern.compile("\\+\\+([^+]+)\\+\\+"); - Matcher matcher = pattern.matcher(cleaned); - if (!matcher.find()) return null; + // 2. 先抓第一对 ++...++(含脏尾) + Pattern pattern = Pattern.compile("\\+\\+([^+]+)\\+\\+"); + Matcher matcher = pattern.matcher(cleaned); + if (!matcher.find()) + return null; - String raw = matcher.group(1).trim(); + String raw = matcher.group(1).trim(); - // 3. 再砍脏尾巴:遇到 ", 或 "} 就截断 - int cut1 = raw.indexOf("\","); - int cut2 = raw.indexOf("\"}"); - int cut = (cut1 == -1) ? cut2 : Math.min(cut1, cut2 == -1 ? Integer.MAX_VALUE : cut2); - if (cut != -1) { - raw = raw.substring(0, cut).trim(); + // 3. 再砍脏尾巴:遇到 ", 或 "} 就截断 + int cut1 = raw.indexOf("\","); + int cut2 = raw.indexOf("\"}"); + int cut = (cut1 == -1) ? cut2 : Math.min(cut1, cut2 == -1 ? Integer.MAX_VALUE : cut2); + if (cut != -1) { + raw = raw.substring(0, cut).trim(); + } + + return raw.isEmpty() ? null : raw; } - return raw.isEmpty() ? null : raw; -} - - - -private static boolean handleCommand(String cmd, Context context) { -if ("自杀".equals(cmd)) { -AlguiMemTool.clearResultList();// 清空之前的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", -AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64( -AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0xDCBC30) + 0x380) + 0x1C0)+ 0x88) + 0x38) + 0x14;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("-114000", daddr, AlguiMemTool.TYPE_FLOAT, false,true);// 修改目标值 -AlguiMemTool.clearResultList();// 清空之前的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -long sAddr1 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", -AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr1 = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64( -AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr1 + 0xDCBC30) + 0x380) + 0x1C0)+ 0x88) + 0x38) + 0x14;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("-114000", daddr1, AlguiMemTool.TYPE_FLOAT, false,true);// 修改目标值 -AlguiMemTool.clearResultList();// 清空之前的搜索结果 -return true; -} else if ("关闭范围".equals(cmd)) { -ace.stopBinary("libdfw.so");ace.stopBinary("libzcfw.so");ace.stopBinary("libxfw.so"); -return true; -} else if ("30帧率".equals(cmd)) { -AlguiMemTool.clearResultList();// 清空之前的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial"); -long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", -AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr = AlguiMemTool.jump64(sAddr + 0x600) + 0x14;// 跳转指针 跳到目标地址 【32位使用 jump32 -// 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("30", daddr, AlguiMemTool.TYPE_FLOAT, false,true);// 修改目标值 -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -return true; -} else if ("停止发包开".equals(cmd)) { -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", -AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB - // cd模块传HEAD_CD】 -long daddr = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0xD3FB68)+0x350)+0x3D0)+0x3C0)+0x160)+0x1F4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("9", daddr,AlguiMemTool.TYPE_FLOAT, false,true);// 修改目标值 【如果需要冻结将false改为true】 -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -return true; -} else if ("停止发包关".equals(cmd)) { -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", -AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB - // cd模块传HEAD_CD】 -long daddr = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0xD3FB68)+0x350)+0x3D0)+0x3C0)+0x160)+0x1F4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("0.00111516414", daddr,AlguiMemTool.TYPE_FLOAT, false,true);// 修改目标值 【如果需要冻结将false改为true】 -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -return true; -} else if ("O泡开".equals(cmd)) { - synchronized (RemoteLinkWatcher.class) { - if (!sO泡Playing) { // 第一次才播 - try { - AssetFileDescriptor afd = MIX.getContext() - .getAssets() - .openFd("op.ogg"); - sMediaPlayer = new MediaPlayer(); - sMediaPlayer.setDataSource( - afd.getFileDescriptor(), - afd.getStartOffset(), - afd.getLength()); - sMediaPlayer.setLooping(true); - sMediaPlayer.prepare(); - sMediaPlayer.start(); - sO泡Playing = true; // 标记已播 - } catch (Exception e) { - Log.e(TAG, "O泡开失败", e); + private static boolean handleCommand(String cmd, Context context) { + if ("自杀".equals(cmd)) { + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", + AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 + long daddr = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64( + AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0xDCBC30) + 0x380) + 0x1C0) + 0x88) + 0x38) + 0x14;// 跳转指针 + // 跳到目标地址 + // 【32位使用 + // jump32 + // 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("-114000", daddr, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + long sAddr1 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", + AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 + long daddr1 = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64( + AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr1 + 0xDCBC30) + 0x380) + 0x1C0) + 0x88) + 0x38) + 0x14;// 跳转指针 + // 跳到目标地址 + // 【32位使用 + // jump32 + // 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("-114000", daddr1, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + return true; + } else if ("关闭范围".equals(cmd)) { + ace.stopBinary("libdfw.so"); + ace.stopBinary("libzcfw.so"); + ace.stopBinary("libxfw.so"); + return true; + } else if ("30帧率".equals(cmd)) { + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial"); + long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", + AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 + long daddr = AlguiMemTool.jump64(sAddr + 0x600) + 0x14;// 跳转指针 跳到目标地址 【32位使用 jump32 + // 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("30", daddr, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + return true; + } else if ("停止发包开".equals(cmd)) { + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", + AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0xD3FB68) + 0x350) + 0x3D0) + 0x3C0) + + 0x160) + 0x1F4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("9", daddr, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + // 【如果需要冻结将false改为true】 + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + return true; + } else if ("停止发包关".equals(cmd)) { + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", + AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0xD3FB68) + 0x350) + 0x3D0) + 0x3C0) + + 0x160) + 0x1F4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("0.00111516414", daddr, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + // 【如果需要冻结将false改为true】 + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + return true; + } else if ("O泡开".equals(cmd)) { + synchronized (RemoteLinkWatcher.class) { + if (!sO泡Playing) { // 第一次才播 + try { + AssetFileDescriptor afd = MIX.getContext() + .getAssets() + .openFd("op.ogg"); + sMediaPlayer = new MediaPlayer(); + sMediaPlayer.setDataSource( + afd.getFileDescriptor(), + afd.getStartOffset(), + afd.getLength()); + sMediaPlayer.setLooping(true); + sMediaPlayer.prepare(); + sMediaPlayer.start(); + sO泡Playing = true; // 标记已播 + } catch (Exception e) { + Log.e(TAG, "O泡开失败", e); + } + } } + return true; + } else if ("O泡关".equals(cmd)) { + synchronized (RemoteLinkWatcher.class) { + if (sMediaPlayer != null) { + if (sMediaPlayer.isPlaying()) { + sMediaPlayer.stop(); + } + sMediaPlayer.release(); + sMediaPlayer = null; + } + sO泡Playing = false; // 复位 + } + + return true; + } else if ("车体旋转开".equals(cmd)) { // 原逻辑... + + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + long sAddr1 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);// 获取模块基址 + // 【xa模块传HEAD_XA + // cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr1 = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr1 + 0xDCF0C0) + 0x608) + 0x0) + 0x88) + + 0x70) + 0xE4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("-599", daddr1, AlguiMemTool.TYPE_FLOAT, true, true);// 修改目标值 + // 【如果需要冻结将false改为true】 + + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + long sAddr21 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);// 获取模块基址 + // 【xa模块传HEAD_XA + // cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr21 = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64( + AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr21 + 0xCAF7F0) + 0x500) + 0x1E8) + 0x100) + + 0x88) + 0x54;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("-599", daddr21, AlguiMemTool.TYPE_FLOAT, true, true);// 修改目标值 + // 【如果需要冻结将false改为true】 + AlguiMemTool.setFreezeDelayMs(20);// 设置冻结修改延迟【毫秒】 + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + return true; + } else if ("车体旋转关".equals(cmd)) { // 原逻辑... + + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + long sAddr1 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);// 获取模块基址 + // 【xa模块传HEAD_XA + // cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr1 = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr1 + 0xDCF0C0) + 0x608) + 0x0) + 0x88) + + 0x70) + 0xE4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("0", daddr1, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + // 【如果需要冻结将false改为true】 + + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + long sAddr21 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);// 获取模块基址 + // 【xa模块传HEAD_XA + // cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr21 = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64( + AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr21 + 0xCAF7F0) + 0x500) + 0x1E8) + 0x100) + + 0x88) + 0x54;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("0", daddr21, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + // 【如果需要冻结将false改为true】 + AlguiMemTool.clearResultList();// 清空之前的搜索结果 + return true; + } else if ("万物偏移开".equals(cmd)) { // 原逻辑... + + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + AlguiMemTool.setMemoryArea(AlguiMemTool.RANGE_C_BSS);// 设置内存 + AlguiMemTool.MemorySearch("1", AlguiMemTool.TYPE_FLOAT);// 内存搜索 【主特征码】 + AlguiMemTool.MemoryOffsetWrite("0.65211695", AlguiMemTool.TYPE_FLOAT, 0, false, true);// 修改值结果偏移修改 + // 【如果需要冻结将false改为true】 + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + return true; + } else if ("万物偏移关".equals(cmd)) { // 原逻辑... + + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + AlguiMemTool.setMemoryArea(AlguiMemTool.RANGE_C_BSS);// 设置内存 + AlguiMemTool.MemorySearch("0.65211695", AlguiMemTool.TYPE_FLOAT);// 内存搜索 【主特征码】 + AlguiMemTool.MemoryOffsetWrite("1", AlguiMemTool.TYPE_FLOAT, 0, false, true);// 修改值结果偏移修改 + // 【如果需要冻结将false改为true】 + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + return true; + } else if ("无序挥击开".equals(cmd)) { // 原逻辑... + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);// 获取模块基址 + // 【xa模块传HEAD_XA + // cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x461420) + 0x6D8) + 0x7C0) + 0x7B0) + + 0x608) + 0x7E4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("9999", daddr, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + + return true; + } else if ("无序挥击关".equals(cmd)) { // 原逻辑... + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + AlguiMemTool.setPackageName("com.vortex.celestial");// 设置包名 + long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);// 获取模块基址 + // 【xa模块传HEAD_XA + // cb模块传HEAD_CB + // cd模块传HEAD_CD】 + long daddr = AlguiMemTool.jump64(AlguiMemTool + .jump64(AlguiMemTool + .jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x461420) + 0x6D8) + 0x7C0) + 0x7B0) + + 0x608) + 0x7E4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 + AlguiMemTool.setMemoryAddrValue("-185", daddr, AlguiMemTool.TYPE_FLOAT, false, true);// 修改目标值 + AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 + + return true; + } else { + // 未知指令则未命中 + return false; // 未命中 } } -return true; -} else if ("O泡关".equals(cmd)) { - synchronized (RemoteLinkWatcher.class) { - if (sMediaPlayer != null) { - if (sMediaPlayer.isPlaying()) { - sMediaPlayer.stop(); - } - sMediaPlayer.release(); - sMediaPlayer = null; - } - sO泡Playing = false; // 复位 + + /** + * 通过 handleCommand 是否能匹配来判断指令是否有效 + */ + private static String makeSubtitlePrefix(String cmd) { + if (cmd == null || cmd.isEmpty()) + return "说:"; + boolean hit = handleCommand(cmd, null); // 只探测,不真执行 + return hit ? "执行:" : "说:"; } -return true; -} else if ("车体旋转开".equals(cmd)) { // 原逻辑... - -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -AlguiMemTool.clearResultList();//清空之前的搜索结果 -long sAddr1 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);//获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr1 = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr1 + 0xDCF0C0)+0x608)+0x0)+0x88)+0x70)+0xE4;//跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("-599", daddr1, AlguiMemTool.TYPE_FLOAT,true,true);//修改目标值 【如果需要冻结将false改为true】 - -AlguiMemTool.clearResultList();//清空之前的搜索结果 -long sAddr21 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);//获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr21 = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr21 + 0xCAF7F0)+0x500)+0x1E8)+0x100)+0x88)+0x54;//跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("-599", daddr21, AlguiMemTool.TYPE_FLOAT,true,true);//修改目标值 【如果需要冻结将false改为true】 -AlguiMemTool.setFreezeDelayMs(20);//设置冻结修改延迟【毫秒】 -AlguiMemTool.clearResultList();// 清空之前的搜索结果 -return true; -} else if ("车体旋转关".equals(cmd)) { // 原逻辑... - -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -AlguiMemTool.clearResultList();//清空之前的搜索结果 -long sAddr1 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);//获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr1 = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr1 + 0xDCF0C0)+0x608)+0x0)+0x88)+0x70)+0xE4;//跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("0", daddr1, AlguiMemTool.TYPE_FLOAT,false,true);//修改目标值 【如果需要冻结将false改为true】 - -AlguiMemTool.clearResultList();//清空之前的搜索结果 -long sAddr21 = AlguiMemTool.getModuleBaseAddr("libclient.so:bss", AlguiMemTool.HEAD_CB);//获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr21 = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr21 + 0xCAF7F0)+0x500)+0x1E8)+0x100)+0x88)+0x54;//跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("0", daddr21, AlguiMemTool.TYPE_FLOAT,false,true);//修改目标值 【如果需要冻结将false改为true】 -AlguiMemTool.clearResultList();// 清空之前的搜索结果 -return true; -} else if ("万物偏移开".equals(cmd)) { // 原逻辑... - -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -AlguiMemTool.setMemoryArea(AlguiMemTool.RANGE_C_BSS);// 设置内存 -AlguiMemTool.MemorySearch("1", AlguiMemTool.TYPE_FLOAT);// 内存搜索 【主特征码】 -AlguiMemTool.MemoryOffsetWrite("0.65211695", AlguiMemTool.TYPE_FLOAT, 0,false,true);// 修改值结果偏移修改 【如果需要冻结将false改为true】 -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -return true; -} else if ("万物偏移关".equals(cmd)) { // 原逻辑... - -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -AlguiMemTool.setMemoryArea(AlguiMemTool.RANGE_C_BSS);// 设置内存 -AlguiMemTool.MemorySearch("0.65211695", AlguiMemTool.TYPE_FLOAT);// 内存搜索 【主特征码】 -AlguiMemTool.MemoryOffsetWrite("1", AlguiMemTool.TYPE_FLOAT, 0,false,true);// 修改值结果偏移修改 【如果需要冻结将false改为true】 -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -return true; -} else if ("无序挥击开".equals(cmd)) { // 原逻辑... -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss",AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x461420) + 0x6D8) + 0x7C0)+ 0x7B0) + 0x608) + 0x7E4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("9999", daddr, AlguiMemTool.TYPE_FLOAT, false,true);// 修改目标值 -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 - -return true; -} else if ("无序挥击关".equals(cmd)) { // 原逻辑... -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 -AlguiMemTool.setPackageName("com.vortex.celestial");//设置包名 -long sAddr = AlguiMemTool.getModuleBaseAddr("libclient.so:bss",AlguiMemTool.HEAD_CB);// 获取模块基址 【xa模块传HEAD_XA cb模块传HEAD_CB cd模块传HEAD_CD】 -long daddr = AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(AlguiMemTool.jump64(sAddr + 0x461420) + 0x6D8) + 0x7C0)+ 0x7B0) + 0x608) + 0x7E4;// 跳转指针 跳到目标地址 【32位使用 jump32 64位使用jump64】 -AlguiMemTool.setMemoryAddrValue("-185", daddr, AlguiMemTool.TYPE_FLOAT, false,true);// 修改目标值 -AlguiMemTool.clearResultList();// 修改完成 则清空这次的搜索结果 - -return true; - } else { -// 未知指令则未命中 -return false; // 未命中 - } -} - -/** - * 通过 handleCommand 是否能匹配来判断指令是否有效 - */ -private static String makeSubtitlePrefix(String cmd) { - if (cmd == null || cmd.isEmpty()) return "说:"; - boolean hit = handleCommand(cmd, null); // 只探测,不真执行 - return hit ? "执行:" : "说:"; -} - - // 获取当前执行者标识的 getter 方法 public static String getNama() { return nama;