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/Mesh.cs b/Bevels/Geometry/Mesh.cs deleted file mode 100644 index c4358b7..0000000 --- a/Bevels/Geometry/Mesh.cs +++ /dev/null @@ -1,407 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -using RobloxFiles.DataTypes; - -namespace BevelGenerator -{ - public class Mesh - { - public int Version; - - public int NumVerts = 0; - public List Verts; - - public int NumFaces = 0; - public List Faces; - - public ushort NumLODs = 0; - public List LODs; - - private static Vector3 ReadVector3(BinaryReader reader) - { - float x = reader.ReadSingle(), - y = reader.ReadSingle(), - z = reader.ReadSingle(); - - 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(); - - if (!header.StartsWith("version 1")) - throw new Exception("Expected version 1 header, got: " + header); - - string version = header.Substring(8); - float vertScale = (version == "1.00" ? 0.5f : 1); - - if (int.TryParse(reader.ReadLine(), out mesh.NumFaces)) - mesh.NumVerts = mesh.NumFaces * 3; - else - throw new Exception("Expected 2nd line to be the polygon count."); - - mesh.Faces = new List(); - mesh.Verts = new List(); - - string polyBuffer = reader.ReadLine(); - MatchCollection matches = Regex.Matches(polyBuffer, @"\[(.*?)\]"); - - int face = 0; - int index = 0; - int target = 0; - - var vertex = new Vertex(); - - foreach (Match m in matches) - { - string vectorStr = m.Groups[1].ToString(); - - float[] coords = vectorStr.Split(',') - .Select(coord => Format.ParseFloat(coord)) - .ToArray(); - - if (target == 0) - vertex.Position = new Vector3(coords) * vertScale; - else if (target == 1) - vertex.Normal = new Vector3(coords); - else if (target == 2) - vertex.UV = new Vector3(coords[0], 1 - coords[1], 0); - - target = (target + 1) % 3; - - if (target == 0) - { - mesh.Verts.Add(vertex); - vertex = new Vertex(); - - if (index % 3 == 0) - { - int v = face * 3; - int[] faceDef = new int[3] { v, v + 1, v + 2 }; - mesh.Faces.Add(faceDef); - } - } - } - - CheckLOD(mesh); - } - - private static void LoadGeometry_Binary(BinaryReader reader, Mesh mesh) - { - byte[] binVersion = reader.ReadBytes(13); - var headerSize = reader.ReadUInt16(); - - var vertSize = reader.ReadByte(); - var faceSize = reader.ReadByte(); - - if (mesh.Version >= 3) - { - var lodRangeSize = reader.ReadUInt16(); - mesh.NumLODs = reader.ReadUInt16(); - } - - mesh.NumVerts = reader.ReadInt32(); - mesh.NumFaces = reader.ReadInt32(); - - mesh.LODs = new List(); - mesh.Faces = new List(); - mesh.Verts = new List(); - - for (int i = 0; i < mesh.NumVerts; i++) - { - var vert = new Vertex() - { - Position = ReadVector3(reader), - Normal = ReadVector3(reader), - UV = ReadVector3(reader) - }; - - if (vertSize > 36) - { - int rgba = reader.ReadInt32(); - int argb = (rgba << 24 | rgba >> 8); - - vert.Color = Color.FromArgb(argb); - vert.HasColor = true; - } - - mesh.Verts.Add(vert); - } - - for (int i = 0; i < mesh.NumFaces; i++) - { - int[] face = new int[3]; - - for (int f = 0; f < 3; f++) - face[f] = reader.ReadInt32(); - - mesh.Faces.Add(face); - } - - if (mesh.NumLODs > 0) - { - for (int i = 0; i < mesh.NumLODs; i++) - { - int lod = reader.ReadInt32(); - mesh.LODs.Add(lod); - } - } - - CheckLOD(mesh); - } - - public void AddLOD(Mesh lodMesh) - { - Verts.AddRange(lodMesh.Verts); - - Faces.AddRange(lodMesh.Faces - .Select(face => face - .Select(i => i + NumVerts) - .ToArray() - ) - ); - - NumVerts = Verts.Count; - NumFaces = Faces.Count; - - LODs.Add(NumFaces); - NumLODs += 1; - } - - public void Save(Stream stream) - { - const ushort HeaderSize = 16; - const byte VertSize = 40; - const byte FaceSize = 12; - const ushort LOD_Size = 4; - - byte[] VersionHeader = Encoding.ASCII.GetBytes("version 3.00\n"); - - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(VersionHeader); - writer.Write(HeaderSize); - - writer.Write(VertSize); - writer.Write(FaceSize); - writer.Write(LOD_Size); - - writer.Write(NumLODs); - writer.Write(NumVerts); - writer.Write(NumFaces); - - for (int i = 0; i < NumVerts; i++) - { - Vertex vertex = Verts[i]; - - Vector3 pos = vertex.Position; - writer.Write(pos.X); - writer.Write(pos.Y); - writer.Write(pos.Z); - - Vector3 norm = vertex.Normal; - writer.Write(norm.X); - writer.Write(norm.Y); - writer.Write(norm.Z); - - Vector3 uv = vertex.UV; - writer.Write(uv.X); - writer.Write(uv.Y); - writer.Write(uv.Z); - - if (vertex.HasColor) - { - var color = vertex.Color; - int argb = color.ToArgb(); - - int rgba = (argb << 8 | argb >> 24); - writer.Write(rgba); - } - else - { - writer.Write(-1); - } - } - - for (int i = 0; i < NumFaces; i++) - { - int[] faces = Faces[i]; - - for (int f = 0; f < 3; f++) - { - int face = faces[f]; - writer.Write(face); - } - } - - for (int i = 0; i < NumLODs; i++) - { - int lod = LODs[i]; - writer.Write(lod); - } - } - } - - public static Mesh FromObjFile(string filePath) - { - string contents = File.ReadAllText(filePath); - - Mesh mesh = new Mesh() - { - Version = 3, - Faces = new List(), - Verts = new List() - }; - - var posTable = new List(); - var normTable = new List(); - - var vertexLookup = new Dictionary(); - - using (StringReader reader = new StringReader(contents)) - { - string line; - - while ((line = reader.ReadLine()) != null) - { - if (line.Length == 0) - continue; - - string[] buffer = line.Split(' '); - string cmd = buffer[0]; - - if (cmd == "v" || cmd == "vn") - { - 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++) - { - string faceDef = buffer[i + 1]; - string[] indices = faceDef.Split('/'); - - int posId = int.Parse(indices[0]) - 1; - int normId = int.Parse(indices[2]) - 1; - - string key = $"{posId}/{normId}"; - - if (!vertexLookup.ContainsKey(key)) - { - int faceId = mesh.NumVerts++; - vertexLookup.Add(key, faceId); - - Vertex vert = new Vertex() - { - Position = posTable[posId], - Normal = normTable[normId], - UV = new Vector3() - }; - - mesh.Verts.Add(vert); - } - - face[i] = vertexLookup[key]; - } - - mesh.Faces.Add(face); - mesh.NumFaces++; - } - } - } - - return CheckLOD(mesh); - } - - public static Mesh FromBuffer(byte[] data) - { - string file = Encoding.ASCII.GetString(data); - - if (!file.StartsWith("version ")) - throw new Exception("Invalid .mesh header!"); - - string versionStr = file.Substring(8, 4); - double version = Format.ParseDouble(versionStr); - - Mesh mesh = new Mesh(); - mesh.Version = (int)version; - - IDisposable disposeThis; - - if (mesh.Version == 1) - { - StringReader buffer = new StringReader(file); - LoadGeometry_Ascii(buffer, mesh); - - disposeThis = buffer; - } - else if (mesh.Version == 2 || mesh.Version == 3) - { - MemoryStream stream = new MemoryStream(data); - - using (BinaryReader reader = new BinaryReader(stream)) - LoadGeometry_Binary(reader, mesh); - - disposeThis = stream; - } - else - { - throw new Exception($"Unknown .mesh file version: {version}"); - } - - disposeThis.Dispose(); - disposeThis = null; - - return mesh; - } - - public static Mesh FromStream(Stream stream) - { - byte[] data; - - using (MemoryStream buffer = new MemoryStream()) - { - stream.CopyTo(buffer); - data = buffer.ToArray(); - } - - return FromBuffer(data); - } - - public static Mesh FromFile(string path) - { - using (FileStream meshStream = File.OpenRead(path)) - { - return FromStream(meshStream); - } - } - } -} \ No newline at end of file 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/Mesh.cs b/Bevels/Mesh.cs new file mode 100644 index 0000000..b082161 --- /dev/null +++ b/Bevels/Mesh.cs @@ -0,0 +1,628 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +using RobloxFiles; +using RobloxFiles.DataTypes; + +namespace BevelGenerator +{ + public class Bone : Instance + { + public int NameIndex; + + public short Id; + public short ParentId; + + public float Unknown; + 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 SkinData + { + public int FacesBegin; + public int FacesLength; + + public int VertsBegin; + public int VertsLength; + + public int NumBones; + public short[] BoneIndexTree; + } + + public struct BoneWeights + { + public byte[] Bones; + public byte[] Weights; + + public override string ToString() + { + var bones = string.Join(", ", Bones); + var weights = string.Join(", ", Weights); + + return $"{{Bones: [{bones}] | Weights: [{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; + public List LODs; + + public int NumBones = 0; + public List Bones; + + 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(), + y = reader.ReadSingle(), + z = reader.ReadSingle(); + + return new Vector3(x, y, z); + } + + 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); + + string version = header.Substring(8); + float vertScale = (version == "1.00" ? 0.5f : 1); + + if (int.TryParse(reader.ReadLine(), out mesh.NumFaces)) + mesh.NumVerts = mesh.NumFaces * 3; + else + throw new Exception("Expected 2nd line to be the polygon count."); + + mesh.Faces = new List(); + mesh.Verts = new List(); + + string polyBuffer = reader.ReadLine(); + MatchCollection matches = Regex.Matches(polyBuffer, @"\[(.*?)\]"); + + int face = 0; + int index = 0; + int target = 0; + + var vertex = new Vertex(); + + foreach (Match m in matches) + { + string vectorStr = m.Groups[1].ToString(); + + float[] coords = vectorStr.Split(',') + .Select(coord => Format.ParseFloat(coord)) + .ToArray(); + + if (target == 0) + vertex.Position = new Vector3(coords) * vertScale; + else if (target == 1) + vertex.Normal = new Vector3(coords); + else if (target == 2) + vertex.UV = new Vector3(coords[0], 1 - coords[1], 0); + + target = (target + 1) % 3; + + if (target == 0) + { + mesh.Verts.Add(vertex); + vertex = new Vertex(); + + if (index % 3 == 0) + { + int v = face * 3; + int[] faceDef = new int[3] { v, v + 1, v + 2 }; + mesh.Faces.Add(faceDef); + } + } + } + } + + private static void LoadGeometry_Binary(BinaryReader reader, Mesh mesh) + { + byte[] binVersion = reader.ReadBytes(13); // version x.xx\n + var headerSize = reader.ReadUInt16(); + + if (mesh.HasSkinning) + { + 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.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.SkinData = new List(); + + // Read Vertices + for (int i = 0; i < mesh.NumVerts; i++) + { + var vert = new Vertex() + { + Position = ReadVector3(reader), + Normal = ReadVector3(reader), + UV = ReadVector3(reader) + }; + + Color? color = null; + + if (mesh.HasVertexColors) + { + int rgba = reader.ReadInt32(); + color = Color.FromArgb(rgba << 24 | rgba >> 8); + } + + vert.Color = color; + mesh.Verts.Add(vert); + } + + if (mesh.HasSkinning) + { + // Read Bone Weights? + 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; + } + } + + // Read Faces + for (int i = 0; i < mesh.NumFaces; i++) + { + int[] face = new int[3]; + + for (int f = 0; f < 3; f++) + face[f] = reader.ReadInt32(); + + mesh.Faces.Add(face); + } + + if (mesh.HasLODs && mesh.NumLODs > 0) + { + // Read LOD ranges + for (int i = 0; i < mesh.NumLODs; i++) + { + int lod = reader.ReadInt32(); + mesh.LODs.Add(lod); + } + } + + if (mesh.HasSkinning) + { + // 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(), + + 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); + } + + // 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); + } + } + + + Debugger.Break(); + } + + public void AddLOD(Mesh lodMesh) + { + Verts.AddRange(lodMesh.Verts); + + Faces.AddRange + ( + lodMesh.Faces.Select + ( + face => face + .Select(i => i + NumVerts) + .ToArray() + ) + ); + + NumVerts = Verts.Count; + NumFaces = Faces.Count; + + LODs.Add(NumFaces); + NumLODs += 1; + } + + public void Save(Stream stream) + { + const ushort HeaderSize = 16; + const byte VertSize = 40; + const byte FaceSize = 12; + const ushort LOD_Size = 4; + + 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)) + { + writer.Write(VersionHeader); + writer.Write(HeaderSize); + + writer.Write(VertSize); + writer.Write(FaceSize); + writer.Write(LOD_Size); + + writer.Write(NumLODs); + writer.Write(NumVerts); + writer.Write(NumFaces); + + for (int i = 0; i < NumVerts; i++) + { + Vertex vertex = Verts[i]; + + Vector3 pos = vertex.Position; + writer.Write(pos.X); + writer.Write(pos.Y); + writer.Write(pos.Z); + + Vector3 norm = vertex.Normal; + writer.Write(norm.X); + writer.Write(norm.Y); + writer.Write(norm.Z); + + Vector3 uv = vertex.UV; + writer.Write(uv.X); + writer.Write(uv.Y); + writer.Write(uv.Z); + + if (vertex.Color.HasValue) + { + var color = vertex.Color.Value; + int argb = color.ToArgb(); + + int rgba = (argb << 8 | argb >> 24); + writer.Write(rgba); + } + else + { + writer.Write(-1); + } + } + + for (int i = 0; i < NumFaces; i++) + { + int[] faces = Faces[i]; + + for (int f = 0; f < 3; f++) + { + int face = faces[f]; + writer.Write(face); + } + } + + for (int i = 0; i < NumLODs; i++) + { + int lod = LODs[i]; + writer.Write(lod); + } + } + } + + public static Mesh FromObjFile(string filePath) + { + string contents = File.ReadAllText(filePath); + + Mesh mesh = new Mesh() + { + Version = 3, + Faces = new List(), + 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)) + { + string line; + + while ((line = reader.ReadLine()) != null) + { + if (line.Length == 0) + continue; + + string[] buffer = line.Split(' '); + string action = buffer[0]; + + switch (action) + { + case "v": + case "vn": + case "vt": + { + float[] input = buffer + .Skip(1) + .Select(float.Parse) + .ToArray(); + + var value = new Vector3(input); + List target = null; + + switch (action) + { + case "v": + { + target = posTable; + break; + } + case "vn": + { + target = normTable; + break; + } + case "vt": + { + target = uvTable; + break; + } + } + + target.Add(value); + break; + } + case "f": + { + int[] face = new int[3]; + + 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 mesh; + } + + public static Mesh FromBuffer(byte[] data) + { + string file = Encoding.ASCII.GetString(data); + + if (!file.StartsWith("version ")) + throw new Exception("Invalid .mesh header!"); + + string versionStr = file.Substring(8, 4); + double version = Format.ParseDouble(versionStr); + + Mesh mesh = new Mesh(); + mesh.Version = (int)version; + + IDisposable disposeThis; + + if (mesh.Version == 1) + { + StringReader buffer = new StringReader(file); + LoadGeometry_Ascii(buffer, mesh); + + disposeThis = buffer; + } + else + { + MemoryStream stream = new MemoryStream(data); + + using (BinaryReader reader = new BinaryReader(stream)) + LoadGeometry_Binary(reader, mesh); + + disposeThis = stream; + } + + disposeThis.Dispose(); + disposeThis = null; + + return mesh; + } + + public static Mesh FromStream(Stream stream) + { + byte[] data; + + using (MemoryStream buffer = new MemoryStream()) + { + stream.CopyTo(buffer); + data = buffer.ToArray(); + } + + return FromBuffer(data); + } + + public static Mesh FromFile(string path) + { + Mesh result; + + using (FileStream meshStream = File.OpenRead(path)) + result = FromStream(meshStream); + + return result; + } + } +} \ No newline at end of file diff --git a/Bevels/Program.cs b/Bevels/Program.cs index 714ae16..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,34 +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; - } + 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] @@ -289,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)