public static void AssociateOpcodes() { instructions[0] = new NOP(); instructions[1] = new PRNT(); instructions[16] = new PUSH(); instructions[17] = new POP(); instructions[18] = new SAVE(); instructions[19] = new CPY(); instructions[20] = new RNDM(); instructions[21] = new EMPTY(); instructions[128] = new ADD(); instructions[129] = new SUB(); instructions[130] = new MUL(); instructions[131] = new DIV(); instructions[132] = new SUB2(); instructions[133] = new DIV2(); instructions[134] = new NEG(); instructions[135] = new ABS(); instructions[144] = new INC(); instructions[145] = new DEC(); instructions[64] = new JMP(); instructions[65] = new JGZ(); instructions[66] = new JLZ(); instructions[67] = new JEZ(); instructions[68] = new JNZ(); instructions[69] = new CALL(); instructions[70] = new RET(); instructions[71] = new LDLOC(); instructions[72] = new STLOC(); instructions[73] = new LDARG(); instructions[74] = new STARG(); instructions[0b10100100] = new CMP();
protected override void ReadFile(byte[] contents) { using (MemoryStream file = new MemoryStream(contents)) using (BinaryRobloxFileReader reader = new BinaryRobloxFileReader(this, file)) { // Verify the signature of the file. byte[] binSignature = reader.ReadBytes(14); string signature = Encoding.UTF7.GetString(binSignature); if (signature != MagicHeader) { throw new InvalidDataException("Provided file's signature does not match BinaryRobloxFile.MagicHeader!"); } // Read header data. Version = reader.ReadUInt16(); NumClasses = reader.ReadUInt32(); NumInstances = reader.ReadUInt32(); Reserved = reader.ReadInt64(); // Begin reading the file chunks. bool reading = true; Classes = new INST[NumClasses]; Instances = new Instance[NumInstances]; while (reading) { try { var chunk = new BinaryRobloxFileChunk(reader); IBinaryFileChunk handler = null; switch (chunk.ChunkType) { case "INST": handler = new INST(); break; case "PROP": handler = new PROP(); break; case "PRNT": handler = new PRNT(); break; case "META": handler = new META(); break; case "SSTR": handler = new SSTR(); break; case "SIGN": handler = new SIGN(); break; case "END\0": ChunksImpl.Add(chunk); reading = false; break; case string unhandled: Console.Error.WriteLine("BinaryRobloxFile - Unhandled chunk-type: {0}!", unhandled); break; default: break; } if (handler != null) { using (var readBuffer = new MemoryStream(chunk.Data)) { using (var dataReader = new BinaryRobloxFileReader(this, readBuffer)) { chunk.Handler = handler; handler.Load(dataReader); } } ChunksImpl.Add(chunk); } } catch (EndOfStreamException) { throw new Exception("Unexpected end of file!"); } } } }
public override void Save(Stream stream) { ////////////////////////////////////////////////////////////////////////// // Generate the chunk data. ////////////////////////////////////////////////////////////////////////// using (var workBuffer = new MemoryStream()) using (var writer = new BinaryRobloxFileWriter(this, workBuffer)) { // Clear the existing data. Referent = "-1"; ChunksImpl.Clear(); NumInstances = 0; NumClasses = 0; SSTR = null; // Recursively capture all instances and classes. writer.RecordInstances(Children); // Apply the recorded instances and classes. writer.ApplyClassMap(); // Write the INST chunks. foreach (INST inst in Classes) { writer.SaveChunk(inst); } // Write the PROP chunks. foreach (INST inst in Classes) { var props = PROP.CollectProperties(writer, inst); foreach (string propName in props.Keys) { PROP prop = props[propName]; writer.SaveChunk(prop); } } // Write the PRNT chunk. var parents = new PRNT(); writer.SaveChunk(parents); // Write the SSTR chunk. if (HasSharedStrings) { writer.SaveChunk(SSTR, 0); } // Write the META chunk. if (HasMetadata) { writer.SaveChunk(META, 0); } // Write the SIGN chunk. if (HasSignatures) { writer.SaveChunk(SIGN); } // Write the END chunk. writer.WriteChunk("END", "</roblox>"); } ////////////////////////////////////////////////////////////////////////// // Write the chunk buffers with the header data ////////////////////////////////////////////////////////////////////////// using (BinaryWriter writer = new BinaryWriter(stream)) { stream.Position = 0; stream.SetLength(0); writer.Write(MagicHeader .Select(ch => (byte)ch) .ToArray()); writer.Write(Version); writer.Write(NumClasses); writer.Write(NumInstances); writer.Write(Reserved); foreach (BinaryRobloxFileChunk chunk in Chunks) { if (chunk.HasWriteBuffer) { byte[] writeBuffer = chunk.WriteBuffer; writer.Write(writeBuffer); } } } }