From c620938a29a92f784d96980834dde4bf68e1dc7c Mon Sep 17 00:00:00 2001 From: CloneTrooper1019 Date: Wed, 3 Jun 2020 22:46:06 -0500 Subject: [PATCH 1/2] Attempting to read v4 meshes Not backwards compatible yet, but I want to stash this for later. --- Bevels/BevelGenerator.csproj | 3 +- Bevels/Geometry/Vertex.cs | 15 --- Bevels/{Geometry => }/Mesh.cs | 209 +++++++++++++++++++++++++++++----- Bevels/Program.cs | 5 + 4 files changed, 185 insertions(+), 47 deletions(-) delete mode 100644 Bevels/Geometry/Vertex.cs rename Bevels/{Geometry => }/Mesh.cs (69%) diff --git a/Bevels/BevelGenerator.csproj b/Bevels/BevelGenerator.csproj index 70b137e..d731aa4 100644 --- a/Bevels/BevelGenerator.csproj +++ b/Bevels/BevelGenerator.csproj @@ -51,8 +51,7 @@ - - + diff --git a/Bevels/Geometry/Vertex.cs b/Bevels/Geometry/Vertex.cs deleted file mode 100644 index 643c7c3..0000000 --- a/Bevels/Geometry/Vertex.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Drawing; -using RobloxFiles.DataTypes; - -namespace BevelGenerator -{ - public class Vertex - { - public Vector3 Position; - public Vector3 Normal; - public Vector3 UV; - - public bool HasColor = false; - public Color Color; - } -} diff --git a/Bevels/Geometry/Mesh.cs b/Bevels/Mesh.cs similarity index 69% rename from Bevels/Geometry/Mesh.cs rename to Bevels/Mesh.cs index c4358b7..ca29cb7 100644 --- a/Bevels/Geometry/Mesh.cs +++ b/Bevels/Mesh.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; @@ -10,19 +11,73 @@ using RobloxFiles.DataTypes; namespace BevelGenerator { + public class Bone + { + public string Name; + public int NameIndex; + + public short Id; + public short Parent; + + public float Angle; + public CFrame CFrame; + + public override string ToString() + { + return $"[Bone: {Name}]"; + } + } + + public class Vertex + { + public Vector3 Position; + public Vector3 Normal; + public Vector3 UV; + + public Color? Color; + public BoneWeights? Weights; + } + + public class ParentLink + { + public int[] UnknownA; + public short[] UnknownB; + } + + public struct BoneWeights + { + public byte[] Bones; + public byte[] Weights; + + public override string ToString() + { + return $"[Bones: {{{string.Join(", ", Bones)}}} | Weights: {{{string.Join(", ", Weights)}}}]"; + } + } + public class Mesh { public int Version; + public ushort NumMeshes = 0; public int NumVerts = 0; public List Verts; - + public int NumFaces = 0; public List Faces; - public ushort NumLODs = 0; + public ushort NumLODs; public List LODs; + public int NumBones = 0; + public List Bones; + + public int NumLinks = 0; + public List Links; + + public int NameTableSize = 0; + public byte[] NameTable; + private static Vector3 ReadVector3(BinaryReader reader) { float x = reader.ReadSingle(), @@ -106,25 +161,27 @@ namespace BevelGenerator private static void LoadGeometry_Binary(BinaryReader reader, Mesh mesh) { - byte[] binVersion = reader.ReadBytes(13); - var headerSize = reader.ReadUInt16(); + byte[] binVersion = reader.ReadBytes(13); // version x.xx\n - var vertSize = reader.ReadByte(); - var faceSize = reader.ReadByte(); - - if (mesh.Version >= 3) - { - var lodRangeSize = reader.ReadUInt16(); - mesh.NumLODs = reader.ReadUInt16(); - } + var headerSize = reader.ReadUInt16(); + mesh.NumMeshes = reader.ReadUInt16(); mesh.NumVerts = reader.ReadInt32(); mesh.NumFaces = reader.ReadInt32(); + mesh.NumLODs = reader.ReadUInt16(); + mesh.NumBones = reader.ReadUInt16(); + + mesh.NameTableSize = reader.ReadInt32(); + mesh.NumLinks = reader.ReadInt32(); + mesh.LODs = new List(); + mesh.Bones = new List(); mesh.Faces = new List(); mesh.Verts = new List(); + mesh.Links = new List(); + // Read Vertices for (int i = 0; i < mesh.NumVerts; i++) { var vert = new Vertex() @@ -134,18 +191,31 @@ namespace BevelGenerator UV = ReadVector3(reader) }; - if (vertSize > 36) - { - int rgba = reader.ReadInt32(); - int argb = (rgba << 24 | rgba >> 8); - - vert.Color = Color.FromArgb(argb); - vert.HasColor = true; - } + int rgba = reader.ReadInt32(); + int argb = (rgba << 24 | rgba >> 8); + vert.Color = Color.FromArgb(argb); mesh.Verts.Add(vert); } + // Read Bone Weights? + var weightSets = new List(); + + for (int i = 0; i < mesh.NumVerts; i++) + { + var vert = mesh.Verts[i]; + + var weights = new BoneWeights() + { + Bones = reader.ReadBytes(4), + Weights = reader.ReadBytes(4) + }; + + vert.Weights = weights; + weightSets.Add(weights); + } + + // Read Faces for (int i = 0; i < mesh.NumFaces; i++) { int[] face = new int[3]; @@ -156,6 +226,7 @@ namespace BevelGenerator mesh.Faces.Add(face); } + // Read LOD ranges if (mesh.NumLODs > 0) { for (int i = 0; i < mesh.NumLODs; i++) @@ -165,15 +236,97 @@ namespace BevelGenerator } } + // Validate LODs CheckLOD(mesh); + + // Read Bones + for (int i = 0; i < mesh.NumBones; i++) + { + float[] cf = new float[12]; + + Bone bone = new Bone() + { + NameIndex = reader.ReadInt32(), + Id = reader.ReadInt16(), + + Parent = reader.ReadInt16(), + Angle = reader.ReadSingle() + }; + + for (int m = 0; m < 12; m++) + { + int index = (m + 3) % 12; + cf[index] = reader.ReadSingle(); + } + + bone.CFrame = new CFrame(cf); + mesh.Bones.Add(bone); + } + + // Read Bone Names + var nameTable = reader.ReadBytes(mesh.NameTableSize); + mesh.NameTable = nameTable; + + foreach (Bone bone in mesh.Bones) + { + int index = bone.NameIndex; + var buffer = new List(); + + while (true) + { + byte next = nameTable[index]; + + if (next > 0) + index++; + else + break; + + buffer.Add(next); + } + + var result = buffer.ToArray(); + bone.Name = Encoding.UTF8.GetString(result); + } + + // Read Skinning Data? + for (int p = 0; p < mesh.NumLinks; p++) + { + var link = new ParentLink(); + mesh.Links.Add(link); + + byte[] data = reader.ReadBytes(72); + var stream = new MemoryStream(data); + + using (var buffer = new BinaryReader(stream)) + { + int[] unknownA = new int[4]; + + for (int i = 0; i < 4; i++) + unknownA[i] = buffer.ReadInt32(); + + int numUnknownB = buffer.ReadInt32(); + short[] unknownB = new short[numUnknownB]; + + for (int i = 0; i < numUnknownB; i++) + unknownB[i] = buffer.ReadInt16(); + + link.UnknownA = unknownA; + link.UnknownB = unknownB; + } + } + + Debugger.Break(); } public void AddLOD(Mesh lodMesh) { Verts.AddRange(lodMesh.Verts); - Faces.AddRange(lodMesh.Faces - .Select(face => face + Faces.AddRange + ( + lodMesh.Faces.Select + ( + face => face .Select(i => i + NumVerts) .ToArray() ) @@ -227,9 +380,9 @@ namespace BevelGenerator writer.Write(uv.Y); writer.Write(uv.Z); - if (vertex.HasColor) + if (vertex.Color.HasValue) { - var color = vertex.Color; + var color = vertex.Color.Value; int argb = color.ToArgb(); int rgba = (argb << 8 | argb >> 24); @@ -363,7 +516,7 @@ namespace BevelGenerator disposeThis = buffer; } - else if (mesh.Version == 2 || mesh.Version == 3) + else { MemoryStream stream = new MemoryStream(data); @@ -372,11 +525,7 @@ namespace BevelGenerator disposeThis = stream; } - else - { - throw new Exception($"Unknown .mesh file version: {version}"); - } - + disposeThis.Dispose(); disposeThis = null; diff --git a/Bevels/Program.cs b/Bevels/Program.cs index 714ae16..0885c8a 100644 --- a/Bevels/Program.cs +++ b/Bevels/Program.cs @@ -266,6 +266,11 @@ namespace BevelGenerator ProcessObjFile(info); return; } + else if (info.Extension == ".bin" || info.Extension == ".mesh") + { + Mesh mesh = Mesh.FromFile(filePath); + Debugger.Break(); + } ProcessModelFile(filePath); } -- 2.40.1 From 5ae02a9a6667320d6d7eabdeb5067522e286a509 Mon Sep 17 00:00:00 2001 From: CloneTrooper1019 Date: Sat, 18 Jul 2020 18:43:58 -0500 Subject: [PATCH 2/2] mesh-v4 finished. --- Bevels/Mesh.cs | 404 +++++++++++++++++++++++++++------------------- Bevels/Program.cs | 90 ++++++++--- 2 files changed, 304 insertions(+), 190 deletions(-) diff --git a/Bevels/Mesh.cs b/Bevels/Mesh.cs index ca29cb7..b082161 100644 --- a/Bevels/Mesh.cs +++ b/Bevels/Mesh.cs @@ -7,19 +7,19 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; +using RobloxFiles; using RobloxFiles.DataTypes; namespace BevelGenerator { - public class Bone + public class Bone : Instance { - public string Name; public int NameIndex; public short Id; - public short Parent; + public short ParentId; - public float Angle; + public float Unknown; public CFrame CFrame; public override string ToString() @@ -38,10 +38,16 @@ namespace BevelGenerator public BoneWeights? Weights; } - public class ParentLink + public class SkinData { - public int[] UnknownA; - public short[] UnknownB; + public int FacesBegin; + public int FacesLength; + + public int VertsBegin; + public int VertsLength; + + public int NumBones; + public short[] BoneIndexTree; } public struct BoneWeights @@ -51,7 +57,10 @@ namespace BevelGenerator public override string ToString() { - return $"[Bones: {{{string.Join(", ", Bones)}}} | Weights: {{{string.Join(", ", Weights)}}}]"; + var bones = string.Join(", ", Bones); + var weights = string.Join(", ", Weights); + + return $"{{Bones: [{bones}] | Weights: [{weights}]}}"; } } @@ -72,12 +81,16 @@ namespace BevelGenerator public int NumBones = 0; public List Bones; - public int NumLinks = 0; - public List Links; + public int NumSkinData = 0; + public List SkinData; public int NameTableSize = 0; public byte[] NameTable; - + + public bool HasLODs => (Version >= 3); + public bool HasSkinning => (Version >= 4); + public bool HasVertexColors { get; private set; } + private static Vector3 ReadVector3(BinaryReader reader) { float x = reader.ReadSingle(), @@ -87,20 +100,10 @@ namespace BevelGenerator return new Vector3(x, y, z); } - private static Mesh CheckLOD(Mesh mesh) - { - if (mesh.NumLODs == 0) - { - mesh.NumLODs = 2; - mesh.LODs = new List { 0, mesh.NumFaces }; - } - - return mesh; - } - private static void LoadGeometry_Ascii(StringReader reader, Mesh mesh) { string header = reader.ReadLine(); + mesh.NumMeshes = 1; if (!header.StartsWith("version 1")) throw new Exception("Expected version 1 header, got: " + header); @@ -155,31 +158,55 @@ namespace BevelGenerator } } } - - CheckLOD(mesh); } private static void LoadGeometry_Binary(BinaryReader reader, Mesh mesh) { byte[] binVersion = reader.ReadBytes(13); // version x.xx\n + var headerSize = reader.ReadUInt16(); - var headerSize = reader.ReadUInt16(); - mesh.NumMeshes = reader.ReadUInt16(); + if (mesh.HasSkinning) + { + mesh.NumMeshes = reader.ReadUInt16(); - mesh.NumVerts = reader.ReadInt32(); - mesh.NumFaces = reader.ReadInt32(); + mesh.NumVerts = reader.ReadInt32(); + mesh.NumFaces = reader.ReadInt32(); - mesh.NumLODs = reader.ReadUInt16(); - mesh.NumBones = reader.ReadUInt16(); + mesh.NumLODs = reader.ReadUInt16(); + mesh.NumBones = reader.ReadUInt16(); - mesh.NameTableSize = reader.ReadInt32(); - mesh.NumLinks = reader.ReadInt32(); + mesh.NameTableSize = reader.ReadInt32(); + mesh.NumSkinData = reader.ReadInt32(); + } + else + { + var sizeof_Vertex = reader.ReadByte(); + mesh.HasVertexColors = (sizeof_Vertex > 36); + + _ = reader.ReadByte(); + + if (mesh.HasLODs) + { + _ = reader.ReadUInt16(); + mesh.NumLODs = reader.ReadUInt16(); + } + + if (mesh.NumLODs > 0) + mesh.NumMeshes = (ushort)(mesh.NumLODs - 1); + else + mesh.NumMeshes = 1; + + mesh.NumVerts = reader.ReadInt32(); + mesh.NumFaces = reader.ReadInt32(); + + mesh.NameTable = new byte[0]; + } mesh.LODs = new List(); mesh.Bones = new List(); mesh.Faces = new List(); mesh.Verts = new List(); - mesh.Links = new List(); + mesh.SkinData = new List(); // Read Vertices for (int i = 0; i < mesh.NumVerts; i++) @@ -191,28 +218,33 @@ namespace BevelGenerator UV = ReadVector3(reader) }; - int rgba = reader.ReadInt32(); - int argb = (rgba << 24 | rgba >> 8); + Color? color = null; - vert.Color = Color.FromArgb(argb); + if (mesh.HasVertexColors) + { + int rgba = reader.ReadInt32(); + color = Color.FromArgb(rgba << 24 | rgba >> 8); + } + + vert.Color = color; mesh.Verts.Add(vert); } - // Read Bone Weights? - var weightSets = new List(); - - for (int i = 0; i < mesh.NumVerts; i++) + if (mesh.HasSkinning) { - var vert = mesh.Verts[i]; - - var weights = new BoneWeights() + // Read Bone Weights? + for (int i = 0; i < mesh.NumVerts; i++) { - Bones = reader.ReadBytes(4), - Weights = reader.ReadBytes(4) - }; + var vert = mesh.Verts[i]; - vert.Weights = weights; - weightSets.Add(weights); + var weights = new BoneWeights() + { + Bones = reader.ReadBytes(4), + Weights = reader.ReadBytes(4) + }; + + vert.Weights = weights; + } } // Read Faces @@ -226,9 +258,9 @@ namespace BevelGenerator mesh.Faces.Add(face); } - // Read LOD ranges - if (mesh.NumLODs > 0) + if (mesh.HasLODs && mesh.NumLODs > 0) { + // Read LOD ranges for (int i = 0; i < mesh.NumLODs; i++) { int lod = reader.ReadInt32(); @@ -236,84 +268,87 @@ namespace BevelGenerator } } - // Validate LODs - CheckLOD(mesh); - - // Read Bones - for (int i = 0; i < mesh.NumBones; i++) + if (mesh.HasSkinning) { - float[] cf = new float[12]; - - Bone bone = new Bone() + // Read Bones + for (int i = 0; i < mesh.NumBones; i++) { - NameIndex = reader.ReadInt32(), - Id = reader.ReadInt16(), + float[] cf = new float[12]; - Parent = reader.ReadInt16(), - Angle = reader.ReadSingle() - }; + Bone bone = new Bone() + { + NameIndex = reader.ReadInt32(), + Id = reader.ReadInt16(), - for (int m = 0; m < 12; m++) - { - int index = (m + 3) % 12; - cf[index] = reader.ReadSingle(); + ParentId = reader.ReadInt16(), + Unknown = reader.ReadSingle() + }; + + for (int m = 0; m < 12; m++) + { + int index = (m + 3) % 12; + cf[index] = reader.ReadSingle(); + } + + bone.CFrame = new CFrame(cf); + mesh.Bones.Add(bone); } - bone.CFrame = new CFrame(cf); - mesh.Bones.Add(bone); + // Read Bone Names & Parents + var nameTable = reader.ReadBytes(mesh.NameTableSize); + mesh.NameTable = nameTable; + + foreach (Bone bone in mesh.Bones) + { + int index = bone.NameIndex; + int parentId = bone.ParentId; + + var buffer = new List(); + + while (true) + { + byte next = nameTable[index]; + + if (next > 0) + index++; + else + break; + + buffer.Add(next); + } + + var result = buffer.ToArray(); + bone.Name = Encoding.UTF8.GetString(result); + + if (parentId >= 0) + { + var parent = mesh.Bones[parentId]; + bone.Parent = parent; + } + } + + // Read Skin Data? + for (int p = 0; p < mesh.NumSkinData; p++) + { + var skinData = new SkinData() + { + FacesBegin = reader.ReadInt32(), + FacesLength = reader.ReadInt32(), + + VertsBegin = reader.ReadInt32(), + VertsLength = reader.ReadInt32(), + + NumBones = reader.ReadInt32(), + BoneIndexTree = new short[26] + }; + + for (int i = 0; i < 26; i++) + skinData.BoneIndexTree[i] = reader.ReadInt16(); + + mesh.SkinData.Add(skinData); + } } - // Read Bone Names - var nameTable = reader.ReadBytes(mesh.NameTableSize); - mesh.NameTable = nameTable; - - foreach (Bone bone in mesh.Bones) - { - int index = bone.NameIndex; - var buffer = new List(); - - while (true) - { - byte next = nameTable[index]; - - if (next > 0) - index++; - else - break; - - buffer.Add(next); - } - - var result = buffer.ToArray(); - bone.Name = Encoding.UTF8.GetString(result); - } - - // Read Skinning Data? - for (int p = 0; p < mesh.NumLinks; p++) - { - var link = new ParentLink(); - mesh.Links.Add(link); - - byte[] data = reader.ReadBytes(72); - var stream = new MemoryStream(data); - - using (var buffer = new BinaryReader(stream)) - { - int[] unknownA = new int[4]; - - for (int i = 0; i < 4; i++) - unknownA[i] = buffer.ReadInt32(); - - int numUnknownB = buffer.ReadInt32(); - short[] unknownB = new short[numUnknownB]; - - for (int i = 0; i < numUnknownB; i++) - unknownB[i] = buffer.ReadInt16(); - - link.UnknownA = unknownA; - link.UnknownB = unknownB; - } - } Debugger.Break(); } @@ -342,11 +377,17 @@ namespace BevelGenerator public void Save(Stream stream) { const ushort HeaderSize = 16; - const byte VertSize = 40; - const byte FaceSize = 12; - const ushort LOD_Size = 4; + const byte VertSize = 40; + const byte FaceSize = 12; + const ushort LOD_Size = 4; - byte[] VersionHeader = Encoding.ASCII.GetBytes("version 3.00\n"); + byte[] VersionHeader = Encoding.UTF8.GetBytes("version 3.00\n"); + + if (NumLODs == 0) + { + NumLODs = 2; + LODs = new List { 0, NumFaces }; + } using (BinaryWriter writer = new BinaryWriter(stream)) { @@ -424,9 +465,10 @@ namespace BevelGenerator Verts = new List() }; + var uvTable = new List(); var posTable = new List(); var normTable = new List(); - + var vertexLookup = new Dictionary(); using (StringReader reader = new StringReader(contents)) @@ -439,59 +481,87 @@ namespace BevelGenerator continue; string[] buffer = line.Split(' '); - string cmd = buffer[0]; + string action = buffer[0]; - if (cmd == "v" || cmd == "vn") + switch (action) { - float[] input = buffer - .Skip(1) - .Select(float.Parse) - .ToArray(); - - var value = new Vector3(input); - var target = (cmd == "v" ? posTable : normTable); - - target.Add(value); - } - else if (cmd == "f") - { - int[] face = new int[3]; - - for (int i = 0; i < 3; i++) + case "v": + case "vn": + case "vt": { - string faceDef = buffer[i + 1]; - string[] indices = faceDef.Split('/'); + float[] input = buffer + .Skip(1) + .Select(float.Parse) + .ToArray(); - int posId = int.Parse(indices[0]) - 1; - int normId = int.Parse(indices[2]) - 1; + var value = new Vector3(input); + List target = null; - string key = $"{posId}/{normId}"; - - if (!vertexLookup.ContainsKey(key)) + switch (action) { - int faceId = mesh.NumVerts++; - vertexLookup.Add(key, faceId); - - Vertex vert = new Vertex() + case "v": { - Position = posTable[posId], - Normal = normTable[normId], - UV = new Vector3() - }; - - mesh.Verts.Add(vert); + target = posTable; + break; + } + case "vn": + { + target = normTable; + break; + } + case "vt": + { + target = uvTable; + break; + } } - face[i] = vertexLookup[key]; + target.Add(value); + break; } + case "f": + { + int[] face = new int[3]; - mesh.Faces.Add(face); - mesh.NumFaces++; + for (int i = 0; i < 3; i++) + { + string faceDef = buffer[i + 1]; + string[] indices = faceDef.Split('/'); + + int uvId = int.Parse(indices[1]) - 1; + int posId = int.Parse(indices[0]) - 1; + int normId = int.Parse(indices[2]) - 1; + + string key = $"{posId}/{uvId}/{normId}"; + + if (!vertexLookup.ContainsKey(key)) + { + int faceId = mesh.NumVerts++; + vertexLookup.Add(key, faceId); + + Vertex vert = new Vertex() + { + Position = posTable[posId], + Normal = normTable[normId], + UV = uvTable[uvId] + }; + + mesh.Verts.Add(vert); + } + + face[i] = vertexLookup[key]; + } + + mesh.Faces.Add(face); + mesh.NumFaces++; + + break; + } } } } - return CheckLOD(mesh); + return mesh; } public static Mesh FromBuffer(byte[] data) @@ -547,10 +617,12 @@ namespace BevelGenerator public static Mesh FromFile(string path) { + Mesh result; + using (FileStream meshStream = File.OpenRead(path)) - { - return FromStream(meshStream); - } + result = FromStream(meshStream); + + return result; } } } \ No newline at end of file diff --git a/Bevels/Program.cs b/Bevels/Program.cs index 0885c8a..2268bb4 100644 --- a/Bevels/Program.cs +++ b/Bevels/Program.cs @@ -11,6 +11,7 @@ using RobloxFiles.Enums; using RobloxFiles.DataTypes; using Microsoft.Win32; +using System.Text.RegularExpressions; namespace BevelGenerator { @@ -20,7 +21,7 @@ namespace BevelGenerator private static string bevelCacheDir; private static string studioCookies = ""; - private static string xCsrfToken = "Fetch"; + private static string xCsrfToken = "FETCH"; private static Random rng = new Random(); @@ -102,7 +103,7 @@ namespace BevelGenerator // Update the X-CSRF-TOKEN. xCsrfToken = response.Headers.Get("X-CSRF-TOKEN"); - // Retry the request again. + // Retry the upload. return UploadMesh(mesh, name, desc); } else @@ -240,39 +241,79 @@ namespace BevelGenerator Console.Clear(); } - static void ProcessObjFile(FileInfo info) + static Mesh PortObjFile(FileInfo info) { + Console.WriteLine("Reading obj file..."); + string objPath = info.FullName; Mesh mesh = Mesh.FromObjFile(objPath); - string meshPath = objPath.Replace(info.Extension, ".mesh"); - FileStream file = File.OpenWrite(meshPath); + Console.WriteLine("Writing mesh file..."); - using (file) + string extension = info.Extension; + string filePath = objPath.Replace(extension, ".mesh"); + + using (FileStream file = File.OpenWrite(filePath)) { file.SetLength(0); mesh.Save(file); } - Debugger.Break(); + return mesh; } static void ProcessFileArg(string filePath) { FileInfo info = new FileInfo(filePath); - if (info.Extension == ".obj") + switch (info.Extension) { - ProcessObjFile(info); - return; - } - else if (info.Extension == ".bin" || info.Extension == ".mesh") - { - Mesh mesh = Mesh.FromFile(filePath); - Debugger.Break(); - } + case ".obj": + Mesh export = PortObjFile(info); - ProcessModelFile(filePath); + Console.Write("Would you like to upload this mesh? (y/n): "); + string answer = Console.ReadLine(); + + if (answer.ToLower()[0] == 'y') + { + Console.Write("Enter a name for this mesh: "); + string name = Console.ReadLine(); + + Console.Write("Enter a description for this mesh: "); + string desc = Console.ReadLine(); + + Console.WriteLine("Uploading mesh..."); + long result = 0; + + try + { + result = UploadMesh(export, name, desc); + } + catch (Exception e) + { + Console.WriteLine($"An error occurred while uploading: {e.Message}"); + } + + if (result > 0) + { + Clipboard.SetText($"rbxassetid://{result}"); + Console.WriteLine($"Result -> rbxassetid://{result} (copied to clipboard)"); + } + + Debugger.Break(); + } + + break; + case ".bin": + case ".mesh": + Mesh import = Mesh.FromFile(filePath); + Debugger.Break(); + + break; + default: + ProcessModelFile(filePath); + break; + } } [STAThread] @@ -294,16 +335,17 @@ namespace BevelGenerator foreach (string name in robloxCookies.GetValueNames()) { string cookie = robloxCookies.GetString(name); + Match match = Regex.Match(cookie, "COOK::<([^>]*)>"); - int startIndex = cookie.IndexOf("COOK::<") + 7; - int endIndex = cookie.IndexOf('>', startIndex); + if (match.Groups.Count > 1) + { + cookie = match.Groups[1].Value; - cookie = cookie.Substring(startIndex, endIndex - startIndex); + if (studioCookies.Length > 0) + studioCookies += "; "; - if (studioCookies.Length > 0) - studioCookies += "; "; - - studioCookies += $"{name}={cookie}"; + studioCookies += $"{name}={cookie}"; + } } if (args.Length > 0) -- 2.40.1