diff --git a/src/Husky/Husky/Games/AdvancedWarfare.cs b/src/Husky/Husky/Games/AdvancedWarfare.cs index 672beda..5e23fe3 100644 --- a/src/Husky/Husky/Games/AdvancedWarfare.cs +++ b/src/Husky/Husky/Games/AdvancedWarfare.cs @@ -409,7 +409,7 @@ public static void ExportBSPData(ProcessReader reader, long assetPoolsAddress, l searchString += String.Format("{0},", Path.GetFileNameWithoutExtension(imageName)); // Get dynamic models from Map Entities - List MapEntities = BlackOps2.CreateMapEntities(mapEnt); + List MapEntities = CreateMapEntities(mapEnt); // Create .JSON with XModel Data List ModelData = CreateXModelDictionary(reader, gfxMapAsset.GfxStaticModelsPointer, (int)gfxMapAsset.GfxStaticModelsCount, MapEntities); @@ -577,18 +577,87 @@ public static WavefrontOBJ.Material ReadMaterial(ProcessReader reader, long addr return entities; } + public unsafe static List CreateMapEntities(string mapEnts) + { + List DynModels = new List(); + string[] Entities = mapEnts.Split(new[] { "\n}\n{" }, StringSplitOptions.None); + foreach (string i in Entities) + { + if (i.Contains("script_model") && i.Contains("\"model\"")) + { + if (i.Contains("\"hq\"") == false && i.Contains("\"sab\"") == false && i.Contains("\"ctf\"") == false && i.Contains("\"sd\"") == false && i.Contains("\"special") == false) + { + DynModels.Add(i); + } + } + } + + List ParsedList = new List(); + Regex reg = new Regex(@"""(.*?)""\s""(.*?)"""); + + foreach (string entity in DynModels) + { + string[] entity_properties = entity.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + Dictionary model_data = new Dictionary(); + foreach (String line in entity_properties) + { + MatchCollection matches = reg.Matches(line); + foreach (Match m in matches) + { + if (m.Groups[1].Value == "model") + { + model_data.Add("Name", m.Groups[2].Value); + } + else if (m.Groups[1].Value == "origin") + { + string[] vec3 = m.Groups[2].Value.Split(new[] { " " }, StringSplitOptions.None); + model_data.Add("PosX", vec3[0]); + model_data.Add("PosY", vec3[1]); + model_data.Add("PosZ", vec3[2]); + } + else if (m.Groups[1].Value == "angles") + { + if (m.Groups[2].Value.Contains("e") == false) + { + string[] vec3 = m.Groups[2].Value.Split(new[] { " " }, StringSplitOptions.None); + model_data.Add("RotX", vec3[2]); + model_data.Add("RotY", vec3[0]); + model_data.Add("RotZ", vec3[1]); + } + } + } + } + model_data.Add("Scale", "1.0000"); + ParsedList.Add(model_data); + } + + return ParsedList; + } + public unsafe static List CreateXModelDictionary(ProcessReader reader, long address, int count, List MapEntities) { + // Force english-US input Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); + // Read buffer var byteBuffer = reader.ReadBytes(address, count * Marshal.SizeOf()); + // Loop number of models we have List MapModels = new List(count); + + // Create list with unnessecary strings in model names + List badStrings = new List() + { + "\"ml", + "\"mv", + }; + for (int i = 0; i < count; i++) { Dictionary ModelData = new Dictionary(); List Position = new List(); List angles = new List(); + // Read Struct var staticModel = ByteUtil.BytesToStruct(byteBuffer, i * Marshal.SizeOf()); // Model Name @@ -616,10 +685,14 @@ public unsafe static List CreateXModelDictionary(ProcessReader read } else { - if (modelName.Contains("ml")) + foreach (string b in badStrings) { - modelName = modelName.Replace("ml", ""); + if (modelName.Contains(b)) + { + modelName = modelName.Replace(b, "\""); + } } + ModelData.Add("Name", CleanInput(modelName)); ModelData.Add("PosX", string.Format("{0:0.0000}", staticModel.X)); ModelData.Add("PosY", string.Format("{0:0.0000}", staticModel.Y)); diff --git a/src/Husky/Husky/Games/BlackOps2.cs b/src/Husky/Husky/Games/BlackOps2.cs index c8a865b..053e136 100644 --- a/src/Husky/Husky/Games/BlackOps2.cs +++ b/src/Husky/Husky/Games/BlackOps2.cs @@ -520,7 +520,7 @@ public static void ExportBSPData(ProcessReader reader, long assetPoolsAddress, l searchString += String.Format("{0},", Path.GetFileNameWithoutExtension(imageName)); // Get dynamic models from Map Entities - List MapEntities = CreateMapEntities(mapEnt); + List MapEntities = CreateMapEntities(mapEnt, printCallback); // Create .JSON with XModel Data List ModelData = CreateXModelDictionary(reader, gfxMapAsset.GfxStaticModelsPointer, (int)gfxMapAsset.GfxStaticModelsCount, MapEntities); @@ -761,7 +761,7 @@ public unsafe static List CreateXModelList(List ModelData) return xmodel_list; } - public unsafe static List CreateMapEntities(string mapEnts) + public unsafe static List CreateMapEntities(string mapEnts, Action printCallback = null) { List DynModels = new List(); string[] Entities = mapEnts.Split(new[] { "\n}\n{" }, StringSplitOptions.None); @@ -777,46 +777,68 @@ public unsafe static List CreateMapEntities(string mapEnts) List ParsedList = new List(); Regex reg = new Regex(@"""(.*?)""\s""(.*?)"""); + // Create list with unnessecary strings in vehicle models + List badStrings = new List() + { + "_static", + "_radiant", + }; + + // Iterate through entities foreach (string entity in DynModels) { + // Split lines in each entity string[] entity_properties = entity.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + + // Create dictionary for XModel data Dictionary model_data = new Dictionary(); + + // Iterate through lines, and get necessary ones foreach (String line in entity_properties) { MatchCollection matches = reg.Matches(line); foreach (Match m in matches) { + // Check if line is a model name if (m.Groups[1].Value == "model") { + // Check if model is a vehicle if (m.Groups[2].Value.Contains("veh")) { - if (m.Groups[2].Value.Contains("static")) - { - model_data.Add("Name", m.Groups[2].Value.Replace("static", "whole")); - } - else if (m.Groups[2].Value.Contains("radiant")) + string modelname = m.Groups[2].Value; + + // Iterate through bad model names and fix them + foreach (string b in badStrings) { - model_data.Add("Name", m.Groups[2].Value.Replace("radiant", "whole")); - } - else if (m.Groups[2].Value.Contains("clean")) - { - model_data.Add("Name", m.Groups[2].Value.Replace("clean", "whole")); + if (modelname.Contains(b)) + { + modelname = modelname.Replace(b, "_whole"); + model_data.Add("Name", modelname); + } } } + + // If model is not a vehicle, just add it. else { model_data.Add("Name", m.Groups[2].Value); } } + + // Check if line is origin (position) else if (m.Groups[1].Value == "origin") { + // Split into Vector3 string[] vec3 = m.Groups[2].Value.Split(new[] { " " }, StringSplitOptions.None); model_data.Add("PosX", vec3[0]); model_data.Add("PosY", vec3[1]); model_data.Add("PosZ", vec3[2]); } + + // Check if line is angles (rotation) else if (m.Groups[1].Value == "angles") { + // Split into Vector3 string[] vec3 = m.Groups[2].Value.Split(new[] { " " }, StringSplitOptions.None); model_data.Add("RotX", vec3[2]); model_data.Add("RotY", vec3[0]); @@ -824,7 +846,11 @@ public unsafe static List CreateMapEntities(string mapEnts) } } } + + // Default model scale to 1 model_data.Add("Scale", "1.0000"); + + // Add model to list ParsedList.Add(model_data); } return ParsedList; diff --git a/src/Husky/Husky/Properties/AssemblyInfo.cs b/src/Husky/Husky/Properties/AssemblyInfo.cs index 156cfbd..9ea719e 100644 --- a/src/Husky/Husky/Properties/AssemblyInfo.cs +++ b/src/Husky/Husky/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.4")] -[assembly: AssemblyFileVersion("1.0.3.4")] +[assembly: AssemblyVersion("1.0.3.5")] +[assembly: AssemblyFileVersion("1.0.3.5")] diff --git a/src/Husky/HuskyUI/Properties/AssemblyInfo.cs b/src/Husky/HuskyUI/Properties/AssemblyInfo.cs index 63f2721..2bcc5a2 100644 --- a/src/Husky/HuskyUI/Properties/AssemblyInfo.cs +++ b/src/Husky/HuskyUI/Properties/AssemblyInfo.cs @@ -49,5 +49,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.3.4")] -[assembly: AssemblyFileVersion("1.0.3.4")] +[assembly: AssemblyVersion("1.0.3.5")] +[assembly: AssemblyFileVersion("1.0.3.5")]