using System.Collections; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Security; using System.Security.Cryptography; using System.Text; using ICSharpCode.SharpZipLib.Zip; using Mono.Xml; using ProtoBuf; using UnityEditor; using UnityEngine; public class RoTool : EditorWindow { [MenuItem("RO_Tool/[运行前准备] ZIP压缩Lua脚本到StreamingAssets目录!!", priority = 1)] public static void MergeLuaAssets() { Debug.Log("Merge Lua Files to Big File From Asset To Content Directory"); CompressFiles(Constants.LuaDir, "Assets/StreamingAssets/" + Constants.LuaDirMergeFile); CompressFiles(Constants.LuaLogicDir, "Assets/StreamingAssets/" + Constants.LuaLogicDirMergeFile); CompressFiles(Constants.LuaPbDir, "Assets/StreamingAssets/" + Constants.LuaPbDirMergeFile); AssetDatabase.Refresh(); } [MenuItem("RO_Tool/[运行前准备] ZIP压缩配置文件到StreamingAssets目录!!", priority = 1)] public static void MergeConfigAssets() { Debug.Log("Merge Config Files to Big File From Asset To Content Directory"); CompressFiles(Constants.XmlConfig, "Assets/StreamingAssets/" + Constants.XmlConfigMergeFile); CompressFiles(Constants.CsvConfig, "Assets/StreamingAssets/" + Constants.CsvConfigMergeFile); AssetDatabase.Refresh(); } [MenuItem("RO_Tool/[运行前准备] 转换XmlSkill配置为ProtoBuf文件到StreamingAssets目录!!", priority = 1)] public static void ConvertXmlSkillConfigAssets() { ConvertSkillXmlToProtobuf(Constants.XmlSkillConfig, "Assets/StreamingAssets/" + Constants.XmlSkillConfigPb); AssetDatabase.Refresh(); } //[MenuItem("RO_Tool/[运行前准备] 转换XmlScene配置为ProtoBuf文件到StreamingAssets目录!!", priority = 1)] public static void MergeSceneXmlConfig() { ConvertSceneXmlToProtobuf(Constants.XmlSceneConfig, "Assets/StreamingAssets/" + Constants.XmlSceneConfigPb); AssetDatabase.Refresh(); } private static HashSet s_ValidExtMap = new HashSet() { ".prefab", ".txt", ".xml", ".txt", ".lua", ".luac", ".csv", ".ogg", ".wav", ".ttf", ".bytes", ".pb" }; private static List getAllFilesPathEX(string path, string searchPattern = "*.*", SearchOption searchOption = SearchOption.AllDirectories) { List all = new List(); if (!Directory.Exists(path)) { return all; } string[] allFiles = Directory.GetFiles(path, searchPattern, searchOption); for (int j = 0; j < allFiles.Length; ++j) { string fileName = allFiles[j]; string ext = Path.GetExtension(fileName); if (string.IsNullOrEmpty(ext)) continue; ext = ext.ToLower(); if (s_ValidExtMap.Contains(ext)) { all.Add(fileName.Replace('\\', '/')); } } return all; } // 压缩文件 static private void CompressFiles(string inputDirectory, string zipPath) { var files = getAllFilesPathEX(inputDirectory); // 确保输出文件夹存在 string directory = Path.GetDirectoryName(zipPath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } // 创建一个ZIP文件并开始写入 using (FileStream zipFile = new FileStream(zipPath, FileMode.Create)) { using (ZipOutputStream zipStream = new ZipOutputStream(zipFile)) { zipStream.SetLevel(6); //zipStream.Password = Constants.ZipPW; foreach (var filePath in files) { if (File.Exists(filePath)) { // 获取文件的名称(不带路径) string fileName = Path.GetFileName(filePath); FileInfo fileInfo = new FileInfo(filePath); byte[] fileBytes = File.ReadAllBytes(filePath); //byte[] aseFileBytes = CommonUtil.Encrypt(fileBytes); Debug.Log($"Added file: {fileName} to the ZIP archive."); // 将文件添加到ZIP档案 ZipEntry entry = new ZipEntry(fileName) { //DateTime = fileInfo.LastWriteTime, //AESKeySize = 128 // 使用 AES 256 位加密 }; zipStream.PutNextEntry(entry); zipStream.Write(fileBytes, 0, fileBytes.Length); zipStream.CloseEntry(); } else { Debug.LogWarning($"File does not exist: {filePath}"); } } } } Debug.Log($"Files successfully compressed into: {zipPath}"); } static private void ConvertSkillXmlToProtobuf(string inputDirectory, string pbPath) { var files = getAllFilesPathEX(inputDirectory); string directory = Path.GetDirectoryName(pbPath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } Dictionary> skillXmlMap = new(); foreach (var filePath in files) { string fileName = Path.GetFileName(filePath); string fileContent = File.ReadAllText(filePath); SecurityParser doc = new SecurityParser(); try { doc.LoadXml(fileContent); var actionEventDatas = new List(); SecurityElement root = doc.SelectSingleNode("FrameEvent"); if (root == null || root.Children == null) return; skillXmlMap[fileName] = actionEventDatas; for (int idx = 0; idx < root.Children.Count; idx++) { var buffNode = root.Children[idx] as SecurityElement; string idStr = buffNode.Attribute("id"); int id = int.Parse(idStr); string frameStr = buffNode.Attribute("endFrame"); int frame = int.Parse(frameStr); int gender = 3; if (!int.TryParse(buffNode.Attribute("gender"), out gender)) { gender = 3; } int jobBranch = 0; int jobStage = 0; int jobType = 0; string tempStr = buffNode.Attribute("jobBranch"); if(!string.IsNullOrEmpty(tempStr)) { int.TryParse(tempStr, out jobBranch); } tempStr = buffNode.Attribute("jobStage"); if(!string.IsNullOrEmpty(tempStr)) { int.TryParse(tempStr, out jobStage); } tempStr = buffNode.Attribute("jobType"); if(!string.IsNullOrEmpty(tempStr)) { int.TryParse(tempStr, out jobType); } if (buffNode.Children == null) continue; ActionEventData aed = new ActionEventData(id, frame,gender,jobType,jobStage,jobBranch); for (int jdx = 0; jdx < buffNode.Children.Count; jdx++) { var eventNode = buffNode.Children[jdx] as SecurityElement; ActionEventParam aep = new ActionEventParam(); int startFrame = 0; int.TryParse(eventNode.Attribute("startFrame"), out startFrame); aep.startFrame = startFrame; int endFrame = 0; int.TryParse(eventNode.Attribute("endFrame"), out endFrame); aep.endFrame = endFrame; int eventType = 0; int.TryParse(eventNode.Attribute("type"), out eventType); aep.eventType = eventType; bool bAffectBySing = false; bool.TryParse(eventNode.Attribute("affectBySing"), out bAffectBySing); aep.bAffectBySing = bAffectBySing; aep.frameParams = new List(); if (eventNode.Children != null) { for (int kdx = 0; kdx < eventNode.Children.Count; kdx++) { var paramNode = eventNode.Children[kdx] as SecurityElement; FrameEventParam param = new FrameEventParam(); param.name = paramNode.Attribute("name"); string valueType = paramNode.Attribute("valueType"); if (string.IsNullOrEmpty(valueType)) { param.sValue = paramNode.Attribute("value"); } else if (valueType.CompareTo("int") == 0) { int nValue = 0; int.TryParse(paramNode.Attribute("value"), out nValue); param.nValue = nValue; } else if (valueType.CompareTo("float") == 0) { float fValue = 0; float.TryParse(paramNode.Attribute("value"), out fValue); param.fValue = fValue; } else { param.sValue = paramNode.Attribute("value"); } aep.frameParams.Add(param); } } aed.AddEvent(aep); } actionEventDatas.Add(aed); } } catch (System.Exception e) { DebugHelper.Assert(false, "exception = {0}", e.Message); return; } } var allActionEventCfg = new AllActionEventCfg() { CfgList = new List() }; using (FileStream pbPFileStream = new FileStream(pbPath, FileMode.Create)) { foreach (var pair in skillXmlMap) { var xmlName = pair.Key; var xmlData = pair.Value; allActionEventCfg.CfgList.Add(new ActionEventCfg() { Name = xmlName, ActionEventDatas = xmlData }); } Serializer.Serialize(pbPFileStream, allActionEventCfg); } } static private void ConvertSceneXmlToProtobuf(string inputDirectory, string pbPath) { var files = getAllFilesPathEX(inputDirectory); string directory = Path.GetDirectoryName(pbPath); if (!Directory.Exists(directory)) { Directory.CreateDirectory(directory); } var _AllXMLSpawnPointsCfg = new AllXMLSpawnPointsCfg() { XMLSpawnPointsCfgs = new List() }; foreach (var filePath in files) { string fileName = Path.GetFileNameWithoutExtension(filePath); string fileContent = File.ReadAllText(filePath); var _XMLSpawnPoints = new XMLSpawnPoints() { SpawnPointList = new() }; _AllXMLSpawnPointsCfg.XMLSpawnPointsCfgs.Add(new XMLSpawnPointsCfg() { CfgName = fileName, XMLSpawnPoints = _XMLSpawnPoints, }); SecurityParser doc = new SecurityParser(); doc.LoadXml(fileContent); System.Security.SecurityElement root = doc.SelectSingleNode("SpawnPoints"); if (root == null || root.Children == null) return; for (int idx = 0; idx < root.Children.Count; idx++) { var spNode = root.Children[idx] as System.Security.SecurityElement; var _XMLSpawnPoint = LoadCfgXml(spNode); _XMLSpawnPoints.SpawnPointList.Add(_XMLSpawnPoint); } } using (FileStream pbPFileStream = new FileStream(pbPath, FileMode.Create)) { Serializer.Serialize(pbPFileStream, _AllXMLSpawnPointsCfg); } } private static XMLSpawnPoint LoadCfgXml(SecurityElement spNode) { SpawnPointType mType; float mPos_x = 0; float mPos_y = 0; float mPos_z = 0; float mRot_x = 0; float mRot_y = 0; float mRot_z = 0; float mTransferPos_x = 0; float mTransferPos_y = 0; float mTransferPos_z = 0; float mTransferRot_x = 0; float mTransferRot_y = 0; float mTransferRot_z = 0; float mBossCamPos_x = 0; float mBossCamPos_y = 0; float mBossCamPos_z = 0; float mBossCamRot_x = 0; float mBossCamRot_y = 0; float mBossCamRot_z = 0; float mActorDist = 3; float mHorSpace = 2; float mVerSpace = 2; float mCamFar = 0; List mPointList = new List(); if (spNode == null) return null; if (spNode.Children == null) return null; int type = 0; int.TryParse(spNode.Attribute("type"), out type); mType = (SpawnPointType)type; float.TryParse(spNode.Attribute("px"), out mPos_x); float.TryParse(spNode.Attribute("py"), out mPos_y); float.TryParse(spNode.Attribute("pz"), out mPos_z); float.TryParse(spNode.Attribute("rx"), out mRot_x); float.TryParse(spNode.Attribute("ry"), out mRot_y); float.TryParse(spNode.Attribute("rz"), out mRot_z); float.TryParse(spNode.Attribute("actorReadyDist"), out mActorDist); float.TryParse(spNode.Attribute("hSpace"), out mHorSpace); float.TryParse(spNode.Attribute("vSpace"), out mVerSpace); for (int idx =0; idx < spNode.Children.Count;idx++) { var pointNode = spNode.Children[idx] as SecurityElement; if(pointNode.Tag.CompareTo("Transfer") == 0) { float.TryParse(pointNode.Attribute("px"), out mTransferPos_x); float.TryParse(pointNode.Attribute("py"), out mTransferPos_y); float.TryParse(pointNode.Attribute("pz"), out mTransferPos_z); float.TryParse(pointNode.Attribute("rx"), out mTransferRot_x); float.TryParse(pointNode.Attribute("ry"), out mTransferRot_y); float.TryParse(pointNode.Attribute("rz"), out mTransferRot_z); } else if(pointNode.Tag.CompareTo("Camera") == 0) { float.TryParse(pointNode.Attribute("px"), out mBossCamPos_x); float.TryParse(pointNode.Attribute("py"), out mBossCamPos_y); float.TryParse(pointNode.Attribute("pz"), out mBossCamPos_z); float.TryParse(pointNode.Attribute("rx"), out mBossCamRot_x); float.TryParse(pointNode.Attribute("ry"), out mBossCamRot_y); float.TryParse(pointNode.Attribute("rz"), out mBossCamRot_z); float.TryParse(pointNode.Attribute("far"), out mCamFar); } else { MonsterSpawnLoc loc = new MonsterSpawnLoc(); float.TryParse(pointNode.Attribute("px"), out loc.pos.x); float.TryParse(pointNode.Attribute("py"), out loc.pos.y); float.TryParse(pointNode.Attribute("pz"), out loc.pos.z); float.TryParse(pointNode.Attribute("rx"), out loc.rot.x); float.TryParse(pointNode.Attribute("ry"), out loc.rot.y); float.TryParse(pointNode.Attribute("rz"), out loc.rot.z); int.TryParse(pointNode.Attribute("npcId"), out loc.npcId); mPointList.Add(loc); } } var _Points = new List(); foreach (var point in mPointList) { _Points.Add(new XMLPoint() { NpcId = point.npcId, Px = point.pos.x, Py = point.pos.y, Pz = point.pos.z, Rx = point.rot.x, Ry = point.rot.y, Rz = point.rot.z, }); } var _Transfer = new XMLTransfer() { Px = mTransferRot_x, Py = mTransferRot_y, Pz = mTransferRot_z, Rx = mTransferRot_x, Ry = mTransferRot_y, Rz = mTransferRot_z, }; var _Camera = new XMLCamera() { Far = mCamFar, Px = mBossCamPos_x, Py = mBossCamPos_y, Pz = mBossCamPos_z, Rx = mBossCamRot_x, Ry = mBossCamRot_y, Rz = mBossCamRot_z, }; return new XMLSpawnPoint() { Type = (int)mType, ActorReadyDist = mActorDist, HSpace = mHorSpace, VSpace = mVerSpace, Px = mPos_x, Py = mPos_y, Pz = mPos_z, Rx = mRot_x, Ry = mRot_y, Rz = mRot_z, Points = _Points, Transfer = _Transfer, Camera = _Camera }; } }