add bsdiff
This commit is contained in:
10
.gitignore
vendored
10
.gitignore
vendored
@@ -31,13 +31,9 @@ build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
/uploadApk/file/config.mdpi.apk
|
||||
/uploadApk/file/FLYSN-68-V3.2.8-20240829-192522-G6Release.apk
|
||||
/uploadApk/file/FLYSN-71-V3.3.1-20250307-175850-Huaruian8768Release.apk
|
||||
/uploadApk/file/MIR4_0.442318_APKPure.xapk
|
||||
/uploadApk/icon/7110e12ad7dec55cf925b72f266df7ed.png
|
||||
/uploadApk/icon/268119212d35253700c802830449316a.png
|
||||
/uploadApk/icon/d016c8c75162d1ae4c3ffbf7a178a111.png
|
||||
/uploadApk/file/
|
||||
/uploadApk/icon/
|
||||
/uploadApk/patch/
|
||||
/hs_err_pid14160.log
|
||||
/hs_err_pid19016.log
|
||||
/hs_err_pid28008.log
|
||||
|
||||
BIN
bsdiff/win/bsdiff.exe
Normal file
BIN
bsdiff/win/bsdiff.exe
Normal file
Binary file not shown.
BIN
bsdiff/win/bspatch.exe
Normal file
BIN
bsdiff/win/bspatch.exe
Normal file
Binary file not shown.
@@ -16,7 +16,7 @@ import java.util.Optional;
|
||||
|
||||
@RestController
|
||||
public class CheckUpdateController {
|
||||
public static Logger logger = LogManager.getLogger(UploadApkController.class);
|
||||
public static Logger logger = LogManager.getLogger(CheckUpdateController.class);
|
||||
|
||||
@Autowired
|
||||
private ApkInfoService apkInfoService;
|
||||
@@ -49,6 +49,10 @@ public class CheckUpdateController {
|
||||
@GetMapping("/android/get_all")
|
||||
public Result getAll() {
|
||||
List<ApkInfo> apkInfoList = apkInfoService.getAll();
|
||||
if (apkInfoList==null||apkInfoList.isEmpty()){
|
||||
return Result.notFound();
|
||||
}else {
|
||||
return Result.success().setData(apkInfoList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.mir4updater.backend.controller.apk;
|
||||
|
||||
import com.mir4updater.backend.entity.ApkInfo;
|
||||
import com.mir4updater.backend.result.Result;
|
||||
import com.mir4updater.backend.service.ApkInfoService;
|
||||
import com.mir4updater.backend.utils.HashUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
public class CreateDiffPatchFile {
|
||||
public static Logger logger = LogManager.getLogger(CreateDiffPatchFile.class);
|
||||
|
||||
private static final String UPLOAD_PATH = "uploadApk";
|
||||
|
||||
public static final String PATCH_PATH = "patch";
|
||||
@Autowired
|
||||
private ApkInfoService apkInfoService;
|
||||
|
||||
@PostMapping("/android/create_patch")
|
||||
public Result uploadApk(@RequestParam("old_id") int oldId, @RequestParam("new_id") int newId) throws Exception {
|
||||
String projectPath = System.getProperty("user.dir");
|
||||
String patchPath = projectPath + File.separator + UPLOAD_PATH + File.separator + PATCH_PATH + File.separator;
|
||||
File patchFileDir = new File(patchPath);
|
||||
if (!patchFileDir.exists()) {
|
||||
patchFileDir.mkdirs();
|
||||
}
|
||||
|
||||
ApkInfo oldApkInfo = apkInfoService.getApkInfo(oldId);
|
||||
ApkInfo newApkInfo = apkInfoService.getApkInfo(newId);
|
||||
if (oldApkInfo == null || newApkInfo == null) {
|
||||
return Result.notFound();
|
||||
}
|
||||
if (!Objects.equals(oldApkInfo.getPackageName(), newApkInfo.getPackageName())) {
|
||||
return Result.error("包名不一致");
|
||||
}
|
||||
if (oldApkInfo.getVersionCode() >= newApkInfo.getVersionCode()) {
|
||||
return Result.error("旧版本号不能大于等于新版本号");
|
||||
}
|
||||
File patchFile = new File(patchPath + oldApkInfo.getPackageName() + "_" + oldApkInfo.getVersionCode() + "_" + newApkInfo.getVersionCode() + ".patch");
|
||||
|
||||
// 根据操作系统选择命令
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
String command;
|
||||
if (os.contains("win")) {
|
||||
command = "bsdiff" + File.separator + "win" + File.separator + "bsdiff.exe";
|
||||
} else if (os.contains("nix") || os.contains("mac")) {
|
||||
command = "bsdiff" + File.separator + "linux" + File.separator + "bsdiff";
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unsupported OS");
|
||||
}
|
||||
File file = new File(command);
|
||||
logger.info("bsdiff file exists = " + file.exists());
|
||||
|
||||
// 将 command 和 arg 合并成一个数组,command 作为第一个参数
|
||||
List<String> cmdArgs = new ArrayList<>();
|
||||
cmdArgs.add(command); // 第一个参数是命令本身
|
||||
cmdArgs.add(oldApkInfo.getFilePath());// 后续参数
|
||||
cmdArgs.add(newApkInfo.getFilePath());
|
||||
cmdArgs.add(patchFile.getAbsolutePath());
|
||||
|
||||
logger.info("bsdiff args = " + cmdArgs);
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(cmdArgs); // 传入合并后的参数列表
|
||||
pb.redirectErrorStream(true); // 合并错误流和输入流
|
||||
Process process = pb.start();
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
logger.info("退出码: " + exitCode);
|
||||
|
||||
// 读取输出
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String result = reader.lines().collect(Collectors.joining("\n"));
|
||||
if (exitCode == 0) {
|
||||
String md5 = HashUtils.getFileMD5(patchFile);
|
||||
logger.info("patchFile md5 = " + md5);
|
||||
return Result.success(md5);
|
||||
} else {
|
||||
return Result.error(result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,32 +33,43 @@ import java.util.zip.ZipFile;
|
||||
|
||||
@RestController
|
||||
public class UploadApkController {
|
||||
private static final String UPLOAD_PATH = "uploadApk";
|
||||
private static final String APK_FILE_PATH = "file";
|
||||
private static final String ICON_PATH = "icon";
|
||||
private static final String TEMP_PATH = "tmp";
|
||||
|
||||
public static Logger logger = LogManager.getLogger(UploadApkController.class);
|
||||
|
||||
@Autowired
|
||||
private ApkInfoService apkInfoService;
|
||||
private static final String UPLOAD_PATH = "uploadApk";
|
||||
private static final String ApkFilePath = "file";
|
||||
private static final String ICON_PATH = "icon";
|
||||
|
||||
|
||||
@PostMapping("/android/upload_apk")
|
||||
public Result uploadApk(@RequestParam("file") MultipartFile multipartFile) throws Exception {
|
||||
if (multipartFile != null && !multipartFile.isEmpty()) {
|
||||
String projectPath = System.getProperty("user.dir");
|
||||
logger.info("当前项目路径为:" + projectPath);
|
||||
String dirPath = projectPath + File.separator + UPLOAD_PATH + File.separator + ApkFilePath;
|
||||
|
||||
String apkPath = projectPath + File.separator + UPLOAD_PATH + File.separator + APK_FILE_PATH;
|
||||
String iconPath = projectPath + File.separator + UPLOAD_PATH + File.separator + ICON_PATH + File.separator;
|
||||
File dirFile = new File(dirPath);
|
||||
if (!dirFile.exists()) {
|
||||
dirFile.mkdirs();
|
||||
String tempPath = projectPath + File.separator + UPLOAD_PATH + File.separator + TEMP_PATH + File.separator;
|
||||
|
||||
File apkFileDir = new File(apkPath);
|
||||
if (!apkFileDir.exists()) {
|
||||
apkFileDir.mkdirs();
|
||||
}
|
||||
File iconFilePath = new File(iconPath);
|
||||
if (!iconFilePath.exists()) {
|
||||
iconFilePath.mkdirs();
|
||||
File iconFileDir = new File(iconPath);
|
||||
if (!iconFileDir.exists()) {
|
||||
iconFileDir.mkdirs();
|
||||
}
|
||||
File tempFileDir = new File(tempPath);
|
||||
if (!tempFileDir.exists()) {
|
||||
tempFileDir.mkdirs();
|
||||
}
|
||||
|
||||
//1.接收上传的应用,写入到硬盘
|
||||
String originalFilename = multipartFile.getOriginalFilename();
|
||||
File file = new File(dirPath + File.separator + originalFilename);
|
||||
File file = new File(apkPath + File.separator + originalFilename);
|
||||
logger.info("file path = " + file.getAbsolutePath());
|
||||
|
||||
try {
|
||||
@@ -82,7 +93,7 @@ public class UploadApkController {
|
||||
if (isAPK(file)) {
|
||||
logger.info("file type is apk");
|
||||
//调用工具类解析apk
|
||||
//analysisAPK(dirFile.getAbsolutePath(), file.getAbsolutePath());
|
||||
//analysisAPK(apkFileDir.getAbsolutePath(), file.getAbsolutePath());
|
||||
ApkFile apkFile = new ApkFile(file);
|
||||
ApkMeta apkMeta = apkFile.getApkMeta();
|
||||
|
||||
@@ -118,9 +129,9 @@ public class UploadApkController {
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
e.printStackTrace();
|
||||
logger.info(e.getMessage());
|
||||
File file1 = new File(file.getAbsolutePath());
|
||||
logger.info("delete:" + file1.delete());
|
||||
return Result.error().setMessage("apk文件无效");
|
||||
} finally {
|
||||
apkFile.close();
|
||||
}
|
||||
|
||||
return Result.success().setMessage("上传成功");
|
||||
@@ -200,15 +211,14 @@ public class UploadApkController {
|
||||
}
|
||||
|
||||
// 判断是否为APK
|
||||
public static boolean isAPK(File file) {
|
||||
public static boolean isAPK(File file) throws IOException {
|
||||
// 检查扩展名是否为.apk
|
||||
if (file.getName().toLowerCase().endsWith(".apk")) {
|
||||
// 进一步验证是否为有效的APK文件
|
||||
try (ZipFile zipFile = new ZipFile(file)) {
|
||||
return zipFile.getEntry("AndroidManifest.xml") != null;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
ZipFile zipFile = new ZipFile(file);
|
||||
boolean apkFile = zipFile.getEntry("AndroidManifest.xml") != null;
|
||||
zipFile.close();
|
||||
return apkFile;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -241,6 +251,7 @@ public class UploadApkController {
|
||||
// hasOBB = true;
|
||||
// }
|
||||
}
|
||||
zipFile.close();
|
||||
// XAPK通常包含至少一个APK或OBB数据
|
||||
return hasAPK || hasJson;
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Collections;
|
||||
|
||||
@RestController
|
||||
public class UploadPakFileController {
|
||||
public static Logger logger = LogManager.getLogger(UploadApkController.class);
|
||||
public static Logger logger = LogManager.getLogger(UploadPakFileController.class);
|
||||
private static final String UPLOAD_PATH = "uploadPak";
|
||||
|
||||
static {
|
||||
|
||||
@@ -9,5 +9,6 @@ import java.util.List;
|
||||
public interface ApkInfoRepository extends JpaRepository<ApkInfo, Long> {
|
||||
// 自定义查询方法(可选)
|
||||
List<ApkInfo> findApkInfosByPackageName(String pkg);
|
||||
ApkInfo findApkInfoByAppId(int id);
|
||||
List<ApkInfo> findAll();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ public class ApkInfoService {
|
||||
return apkInfoRepository.findApkInfosByPackageName(pkg);
|
||||
}
|
||||
|
||||
public ApkInfo getApkInfo(int id) {
|
||||
return apkInfoRepository.findApkInfoByAppId(id);
|
||||
}
|
||||
|
||||
public List<ApkInfo> getAll() {
|
||||
return apkInfoRepository.findAll();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user