diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b7205ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +bin/* +obj/* +packages/* +.vs/* +*.suo +*.ide \ No newline at end of file diff --git a/BinaryFormat/BinaryFile.cs b/BinaryFormat/BinaryFile.cs new file mode 100644 index 0000000..c4c614d --- /dev/null +++ b/BinaryFormat/BinaryFile.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Text; +using Roblox.BinaryFormat.Chunks; + +namespace Roblox.BinaryFormat +{ + public class RobloxBinaryFile : RobloxFile + { + public const string FileSignature = " BinaryChunks = new List(); + + public readonly PRNT ParentIds; + public readonly META Metadata; + + public readonly Dictionary INSTs = new Dictionary(); + public readonly List PROPs = new List(); + + public readonly RobloxInstance[] Instances; + + public readonly ushort Version; + public readonly uint NumTypes; + public readonly uint NumInstances; + public readonly long Reserved; + + public RobloxBinaryFile(byte[] contents) + { + using (MemoryStream file = new MemoryStream(contents)) + using (RobloxBinaryReader reader = new RobloxBinaryReader(file)) + { + byte[] binSignature = reader.ReadBytes(14); + string signature = Encoding.UTF7.GetString(binSignature); + + if (signature != FileSignature) + throw new InvalidDataException("Signature does not match RobloxBinaryFile.FileSignature!"); + + Version = reader.ReadUInt16(); + NumTypes = reader.ReadUInt32(); + NumInstances = reader.ReadUInt32(); + Reserved = reader.ReadInt64(); + + // Begin reading the file chunks. + bool reading = true; + Instances = new RobloxInstance[NumInstances]; + BinaryChunks = new List(); + + while (reading) + { + try + { + RobloxBinaryChunk chunk = new RobloxBinaryChunk(reader); + BinaryChunks.Add(chunk); + + switch (chunk.ChunkType) + { + case "INST": + INST inst = new INST(chunk); + INSTs.Add(inst.TypeIndex, inst); + break; + case "PROP": + PROP prop = new PROP(chunk); + PROPs.Add(prop); + break; + case "PRNT": + PRNT prnt = new PRNT(chunk); + ParentIds = prnt; + break; + case "META": + META meta = new META(chunk); + Metadata = meta; + break; + case "END\0": + reading = false; + break; + default: + BinaryChunks.Remove(chunk); + break; + } + } + catch (EndOfStreamException) + { + throw new Exception("Unexpected end of file!"); + } + } + + foreach (INST chunk in INSTs.Values) + { + foreach (int id in chunk.InstanceIds) + { + RobloxInstance inst = new RobloxInstance(); + inst.ClassName = chunk.TypeName; + Instances[id] = inst; + } + } + + foreach (PROP prop in PROPs) + { + INST chunk = INSTs[prop.Index]; + prop.ReadPropertyValues(chunk, Instances); + } + + for (int i = 0; i < ParentIds.NumRelations; i++) + { + int childId = ParentIds.ChildrenIds[i]; + int parentId = ParentIds.ParentIds[i]; + + RobloxInstance child = Instances[childId]; + + if (parentId >= 0) + { + var parent = Instances[parentId]; + child.Parent = parent; + } + else + { + Trunk.Add(child); + } + } + } + } + } +} diff --git a/BinaryFormat/Chunk.cs b/BinaryFormat/Chunk.cs new file mode 100644 index 0000000..8471631 --- /dev/null +++ b/BinaryFormat/Chunk.cs @@ -0,0 +1,57 @@ +using System; +using System.IO; +using System.Text; +using LZ4; + +namespace Roblox.BinaryFormat +{ + public class RobloxBinaryChunk + { + public readonly string ChunkType; + + public readonly int CompressedSize; + public readonly byte[] CompressedData; + + public readonly int Size; + public readonly int Reserved; + public readonly byte[] Data; + + public bool HasCompressedData => (CompressedSize > 0); + + public override string ToString() + { + return ChunkType + " Chunk [" + Size + ']'; + } + + public RobloxBinaryReader GetReader(string chunkType) + { + if (ChunkType == chunkType) + { + MemoryStream buffer = new MemoryStream(Data); + return new RobloxBinaryReader(buffer); + } + + throw new Exception("Expected " + chunkType + " ChunkType from the input RobloxBinaryChunk"); + } + + public RobloxBinaryChunk(RobloxBinaryReader reader) + { + byte[] bChunkType = reader.ReadBytes(4); + ChunkType = Encoding.ASCII.GetString(bChunkType); + + CompressedSize = reader.ReadInt32(); + Size = reader.ReadInt32(); + Reserved = reader.ReadInt32(); + + if (HasCompressedData) + { + CompressedData = reader.ReadBytes(CompressedSize); + Data = LZ4Codec.Decode(CompressedData, 0, CompressedSize, Size); + } + else + { + Data = reader.ReadBytes(Size); + } + } + } +} diff --git a/BinaryFormat/ChunkTypes/INST.cs b/BinaryFormat/ChunkTypes/INST.cs new file mode 100644 index 0000000..1fd0dee --- /dev/null +++ b/BinaryFormat/ChunkTypes/INST.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.IO; + +namespace Roblox.BinaryFormat.Chunks +{ + public class INST + { + public readonly int TypeIndex; + public readonly string TypeName; + public readonly bool IsService; + public readonly int NumInstances; + public readonly int[] InstanceIds; + + public Dictionary Properties; + + public override string ToString() + { + return TypeName; + } + + public INST(RobloxBinaryChunk chunk) + { + using (RobloxBinaryReader reader = chunk.GetReader("INST")) + { + TypeIndex = reader.ReadInt32(); + TypeName = reader.ReadString(); + IsService = reader.ReadBoolean(); + + NumInstances = reader.ReadInt32(); + InstanceIds = reader.ReadInstanceIds(NumInstances); + } + + Properties = new Dictionary(); + } + } +} diff --git a/BinaryFormat/ChunkTypes/META.cs b/BinaryFormat/ChunkTypes/META.cs new file mode 100644 index 0000000..0d8a0d2 --- /dev/null +++ b/BinaryFormat/ChunkTypes/META.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.IO; + +namespace Roblox.BinaryFormat.Chunks +{ + public class META + { + public int NumEntries; + public Dictionary Entries; + + public META(RobloxBinaryChunk chunk) + { + using (RobloxBinaryReader reader = chunk.GetReader("META")) + { + NumEntries = reader.ReadInt32(); + Entries = new Dictionary(NumEntries); + + for (int i = 0; i < NumEntries; i++) + { + string key = reader.ReadString(); + string value = reader.ReadString(); + Entries.Add(key, value); + } + } + } + } +} diff --git a/BinaryFormat/ChunkTypes/PRNT.cs b/BinaryFormat/ChunkTypes/PRNT.cs new file mode 100644 index 0000000..3da3969 --- /dev/null +++ b/BinaryFormat/ChunkTypes/PRNT.cs @@ -0,0 +1,23 @@ +namespace Roblox.BinaryFormat.Chunks +{ + public class PRNT + { + public readonly byte Format; + public readonly int NumRelations; + + public readonly int[] ChildrenIds; + public readonly int[] ParentIds; + + public PRNT(RobloxBinaryChunk chunk) + { + using (RobloxBinaryReader reader = chunk.GetReader("PRNT")) + { + Format = reader.ReadByte(); + NumRelations = reader.ReadInt32(); + + ChildrenIds = reader.ReadInstanceIds(NumRelations); + ParentIds = reader.ReadInstanceIds(NumRelations); + } + } + } +} diff --git a/BinaryFormat/ChunkTypes/PROP.cs b/BinaryFormat/ChunkTypes/PROP.cs new file mode 100644 index 0000000..36a6088 --- /dev/null +++ b/BinaryFormat/ChunkTypes/PROP.cs @@ -0,0 +1,422 @@ +using System; +using System.IO; +using System.Linq; + +using Roblox.Enums; +using Roblox.DataTypes; +using Roblox.DataTypes.Utility; + +namespace Roblox.BinaryFormat.Chunks +{ + public class PROP + { + public int Index { get; private set; } + public string Name { get; private set; } + + public readonly PropertyType Type; + public RobloxProperty[] Properties => props; + + private RobloxBinaryReader reader; + private RobloxProperty[] props; + + public override string ToString() + { + Type PropertyType = typeof(PropertyType); + return '[' + Enum.GetName(PropertyType, Type) + "] " + Name; + } + + public PROP(RobloxBinaryChunk chunk) + { + reader = chunk.GetReader("PROP"); + + Index = reader.ReadInt32(); + Name = reader.ReadString(); + + try + { + byte propType = reader.ReadByte(); + Type = (PropertyType)propType; + } + catch + { + Type = PropertyType.Unknown; + } + } + + public void ReadPropertyValues(INST instChunk, RobloxInstance[] instMap) + { + int[] ids = instChunk.InstanceIds; + int instCount = ids.Length; + + props = new RobloxProperty[instCount]; + + for (int i = 0; i < instCount; i++) + { + RobloxProperty prop = new RobloxProperty(); + prop.Name = Name; + prop.Type = Type; + + Properties[i] = prop; + instMap[ids[i]].Properties.Add(prop); + } + + // Setup some short-hand functions for frequently used actions. + var readInstanceInts = new Func(() => reader.ReadInts(instCount)); + var readInstanceFloats = new Func(() => reader.ReadFloats(instCount)); + + var loadProperties = new Action>(read => + { + for (int i = 0; i < instCount; i++) + { + object result = read(i); + props[i].Value = result; + } + }); + + // Process the property data based on the property type. + switch (Type) + { + case PropertyType.String: + loadProperties(i => reader.ReadString()); + break; + case PropertyType.Bool: + loadProperties(i => reader.ReadBoolean()); + break; + case PropertyType.Int: + int[] ints = readInstanceInts(); + loadProperties(i => ints[i]); + break; + case PropertyType.Float: + float[] floats = readInstanceFloats(); + loadProperties(i => floats[i]); + break; + case PropertyType.Double: + loadProperties(i => reader.ReadDouble()); + break; + case PropertyType.UDim: + float[] scales = readInstanceFloats(); + int[] offsets = readInstanceInts(); + + loadProperties(i => + { + float scale = scales[i]; + int offset = offsets[i]; + return new UDim(scale, offset); + }); + + break; + case PropertyType.UDim2: + float[] scalesX = readInstanceFloats(), scalesY = readInstanceFloats(); + int[] offsetsX = readInstanceInts(), offsetsY = readInstanceInts(); + + loadProperties(i => + { + float scaleX = scalesX[i], scaleY = scalesY[i]; + int offsetX = offsetsX[i], offsetY = offsetsY[i]; + return new UDim2(scaleX, offsetX, scaleY, offsetY); + }); + + break; + case PropertyType.Ray: + loadProperties(i => + { + float[] rawOrigin = reader.ReadFloats(3); + Vector3 origin = new Vector3(rawOrigin); + + float[] rawDirection = reader.ReadFloats(3); + Vector3 direction = new Vector3(rawDirection); + + return new Ray(origin, direction); + }); + + break; + case PropertyType.Faces: + loadProperties(i => + { + byte faces = reader.ReadByte(); + return (Faces)faces; + }); + + break; + case PropertyType.Axes: + loadProperties(i => + { + byte axes = reader.ReadByte(); + return (Axes)axes; + }); + + break; + case PropertyType.BrickColor: + int[] brickColors = readInstanceInts(); + + loadProperties(i => + { + int number = brickColors[i]; + return BrickColor.New(number); + }); + + break; + case PropertyType.Color3: + float[] color3_R = readInstanceFloats(), + color3_G = readInstanceFloats(), + color3_B = readInstanceFloats(); + + loadProperties(i => + { + float r = color3_R[i], + g = color3_G[i], + b = color3_B[i]; + + return new Color3(r, g, b); + }); + + break; + case PropertyType.Vector2: + float[] vector2_X = readInstanceFloats(), + vector2_Y = readInstanceFloats(); + + loadProperties(i => + { + float x = vector2_X[i], + y = vector2_Y[i]; + + return new Vector2(x, y); + }); + + break; + case PropertyType.Vector3: + float[] vector3_X = readInstanceFloats(), + vector3_Y = readInstanceFloats(), + vector3_Z = readInstanceFloats(); + + loadProperties(i => + { + float x = vector3_X[i], + y = vector3_Y[i], + z = vector3_Z[i]; + + return new Vector3(x, y, z); + }); + + break; + case PropertyType.CFrame: + case PropertyType.Quaternion: + // Temporarily load the rotation matrices into their properties. + // We'll update them to CFrames once we iterate over the position data. + + loadProperties(i => + { + byte orientId = reader.ReadByte(); + + if (orientId > 0) + { + NormalId normX = (NormalId)((orientId - 1) / 6); + Vector3 R0 = Vector3.FromNormalId(normX); + + NormalId normY = (NormalId)((orientId - 1) % 6); + Vector3 R1 = Vector3.FromNormalId(normY); + + // Compute R2 using the cross product of R0 and R1. + Vector3 R2 = R0.Cross(R1); + + // Generate the rotation matrix and return it. + return new float[9] + { + R0.X, R0.Y, R0.Z, + R1.X, R1.Y, R1.Z, + R2.X, R2.Y, R2.Z, + }; + } + else if (Type == PropertyType.Quaternion) + { + float qx = reader.ReadSingle(), + qy = reader.ReadSingle(), + qz = reader.ReadSingle(), + qw = reader.ReadSingle(); + + Quaternion quat = new Quaternion(qx, qy, qz, qw); + var rotation = quat.ToCFrame(); + + return rotation.GetComponents(); + } + else + { + float[] matrix = new float[9]; + + for (int m = 0; m < 9; m++) + { + float value = reader.ReadSingle(); + matrix[m] = value; + } + + return matrix; + } + }); + + float[] cframe_X = readInstanceFloats(), + cframe_Y = readInstanceFloats(), + cframe_Z = readInstanceFloats(); + + loadProperties(i => + { + float[] matrix = props[i].Value as float[]; + + float x = cframe_X[i], + y = cframe_Y[i], + z = cframe_Z[i]; + + float[] position = new float[3] { x, y, z }; + float[] components = position.Concat(matrix).ToArray(); + + return new CFrame(components); + }); + + break; + case PropertyType.Enum: + uint[] enums = reader.ReadInterwovenValues(instCount, BitConverter.ToUInt32); + loadProperties(i => enums[i]); + break; + case PropertyType.Ref: + int[] instIds = reader.ReadInstanceIds(instCount); + + loadProperties(i => + { + int instId = instIds[i]; + return instId >= 0 ? instMap[instId] : null; + }); + + break; + case PropertyType.Vector3int16: + loadProperties(i => + { + short x = reader.ReadInt16(), + y = reader.ReadInt16(), + z = reader.ReadInt16(); + + return new Vector3int16(x, y, z); + }); + + break; + case PropertyType.NumberSequence: + loadProperties(i => + { + int keys = reader.ReadInt32(); + var keypoints = new NumberSequenceKeypoint[keys]; + + for (int key = 0; key < keys; key++) + { + float time = reader.ReadSingle(), + value = reader.ReadSingle(), + envelope = reader.ReadSingle(); + + keypoints[key] = new NumberSequenceKeypoint(time, value, envelope); + } + + return new NumberSequence(keypoints); + }); + + break; + case PropertyType.ColorSequence: + loadProperties(i => + { + int keys = reader.ReadInt32(); + var keypoints = new ColorSequenceKeypoint[keys]; + + for (int key = 0; key < keys; key++) + { + float time = reader.ReadSingle(), + R = reader.ReadSingle(), + G = reader.ReadSingle(), + B = reader.ReadSingle(), + envelope = reader.ReadSingle(); // unused, but still written + + keypoints[key] = new ColorSequenceKeypoint(time, new Color3(R, G, B)); + } + + return new ColorSequence(keypoints); + }); + + break; + case PropertyType.NumberRange: + loadProperties(i => + { + float min = reader.ReadSingle(); + float max = reader.ReadSingle(); + + return new NumberRange(min, max); + }); + + break; + case PropertyType.Rect: + float[] Rect_X0 = readInstanceFloats(), + Rect_Y0 = readInstanceFloats(), + Rect_X1 = readInstanceFloats(), + Rect_Y1 = readInstanceFloats(); + + loadProperties(i => + { + float x0 = Rect_X0[i], + y0 = Rect_Y0[i], + x1 = Rect_X1[i], + y1 = Rect_Y1[i]; + + return new Rect(x0, y0, x1, y1); + }); + + break; + case PropertyType.PhysicalProperties: + loadProperties(i => + { + bool custom = reader.ReadBoolean(); + + if (custom) + { + float density = reader.ReadSingle(), + friction = reader.ReadSingle(), + elasticity = reader.ReadSingle(), + frictionWeight = reader.ReadSingle(), + elasticityWeight = reader.ReadSingle(); + + return new PhysicalProperties + ( + density, + friction, + elasticity, + frictionWeight, + elasticityWeight + ); + } + + return null; + }); + + break; + case PropertyType.Color3uint8: + byte[] color3uint8_R = reader.ReadBytes(instCount), + color3uint8_G = reader.ReadBytes(instCount), + color3uint8_B = reader.ReadBytes(instCount); + + loadProperties(i => + { + byte r = color3uint8_R[i], + g = color3uint8_G[i], + b = color3uint8_B[i]; + + return Color3.fromRGB(r, g, b); + }); + + break; + case PropertyType.Int64: + long[] int64s = reader.ReadInterwovenValues(instCount, (buffer, start) => + { + long result = BitConverter.ToInt64(buffer, start); + return (long)((ulong)result >> 1) ^ (-(result & 1)); + }); + + loadProperties(i => int64s[i]); + break; + + } + } + } +} \ No newline at end of file diff --git a/BinaryFormat/Reader.cs b/BinaryFormat/Reader.cs new file mode 100644 index 0000000..9917fc6 --- /dev/null +++ b/BinaryFormat/Reader.cs @@ -0,0 +1,77 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + +using Roblox.DataTypes; + +namespace Roblox.BinaryFormat +{ + public class RobloxBinaryReader : BinaryReader + { + public RobloxBinaryReader(Stream stream) : base(stream) { } + + public T[] ReadInterwovenValues(int count, Func decode) where T : struct + { + int bufferSize = Marshal.SizeOf(); + + byte[] interwoven = ReadBytes(count * bufferSize); + T[] values = new T[count]; + + for (int i = 0; i < count; i++) + { + long unwind = 0; + + for (int weave = 0; weave < bufferSize; weave++) + { + long splice = interwoven[(weave * count) + i]; + int strand = (bufferSize - weave - 1) * 8; + unwind |= (splice << strand); + } + + byte[] buffer = BitConverter.GetBytes(unwind); + values[i] = decode(buffer, 0); + } + + return values; + } + + public int[] ReadInts(int count) + { + return ReadInterwovenValues(count, (buffer, start) => + { + int value = BitConverter.ToInt32(buffer, start); + return (value >> 1) ^ (-(value & 1)); + }); + } + + public float[] ReadFloats(int count) + { + return ReadInterwovenValues(count, (buffer, start) => + { + uint u = BitConverter.ToUInt32(buffer, start); + uint i = (u >> 1) | (u << 31); + + byte[] b = BitConverter.GetBytes(i); + return BitConverter.ToSingle(b, 0); + }); + } + + public int[] ReadInstanceIds(int count) + { + int[] values = ReadInts(count); + + for (int i = 1; i < count; ++i) + values[i] += values[i - 1]; + + return values; + } + + public override string ReadString() + { + int length = ReadInt32(); + byte[] buffer = ReadBytes(length); + return Encoding.UTF8.GetString(buffer); + } + } +} diff --git a/Core/Enums.cs b/Core/Enums.cs new file mode 100644 index 0000000..5ffe581 --- /dev/null +++ b/Core/Enums.cs @@ -0,0 +1,2116 @@ +// This is an auto-generated list of all available enums on Roblox! +// Updated as of 0.369.1.273919 + +namespace Roblox.Enums +{ + public enum ActionType + { + Nothing, + Pause, + Lose, + Draw, + Win + } + + public enum ActuatorRelativeTo + { + Attachment0, + Attachment1, + World + } + + public enum ActuatorType + { + None, + Motor, + Servo + } + + public enum AnimationPriority + { + Idle, + Movement, + Action, + Core = 1000 + } + + public enum AppShellActionType + { + None, + OpenApp, + TapChatTab, + TapConversationEntry, + TapAvatarTab, + ReadConversation, + TapGamePageTab, + TapHomePageTab, + GamePageLoaded, + HomePageLoaded, + AvatarEditorPageLoaded + } + + public enum AspectType + { + FitWithinMaxSize, + ScaleWithParentSize + } + + public enum AssetType + { + Image, + TeeShirt, + Audio, + Mesh, + Lua, + Hat = 8, + Place, + Model, + Shirt, + Pants, + Decal, + Head = 17, + Face, + Gear, + Badge = 21, + Animation = 24, + Torso = 27, + RightArm, + LeftArm, + LeftLeg, + RightLeg, + Package, + GamePass = 34, + Plugin = 38, + MeshPart = 40, + HairAccessory, + FaceAccessory, + NeckAccessory, + ShoulderAccessory, + FrontAccessory, + BackAccessory, + WaistAccessory, + ClimbAnimation, + DeathAnimation, + FallAnimation, + IdleAnimation, + JumpAnimation, + RunAnimation, + SwimAnimation, + WalkAnimation, + PoseAnimation, + EarAccessory, + EyeAccessory + } + + public enum AutoJointsMode + { + Default, + Explicit, + LegacyImplicit + } + + public enum AvatarContextMenuOption + { + Friend, + Chat, + Emote + } + + public enum AvatarJointPositionType + { + Fixed, + ArtistIntent + } + + public enum Axis + { + X, + Y, + Z + } + + public enum BinType + { + Script, + GameTool, + Grab, + Clone, + Hammer + } + + public enum BodyPart + { + Head, + Torso, + LeftArm, + RightArm, + LeftLeg, + RightLeg + } + + public enum BodyPartR15 + { + Head, + UpperTorso, + LowerTorso, + LeftFoot, + LeftLowerLeg, + LeftUpperLeg, + RightFoot, + RightLowerLeg, + RightUpperLeg, + LeftHand, + LeftLowerArm, + LeftUpperArm, + RightHand, + RightLowerArm, + RightUpperArm, + RootPart, + Unknown = 17 + } + + public enum Button + { + Dismount = 8, + Jump = 32 + } + + public enum ButtonStyle + { + Custom, + RobloxButtonDefault, + RobloxButton, + RobloxRoundButton, + RobloxRoundDefaultButton, + RobloxRoundDropdownButton + } + + public enum CameraMode + { + Classic, + LockFirstPerson + } + + public enum CameraPanMode + { + Classic, + EdgeBump + } + + public enum CameraType + { + Fixed, + Attach, + Watch, + Track, + Follow, + Custom, + Scriptable, + Orbital + } + + public enum CellBlock + { + Solid, + VerticalWedge, + CornerWedge, + InverseCornerWedge, + HorizontalWedge + } + + public enum CellMaterial + { + Empty, + Grass, + Sand, + Brick, + Granite, + Asphalt, + Iron, + Aluminum, + Gold, + WoodPlank, + WoodLog, + Gravel, + CinderBlock, + MossyStone, + Cement, + RedPlastic, + BluePlastic, + Water + } + + public enum CellOrientation + { + NegZ, + X, + Z, + NegX + } + + public enum CenterDialogType + { + UnsolicitedDialog, + PlayerInitiatedDialog, + ModalDialog, + QuitDialog + } + + public enum ChatCallbackType + { + OnCreatingChatWindow, + OnClientSendingMessage, + OnClientFormattingMessage, + OnServerReceivingMessage = 17 + } + + public enum ChatColor + { + Blue, + Green, + Red, + White + } + + public enum ChatMode + { + Menu, + TextAndMenu + } + + public enum ChatPrivacyMode + { + AllUsers, + NoOne, + Friends + } + + public enum ChatStyle + { + Classic, + Bubble, + ClassicAndBubble + } + + public enum CollisionFidelity + { + Default, + Hull, + Box + } + + public enum ComputerCameraMovementMode + { + Default, + Classic, + Follow, + Orbital + } + + public enum ComputerMovementMode + { + Default, + KeyboardMouse, + ClickToMove + } + + public enum ConnectionError + { + OK, + DisconnectErrors = 256, + DisconnectBadhash, + DisconnectSecurityKeyMismatch, + DisconnectProtocolMismatch, + DisconnectReceivePacketError, + DisconnectReceivePacketStreamError, + DisconnectSendPacketError, + DisconnectIllegalTeleport, + DisconnectDuplicatePlayer, + DisconnectDuplicateTicket, + DisconnectTimeout, + DisconnectLuaKick, + DisconnectOnRemoteSysStats, + DisconnectHashTimeout, + DisconnectCloudEditKick, + DisconnectPlayerless, + DisconnectNewSecurityKeyMismatch, + DisconnectEvicted, + DisconnectDevMaintenance, + DisconnectRobloxMaintenance, + DisconnectRejoin, + DisconnectConnectionLost, + DisconnectIdle, + DisconnectRaknetErrors, + DisconnectWrongVersion, + PlacelaunchErrors = 512, + PlacelaunchDisabled = 515, + PlacelaunchError, + PlacelaunchGameEnded, + PlacelaunchGameFull, + PlacelaunchUserLeft = 522, + PlacelaunchRestricted, + PlacelaunchUnauthorized, + PlacelaunchFlooded, + PlacelaunchHashExpired, + PlacelaunchHashException, + PlacelaunchPartyCannotFit, + PlacelaunchHttpError, + PlacelaunchCustomMessage = 610, + PlacelaunchOtherError, + TeleportErrors = 768, + TeleportFailure, + TeleportGameNotFound, + TeleportGameEnded, + TeleportGameFull, + TeleportUnauthorized, + TeleportFlooded, + TeleportIsTeleporting + } + + public enum ConnectionState + { + Connected, + Disconnected + } + + public enum ContextActionPriority + { + Low = 1000, + Default = 2000, + Medium, + High = 3000 + } + + public enum ContextActionResult + { + Sink, + Pass + } + + public enum ControlMode + { + Classic, + MouseLockSwitch + } + + public enum CoreGuiType + { + PlayerList, + Health, + Backpack, + Chat, + All + } + + public enum CreatorType + { + User, + Group + } + + public enum CurrencyType + { + Default, + Robux, + Tix + } + + public enum CustomCameraMode + { + Default, + Classic, + Follow + } + + public enum DEPRECATED_DebuggerDataModelPreference + { + Server, + Client + } + + public enum DataStoreRequestType + { + GetAsync, + SetIncrementAsync, + UpdateAsync, + GetSortedAsync, + SetIncrementSortedAsync, + OnUpdate + } + + public enum DevCameraOcclusionMode + { + Zoom, + Invisicam + } + + public enum DevComputerCameraMovementMode + { + UserChoice, + Classic, + Follow, + Orbital + } + + public enum DevComputerMovementMode + { + UserChoice, + KeyboardMouse, + ClickToMove, + Scriptable + } + + public enum DevTouchCameraMovementMode + { + UserChoice, + Classic, + Follow, + Orbital + } + + public enum DevTouchMovementMode + { + UserChoice, + Thumbstick, + DPad, + Thumbpad, + ClickToMove, + Scriptable, + DynamicThumbstick + } + + public enum DeveloperMemoryTag + { + Internal, + HttpCache, + Instances, + Signals, + LuaHeap, + Script, + PhysicsCollision, + PhysicsParts, + GraphicsSolidModels, + GraphicsMeshParts, + GraphicsParticles, + GraphicsParts, + GraphicsSpatialHash, + GraphicsTerrain, + GraphicsTexture, + GraphicsTextureCharacter, + Sounds, + StreamingSounds, + TerrainVoxels, + Gui = 20, + Animation, + Navigation + } + + public enum DialogBehaviorType + { + SinglePlayer, + MultiplePlayers + } + + public enum DialogPurpose + { + Quest, + Help, + Shop + } + + public enum DialogTone + { + Neutral, + Friendly, + Enemy + } + + public enum DominantAxis + { + Width, + Height + } + + public enum EasingDirection + { + In, + Out, + InOut + } + + public enum EasingStyle + { + Linear, + Sine, + Back, + Quad, + Quart, + Quint, + Bounce, + Elastic + } + + public enum ElasticBehavior + { + WhenScrollable, + Always, + Never + } + + public enum EnviromentalPhysicsThrottle + { + DefaultAuto, + Disabled, + Always, + Skip2, + Skip4, + Skip8, + Skip16 + } + + public enum ErrorReporting + { + DontReport, + Prompt, + Report + } + + public enum ExplosionType + { + NoCraters, + Craters, + CratersAndDebris + } + + public enum FillDirection + { + Horizontal, + Vertical + } + + public enum FilterResult + { + Accepted, + Rejected + } + + public enum Font + { + Legacy, + Arial, + ArialBold, + SourceSans, + SourceSansBold, + SourceSansLight, + SourceSansItalic, + Bodoni, + Garamond, + Cartoon, + Code, + Highway, + SciFi, + Arcade, + Fantasy, + Antique, + SourceSansSemibold, + Gotham, + GothamSemibold, + GothamBold, + GothamBlack + } + + public enum FontSize + { + Size8, + Size9, + Size10, + Size11, + Size12, + Size14, + Size18, + Size24, + Size36, + Size48, + Size28, + Size32, + Size42, + Size60, + Size96 + } + + public enum FormFactor + { + Symmetric, + Brick, + Plate, + Custom + } + + public enum FrameStyle + { + Custom, + ChatBlue, + RobloxSquare, + RobloxRound, + ChatGreen, + ChatRed, + DropShadow + } + + public enum FramerateManagerMode + { + Automatic, + On, + Off + } + + public enum FriendRequestEvent + { + Issue, + Revoke, + Accept, + Deny + } + + public enum FriendStatus + { + Unknown, + NotFriend, + Friend, + FriendRequestSent, + FriendRequestReceived + } + + public enum FunctionalTestResult + { + Passed, + Warning, + Error + } + + public enum GameAvatarType + { + R6, + R15, + PlayerChoice + } + + public enum GearGenreSetting + { + AllGenres, + MatchingGenreOnly + } + + public enum GearType + { + MeleeWeapons, + RangedWeapons, + Explosives, + PowerUps, + NavigationEnhancers, + MusicalInstruments, + SocialItems, + BuildingTools, + Transport + } + + public enum Genre + { + All, + TownAndCity, + Fantasy, + SciFi, + Ninja, + Scary, + Pirate, + Adventure, + Sports, + Funny, + WildWest, + War, + SkatePark, + Tutorial + } + + public enum GraphicsMode + { + Automatic, + Direct3D11, + Direct3D9, + OpenGL, + Metal, + Vulkan, + NoGraphics + } + + public enum HandlesStyle + { + Resize, + Movement + } + + public enum HorizontalAlignment + { + Center, + Left, + Right + } + + public enum HoverAnimateSpeed + { + VerySlow, + Slow, + Medium, + Fast, + VeryFast + } + + public enum HttpCachePolicy + { + None, + Full, + DataOnly, + Default, + InternalRedirectRefresh + } + + public enum HttpContentType + { + ApplicationJson, + ApplicationXml, + ApplicationUrlEncoded, + TextPlain, + TextXml + } + + public enum HttpError + { + OK, + InvalidUrl, + DnsResolve, + ConnectFail, + OutOfMemory, + TimedOut, + TooManyRedirects, + InvalidRedirect, + NetFail, + Aborted, + SslConnectFail, + Unknown + } + + public enum HttpRequestType + { + Default, + MarketplaceService = 2, + Players = 7, + Chat = 15, + Avatar, + Analytics = 22 + } + + public enum HumanoidDisplayDistanceType + { + Viewer, + Subject, + None + } + + public enum HumanoidHealthDisplayType + { + DisplayWhenDamaged, + AlwaysOn, + AlwaysOff + } + + public enum HumanoidRigType + { + R6, + R15 + } + + public enum HumanoidStateType + { + FallingDown, + Ragdoll, + GettingUp, + Jumping, + Swimming, + Freefall, + Flying, + Landed, + Running, + RunningNoPhysics = 10, + StrafingNoPhysics, + Climbing, + Seated, + PlatformStanding, + Dead, + Physics, + None = 18 + } + + public enum InOut + { + Edge, + Inset, + Center + } + + public enum InfoType + { + Asset, + Product, + GamePass + } + + public enum InitialDockState + { + Top, + Bottom, + Left, + Right, + Float + } + + public enum InputType + { + NoInput, + Constant = 12, + Sin + } + + public enum JointCreationMode + { + All, + Surface, + None + } + + public enum JointType + { + Weld, + Snap = 3, + Rotate = 7, + RotateP, + RotateV, + Glue, + None = 28 + } + + public enum KeyCode + { + Unknown, + Backspace = 8, + Tab, + Clear = 12, + Return, + Pause = 19, + Escape = 27, + Space = 32, + QuotedDouble = 34, + Hash, + Dollar, + Percent, + Ampersand, + Quote, + LeftParenthesis, + RightParenthesis, + Asterisk, + Plus, + Comma, + Minus, + Period, + Slash, + Zero, + One, + Two, + Three, + Four, + Five, + Six, + Seven, + Eight, + Nine, + Colon, + Semicolon, + LessThan, + Equals, + GreaterThan, + Question, + At, + LeftBracket = 91, + BackSlash, + RightBracket, + Caret, + Underscore, + Backquote, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + LeftCurly, + Pipe, + RightCurly, + Tilde, + Delete, + World0 = 160, + World1, + World2, + World3, + World4, + World5, + World6, + World7, + World8, + World9, + World10, + World11, + World12, + World13, + World14, + World15, + World16, + World17, + World18, + World19, + World20, + World21, + World22, + World23, + World24, + World25, + World26, + World27, + World28, + World29, + World30, + World31, + World32, + World33, + World34, + World35, + World36, + World37, + World38, + World39, + World40, + World41, + World42, + World43, + World44, + World45, + World46, + World47, + World48, + World49, + World50, + World51, + World52, + World53, + World54, + World55, + World56, + World57, + World58, + World59, + World60, + World61, + World62, + World63, + World64, + World65, + World66, + World67, + World68, + World69, + World70, + World71, + World72, + World73, + World74, + World75, + World76, + World77, + World78, + World79, + World80, + World81, + World82, + World83, + World84, + World85, + World86, + World87, + World88, + World89, + World90, + World91, + World92, + World93, + World94, + World95, + KeypadZero, + KeypadOne, + KeypadTwo, + KeypadThree, + KeypadFour, + KeypadFive, + KeypadSix, + KeypadSeven, + KeypadEight, + KeypadNine, + KeypadPeriod, + KeypadDivide, + KeypadMultiply, + KeypadMinus, + KeypadPlus, + KeypadEnter, + KeypadEquals, + Up, + Down, + Right, + Left, + Insert, + Home, + End, + PageUp, + PageDown, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + NumLock = 300, + CapsLock, + ScrollLock, + RightShift, + LeftShift, + RightControl, + LeftControl, + RightAlt, + LeftAlt, + RightMeta, + LeftMeta, + LeftSuper, + RightSuper, + Mode, + Compose, + Help, + Print, + SysReq, + Break, + Menu, + Power, + Euro, + Undo, + ButtonX = 1000, + ButtonY, + ButtonA, + ButtonB, + ButtonR1, + ButtonL1, + ButtonR2, + ButtonL2, + ButtonR3, + ButtonL3, + ButtonStart, + ButtonSelect, + DPadLeft, + DPadRight, + DPadUp, + DPadDown, + Thumbstick1, + Thumbstick2 + } + + public enum KeywordFilterType + { + Include, + Exclude + } + + public enum Language + { + Default + } + + public enum LeftRight + { + Left, + Center, + Right + } + + public enum LevelOfDetailSetting + { + Low, + Medium, + High + } + + public enum Limb + { + Head, + Torso, + LeftArm, + RightArm, + LeftLeg, + RightLeg, + Unknown + } + + public enum ListDisplayMode + { + Horizontal, + Vertical + } + + public enum ListenerType + { + Camera, + CFrame, + ObjectPosition, + ObjectCFrame + } + + public enum Material + { + Plastic = 256, + SmoothPlastic = 272, + Neon = 288, + Wood = 512, + WoodPlanks = 528, + Marble = 784, + Basalt = 788, + Slate = 800, + CrackedLava = 804, + Concrete = 816, + Limestone = 820, + Granite = 832, + Pavement = 836, + Brick = 848, + Pebble = 864, + Cobblestone = 880, + Rock = 896, + Sandstone = 912, + CorrodedMetal = 1040, + DiamondPlate = 1056, + Foil = 1072, + Metal = 1088, + Grass = 1280, + LeafyGrass = 1284, + Sand = 1296, + Fabric = 1312, + Snow = 1328, + Mud = 1344, + Ground = 1360, + Asphalt = 1376, + Salt = 1392, + Ice = 1536, + Glacier = 1552, + Glass = 1568, + Air = 1792, + Water = 2048 + } + + public enum MembershipType + { + None, + BuildersClub, + TurboBuildersClub, + OutrageousBuildersClub + } + + public enum MeshType + { + Head, + Torso, + Wedge, + Sphere, + Cylinder, + FileMesh, + Brick, + Prism, + Pyramid, + ParallelRamp, + RightAngleRamp, + CornerWedge + } + + public enum MessageType + { + MessageOutput, + MessageInfo, + MessageWarning, + MessageError + } + + public enum MouseBehavior + { + Default, + LockCenter, + LockCurrentPosition + } + + public enum MoveState + { + Stopped, + Coasting, + Pushing, + Stopping, + AirFree + } + + public enum NameOcclusion + { + NoOcclusion, + EnemyOcclusion, + OccludeAll + } + + public enum NetworkOwnership + { + Automatic, + Manual, + OnContact + } + + public enum NormalId + { + Right, + Top, + Back, + Left, + Bottom, + Front + } + + public enum OutputLayoutMode + { + Horizontal, + Vertical + } + + public enum OverrideMouseIconBehavior + { + None, + ForceShow, + ForceHide + } + + public enum PacketPriority + { + IMMEDIATE_PRIORITY, + HIGH_PRIORITY, + MEDIUM_PRIORITY, + LOW_PRIORITY + } + + public enum PartType + { + Ball, + Block, + Cylinder + } + + public enum PathStatus + { + Success, + ClosestNoPath, + ClosestOutOfRange, + FailStartNotEmpty, + FailFinishNotEmpty, + NoPath + } + + public enum PathWaypointAction + { + Walk, + Jump + } + + public enum PermissionLevelShown + { + Game, + RobloxGame, + RobloxScript, + Studio, + Roblox + } + + public enum Platform + { + Windows, + OSX, + IOS, + Android, + XBoxOne, + PS4, + PS3, + XBox360, + WiiU, + NX, + Ouya, + AndroidTV, + Chromecast, + Linux, + SteamOS, + WebOS, + DOS, + BeOS, + UWP, + None + } + + public enum PlaybackState + { + Begin, + Delayed, + Playing, + Paused, + Completed, + Cancelled + } + + public enum PlayerActions + { + CharacterForward, + CharacterBackward, + CharacterLeft, + CharacterRight, + CharacterJump + } + + public enum PlayerChatType + { + All, + Team, + Whisper + } + + public enum PoseEasingDirection + { + In, + Out, + InOut + } + + public enum PoseEasingStyle + { + Linear, + Constant, + Elastic, + Cubic, + Bounce + } + + public enum PrivilegeType + { + Banned, + Visitor = 10, + Member = 128, + Admin = 240, + Owner = 255 + } + + public enum ProductPurchaseDecision + { + NotProcessedYet, + PurchaseGranted + } + + public enum QualityLevel + { + Automatic, + Level01, + Level02, + Level03, + Level04, + Level05, + Level06, + Level07, + Level08, + Level09, + Level10, + Level11, + Level12, + Level13, + Level14, + Level15, + Level16, + Level17, + Level18, + Level19, + Level20, + Level21 + } + + public enum R15CollisionType + { + OuterBox, + InnerBox + } + + public enum RenderFidelity + { + Automatic, + Precise + } + + public enum RenderPriority + { + First, + Input = 100, + Camera = 200, + Character = 300, + Last = 2000 + } + + public enum RenderingTestComparisonMethod + { + psnr, + diff + } + + public enum ReverbType + { + NoReverb, + GenericReverb, + PaddedCell, + Room, + Bathroom, + LivingRoom, + StoneRoom, + Auditorium, + ConcertHall, + Cave, + Arena, + Hangar, + CarpettedHallway, + Hallway, + StoneCorridor, + Alley, + Forest, + City, + Mountains, + Quarry, + Plain, + ParkingLot, + SewerPipe, + UnderWater + } + + public enum RibbonTool + { + Select, + Scale, + Rotate, + Move, + Transform, + ColorPicker, + MaterialPicker, + Group, + Ungroup, + None + } + + public enum RollOffMode + { + Inverse, + Linear, + LinearSquare, + InverseTapered + } + + public enum RotationType + { + MovementRelative, + CameraRelative + } + + public enum RuntimeUndoBehavior + { + Aggregate, + Snapshot, + Hybrid + } + + public enum SaveFilter + { + SaveWorld, + SaveGame, + SaveAll + } + + public enum SavedQualitySetting + { + Automatic, + QualityLevel1, + QualityLevel2, + QualityLevel3, + QualityLevel4, + QualityLevel5, + QualityLevel6, + QualityLevel7, + QualityLevel8, + QualityLevel9, + QualityLevel10 + } + + public enum ScaleType + { + Stretch, + Slice, + Tile, + Fit, + Crop + } + + public enum ScreenOrientation + { + LandscapeLeft, + LandscapeRight, + LandscapeSensor, + Portrait, + Sensor + } + + public enum ScrollBarInset + { + None, + ScrollBar, + Always + } + + public enum ScrollingDirection + { + X, + Y, + XY = 4 + } + + public enum ServerAudioBehavior + { + Enabled, + Muted, + OnlineGame + } + + public enum SizeConstraint + { + RelativeXY, + RelativeXX, + RelativeYY + } + + public enum SortOrder + { + Name, + Custom, + LayoutOrder + } + + public enum SoundType + { + NoSound, + Boing, + Bomb, + Break, + Click, + Clock, + Slingshot, + Page, + Ping, + Snap, + Splat, + Step, + StepOn, + Swoosh, + Victory + } + + public enum SpecialKey + { + Insert, + Home, + End, + PageUp, + PageDown, + ChatHotkey + } + + public enum StartCorner + { + TopLeft, + TopRight, + BottomLeft, + BottomRight + } + + public enum Status + { + Poison, + Confusion + } + + public enum StudioStyleGuideColor + { + MainBackground, + Titlebar, + Dropdown, + Tooltip, + Notification, + ScrollBar, + ScrollBarBackground, + TabBar, + Tab, + RibbonTab, + RibbonTabTopBar, + Button, + MainButton, + RibbonButton, + ViewPortBackground, + InputFieldBackground, + Item, + TableItem, + CategoryItem, + GameSettingsTableItem, + GameSettingsTooltip, + EmulatorBar, + EmulatorDropDown, + ColorPickerFrame, + CurrentMarker, + Border, + Shadow, + Light, + Dark, + Mid, + MainText, + SubText, + TitlebarText, + BrightText, + DimmedText, + LinkText, + WarningText, + ErrorText, + InfoText, + SensitiveText, + ScriptSideWidget, + ScriptBackground, + ScriptText, + ScriptSelectionText, + ScriptSelectionBackground, + ScriptFindSelectionBackground, + ScriptMatchingWordSelectionBackground, + ScriptOperator, + ScriptNumber, + ScriptString, + ScriptComment, + ScriptPreprocessor, + ScriptKeyword, + ScriptBuiltInFunction, + ScriptWarning, + ScriptError, + DebuggerCurrentLine, + DebuggerErrorLine, + DiffFilePathText, + DiffTextHunkInfo, + DiffTextNoChange, + DiffTextAddition, + DiffTextDeletion, + DiffTextSeparatorBackground, + DiffTextNoChangeBackground, + DiffTextAdditionBackground, + DiffTextDeletionBackground, + DiffLineNum, + DiffLineNumSeparatorBackground, + DiffLineNumNoChangeBackground, + DiffLineNumAdditionBackground, + DiffLineNumDeletionBackground, + DiffFilePathBackground, + DiffFilePathBorder, + Separator, + ButtonBorder, + ButtonText, + InputFieldBorder, + CheckedFieldBackground, + CheckedFieldBorder, + CheckedFieldIndicator, + HeaderSection, + Midlight, + StatusBar + } + + public enum StudioStyleGuideModifier + { + Default, + Selected, + Pressed, + Disabled, + Hover + } + + public enum Style + { + AlternatingSupports, + BridgeStyleSupports, + NoSupports + } + + public enum SurfaceConstraint + { + None, + Hinge, + SteppingMotor, + Motor + } + + public enum SurfaceType + { + Smooth, + Glue, + Weld, + Studs, + Inlet, + Universal, + Hinge, + Motor, + SteppingMotor, + SmoothNoOutlines = 10 + } + + public enum SwipeDirection + { + Right, + Left, + Up, + Down, + None + } + + public enum TableMajorAxis + { + RowMajor, + ColumnMajor + } + + public enum Technology + { + Legacy, + Voxel + } + + public enum TeleportResult + { + Success, + Failure, + GameNotFound, + GameEnded, + GameFull, + Unauthorized, + Flooded, + IsTeleporting + } + + public enum TeleportState + { + RequestedFromServer, + Started, + WaitingForServer, + Failed, + InProgress + } + + public enum TeleportType + { + ToPlace, + ToInstance, + ToReservedServer + } + + public enum TextFilterContext + { + PublicChat, + PrivateChat + } + + public enum TextTruncate + { + None, + AtEnd + } + + public enum TextXAlignment + { + Left, + Right, + Center + } + + public enum TextYAlignment + { + Top, + Center, + Bottom + } + + public enum TextureMode + { + Stretch, + Wrap, + Static + } + + public enum TextureQueryType + { + NonHumanoid, + NonHumanoidOrphaned, + Humanoid, + HumanoidOrphaned + } + + public enum ThreadPoolConfig + { + Auto, + Threads1, + Threads2, + Threads3, + Threads4, + Threads8 = 8, + Threads16 = 16, + PerCore1 = 101, + PerCore2, + PerCore3, + PerCore4 + } + + public enum ThrottlingPriority + { + Default, + ElevatedOnServer, + Extreme + } + + public enum ThumbnailSize + { + Size48x48, + Size180x180, + Size420x420, + Size60x60, + Size100x100, + Size150x150, + Size352x352 + } + + public enum ThumbnailType + { + HeadShot, + AvatarBust, + AvatarThumbnail + } + + public enum TickCountSampleMethod + { + Fast, + Benchmark, + Precise + } + + public enum TopBottom + { + Top, + Center, + Bottom + } + + public enum TouchCameraMovementMode + { + Default, + Classic, + Follow, + Orbital + } + + public enum TouchMovementMode + { + Default, + Thumbstick, + DPad, + Thumbpad, + ClickToMove, + DynamicThumbstick + } + + public enum TweenStatus + { + Canceled, + Completed + } + + public enum UITheme + { + Light, + Dark + } + + public enum UiMessageType + { + UiMessageError, + UiMessageInfo + } + + public enum UploadSetting + { + Never, + Ask, + Always + } + + public enum UserCFrame + { + Head, + LeftHand, + RightHand + } + + public enum UserInputState + { + Begin, + Change, + End, + Cancel, + None + } + + public enum UserInputType + { + MouseButton1, + MouseButton2, + MouseButton3, + MouseWheel, + MouseMovement, + Touch = 7, + Keyboard, + Focus, + Accelerometer, + Gyro, + Gamepad1, + Gamepad2, + Gamepad3, + Gamepad4, + Gamepad5, + Gamepad6, + Gamepad7, + Gamepad8, + TextInput, + None + } + + public enum VRTouchpad + { + Left, + Right + } + + public enum VRTouchpadMode + { + Touch, + VirtualThumbstick, + ABXY + } + + public enum VerticalAlignment + { + Center, + Top, + Bottom + } + + public enum VerticalScrollBarPosition + { + Right, + Left + } + + public enum VibrationMotor + { + Large, + Small, + LeftTrigger, + RightTrigger, + LeftHand, + RightHand + } + + public enum VideoQualitySettings + { + LowResolution, + MediumResolution, + HighResolution + } + + public enum VirtualInputMode + { + None, + Recording, + Playing + } + + public enum WaterDirection + { + NegX, + X, + NegY, + Y, + NegZ, + Z + } + + public enum WaterForce + { + None, + Small, + Medium, + Strong, + Max + } + + public enum ZIndexBehavior + { + Global, + Sibling + } +} \ No newline at end of file diff --git a/Core/Instance.cs b/Core/Instance.cs new file mode 100644 index 0000000..bf33e3b --- /dev/null +++ b/Core/Instance.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace Roblox +{ + public class RobloxInstance + { + private List _children = new List(); + private RobloxInstance _parent; + + public string ClassName; + public List Properties = new List(); + + public bool IsAncestorOf(RobloxInstance other) + { + while (other != null) + { + if (other == this) + return true; + + other = other.Parent; + } + + return false; + } + + public bool IsDescendantOf(RobloxInstance other) + { + return other.IsAncestorOf(this); + } + + public RobloxInstance Parent + { + get { return _parent; } + set + { + if (IsAncestorOf(value)) + throw new Exception("Parent would result in circular reference."); + + if (Parent == this) + throw new Exception("Attempt to set parent to self"); + + if (_parent != null) + _parent._children.Remove(this); + + value._children.Add(this); + _parent = value; + } + } + + public ReadOnlyCollection Children + { + get { return _children.AsReadOnly(); } + } + + public object ReadProperty(string propertyName) + { + RobloxProperty property = Properties + .Where((prop) => prop.Name == propertyName) + .First(); + + return property.Value; + } + + public bool TryReadProperty(string propertyName, out T value) + { + try + { + object result = ReadProperty(propertyName); + value = (T)result; + + return true; + } + catch + { + value = default(T); + return false; + } + } + + public override string ToString() + { + var name = ""; + TryReadProperty("Name", out name); + + return '[' + ClassName + ']' + name; + } + } +} diff --git a/Core/Property.cs b/Core/Property.cs new file mode 100644 index 0000000..477f9ea --- /dev/null +++ b/Core/Property.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Roblox +{ + public enum PropertyType + { + Unknown, + String, + Bool, + Int, + Float, + Double, + UDim, + UDim2, + Ray, + Faces, + Axes, + BrickColor, + Color3, + Vector2, + Vector3, + Vector2int16, + CFrame, + Quaternion, + Enum, + Ref, + Vector3int16, + NumberSequence, + ColorSequence, + NumberRange, + Rect, + PhysicalProperties, + Color3uint8, + Int64 + } + + public class RobloxProperty + { + public string Name; + public PropertyType Type; + public object Value; + + public override string ToString() + { + Type PropertyType = typeof(PropertyType); + + string typeName = Enum.GetName(PropertyType, Type); + string valueLabel; + + if (Value != null) + valueLabel = Value.ToString(); + else + valueLabel = "?"; + + return string.Join(" ", typeName, Name, '=', valueLabel); + } + } +} diff --git a/Core/RobloxFile.cs b/Core/RobloxFile.cs new file mode 100644 index 0000000..60e0169 --- /dev/null +++ b/Core/RobloxFile.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Roblox +{ + public class RobloxFile + { + public List Trunk { get; private set; } + } +} diff --git a/DataTypes/Axes.cs b/DataTypes/Axes.cs new file mode 100644 index 0000000..6640e2e --- /dev/null +++ b/DataTypes/Axes.cs @@ -0,0 +1,13 @@ +using System; +using Roblox.Enums; + +namespace Roblox.DataTypes +{ + [Flags] + public enum Axes + { + X = 0 << Axis.X, + Y = 0 << Axis.Y, + Z = 0 << Axis.Z, + } +} diff --git a/DataTypes/BrickColor.cs b/DataTypes/BrickColor.cs new file mode 100644 index 0000000..d818f14 --- /dev/null +++ b/DataTypes/BrickColor.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Roblox.DataTypes.Utility; + +namespace Roblox.DataTypes +{ + public class BrickColor + { + public readonly int Number; + public readonly string Name; + public readonly Color3 Color; + + public float R => Color.R; + public float G => Color.G; + public float B => Color.B; + + public override string ToString() => Name; + + private static List ByPalette; + private static Dictionary ByNumber; + private static Dictionary ByName; + + private static Random RNG = new Random(); + + private const string DefaultName = "Medium stone grey"; + private const int DefaultNumber = 194; + + internal BrickColor(int number, int rgb, string name) + { + int r = (rgb / 65536) % 256; + int g = (rgb / 256) % 256; + int b = rgb % 256; + + Name = name; + Number = number; + + Color = Color3.fromRGB(r, g, b); + } + + static BrickColor() + { + ByName = BrickColors.ColorMap.ToDictionary(brickColor => brickColor.Name); + ByNumber = BrickColors.ColorMap.ToDictionary(brickColor => brickColor.Number); + ByPalette = BrickColors.PaletteMap.Select(number => ByNumber[number]).ToList(); + } + + public static BrickColor New(string name) + { + if (!ByName.ContainsKey(name)) + name = DefaultName; + + return ByName[name]; + } + + public static BrickColor New(int number) + { + if (!ByNumber.ContainsKey(number)) + number = DefaultNumber; + + return ByNumber[number]; + } + + public static BrickColor New(Color3 color) + { + return New(color.R, color.G, color.B); + } + + public static BrickColor New(float r = 0, float g = 0, float b = 0) + { + BrickColor bestMatch = New(-1); + float closest = float.MaxValue; + + foreach (BrickColor brickColor in BrickColors.ColorMap) + { + float dist = Math.Abs(brickColor.R - r) + + Math.Abs(brickColor.G - g) + + Math.Abs(brickColor.B - b); + + if (dist < closest) + { + // Return this BrickColor if its an exact match. + if (dist == 0.0f) + return brickColor; + + bestMatch = brickColor; + closest = dist; + } + } + + return bestMatch; + } + + public static BrickColor Random() + { + int index = RNG.Next(ByPalette.Count); + return ByPalette[index]; + } + + public static BrickColor Palette(int index) + { + if (index < 0 || index >= ByPalette.Count) + throw new Exception("Palette index was out of range."); + + return ByPalette[index]; + } + + public static BrickColor White() => New("White"); + public static BrickColor Gray() => New("Medium stone grey"); + public static BrickColor DarkGray() => New("Dark stone grey"); + public static BrickColor Black() => New("Black"); + public static BrickColor Red() => New("Bright red"); + public static BrickColor Yellow() => New("Bright yellow"); + public static BrickColor Green() => New("Dark green"); + public static BrickColor Blue() => New("Bright blue"); + } +} \ No newline at end of file diff --git a/DataTypes/CFrame.cs b/DataTypes/CFrame.cs new file mode 100644 index 0000000..ec1b2ba --- /dev/null +++ b/DataTypes/CFrame.cs @@ -0,0 +1,331 @@ +using System; +using Roblox.DataTypes.Utility; + +namespace Roblox.DataTypes +{ + public class CFrame + { + private float m11 = 1, m12 = 0, m13 = 0, m14 = 0; + private float m21 = 0, m22 = 1, m23 = 0, m24 = 0; + private float m31 = 0, m32 = 0, m33 = 1, m34 = 0; + private const float m41 = 0, m42 = 0, m43 = 0, m44 = 1; + + public float X => m14; + public float Y => m24; + public float Z => m34; + + public Vector3 Position => new Vector3(X, Y, Z); + + public Vector3 LookVector => new Vector3(-m13, -m23, -m33); + public Vector3 RightVector => new Vector3( m11, m21, m31); + public Vector3 UpVector => new Vector3( m12, m22, m32); + + public CFrame(Vector3 pos) + { + m14 = pos.X; + m24 = pos.Y; + m34 = pos.Z; + } + + public CFrame(Vector3 eye, Vector3 look) + { + Vector3 zAxis = (eye - look).Unit; + Vector3 xAxis = Vector3.Up.Cross(zAxis); + Vector3 yAxis = zAxis.Cross(xAxis); + + if (xAxis.Magnitude == 0) + { + if (zAxis.Y < 0) + { + xAxis = new Vector3(0, 0, -1); + yAxis = new Vector3(1, 0, 0); + zAxis = new Vector3(0, -1, 0); + } + else + { + xAxis = new Vector3(0, 0, 1); + yAxis = new Vector3(1, 0, 0); + zAxis = new Vector3(0, 1, 0); + } + } + + m11 = xAxis.X; m12 = yAxis.X; m13 = zAxis.X; m14 = eye.X; + m21 = xAxis.Y; m22 = yAxis.Y; m23 = zAxis.Y; m24 = eye.Y; + m31 = xAxis.Z; m32 = yAxis.Z; m33 = zAxis.Z; m34 = eye.Z; + } + + public CFrame(float nx = 0, float ny = 0, float nz = 0) + { + m14 = nx; + m24 = ny; + m34 = nz; + } + + public CFrame(float nx, float ny, float nz, float i, float j, float k, float w) + { + float ii = i * i; + float jj = j * j; + float kk = k * k; + + m14 = nx; + m24 = ny; + m34 = nz; + + m11 = 1 - 2 * jj - 2 * kk; + m12 = 2 * (i * j - k * w); + m13 = 2 * (i * k + j * w); + + m21 = 2 * (i * j + k * w); + m22 = 1 - 2 * ii - 2 * kk; + m23 = 2 * (j * k - i * w); + + m31 = 2 * (i * k - j * w); + m32 = 2 * (j * k + i * w); + m33 = 1 - 2 * ii - 2 * jj; + } + + public CFrame(float n14, float n24, float n34, float n11, float n12, float n13, float n21, float n22, float n23, float n31, float n32, float n33) + { + m14 = n14; m24 = n24; m34 = n34; + m11 = n11; m12 = n12; m13 = n13; + m21 = n21; m22 = n22; m23 = n23; + m31 = n31; m32 = n32; m33 = n33; + } + + public CFrame(params float[] comp) + { + if (comp.Length < 12) + throw new Exception("There should be 12 floats provided to construct CFrame with an array of floats"); + + m14 = comp[0]; m24 = comp[1]; m34 = comp[2]; + m11 = comp[3]; m12 = comp[4]; m13 = comp[5]; + m21 = comp[6]; m22 = comp[7]; m23 = comp[8]; + m31 = comp[9]; m32 = comp[10]; m33 = comp[11]; + } + + public static CFrame operator +(CFrame a, Vector3 b) + { + float[] ac = a.GetComponents(); + + float x = ac[0], y = ac[1], z = ac[2], + m11 = ac[3], m12 = ac[4], m13 = ac[5], + m21 = ac[6], m22 = ac[7], m23 = ac[8], + m31 = ac[9], m32 = ac[10], m33 = ac[11]; + + return new CFrame(x + b.X, y + b.Y, z + b.Z, m11, m12, m13, m21, m22, m23, m31, m32, m33); + } + + public static CFrame operator -(CFrame a, Vector3 b) + { + float[] ac = a.GetComponents(); + + float x = ac[0], y = ac[1], z = ac[2], + m11 = ac[3], m12 = ac[4], m13 = ac[5], + m21 = ac[6], m22 = ac[7], m23 = ac[8], + m31 = ac[9], m32 = ac[10], m33 = ac[11]; + + return new CFrame(x - b.X, y - b.Y, z - b.Z, m11, m12, m13, m21, m22, m23, m31, m32, m33); + } + + public static Vector3 operator *(CFrame a, Vector3 b) + { + float[] ac = a.GetComponents(); + float x = ac[0], y = ac[1], z = ac[2], + m11 = ac[3], m12 = ac[4], m13 = ac[5], + m21 = ac[6], m22 = ac[7], m23 = ac[8], + m31 = ac[9], m32 = ac[10], m33 = ac[11]; + + Vector3 right = new Vector3(m11, m21, m31); + Vector3 up = new Vector3(m12, m22, m32); + Vector3 back = new Vector3(m13, m23, m33); + return a.Position + b.X * right + b.Y * up + b.Z * back; + } + + public static CFrame operator *(CFrame a, CFrame b) + { + float[] ac = a.GetComponents(); + float[] bc = b.GetComponents(); + + float a14 = ac[0], a24 = ac[1], a34 = ac[2], + a11 = ac[3], a12 = ac[4], a13 = ac[5], + a21 = ac[6], a22 = ac[7], a23 = ac[8], + a31 = ac[9], a32 = ac[10], a33 = ac[11]; + + float b14 = bc[0], b24 = bc[1], b34 = bc[2], + b11 = bc[3], b12 = bc[4], b13 = bc[5], + b21 = bc[6], b22 = bc[7], b23 = bc[8], + b31 = bc[9], b32 = bc[10], b33 = bc[11]; + + float n11 = a11 * b11 + a12 * b21 + a13 * b31 + a14 * m41; + float n12 = a11 * b12 + a12 * b22 + a13 * b32 + a14 * m42; + float n13 = a11 * b13 + a12 * b23 + a13 * b33 + a14 * m43; + float n14 = a11 * b14 + a12 * b24 + a13 * b34 + a14 * m44; + + float n21 = a21 * b11 + a22 * b21 + a23 * b31 + a24 * m41; + float n22 = a21 * b12 + a22 * b22 + a23 * b32 + a24 * m42; + float n23 = a21 * b13 + a22 * b23 + a23 * b33 + a24 * m43; + float n24 = a21 * b14 + a22 * b24 + a23 * b34 + a24 * m44; + + float n31 = a31 * b11 + a32 * b21 + a33 * b31 + a34 * m41; + float n32 = a31 * b12 + a32 * b22 + a33 * b32 + a34 * m42; + float n33 = a31 * b13 + a32 * b23 + a33 * b33 + a34 * m43; + float n34 = a31 * b14 + a32 * b24 + a33 * b34 + a34 * m44; + + float n41 = 0 * b11 + m42 * b21 + m43 * b31 + m44 * m41; + float n42 = 0 * b12 + m42 * b22 + m43 * b32 + m44 * m42; + float n43 = 0 * b13 + m42 * b23 + m43 * b33 + m44 * m43; + float n44 = 0 * b14 + m42 * b24 + m43 * b34 + m44 * m44; + + return new CFrame(n14, n24, n34, n11, n12, n13, n21, n22, n23, n31, n32, n33); + } + + public override string ToString() + { + return string.Join(", ", GetComponents()); + } + + private static Vector3 VectorAxisAngle(Vector3 vec, Vector3 axis, float theta) + { + Vector3 unit = vec.Unit; + + float cosAng = (float)Math.Cos(theta); + float sinAng = (float)Math.Sin(theta); + + return axis * cosAng + axis.Dot(unit) * unit * + (1 - cosAng) + unit.Cross(axis) * sinAng; + } + + public CFrame Inverse() + { + float[] ac = GetComponents(); + + float a14 = ac[0], a24 = ac[1], a34 = ac[2], + a11 = ac[3], a12 = ac[4], a13 = ac[5], + a21 = ac[6], a22 = ac[7], a23 = ac[8], + a31 = ac[9], a32 = ac[10], a33 = ac[11]; + + float det = ( a11 * a22 * a33 * m44 + a11 * a23 * a34 * m42 + a11 * a24 * a32 * m43 + + a12 * a21 * a34 * m43 + a12 * a23 * a31 * m44 + a12 * a24 * a33 * m41 + + a13 * a21 * a32 * m44 + a13 * a22 * a34 * m41 + a13 * a24 * a31 * m42 + + a14 * a21 * a33 * m42 + a14 * a22 * a31 * m43 + a14 * a23 * a32 * m41 + - a11 * a22 * a34 * m43 - a11 * a23 * a32 * m44 - a11 * a24 * a33 * m42 + - a12 * a21 * a33 * m44 - a12 * a23 * a34 * m41 - a12 * a24 * a31 * m43 + - a13 * a21 * a34 * m42 - a13 * a22 * a31 * m44 - a13 * a24 * a32 * m41 + - a14 * a21 * a32 * m43 - a14 * a22 * a33 * m41 - a14 * a23 * a31 * m42 ); + + if (det == 0) + return this; + + float b11 = (a22 * a33 * m44 + a23 * a34 * m42 + a24 * a32 * m43 - a22 * a34 * m43 - a23 * a32 * m44 - a24 * a33 * m42) / det; + float b12 = (a12 * a34 * m43 + a13 * a32 * m44 + a14 * a33 * m42 - a12 * a33 * m44 - a13 * a34 * m42 - a14 * a32 * m43) / det; + float b13 = (a12 * a23 * m44 + a13 * a24 * m42 + a14 * a22 * m43 - a12 * a24 * m43 - a13 * a22 * m44 - a14 * a23 * m42) / det; + float b14 = (a12 * a24 * a33 + a13 * a22 * a34 + a14 * a23 * a32 - a12 * a23 * a34 - a13 * a24 * a32 - a14 * a22 * a33) / det; + + float b21 = (a21 * a34 * m43 + a23 * a31 * m44 + a24 * a33 * m41 - a21 * a33 * m44 - a23 * a34 * m41 - a24 * a31 * m43) / det; + float b22 = (a11 * a33 * m44 + a13 * a34 * m41 + a14 * a31 * m43 - a11 * a34 * m43 - a13 * a31 * m44 - a14 * a33 * m41) / det; + float b23 = (a11 * a24 * m43 + a13 * a21 * m44 + a14 * a23 * m41 - a11 * a23 * m44 - a13 * a24 * m41 - a14 * a21 * m43) / det; + float b24 = (a11 * a23 * a34 + a13 * a24 * a31 + a14 * a21 * a33 - a11 * a24 * a33 - a13 * a21 * a34 - a14 * a23 * a31) / det; + + float b31 = (a21 * a32 * m44 + a22 * a34 * m41 + a24 * a31 * m42 - a21 * a34 * m42 - a22 * a31 * m44 - a24 * a32 * m41) / det; + float b32 = (a11 * a34 * m42 + a12 * a31 * m44 + a14 * a32 * m41 - a11 * a32 * m44 - a12 * a34 * m41 - a14 * a31 * m42) / det; + float b33 = (a11 * a22 * m44 + a12 * a24 * m41 + a14 * a21 * m42 - a11 * a24 * m42 - a12 * a21 * m44 - a14 * a22 * m41) / det; + float b34 = (a11 * a24 * a32 + a12 * a21 * a34 + a14 * a22 * a31 - a11 * a22 * a34 - a12 * a24 * a31 - a14 * a21 * a32) / det; + + float b41 = (a21 * a33 * m42 + a22 * a31 * m43 + a23 * a32 * m41 - a21 * a32 * m43 - a22 * a33 * m41 - a23 * a31 * m42) / det; + float b42 = (a11 * a32 * m43 + a12 * a33 * m41 + a13 * a31 * m42 - a11 * a33 * m42 - a12 * a31 * m43 - a13 * a32 * m41) / det; + float b43 = (a11 * a23 * m42 + a12 * a21 * m43 + a13 * a22 * m41 - a11 * a22 * m43 - a12 * a23 * m41 - a13 * a21 * m42) / det; + float b44 = (a11 * a22 * a33 + a12 * a23 * a31 + a13 * a21 * a32 - a11 * a23 * a32 - a12 * a21 * a33 - a13 * a22 * a31) / det; + + return new CFrame(b14, b24, b34, b11, b12, b13, b21, b22, b23, b31, b32, b33); + } + + public static CFrame FromAxisAngle(Vector3 axis, float theta) + { + Vector3 r = VectorAxisAngle(axis, Vector3.Right, theta); + Vector3 u = VectorAxisAngle(axis, Vector3.Up, theta); + Vector3 b = VectorAxisAngle(axis, Vector3.Back, theta); + + return new CFrame(0, 0, 0, r.X, u.X, b.X, r.Y, u.Y, b.Y, r.Z, u.Z, b.Z); + } + + public static CFrame Angles(float x, float y, float z) + { + CFrame cfx = FromAxisAngle(Vector3.Right, x); + CFrame cfy = FromAxisAngle(Vector3.Up, y); + CFrame cfz = FromAxisAngle(Vector3.Back, z); + + return cfx * cfy * cfz; + } + + public static CFrame FromEulerAnglesXYZ(float x, float y, float z) + { + return Angles(x, y, z); + } + + public CFrame Lerp(CFrame other, float t) + { + if (t == 0.0f) + { + return this; + } + else if (t == 1.0f) + { + return other; + } + else + { + Quaternion q1 = new Quaternion(this); + Quaternion q2 = new Quaternion(other); + + CFrame rot = q1.Slerp(q2, t).ToCFrame(); + Vector3 pos = Position.Lerp(other.Position, t); + + return new CFrame(pos) * rot; + } + } + + public CFrame ToWorldSpace(CFrame cf2) + { + return this * cf2; + } + + public CFrame ToObjectSpace(CFrame other) + { + return Inverse() * other; + } + + public Vector3 PointToWorldSpace(Vector3 v) + { + return this * v; + } + + public Vector3 PointToObjectSpace(Vector3 v) + { + return Inverse() * v; + } + + public Vector3 VectorToWorldSpace(Vector3 v) + { + return (this - Position) * v; + } + + public Vector3 VectorToObjectSpace(Vector3 v) + { + return (this - Position).Inverse() * v; + } + + public float[] GetComponents() + { + return new float[] { m14, m24, m34, m11, m12, m13, m21, m22, m23, m31, m32, m33 }; + } + + public float[] toEulerAnglesXYZ() + { + float x = (float)Math.Atan2(-m23, m33); + float y = (float)Math.Asin(m13); + float z = (float)Math.Atan2(-m12, m11); + + return new float[] { x, y, z }; + } + } +} \ No newline at end of file diff --git a/DataTypes/Color3.cs b/DataTypes/Color3.cs new file mode 100644 index 0000000..43301a2 --- /dev/null +++ b/DataTypes/Color3.cs @@ -0,0 +1,91 @@ +using System; + +namespace Roblox.DataTypes +{ + public struct Color3 + { + public readonly float R, G, B; + + public Color3(float r = 0, float g = 0, float b = 0) + { + R = r; + G = g; + B = b; + } + + public override string ToString() + { + return string.Join(", ", R, G, B); + } + + public static Color3 fromRGB(int r = 0, int g = 0, int b = 0) + { + return new Color3(r / 255f, g / 255f, b / 255f); + } + + public static Color3 fromHSV(float h = 0, float s = 0, float v = 0) + { + int i = (int)Math.Min(5, Math.Floor(6.0 * h)); + float f = 6.0f * h - i; + + float m = v * (1.0f - (s)); + float n = v * (1.0f - (s * f)); + float k = v * (1.0f - (s * (1 - f))); + + switch (i) + { + case 0: + return new Color3(v, k, m); + case 1: + return new Color3(n, v, m); + case 2: + return new Color3(m, v, k); + case 3: + return new Color3(m, n, v); + case 4: + return new Color3(k, m, v); + case 5: + return new Color3(v, m, n); + default: + return new Color3(); + } + } + + public static float[] toHSV(Color3 color) + { + float val = Math.Max(Math.Max(color.R, color.G), color.B); + + if (Math.Abs(val) < 0.001f) + return new float[3] { 0, 0, 0 }; + + float hue = Math.Min(Math.Min(color.R, color.G), color.B); + float sat = (val - hue) / val; + + if (Math.Abs(sat) >= 0.001f) + { + Vector3 rgbN = val - new Vector3(color.R, color.G, color.B); + rgbN /= (val - hue); + + if (color.R == val) + hue = (color.G == hue) ? 5.0f + rgbN.Z : 1.0f - rgbN.Y; + else if (color.G == val) + hue = (color.B == hue) ? 1.0f + rgbN.X : 3.0f - rgbN.Z; + else + hue = (color.R == hue) ? 3.0f + rgbN.Y : 5.0f - rgbN.Z; + + hue /= 6.0f; + } + + return new float[3] { hue, sat, val }; + } + + public Color3 Lerp(Color3 other, float alpha) + { + float r = (R + (other.R - R) * alpha); + float g = (G + (other.G - G) * alpha); + float b = (B + (other.B - B) * alpha); + + return new Color3(r, g, b); + } + } +} diff --git a/DataTypes/ColorSequence.cs b/DataTypes/ColorSequence.cs new file mode 100644 index 0000000..543c76e --- /dev/null +++ b/DataTypes/ColorSequence.cs @@ -0,0 +1,52 @@ +using System; + +namespace Roblox.DataTypes +{ + public struct ColorSequence + { + public readonly ColorSequenceKeypoint[] Keypoints; + + public ColorSequence(Color3 c) + { + ColorSequenceKeypoint a = new ColorSequenceKeypoint(0, c); + ColorSequenceKeypoint b = new ColorSequenceKeypoint(1, c); + + Keypoints = new ColorSequenceKeypoint[2] { a, b }; + } + + public ColorSequence(Color3 c0, Color3 c1) + { + ColorSequenceKeypoint a = new ColorSequenceKeypoint(0, c0); + ColorSequenceKeypoint b = new ColorSequenceKeypoint(1, c1); + + Keypoints = new ColorSequenceKeypoint[2] { a, b }; + } + + public ColorSequence(ColorSequenceKeypoint[] keypoints) + { + int len = keypoints.Length; + + if (len < 2) + throw new Exception("ColorSequence: requires at least 2 keypoints"); + else if (len > 20) + throw new Exception("ColorSequence: table is too long."); + + for (int i = 1; i < len; i++) + if (keypoints[i-1].Time > keypoints[i].Time) + throw new Exception("ColorSequence: all keypoints must be ordered by time"); + + if (keypoints[0].Time < 0) + throw new Exception("ColorSequence must start at time=0.0"); + + if (keypoints[len-1].Time > 1) + throw new Exception("ColorSequence must end at time=1.0"); + + Keypoints = keypoints; + } + + public override string ToString() + { + return string.Join(" ", Keypoints); + } + } +} diff --git a/DataTypes/ColorSequenceKeypoint.cs b/DataTypes/ColorSequenceKeypoint.cs new file mode 100644 index 0000000..c807308 --- /dev/null +++ b/DataTypes/ColorSequenceKeypoint.cs @@ -0,0 +1,19 @@ +namespace Roblox.DataTypes +{ + public struct ColorSequenceKeypoint + { + public readonly float Time; + public readonly Color3 Color; + + public ColorSequenceKeypoint(float time, Color3 color) + { + Time = time; + Color = color; + } + + public override string ToString() + { + return string.Join(" ", Time, Color.R, Color.G, Color.B, 0); + } + } +} diff --git a/DataTypes/Faces.cs b/DataTypes/Faces.cs new file mode 100644 index 0000000..04ac9de --- /dev/null +++ b/DataTypes/Faces.cs @@ -0,0 +1,16 @@ +using System; +using Roblox.Enums; + +namespace Roblox.DataTypes +{ + [Flags] + public enum Faces + { + Right = 0 << NormalId.Right, + Top = 0 << NormalId.Top, + Back = 0 << NormalId.Back, + Left = 0 << NormalId.Left, + Bottom = 0 << NormalId.Bottom, + Front = 0 << NormalId.Front, + } +} diff --git a/DataTypes/NumberRange.cs b/DataTypes/NumberRange.cs new file mode 100644 index 0000000..49c7a39 --- /dev/null +++ b/DataTypes/NumberRange.cs @@ -0,0 +1,24 @@ +using System; + +namespace Roblox.DataTypes +{ + public struct NumberRange + { + public readonly float Min; + public readonly float Max; + + public NumberRange(float min, float max) + { + if (max - min < 0) + throw new Exception("NumberRange: invalid range"); + + Min = min; + Max = max; + } + + public override string ToString() + { + return string.Join(" ", Min, Max); + } + } +} diff --git a/DataTypes/NumberSequence.cs b/DataTypes/NumberSequence.cs new file mode 100644 index 0000000..442de8f --- /dev/null +++ b/DataTypes/NumberSequence.cs @@ -0,0 +1,52 @@ +using System; + +namespace Roblox.DataTypes +{ + public struct NumberSequence + { + public readonly NumberSequenceKeypoint[] Keypoints; + + public NumberSequence(float n) + { + NumberSequenceKeypoint a = new NumberSequenceKeypoint(0, n); + NumberSequenceKeypoint b = new NumberSequenceKeypoint(1, n); + + Keypoints = new NumberSequenceKeypoint[2] { a, b }; + } + + public NumberSequence(float n0, float n1) + { + NumberSequenceKeypoint a = new NumberSequenceKeypoint(0, n0); + NumberSequenceKeypoint b = new NumberSequenceKeypoint(1, n1); + + Keypoints = new NumberSequenceKeypoint[2] { a, b }; + } + + public NumberSequence(NumberSequenceKeypoint[] keypoints) + { + int len = keypoints.Length; + + if (len < 2) + throw new Exception("NumberSequence: requires at least 2 keypoints"); + else if (len > 20) + throw new Exception("NumberSequence: table is too long."); + + for (int i = 1; i < len; i++) + if (keypoints[i - 1].Time > keypoints[i].Time) + throw new Exception("NumberSequence: all keypoints must be ordered by time"); + + if (keypoints[0].Time < 0) + throw new Exception("NumberSequence must start at time=0.0"); + + if (keypoints[len - 1].Time > 1) + throw new Exception("NumberSequence must end at time=1.0"); + + Keypoints = keypoints; + } + + public override string ToString() + { + return string.Join(" ", Keypoints); + } + } +} diff --git a/DataTypes/NumberSequenceKeypoint.cs b/DataTypes/NumberSequenceKeypoint.cs new file mode 100644 index 0000000..f16ffa1 --- /dev/null +++ b/DataTypes/NumberSequenceKeypoint.cs @@ -0,0 +1,21 @@ +namespace Roblox.DataTypes +{ + public struct NumberSequenceKeypoint + { + public readonly float Time; + public readonly float Value; + public readonly float Envelope; + + public NumberSequenceKeypoint(float time, float value, float envelope = 0) + { + Time = time; + Value = value; + Envelope = envelope; + } + + public override string ToString() + { + return string.Join(" ", Time, Value, Envelope); + } + } +} diff --git a/DataTypes/PathWaypoint.cs b/DataTypes/PathWaypoint.cs new file mode 100644 index 0000000..934ebdf --- /dev/null +++ b/DataTypes/PathWaypoint.cs @@ -0,0 +1,29 @@ +using System; +using Roblox.Enums; + +namespace Roblox.DataTypes +{ + public struct PathWaypoint + { + public readonly Vector3 Position; + public readonly PathWaypointAction Action; + + public PathWaypoint(Vector3? position) + { + Position = position ?? Vector3.Zero; + Action = PathWaypointAction.Walk; + } + + public PathWaypoint(Vector3 position, PathWaypointAction action = PathWaypointAction.Walk) + { + Position = position; + Action = action; + } + + public override string ToString() + { + Type PathWaypointAction = typeof(PathWaypointAction); + return '{' + Position + "} " + Enum.GetName(PathWaypointAction, Action); + } + } +} diff --git a/DataTypes/PhysicalProperties.cs b/DataTypes/PhysicalProperties.cs new file mode 100644 index 0000000..294e1e0 --- /dev/null +++ b/DataTypes/PhysicalProperties.cs @@ -0,0 +1,50 @@ +using Roblox.Enums; +using Roblox.DataTypes.Utility; + +namespace Roblox.DataTypes +{ + public struct PhysicalProperties + { + public readonly float Density; + public readonly float Friction; + public readonly float Elasticity; + + public float FrictionWeight; + public float ElasticityWeight; + + public PhysicalProperties(Material material) + { + Density = MaterialInfo.DensityMap[material]; + Friction = MaterialInfo.FrictionMap[material]; + Elasticity = MaterialInfo.ElasticityMap[material]; + + FrictionWeight = 1; + ElasticityWeight = 1; + } + + public PhysicalProperties(float density, float friction, float elasticity) + { + Density = density; + Friction = friction; + Elasticity = elasticity; + + FrictionWeight = 1; + ElasticityWeight = 1; + } + + public PhysicalProperties(float density, float friction, float elasticity, float frictionWeight, float elasticityWeight) + { + Density = density; + Friction = friction; + Elasticity = elasticity; + + FrictionWeight = frictionWeight; + ElasticityWeight = elasticityWeight; + } + + public override string ToString() + { + return string.Join(", ", Density, Friction, Elasticity, FrictionWeight, ElasticityWeight); + } + } +} diff --git a/DataTypes/Ray.cs b/DataTypes/Ray.cs new file mode 100644 index 0000000..6e74309 --- /dev/null +++ b/DataTypes/Ray.cs @@ -0,0 +1,47 @@ +namespace Roblox.DataTypes +{ + public struct Ray + { + public readonly Vector3 Origin; + public readonly Vector3 Direction; + + public Ray Unit + { + get + { + Ray unit; + + if (Direction.Magnitude == 1.0f) + unit = this; + else + unit = new Ray(Origin, Direction.Unit); + + return unit; + } + } + + public Ray(Vector3 origin, Vector3 direction) + { + Origin = origin; + Direction = direction; + } + + public override string ToString() + { + return '{' + Origin + "}, {" + Direction + '}'; + } + + public Vector3 ClosestPoint(Vector3 point) + { + Vector3 offset = point - Origin; + float diff = offset.Dot(Direction) / Direction.Dot(Direction); + return Origin + (diff * Direction); + } + + public float Distance(Vector3 point) + { + Vector3 projected = ClosestPoint(point); + return (point - projected).Magnitude; + } + } +} diff --git a/DataTypes/Rect.cs b/DataTypes/Rect.cs new file mode 100644 index 0000000..382bf22 --- /dev/null +++ b/DataTypes/Rect.cs @@ -0,0 +1,28 @@ +namespace Roblox.DataTypes +{ + public struct Rect + { + public readonly Vector2 Min; + public readonly Vector2 Max; + + public float Width => (Max - Min).X; + public float Height => (Max - Min).Y; + + public Rect(Vector2? min, Vector2? max) + { + Min = min ?? Vector2.Zero; + Max = max ?? Vector2.Zero; + } + + public Rect(float minX, float minY, float maxX, float maxY) + { + Min = new Vector2(minX, minY); + Max = new Vector2(maxX, maxY); + } + + public override string ToString() + { + return string.Join(", ", Min, Max); + } + } +} diff --git a/DataTypes/Region3.cs b/DataTypes/Region3.cs new file mode 100644 index 0000000..32e2bbd --- /dev/null +++ b/DataTypes/Region3.cs @@ -0,0 +1,43 @@ +using System; + +namespace Roblox.DataTypes +{ + public struct Region3 + { + public readonly CFrame CFrame; + public readonly Vector3 Size; + + public Region3(Vector3 a, Vector3 b) + { + CFrame = new CFrame((a + b) / 2); + Size = b - a; + } + + public override string ToString() + { + return CFrame + "; " + Size; + } + + public Region3 ExpandToGrid(float resolution) + { + Vector3 min = (CFrame - (Size / 2)).Position / resolution; + Vector3 max = (CFrame + (Size / 2)).Position / resolution; + + Vector3 emin = new Vector3 + ( + (float)Math.Floor(min.X) * resolution, + (float)Math.Floor(min.Y) * resolution, + (float)Math.Floor(min.Z) * resolution + ); + + Vector3 emax = new Vector3 + ( + (float)Math.Floor(max.X) * resolution, + (float)Math.Floor(max.Y) * resolution, + (float)Math.Floor(max.Z) * resolution + ); + + return new Region3(emin, emax); + } + } +} diff --git a/DataTypes/Region3int16.cs b/DataTypes/Region3int16.cs new file mode 100644 index 0000000..e3eb36f --- /dev/null +++ b/DataTypes/Region3int16.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Roblox.DataTypes +{ + public struct Region3int16 + { + public readonly Vector3int16 Min, Max; + + public Region3int16(Vector3int16? min, Vector3int16? max) + { + Min = min ?? new Vector3int16(); + Max = max ?? new Vector3int16(); + } + + public override string ToString() + { + return string.Join("; ", Min, Max); + } + } +} diff --git a/DataTypes/UDim.cs b/DataTypes/UDim.cs new file mode 100644 index 0000000..8f64237 --- /dev/null +++ b/DataTypes/UDim.cs @@ -0,0 +1,29 @@ +namespace Roblox.DataTypes +{ + public struct UDim + { + public readonly float Scale; + public readonly int Offset; + + public UDim(float scale = 0, int offset = 0) + { + Scale = scale; + Offset = offset; + } + + public static UDim operator+(UDim a, UDim b) + { + return new UDim(a.Scale + b.Scale, a.Offset + b.Offset); + } + + public static UDim operator-(UDim a, UDim b) + { + return new UDim(a.Scale - b.Scale, a.Offset - b.Offset); + } + + public override string ToString() + { + return string.Join(", ", Scale, Offset); + } + } +} \ No newline at end of file diff --git a/DataTypes/UDim2.cs b/DataTypes/UDim2.cs new file mode 100644 index 0000000..2ed5f09 --- /dev/null +++ b/DataTypes/UDim2.cs @@ -0,0 +1,38 @@ +namespace Roblox.DataTypes +{ + public struct UDim2 + { + public readonly UDim X, Y; + + public UDim Width => X; + public UDim Height => Y; + + public UDim2(float scaleX, int offsetX, float scaleY, int offsetY) + { + X = new UDim(scaleX, offsetX); + Y = new UDim(scaleY, offsetY); + } + + public UDim2(UDim x, UDim y) + { + X = x; + Y = y; + } + + public override string ToString() + { + return '{' + X.ToString() + "},{" + Y.ToString() + '}'; + } + + public UDim2 Lerp(UDim2 other, float alpha) + { + float scaleX = X.Scale + ((other.X.Scale - X.Scale) * alpha); + int offsetX = X.Offset + (int)((other.X.Offset - X.Offset) * alpha); + + float scaleY = Y.Scale + ((other.Y.Scale - Y.Scale) * alpha); + int offsetY = Y.Offset + (int)((other.Y.Offset - Y.Offset) * alpha); + + return new UDim2(scaleX, offsetX, scaleY, offsetY); + } + } +} diff --git a/DataTypes/Utility/BrickColors.cs b/DataTypes/Utility/BrickColors.cs new file mode 100644 index 0000000..5e033c3 --- /dev/null +++ b/DataTypes/Utility/BrickColors.cs @@ -0,0 +1,251 @@ +using System.Collections.Generic; +using Roblox.DataTypes; + +namespace Roblox.DataTypes.Utility +{ + public static class BrickColors + { + /// + /// This represents Roblox's static palette of BrickColors. + /// Each int refers to the `Number` identifying a BrickColor. + /// It is used by the BrickColor.palette constructor, which + /// is in turn used by the BrickColor.random constructor. + /// + + public static readonly int[] PaletteMap = new int[128] + { + 141, 301, 107, 26, 1012, 303, 1011, 304, + 28, 1018, 302, 305, 306, 307, 308, 1021, + 309, 310, 1019, 135, 102, 23, 1010, 312, + 313, 37, 1022, 1020, 1027, 311, 315, 1023, + 1031, 316, 151, 317, 318, 319, 1024, 314, + 1013, 1006, 321, 322, 104, 1008, 119, 323, + 324, 325, 320, 11, 1026, 1016, 1032, 1015, + 327, 1005, 1009, 29, 328, 1028, 208, 45, + 329, 330, 331, 1004, 21, 332, 333, 24, + 334, 226, 1029, 335, 336, 342, 343, 338, + 1007, 339, 133, 106, 340, 341, 1001, 1, + 9, 1025, 337, 344, 345, 1014, 105, 346, + 347, 348, 349, 1030, 125, 101, 350, 192, + 351, 352, 353, 354, 1002, 5, 18, 217, + 355, 356, 153, 357, 358, 359, 360, 38, + 361, 362, 199, 194, 363, 364, 365, 1003, + }; + + /// + /// This contains a list of all available BrickColors on Roblox. + /// + + public static IReadOnlyCollection ColorMap = new List() + { + new BrickColor( 1, 0xF2F3F3, "White"), + new BrickColor( 2, 0xA1A5A2, "Grey"), + new BrickColor( 3, 0xF9E999, "Light yellow"), + new BrickColor( 5, 0xD7C59A, "Brick yellow"), + new BrickColor( 6, 0xC2DAB8, "Light green (Mint)"), + new BrickColor( 9, 0xE8BAC8, "Light reddish violet"), + new BrickColor( 11, 0x80BBDB, "Pastel Blue"), + new BrickColor( 12, 0xCB8442, "Light orange brown"), + new BrickColor( 18, 0xCC8E69, "Nougat"), + new BrickColor( 21, 0xC4281C, "Bright red"), + new BrickColor( 22, 0xC470A0, "Med. reddish violet"), + new BrickColor( 23, 0x0D69AC, "Bright blue"), + new BrickColor( 24, 0xF5CD30, "Bright yellow"), + new BrickColor( 25, 0x624732, "Earth orange"), + new BrickColor( 26, 0x1B2A35, "Black"), + new BrickColor( 27, 0x6D6E6C, "Dark grey"), + new BrickColor( 28, 0x287F47, "Dark green"), + new BrickColor( 29, 0xA1C48C, "Medium green"), + new BrickColor( 36, 0xF3CF9B, "Lig. Yellowich orange"), + new BrickColor( 37, 0x4B974B, "Bright green"), + new BrickColor( 38, 0xA05F35, "Dark orange"), + new BrickColor( 39, 0xC1CADE, "Light bluish violet"), + new BrickColor( 40, 0xECECEC, "Transparent"), + new BrickColor( 41, 0xCD544B, "Tr. Red"), + new BrickColor( 42, 0xC1DFF0, "Tr. Lg blue"), + new BrickColor( 43, 0x7BB6E8, "Tr. Blue"), + new BrickColor( 44, 0xF7F18D, "Tr. Yellow"), + new BrickColor( 45, 0xB4D2E4, "Light blue"), + new BrickColor( 47, 0xD9856C, "Tr. Flu. Reddish orange"), + new BrickColor( 48, 0x84B68D, "Tr. Green"), + new BrickColor( 49, 0xF8F184, "Tr. Flu. Green"), + new BrickColor( 50, 0xECE8DE, "Phosph. White"), + new BrickColor( 100, 0xEEC4B6, "Light red"), + new BrickColor( 101, 0xDA867A, "Medium red"), + new BrickColor( 102, 0x6E99CA, "Medium blue"), + new BrickColor( 103, 0xC7C1B7, "Light grey"), + new BrickColor( 104, 0x6B327C, "Bright violet"), + new BrickColor( 105, 0xE29B40, "Br. yellowish orange"), + new BrickColor( 106, 0xDA8541, "Bright orange"), + new BrickColor( 107, 0x008F9C, "Bright bluish green"), + new BrickColor( 108, 0x685C43, "Earth yellow"), + new BrickColor( 110, 0x435493, "Bright bluish violet"), + new BrickColor( 111, 0xBFB7B1, "Tr. Brown"), + new BrickColor( 112, 0x6874AC, "Medium bluish violet"), + new BrickColor( 113, 0xE5ADC8, "Tr. Medi. reddish violet"), + new BrickColor( 115, 0xC7D23C, "Med. yellowish green"), + new BrickColor( 116, 0x55A5AF, "Med. bluish green"), + new BrickColor( 118, 0xB7D7D5, "Light bluish green"), + new BrickColor( 119, 0xA4BD47, "Br. yellowish green"), + new BrickColor( 120, 0xD9E4A7, "Lig. yellowish green"), + new BrickColor( 121, 0xE7AC58, "Med. yellowish orange"), + new BrickColor( 123, 0xD36F4C, "Br. reddish orange"), + new BrickColor( 124, 0x923978, "Bright reddish violet"), + new BrickColor( 125, 0xEAB892, "Light orange"), + new BrickColor( 126, 0xA5A5CB, "Tr. Bright bluish violet"), + new BrickColor( 127, 0xDCBC81, "Gold"), + new BrickColor( 128, 0xAE7A59, "Dark nougat"), + new BrickColor( 131, 0x9CA3A8, "Silver"), + new BrickColor( 133, 0xD5733D, "Neon orange"), + new BrickColor( 134, 0xD8DD56, "Neon green"), + new BrickColor( 135, 0x74869D, "Sand blue"), + new BrickColor( 136, 0x877C90, "Sand violet"), + new BrickColor( 137, 0xE09864, "Medium orange"), + new BrickColor( 138, 0x958A73, "Sand yellow"), + new BrickColor( 140, 0x203A56, "Earth blue"), + new BrickColor( 141, 0x27462D, "Earth green"), + new BrickColor( 143, 0xCFE2F7, "Tr. Flu. Blue"), + new BrickColor( 145, 0x7988A1, "Sand blue metallic"), + new BrickColor( 146, 0x958EA3, "Sand violet metallic"), + new BrickColor( 147, 0x938767, "Sand yellow metallic"), + new BrickColor( 148, 0x575857, "Dark grey metallic"), + new BrickColor( 149, 0x161D32, "Black metallic"), + new BrickColor( 150, 0xABADAC, "Light grey metallic"), + new BrickColor( 151, 0x789082, "Sand green"), + new BrickColor( 153, 0x957977, "Sand red"), + new BrickColor( 154, 0x7B2E2F, "Dark red"), + new BrickColor( 157, 0xFFF67B, "Tr. Flu. Yellow"), + new BrickColor( 158, 0xE1A4C2, "Tr. Flu. Red"), + new BrickColor( 168, 0x756C62, "Gun metallic"), + new BrickColor( 176, 0x97695B, "Red flip/flop"), + new BrickColor( 178, 0xB48455, "Yellow flip/flop"), + new BrickColor( 179, 0x898788, "Silver flip/flop"), + new BrickColor( 180, 0xD7A94B, "Curry"), + new BrickColor( 190, 0xF9D62E, "Fire Yellow"), + new BrickColor( 191, 0xE8AB2D, "Flame yellowish orange"), + new BrickColor( 192, 0x694028, "Reddish brown"), + new BrickColor( 193, 0xCF6024, "Flame reddish orange"), + new BrickColor( 194, 0xA3A2A5, "Medium stone grey"), + new BrickColor( 195, 0x4667A4, "Royal blue"), + new BrickColor( 196, 0x23478B, "Dark Royal blue"), + new BrickColor( 198, 0x8E4285, "Bright reddish lilac"), + new BrickColor( 199, 0x635F62, "Dark stone grey"), + new BrickColor( 200, 0x828A5D, "Lemon metalic"), + new BrickColor( 208, 0xE5E4DF, "Light stone grey"), + new BrickColor( 209, 0xB08E44, "Dark Curry"), + new BrickColor( 210, 0x709578, "Faded green"), + new BrickColor( 211, 0x79B5B5, "Turquoise"), + new BrickColor( 212, 0x9FC3E9, "Light Royal blue"), + new BrickColor( 213, 0x6C81B7, "Medium Royal blue"), + new BrickColor( 216, 0x904C2A, "Rust"), + new BrickColor( 217, 0x7C5C46, "Brown"), + new BrickColor( 218, 0x96709F, "Reddish lilac"), + new BrickColor( 219, 0x6B629B, "Lilac"), + new BrickColor( 220, 0xA7A9CE, "Light lilac"), + new BrickColor( 221, 0xCD6298, "Bright purple"), + new BrickColor( 222, 0xE4ADC8, "Light purple"), + new BrickColor( 223, 0xDC9095, "Light pink"), + new BrickColor( 224, 0xF0D5A0, "Light brick yellow"), + new BrickColor( 225, 0xEBB87F, "Warm yellowish orange"), + new BrickColor( 226, 0xFDEA8D, "Cool yellow"), + new BrickColor( 232, 0x7DBBDD, "Dove blue"), + new BrickColor( 268, 0x342B75, "Medium lilac"), + new BrickColor( 301, 0x506D54, "Slime green"), + new BrickColor( 302, 0x5B5D69, "Smoky grey"), + new BrickColor( 303, 0x0010B0, "Dark blue"), + new BrickColor( 304, 0x2C651D, "Parsley green"), + new BrickColor( 305, 0x527CAE, "Steel blue"), + new BrickColor( 306, 0x335882, "Storm blue"), + new BrickColor( 307, 0x102ADC, "Lapis"), + new BrickColor( 308, 0x3D1585, "Dark indigo"), + new BrickColor( 309, 0x348E40, "Sea green"), + new BrickColor( 310, 0x5B9A4C, "Shamrock"), + new BrickColor( 311, 0x9FA1AC, "Fossil"), + new BrickColor( 312, 0x592259, "Mulberry"), + new BrickColor( 313, 0x1F801D, "Forest green"), + new BrickColor( 314, 0x9FADC0, "Cadet blue"), + new BrickColor( 315, 0x0989CF, "Electric blue"), + new BrickColor( 316, 0x7B007B, "Eggplant"), + new BrickColor( 317, 0x7C9C6B, "Moss"), + new BrickColor( 318, 0x8AAB85, "Artichoke"), + new BrickColor( 319, 0xB9C4B1, "Sage green"), + new BrickColor( 320, 0xCACBD1, "Ghost grey"), + new BrickColor( 321, 0xA75E9B, "Lilac"), + new BrickColor( 322, 0x7B2F7B, "Plum"), + new BrickColor( 323, 0x94BE81, "Olivine"), + new BrickColor( 324, 0xA8BD99, "Laurel green"), + new BrickColor( 325, 0xDFDFDE, "Quill grey"), + new BrickColor( 327, 0x970000, "Crimson"), + new BrickColor( 328, 0xB1E5A6, "Mint"), + new BrickColor( 329, 0x98C2DB, "Baby blue"), + new BrickColor( 330, 0xFF98DC, "Carnation pink"), + new BrickColor( 331, 0xFF5959, "Persimmon"), + new BrickColor( 332, 0x750000, "Maroon"), + new BrickColor( 333, 0xEFB838, "Gold"), + new BrickColor( 334, 0xF8D96D, "Daisy orange"), + new BrickColor( 335, 0xE7E7EC, "Pearl"), + new BrickColor( 336, 0xC7D4E4, "Fog"), + new BrickColor( 337, 0xFF9494, "Salmon"), + new BrickColor( 338, 0xBE6862, "Terra Cotta"), + new BrickColor( 339, 0x562424, "Cocoa"), + new BrickColor( 340, 0xF1E7C7, "Wheat"), + new BrickColor( 341, 0xFEF3BB, "Buttermilk"), + new BrickColor( 342, 0xE0B2D0, "Mauve"), + new BrickColor( 343, 0xD490BD, "Sunrise"), + new BrickColor( 344, 0x965555, "Tawny"), + new BrickColor( 345, 0x8F4C2A, "Rust"), + new BrickColor( 346, 0xD3BE96, "Cashmere"), + new BrickColor( 347, 0xE2DCBC, "Khaki"), + new BrickColor( 348, 0xEDEAEA, "Lily white"), + new BrickColor( 349, 0xE9DADA, "Seashell"), + new BrickColor( 350, 0x883E3E, "Burgundy"), + new BrickColor( 351, 0xBC9B5D, "Cork"), + new BrickColor( 352, 0xC7AC78, "Burlap"), + new BrickColor( 353, 0xCABFA3, "Beige"), + new BrickColor( 354, 0xBBB3B2, "Oyster"), + new BrickColor( 355, 0x6C584B, "Pine Cone"), + new BrickColor( 356, 0xA0844F, "Fawn brown"), + new BrickColor( 357, 0x958988, "Hurricane grey"), + new BrickColor( 358, 0xABA89E, "Cloudy grey"), + new BrickColor( 359, 0xAF9483, "Linen"), + new BrickColor( 360, 0x966766, "Copper"), + new BrickColor( 361, 0x564236, "Dirt brown"), + new BrickColor( 362, 0x7E683F, "Bronze"), + new BrickColor( 363, 0x69665C, "Flint"), + new BrickColor( 364, 0x5A4C42, "Dark taupe"), + new BrickColor( 365, 0x6A3909, "Burnt Sienna"), + new BrickColor(1001, 0xF8F8F8, "Institutional white"), + new BrickColor(1002, 0xCDCDCD, "Mid gray"), + new BrickColor(1003, 0x111111, "Really black"), + new BrickColor(1004, 0xFF0000, "Really red"), + new BrickColor(1005, 0xFFB000, "Deep orange"), + new BrickColor(1006, 0xB480FF, "Alder"), + new BrickColor(1007, 0xA34B4B, "Dusty Rose"), + new BrickColor(1008, 0xC1BE42, "Olive"), + new BrickColor(1009, 0xFFFF00, "New Yeller"), + new BrickColor(1010, 0x0000FF, "Really blue"), + new BrickColor(1011, 0x002060, "Navy blue"), + new BrickColor(1012, 0x2154B9, "Deep blue"), + new BrickColor(1013, 0x04AFEC, "Cyan"), + new BrickColor(1014, 0xAA5500, "CGA brown"), + new BrickColor(1015, 0xAA00AA, "Magenta"), + new BrickColor(1016, 0xFF66CC, "Pink"), + new BrickColor(1017, 0xFFAF00, "Deep orange"), + new BrickColor(1018, 0x12EED4, "Teal"), + new BrickColor(1019, 0x00FFFF, "Toothpaste"), + new BrickColor(1020, 0x00FF00, "Lime green"), + new BrickColor(1021, 0x3A7D15, "Camo"), + new BrickColor(1022, 0x7F8E64, "Grime"), + new BrickColor(1023, 0x8C5B9F, "Lavender"), + new BrickColor(1024, 0xAFDDFF, "Pastel light blue"), + new BrickColor(1025, 0xFFC9C9, "Pastel orange"), + new BrickColor(1026, 0xB1A7FF, "Pastel violet"), + new BrickColor(1027, 0x9FF3E9, "Pastel blue-green"), + new BrickColor(1028, 0xCCFFCC, "Pastel green"), + new BrickColor(1029, 0xFFFFCC, "Pastel yellow"), + new BrickColor(1030, 0xFFCC99, "Pastel brown"), + new BrickColor(1031, 0x6225D1, "Royal purple"), + new BrickColor(1032, 0xFF00BF, "Hot pink"), + }; + } +} \ No newline at end of file diff --git a/DataTypes/Utility/MaterialInfo.cs b/DataTypes/Utility/MaterialInfo.cs new file mode 100644 index 0000000..97d1512 --- /dev/null +++ b/DataTypes/Utility/MaterialInfo.cs @@ -0,0 +1,128 @@ +using System.Collections.Generic; +using Roblox.Enums; + +namespace Roblox.DataTypes.Utility +{ + public static class MaterialInfo + { + public static IReadOnlyDictionary DensityMap = new Dictionary() + { + {Material.Air, 0.01f}, + {Material.Asphalt, 2.36f}, + {Material.Basalt, 2.69f}, + {Material.Brick, 1.92f}, + {Material.Cobblestone, 2.69f}, + {Material.Concrete, 2.40f}, + {Material.CorrodedMetal, 7.85f}, + {Material.CrackedLava, 2.69f}, + {Material.DiamondPlate, 7.85f}, + {Material.Fabric, 0.70f}, + {Material.Foil, 2.70f}, + {Material.Glacier, 0.92f}, + {Material.Glass, 2.40f}, + {Material.Granite, 2.69f}, + {Material.Grass, 0.90f}, + {Material.Ground, 0.90f}, + {Material.Ice, 0.92f}, + {Material.LeafyGrass, 0.90f}, + {Material.Limestone, 2.69f}, + {Material.Marble, 2.56f}, + {Material.Metal, 7.85f}, + {Material.Mud, 0.90f}, + {Material.Neon, 0.70f}, + {Material.Pavement, 2.69f}, + {Material.Pebble, 2.40f}, + {Material.Plastic, 0.70f}, + {Material.Rock, 2.69f}, + {Material.Salt, 2.16f}, + {Material.Sand, 1.60f}, + {Material.Sandstone, 2.69f}, + {Material.Slate, 2.69f}, + {Material.SmoothPlastic, 0.70f}, + {Material.Snow, 0.90f}, + {Material.Water, 1.00f}, + {Material.Wood, 0.35f}, + {Material.WoodPlanks, 0.35f}, + }; + + public static IReadOnlyDictionary ElasticityMap = new Dictionary() + { + {Material.Air, 0.01f}, + {Material.Asphalt, 0.20f}, + {Material.Basalt, 0.15f}, + {Material.Brick, 0.15f}, + {Material.Cobblestone, 0.17f}, + {Material.Concrete, 0.20f}, + {Material.CorrodedMetal, 0.20f}, + {Material.CrackedLava, 0.15f}, + {Material.DiamondPlate, 0.25f}, + {Material.Fabric, 0.05f}, + {Material.Foil, 0.25f}, + {Material.Glacier, 0.15f}, + {Material.Glass, 0.20f}, + {Material.Granite, 0.20f}, + {Material.Grass, 0.10f}, + {Material.Ground, 0.10f}, + {Material.Ice, 0.15f}, + {Material.LeafyGrass, 0.10f}, + {Material.Limestone, 0.15f}, + {Material.Marble, 0.17f}, + {Material.Metal, 0.25f}, + {Material.Mud, 0.07f}, + {Material.Neon, 0.20f}, + {Material.Pavement, 0.17f}, + {Material.Pebble, 0.17f}, + {Material.Plastic, 0.50f}, + {Material.Rock, 0.17f}, + {Material.Salt, 0.05f}, + {Material.Sand, 0.05f}, + {Material.Sandstone, 0.15f}, + {Material.Slate, 0.20f}, + {Material.SmoothPlastic, 0.50f}, + {Material.Snow, 0.03f}, + {Material.Water, 0.01f}, + {Material.Wood, 0.20f}, + {Material.WoodPlanks, 0.20f}, + }; + + public static IReadOnlyDictionary FrictionMap = new Dictionary() + { + {Material.Air, 0.01f}, + {Material.Asphalt, 0.80f}, + {Material.Basalt, 0.70f}, + {Material.Brick, 0.80f}, + {Material.Cobblestone, 0.50f}, + {Material.Concrete, 0.70f}, + {Material.CorrodedMetal, 0.70f}, + {Material.CrackedLava, 0.65f}, + {Material.DiamondPlate, 0.35f}, + {Material.Fabric, 0.35f}, + {Material.Foil, 0.40f}, + {Material.Glacier, 0.05f}, + {Material.Glass, 0.25f}, + {Material.Granite, 0.40f}, + {Material.Grass, 0.40f}, + {Material.Ground, 0.45f}, + {Material.Ice, 0.02f}, + {Material.LeafyGrass, 0.40f}, + {Material.Limestone, 0.50f}, + {Material.Marble, 0.20f}, + {Material.Metal, 0.40f}, + {Material.Mud, 0.30f}, + {Material.Neon, 0.30f}, + {Material.Pavement, 0.50f}, + {Material.Pebble, 0.40f}, + {Material.Plastic, 0.30f}, + {Material.Rock, 0.50f}, + {Material.Salt, 0.50f}, + {Material.Sand, 0.50f}, + {Material.Sandstone, 0.50f}, + {Material.Slate, 0.40f}, + {Material.SmoothPlastic, 0.20f}, + {Material.Snow, 0.30f}, + {Material.Water, 0.00f}, + {Material.Wood, 0.48f}, + {Material.WoodPlanks, 0.48f}, + }; + } +} \ No newline at end of file diff --git a/DataTypes/Utility/Quaternion.cs b/DataTypes/Utility/Quaternion.cs new file mode 100644 index 0000000..a70e6e5 --- /dev/null +++ b/DataTypes/Utility/Quaternion.cs @@ -0,0 +1,207 @@ +using System; + +namespace Roblox.DataTypes.Utility +{ + public class Quaternion + { + public readonly float X; + public readonly float Y; + public readonly float Z; + public readonly float W; + + public float Magnitude + { + get + { + float squared = Dot(this); + double magnitude = Math.Sqrt(squared); + + return (float)magnitude; + } + } + + public Quaternion(float x, float y, float z, float w) + { + X = x; + Y = y; + Z = z; + W = w; + } + + public Quaternion(Vector3 qv, float qw) + { + X = qv.X; + Y = qv.Y; + Z = qv.Z; + W = qw; + } + + public Quaternion(CFrame cf) + { + CFrame matrix = (cf - cf.Position); + float[] ac = cf.GetComponents(); + + float m41 = ac[0], m42 = ac[1], m43 = ac[2], + m11 = ac[3], m12 = ac[4], m13 = ac[5], + m21 = ac[6], m22 = ac[7], m23 = ac[8], + m31 = ac[9], m32 = ac[10], m33 = ac[11]; + + float trace = m11 + m22 + m33; + + if (trace > 0) + { + float s = (float)Math.Sqrt(1 + trace); + float r = 0.5f / s; + + W = s * 0.5f; + X = (m32 - m23) * r; + Y = (m13 - m31) * r; + Z = (m21 - m12) * r; + } + else + { + float big = Math.Max(Math.Max(m11, m22), m33); + + if (big == m11) + { + float s = (float)Math.Sqrt(1 + m11 - m22 - m33); + float r = 0.5f / s; + + W = (m32 - m23) * r; + X = 0.5f * s; + Y = (m21 + m12) * r; + Z = (m13 + m31) * r; + } + else if (big == m22) + { + float s = (float)Math.Sqrt(1 - m11 + m22 - m33); + float r = 0.5f / s; + + W = (m13 - m31) * r; + X = (m21 + m12) * r; + Y = 0.5f * s; + Z = (m32 + m23) * r; + } + else if (big == m33) + { + float s = (float)Math.Sqrt(1 - m11 - m22 + m33); + float r = 0.5f / s; + + W = (m21 - m12) * r; + X = (m13 + m31) * r; + Y = (m32 + m23) * r; + Z = 0.5f * s; + } + } + } + + public float Dot(Quaternion other) + { + return (X * other.X) + (Y * other.Y) + (Z * other.Z) + (W * other.W); + } + + public Quaternion Lerp(Quaternion other, float alpha) + { + Quaternion result = this * (1.0f - alpha) + other * alpha; + return result / result.Magnitude; + } + + public Quaternion Slerp(Quaternion other, float alpha) + { + float cosAng = Dot(other); + + if (cosAng < 0) + { + other = -other; + cosAng = -cosAng; + } + + double ang = Math.Acos(cosAng); + + if (ang >= 0.05f) + { + float scale0 = (float)Math.Sin((1.0f - alpha) * ang); + float scale1 = (float)Math.Sin(alpha * ang); + float denom = (float)Math.Sin(ang); + + return ((this * scale0) + (other * scale1)) / denom; + } + else + { + return Lerp(other, alpha); + } + } + + public CFrame ToCFrame() + { + float xc = X * 2f; + float yc = Y * 2f; + float zc = Z * 2f; + + float xx = X * xc; + float xy = X * yc; + float xz = X * zc; + + float wx = W * xc; + float wy = W * yc; + float wz = W * zc; + + float yy = Y * yc; + float yz = Y * zc; + float zz = Z * zc; + + return new CFrame + ( + 0, 0, 0, + + 1f - (yy + zz), + xy - wz, + xz + wy, + + xy + wz, + 1f - (xx + zz), + yz - wx, + + xz - wy, + yz + wx, + 1f - (xx + yy) + ); + } + + public static Quaternion operator +(Quaternion a, Quaternion b) + { + return new Quaternion(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); + } + + public static Quaternion operator -(Quaternion a, Quaternion b) + { + return new Quaternion(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); + } + + public static Quaternion operator *(Quaternion a, float f) + { + return new Quaternion(a.X * f, a.Y * f, a.Z * f, a.W * f); + } + + public static Quaternion operator /(Quaternion a, float f) + { + return new Quaternion(a.X / f, a.Y / f, a.Z / f, a.W / f); + } + + public static Quaternion operator -(Quaternion a) + { + return new Quaternion(-a.X, -a.Y, -a.Z, -a.W); + } + + public static Quaternion operator *(Quaternion a, Quaternion b) + { + Vector3 v1 = new Vector3(a.X, a.Y, a.Z); + float s1 = a.W; + + Vector3 v2 = new Vector3(b.X, b.Y, b.Z); + float s2 = b.W; + + return new Quaternion(s1 * v2 + s2 * v1 + v1.Cross(v2), s1 * s2 - v1.Dot(v2)); + } + } +} diff --git a/DataTypes/Vector2.cs b/DataTypes/Vector2.cs new file mode 100644 index 0000000..3542e26 --- /dev/null +++ b/DataTypes/Vector2.cs @@ -0,0 +1,100 @@ +using System; + +namespace Roblox.DataTypes +{ + public struct Vector2 + { + public readonly float X, Y; + + public float Magnitude + { + get + { + float product = Dot(this); + double magnitude = Math.Sqrt(product); + + return (float)magnitude; + } + } + + public Vector2 Unit + { + get { return this / Magnitude; } + } + + public Vector2(float x = 0, float y = 0) + { + X = x; + Y = y; + } + + public Vector2(float[] coords) + { + X = coords.Length > 0 ? coords[0] : 0; + Y = coords.Length > 1 ? coords[1] : 0; + } + + private delegate Vector2 Operator(Vector2 a, Vector2 b); + + private static Vector2 upcastFloatOp(Vector2 vec, float num, Operator upcast) + { + Vector2 numVec = new Vector2(num, num); + return upcast(vec, numVec); + } + + private static Vector2 upcastFloatOp(float num, Vector2 vec, Operator upcast) + { + Vector2 numVec = new Vector2(num, num); + return upcast(numVec, vec); + } + + private static Operator add = new Operator((a, b) => new Vector2(a.X + b.X, a.Y + b.Y)); + private static Operator sub = new Operator((a, b) => new Vector2(a.X - b.X, a.Y - b.Y)); + private static Operator mul = new Operator((a, b) => new Vector2(a.X * b.X, a.Y * b.Y)); + private static Operator div = new Operator((a, b) => new Vector2(a.X / b.X, a.Y / b.Y)); + + public static Vector2 operator +(Vector2 a, Vector2 b) => add(a, b); + public static Vector2 operator +(Vector2 v, float n) => upcastFloatOp(v, n, add); + public static Vector2 operator +(float n, Vector2 v) => upcastFloatOp(n, v, add); + + public static Vector2 operator -(Vector2 a, Vector2 b) => sub(a, b); + public static Vector2 operator -(Vector2 v, float n) => upcastFloatOp(v, n, sub); + public static Vector2 operator -(float n, Vector2 v) => upcastFloatOp(n, v, sub); + + public static Vector2 operator *(Vector2 a, Vector2 b) => mul(a, b); + public static Vector2 operator *(Vector2 v, float n) => upcastFloatOp(v, n, mul); + public static Vector2 operator *(float n, Vector2 v) => upcastFloatOp(n, v, mul); + + public static Vector2 operator /(Vector2 a, Vector2 b) => div(a, b); + public static Vector2 operator /(Vector2 v, float n) => upcastFloatOp(v, n, div); + public static Vector2 operator /(float n, Vector2 v) => upcastFloatOp(n, v, div); + + public static Vector2 Zero => new Vector2(0, 0); + + public override string ToString() + { + return string.Join(", ", X, Y); + } + + public float Dot(Vector2 other) + { + float dotX = X * other.X; + float dotY = Y * other.Y; + + return dotX + dotY; + } + + public Vector2 Cross(Vector2 other) + { + float crossX = X * other.Y; + float crossY = Y * other.X; + + return new Vector2(crossX, crossY); + } + + public Vector2 Lerp(Vector2 other, float t) + { + return this + (other - this) * t; + } + } +} \ No newline at end of file diff --git a/DataTypes/Vector3.cs b/DataTypes/Vector3.cs new file mode 100644 index 0000000..fc83724 --- /dev/null +++ b/DataTypes/Vector3.cs @@ -0,0 +1,133 @@ +using System; +using Roblox.Enums; + +namespace Roblox.DataTypes +{ + public struct Vector3 + { + public readonly float X, Y, Z; + + public float Magnitude + { + get + { + float product = Dot(this); + double magnitude = Math.Sqrt(product); + + return (float)magnitude; + } + } + + public Vector3 Unit + { + get { return this / Magnitude; } + } + + public Vector3(float x = 0, float y = 0, float z = 0) + { + X = x; + Y = y; + Z = z; + } + + public Vector3(float[] coords) + { + X = coords.Length > 0 ? coords[0] : 0; + Y = coords.Length > 1 ? coords[1] : 0; + Z = coords.Length > 2 ? coords[2] : 0; + } + + public static Vector3 FromAxis(Axis axis) + { + float[] coords = new float[3] { 0f, 0f, 0f }; + + int index = (int)axis; + coords[index] = 1f; + + return new Vector3(coords); + } + + public static Vector3 FromNormalId(NormalId normalId) + { + float[] coords = new float[3] { 0f, 0f, 0f }; + + int index = (int)normalId; + coords[index % 3] = (index > 2 ? -1f : 1f); + + return new Vector3(coords); + } + + private delegate Vector3 Operator(Vector3 a, Vector3 b); + + private static Vector3 upcastFloatOp(Vector3 vec, float num, Operator upcast) + { + Vector3 numVec = new Vector3(num, num, num); + return upcast(vec, numVec); + } + + private static Vector3 upcastFloatOp(float num, Vector3 vec, Operator upcast) + { + Vector3 numVec = new Vector3(num, num, num); + return upcast(numVec, vec); + } + + private static Operator add = new Operator((a, b) => new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z)); + private static Operator sub = new Operator((a, b) => new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z)); + private static Operator mul = new Operator((a, b) => new Vector3(a.X * b.X, a.Y * b.Y, a.Z * b.Z)); + private static Operator div = new Operator((a, b) => new Vector3(a.X / b.X, a.Y / b.Y, a.Z / b.Z)); + + public static Vector3 operator +(Vector3 a, Vector3 b) => add(a, b); + public static Vector3 operator +(Vector3 v, float n) => upcastFloatOp(v, n, add); + public static Vector3 operator +(float n, Vector3 v) => upcastFloatOp(n, v, add); + + public static Vector3 operator -(Vector3 a, Vector3 b) => sub(a, b); + public static Vector3 operator -(Vector3 v, float n) => upcastFloatOp(v, n, sub); + public static Vector3 operator -(float n, Vector3 v) => upcastFloatOp(n, v, sub); + + public static Vector3 operator *(Vector3 a, Vector3 b) => mul(a, b); + public static Vector3 operator *(Vector3 v, float n) => upcastFloatOp(v, n, mul); + public static Vector3 operator *(float n, Vector3 v) => upcastFloatOp(n, v, mul); + + public static Vector3 operator /(Vector3 a, Vector3 b) => div(a, b); + public static Vector3 operator /(Vector3 v, float n) => upcastFloatOp(v, n, div); + public static Vector3 operator /(float n, Vector3 v) => upcastFloatOp(n, v, div); + + public static Vector3 Zero => new Vector3(0, 0, 0); + public static Vector3 Right => new Vector3(1, 0, 0); + public static Vector3 Up => new Vector3(0, 1, 0); + public static Vector3 Back => new Vector3(0, 0, 1); + + public override string ToString() + { + return string.Join(", ", X, Y, Z); + } + + public float Dot(Vector3 other) + { + float dotX = X * other.X; + float dotY = Y * other.Y; + float dotZ = Z * other.Z; + + return dotX + dotY + dotZ; + } + + public Vector3 Cross(Vector3 other) + { + float crossX = Y * other.Z - other.Y * Z; + float crossY = Z * other.X - other.Z * X; + float crossZ = X * other.Y - other.X * Y; + + return new Vector3(crossX, crossY, crossZ); + } + + public Vector3 Lerp(Vector3 other, float t) + { + return this + (other - this) * t; + } + + public bool isClose(Vector3 other, float epsilon = 0.0f) + { + return (other - this).Magnitude <= Math.Abs(epsilon); + } + } +} diff --git a/DataTypes/Vector3int16.cs b/DataTypes/Vector3int16.cs new file mode 100644 index 0000000..265bfbb --- /dev/null +++ b/DataTypes/Vector3int16.cs @@ -0,0 +1,69 @@ +using System; + +namespace Roblox.DataTypes +{ + public struct Vector3int16 + { + public readonly short X, Y, Z; + + public Vector3int16(short x = 0, short y = 0, short z = 0) + { + X = x; + Y = y; + Z = z; + } + + public Vector3int16(int x = 0, int y = 0, int z = 0) + { + X = (short)x; + Y = (short)y; + Z = (short)z; + } + + public override string ToString() + { + return string.Join(", ", X, Y, Z); + } + + private delegate Vector3int16 Operator(Vector3int16 a, Vector3int16 b); + + private static Vector3int16 upcastShortOp(Vector3int16 vec, short num, Operator upcast) + { + Vector3int16 numVec = new Vector3int16(num, num, num); + return upcast(vec, numVec); + } + + private static Vector3int16 upcastShortOp(short num, Vector3int16 vec, Operator upcast) + { + Vector3int16 numVec = new Vector3int16(num, num, num); + return upcast(numVec, vec); + } + + private static Operator add = new Operator((a, b) => new Vector3int16(a.X + b.X, a.Y + b.Y, a.Z + b.Z)); + private static Operator sub = new Operator((a, b) => new Vector3int16(a.X - b.X, a.Y - b.Y, a.Z - b.Z)); + private static Operator mul = new Operator((a, b) => new Vector3int16(a.X * b.X, a.Y * b.Y, a.Z * b.Z)); + private static Operator div = new Operator((a, b) => + { + if (b.X == 0 || b.Y == 0 || b.Z == 0) + throw new DivideByZeroException(); + + return new Vector3int16(a.X / b.X, a.Y / b.Y, a.Z / b.Z); + }); + + public static Vector3int16 operator +(Vector3int16 a, Vector3int16 b) => add(a, b); + public static Vector3int16 operator +(Vector3int16 v, short n) => upcastShortOp(v, n, add); + public static Vector3int16 operator +(short n, Vector3int16 v) => upcastShortOp(n, v, add); + + public static Vector3int16 operator -(Vector3int16 a, Vector3int16 b) => sub(a, b); + public static Vector3int16 operator -(Vector3int16 v, short n) => upcastShortOp(v, n, sub); + public static Vector3int16 operator -(short n, Vector3int16 v) => upcastShortOp(n, v, sub); + + public static Vector3int16 operator *(Vector3int16 a, Vector3int16 b) => mul(a, b); + public static Vector3int16 operator *(Vector3int16 v, short n) => upcastShortOp(v, n, mul); + public static Vector3int16 operator *(short n, Vector3int16 v) => upcastShortOp(n, v, mul); + + public static Vector3int16 operator /(Vector3int16 a, Vector3int16 b) => div(a, b); + public static Vector3int16 operator /(Vector3int16 v, short n) => upcastShortOp(v, n, div); + public static Vector3int16 operator /(short n, Vector3int16 v) => upcastShortOp(n, v, div); + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..72eb01e --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RobloxFileFormat")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RobloxFileFormat")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("cf50c0e2-23a7-4dc1-b4b2-e60cde716253")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// 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.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/RobloxFileFormat.csproj b/RobloxFileFormat.csproj new file mode 100644 index 0000000..022f22a --- /dev/null +++ b/RobloxFileFormat.csproj @@ -0,0 +1,99 @@ + + + + + Debug + AnyCPU + {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253} + WinExe + Properties + Roblox + RobloxFileFormat + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + packages\lz4net.1.0.15.93\lib\net4-client\LZ4.dll + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RobloxFileFormat.sln b/RobloxFileFormat.sln new file mode 100644 index 0000000..8c34de1 --- /dev/null +++ b/RobloxFileFormat.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobloxFileFormat", "RobloxFileFormat.csproj", "{CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..161ecfd --- /dev/null +++ b/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file