using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using LitJson; using SimpleHttpServer; using Sog; namespace Operation { [MenuMapping(refc = typeof(SendEmail))] public static class DiffGameData { private const string BaseFilePath = "../cfg/"; private const string BakFilePath = BaseFilePath + "data_bak/"; [RequestMapping("历史数值对比查询", PermissionCode.SELECT_GAME_DATA_DIFF, true)] public static int OnGetDiffDirListHttpReq(string httpApiCmd, JsonData jsondata, HttpResponse rsp, HttpRequest request, HttpQueryParams query, uint httpContextId) { JsonData list = new JsonData(); list.Add("data"); if (!Directory.Exists(BakFilePath)) { Directory.CreateDirectory(BakFilePath); } string[] subdirectories = Directory.GetDirectories(BakFilePath); foreach (var subdirectory in subdirectories) { var tar = subdirectory.Replace(BakFilePath, ""); list.Add(tar); } jsondata["data"] = list; return 0; } [RequestMapping("版本内容对比", PermissionCode.SELECT_GAME_DATA_CONTEXT_DIFF, false)] public static int OnGetDiffContextListHttpReq(string httpApiCmd, JsonData jsondata, HttpResponse rsp, HttpRequest request, HttpQueryParams query, uint httpContextId) { var v1 = query.GetValue("v1"); var v2 = query.GetValue("v2"); var tableName = query.GetValue("table"); if (v1 == v2) { jsondata["code"] = -1; jsondata["msg"] = "版本号错误"; return -1; } var v1p = BaseFilePath + v1 + "/"; if (v1 != "data") { v1p = BakFilePath + v1 + "/"; } var v2p = BaseFilePath + v2 + "/"; if (v2 != "data") { v2p = BakFilePath + v2 + "/"; } var files1 = GetFiles(v1p); var files2 = GetFiles(v2p); // 比较两个目录的文件列表并找出差异 var files = files1.Count() > files2.Count() ? files1 : files2; var diffFiles = new JsonData(); //存在差异的文件 var exists = false; var data = new JsonData(); foreach (var fileName in files) { var equal = FilesEqual(v1p + fileName, v2p + fileName); if (equal) { continue; } diffFiles.Add(fileName); exists = true; var fullPath = v1p + fileName; if (!File.Exists(fullPath)) { continue; } //差异表格 if (string.IsNullOrEmpty(tableName)) { continue; } if (!string.IsNullOrEmpty(tableName) && tableName != fileName) { continue; } //差异表格内容 var mgr = GameConfigMgr.Instance.GetConfigMgr(fileName); var c1 = GameData.GetData(jsondata, mgr); data["c1"] = c1; var fullPath2 = v2p + fileName; var mgr2 = (IConfigManager)Activator.CreateInstance(mgr.GetType()); if (!File.Exists(fullPath2) || mgr2 == null) continue; var b2 = File.ReadAllBytes(fullPath2); mgr2.InitBin(fileName, b2); var c2 = GameData.GetData(jsondata, mgr2); data["c2"] = c2; } if (exists) { jsondata["tables"] = diffFiles; } if (!string.IsNullOrEmpty(tableName)) { jsondata["data"] = data; } jsondata["ret"] = 0; jsondata["code"] = 0; return 0; } [RequestMapping("备份数值配置", PermissionCode.SELECT_GAME_DATA_BAK)] public static int OnBakGameDataHttpReq(string httpApiCmd, JsonData jsondata, HttpResponse rsp, HttpRequest request, HttpQueryParams query, uint httpContextId) { var version = query.GetValue("version"); if (string.IsNullOrEmpty(version)) { jsondata["msg"] = "版本号错误"; jsondata["ret"] = -1; return 0; } var fullPath = BakFilePath + version; //文件夹存在 if (Directory.Exists(fullPath)) { jsondata["msg"] = "本版已存在"; jsondata["ret"] = -1; return 0; } var ret = Directory.CreateDirectory(fullPath); if (!ret.Exists) { jsondata["msg"] = "创建失败"; jsondata["ret"] = -1; return 0; } var targetPatch = BaseFilePath + "data/"; var files = Directory.GetFiles(targetPatch); foreach (var file in files) { var fileName = Path.GetFileName(file); var targetFile = Path.Combine(fullPath, fileName); File.Copy(file, targetFile, true); // 第三个参数 true 表示覆盖目标文件夹下的同名文件 } return 0; } private static IEnumerable GetFiles(string directory) { // 获取目录下的所有文件路径 return Directory.GetFiles(directory, "*.bin", SearchOption.AllDirectories) .Select(file => Path.GetRelativePath(directory, file)); } private static bool FilesEqual(string filePath1, string filePath2) { if (!File.Exists(filePath1)) { return false; } if (!File.Exists(filePath2)) { return false; } var md5 = MD5.Create(); var hash1 = GetFileHash(filePath1, md5); var hash2 = GetFileHash(filePath2, md5); return hash1 == hash2; } private static string GetFileHash(string path, MD5 md5) { var stream = File.OpenRead(path); var hashBytes = md5.ComputeHash(stream); stream.Close(); return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant(); } } }