Exemplo n.º 1
0
        /// <summary>
        /// Creates the command buffer for single eye (left or right)
        /// </summary>
        private void createCommandBufferForSingleEye()
        {
            Camera eye = this.GetComponent <Camera>();

            //Setup orthographic view command buffer:
            float pScreenW, pScreenH;//physical screen width, height

            if (!PEUtils.GetPhysicalScreenSize(out pScreenW, out pScreenH))
            {
                throw new UnityException("Fail to get screen physical size");
            }
            //in case screen ori not correct
            if (pScreenH > pScreenW)
            {
                var t = pScreenH;
                pScreenH = pScreenW;
                pScreenW = t;
            }
//            Debug.LogFormat("Physical w/h: {0}/{1}", pScreenW, pScreenH);
            pScreenW /= 2;

            eye.orthographic = true;
            var phoneProfile = PhoneProfileContainer.GetCurrent();

            eye.orthographicSize = phoneProfile.OrthoRectSize;
            Matrix4x4 matrix_ortho_prj = eye.projectionMatrix;

            Matrix4x4 matrix_World2Cam = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, new Vector3(1, 1, -1));

            if (m_CmdBuffer_SingleEye != null)
            {
                eye.RemoveCommandBuffer(CameraEvent.AfterImageEffects, m_CmdBuffer_SingleEye);
            }
            m_CmdBuffer_SingleEye = new CommandBuffer();
            m_CmdBuffer_SingleEye.SetViewProjectionMatrices(matrix_World2Cam, matrix_ortho_prj);
            m_CmdBuffer_SingleEye.ClearRenderTarget(clearDepth: true, clearColor: false, backgroundColor: Color.black);
            var undistortionRender   = undistortionRoot.transform.GetChild(0).GetComponent <MeshRenderer>();
            var undistortionBGRender = undistortionRoot.transform.GetChild(1).GetComponent <MeshRenderer>();

            m_CmdBuffer_SingleEye.DrawRenderer(undistortionBGRender, undistortionBGRender.sharedMaterial);//order does matter
            m_CmdBuffer_SingleEye.DrawRenderer(undistortionRender, undistortionRender.sharedMaterial);
            eye.AddCommandBuffer(CameraEvent.AfterImageEffects, m_CmdBuffer_SingleEye);


            //Setup rendering camera properties:
            ReflectionLenProfile lenProfile = ReflectionLenProfileContainer.GetLenProfile();
            var hFov = lenProfile.hFov;
            var vFov = lenProfile.vFov;

            eye.SetCameraFov(hFov, vFov);

            #region Alignment

            var projectionMatrix = eye.projectionMatrix;
            projectionMatrix[1, 1] = 1.23646257F;
            projectionMatrix[1, 2] = -0.0777916671F;
            eye.projectionMatrix   = projectionMatrix;

            #endregion
        }
Exemplo n.º 2
0
        unsafe override public void FromRawData(byte[] rawData)
        {
            strings = new SortedList();
            strings.Add(0, String.Empty);
            if (rawData == null)
            {
                return;
            }

            int len = rawData.Length;

            dataLen = len;
            // the first entry in the string heap is always EmptyString
            if (len < 1 || rawData [0] != 0)
            {
                throw new BadMetaDataException("Invalid #Strings heap.");
            }

            int idx = 1;

            for (int i = 1; i < len; i++)
            {
                if (rawData [i] == 0)
                {
                    fixed(void *p = &rawData[idx])
                    {
                        string s = PEUtils.GetString((sbyte *)p, 0, i - idx, Encoding.UTF8);

                        strings.Add(idx, s);
                    }

                    idx = i + 1;
                }
            }
        }
 public void ShouldGenerateNthFibonacciNumber()
 {
     for (var i = 0; i < 20; i++)
     {
         Assert.AreEqual(First20ElementsOfFibonacciSequence()[i], PEUtils.nthFib(i));
     }
 }
Exemplo n.º 4
0
        private static unsafe bool ApplyUser32SetTimerPatch()
        {
            IntPtr original = PEUtils.GetExportedFunctionPointerForModule("USER32.dll", "SetTimer");

            MelonLogger.Msg($"User32::SetTimer original: 0x{(long)original:X}");

            if (original == IntPtr.Zero)
            {
                MelonLogger.Error("Failed to find USER32.dll::SetTimer");
                return(false);
            }

            // We get a native function pointer to User32SetTimerDetour from our current class
            //IntPtr detourPtr = typeof(Core).GetMethod("User32SetTimerDetour", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer();
            IntPtr detourPtr = Marshal.GetFunctionPointerForDelegate((User32SetTimerDelegate)User32SetTimerDetour);

            if (detourPtr == IntPtr.Zero)
            {
                MelonLogger.Error("Failed to find User32SetTimerDetour");
                return(false);
            }

            // And we patch SetTimer to replace it by our hook
            MelonLogger.Msg($"Applying USER32.dll::SetTimer Hook at 0x{original.ToInt64():X}");
            MelonUtils.NativeHookAttach((IntPtr)(&original), detourPtr);
            MelonLogger.Msg($"Creating delegate for original USER32.dll::SetTimer (0x{original.ToInt64():X})");
            user32SetTimerOriginal = (User32SetTimerDelegate)Marshal.GetDelegateForFunctionPointer(original, typeof(User32SetTimerDelegate));
            MelonLogger.Msg("Applied USER32.dll::SetTimer patch");

            return(true);
        }
Exemplo n.º 5
0
        public static void Main(string[] args)
        {
            try
            {
                if (args.Length != 3)
                {
                    Console.Error.WriteLine("Wrong parameter count specified!");
                    Console.Error.WriteLine("Usage: ResourcePatcher.exe <APPHOST.exe> <ASSEMBLY.dll> <IS_WINEXE: 0 or 1>");
                    return;
                }

                var fnTarget  = args[0];
                var fnOrig    = args[1];
                var winExeBit = args[2];
                if (!File.Exists(fnTarget) || !PEUtils.IsPEImage(fnTarget))
                {
                    Console.Error.WriteLine("Non-existant or invalid PE target file specified!");
                    return;
                }

                if (!File.Exists(fnOrig) || !PEUtils.IsPEImage(fnOrig))
                {
                    Console.Error.WriteLine("Non-existant or invalid PE source file specified!");
                    return;
                }

                if (winExeBit.Trim() == "1")
                {
                    Console.Write("Setting Windows GUI bit... ");
                    try
                    {
                        PEUtils.SetWindowsGraphicalUserInterfaceBit(fnTarget);
                        Console.WriteLine("Done!");
                    }
                    catch (AppHostNotCUIException)
                    {
                        Console.Write("Already has bit set!");
                    }
                }
                else
                {
                    Console.WriteLine("Skipped setting WinExe bit...");
                }

                Console.Write("Writing resources... ");
                using (var ru = new ResourceUpdater(fnTarget))
                {
                    ru.AddResourcesFromPEImage(fnOrig);
                    ru.Update();
                }

                Console.WriteLine("Done!");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Unhandles exception: " + ex.Message);
                Environment.Exit(1);
            }
        }
Exemplo n.º 6
0
        public override void PlanElementHandler(object sender, PlanElementEventArg e)
        {
            try
            {
                if (e.PlanElement.GetType() == typeof(Step))
                {
                    ProgramAttributes.PlanElementId = e.Program.Id;
                    var s = (Step)e.PlanElement;

                    if (e.Action.Completed)
                    {
                        if (s.Completed)
                        {
                            // see if responses have spawn elements
                            if (s.Responses != null)
                            {
                                SetCompletedStepResponses(e, s);
                            }

                            if (s.SpawnElement != null)
                            {
                                PEUtils.SpawnElementsInList(s.SpawnElement, e.Program, e.UserId, ProgramAttributes);
                                s.SpawnElement.ForEach(
                                    rse => { if (rse.ElementType > 100)
                                             {
                                                 HandlePlanElementActions(e, e.UserId, rse);
                                             }
                                    });
                            }
                        }
                        else
                        {
                            if (s.Responses != null)
                            {
                                s.Responses.ForEach(r => { r.Delete = true; });
                            }
                        }

                        // save program properties
                        PEUtils.SaveReportingAttributes(ProgramAttributes, e.DomainRequest);
                        // raise process event to register the id
                        OnProcessIdEvent(e.Program);
                    }
                }
                else if (Successor != null)
                {
                    Successor.PlanElementHandler(this, e);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("AD:StepPlanProcessor:PlanElementHandler()::" + ex.Message, ex.InnerException);
            }
        }
 public void ShouldGenerateFibbonacciSequence()
 {
     CollectionAssert.AreEqual(new List <int>()
     {
         1, 1, 2, 3, 5
     }, PEUtils.fibSeq.Take(5).ToList());
     CollectionAssert.AreEqual(new List <int>()
     {
         1, 1, 2, 3, 5
     }, PEUtils.firstNFibs(5).ToList());
     CollectionAssert.AreEqual(First20ElementsOfFibonacciSequence(), PEUtils.fibSeq.Take(20).ToList());
     CollectionAssert.AreEqual(First20ElementsOfFibonacciSequence(), PEUtils.firstNFibs(20).ToList());
 }
Exemplo n.º 8
0
    static void DrawCommands(PEPrefabScript prefabScript)
    {
        var e = GUI.enabled;

        GUI.enabled = true;
        if (GUILayout.Button("Menu", EditorStyles.miniButton))
        {
            var menu = new GenericMenu();
            PEUtils.BuildMenu(menu, prefabScript, PrefabUtility.GetPrefabParent(prefabScript.gameObject) == prefabScript.Prefab);
            menu.ShowAsContext();
        }
        GUI.enabled = e;
    }
Exemplo n.º 9
0
        public PostSaveActionResponse SaveActionResults(PostSaveActionRequest request)
        {
            try
            {
                // need to refactor this into a mediator.
                RelatedChanges.Clear();
                PostSaveActionResponse response = new PostSaveActionResponse();

                Program p      = EndPointUtils.RequestPatientProgramDetail(request);
                Actions action = request.Action;

                // set elementstates to in progress
                Module mod = PEUtils.FindElementById(p.Modules, action.ModuleId);

                // set to in progress
                if (mod.ElementState == (int)ElementState.NotStarted)  //!= 4
                {
                    mod.ElementState   = (int)ElementState.InProgress; //4;
                    mod.StateUpdatedOn = DateTime.UtcNow;
                }

                if (PEUtils.IsActionInitial(p))
                {
                    // set program to in progress
                    if (p.ElementState == (int)ElementState.NotStarted)
                    {
                        p.ElementState   = (int)ElementState.InProgress; //4;
                        p.StateUpdatedOn = System.DateTime.UtcNow;
                    }
                }

                NGUtils.UpdateProgramAction(action, p);

                AddUniquePlanElementToProcessedList(mod);

                // save
                EndPointUtils.SaveAction(request, action.Id, p, false);

                //response.Program = p;
                response.Saved          = true;
                response.RelatedChanges = RelatedChanges;
                response.PatientId      = request.PatientId;
                response.Version        = request.Version;

                return(response);
            }
            catch (Exception ex)
            {
                throw new Exception("AD:InterviewManager:ProcessActionResults()::" + ex.Message, ex.InnerException);
            }
        }
Exemplo n.º 10
0
        public override void PlanElementHandler(object sender, PlanElementEventArg e)
        {
            try
            {
                if (e.PlanElement.GetType() == typeof(Module))
                {
                    Module module = e.PlanElement as Module;
                    //PlanElementUtil.SetProgramInformation(_programAttributes, e.Program);
                    ProgramAttributes.PlanElementId = e.Program.Id;

                    if (module.Actions != null)
                    {
                        module.Completed = PEUtils.GetCompletionStatus(module.Actions);
                        if (module.Completed)
                        {
                            module.CompletedBy    = e.UserId;
                            module.StateUpdatedOn = DateTime.UtcNow;
                            module.ElementState   = (int)ElementState.Completed;
                            module.DateCompleted  = System.DateTime.UtcNow;

                            // look at spawnelement and trigger enabled state.
                            if (module.SpawnElement != null)
                            {
                                PEUtils.SpawnElementsInList(module.SpawnElement, e.Program, e.UserId, ProgramAttributes);
                                module.SpawnElement.ForEach(
                                    rse => { if (rse.ElementType > 100)
                                             {
                                                 HandlePlanElementActions(e, e.UserId, rse);
                                             }
                                    });
                            }

                            // save any program attribute changes
                            PEUtils.SaveReportingAttributes(ProgramAttributes, e.DomainRequest);
                            OnProcessIdEvent(module);
                        }
                    }
                }
                else if (Successor != null)
                {
                    Successor.PlanElementHandler(this, e);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("AD:ModulePlanProcessor:PlanElementHandler()::" + ex.Message, ex.InnerException);
            }
        }
Exemplo n.º 11
0
 public void HandlePlanElementActivation(PlanElementEventArg e, SpawnElement rse)
 {
     try
     {
         PlanElement pe = PEUtils.ActivatePlanElement(rse.ElementId, e.Program);
         if (pe != null)
         {
             OnProcessIdEvent(pe);
         }
     }
     catch (Exception ex)
     {
         throw new Exception("AD:StepPlanProcessor:HandlePlanElementActivation()::" + ex.Message,
                             ex.InnerException);
     }
 }
Exemplo n.º 12
0
        public PostRepeatActionResponse RepeatAction(PostRepeatActionRequest request)
        {
            try
            {
                RelatedChanges.Clear();
                ProcessedElements.Clear();
                var response = new PostRepeatActionResponse();
                response.PlanElems = new PlanElements();

                var p = EndPointUtils.RequestPatientProgramDetail(request);

                // get module reference
                Module mod = PEUtils.FindElementById(p.Modules, request.Action.ModuleId);
                IPlanElementStrategy strategy = new StatePlanElementStrategy(new SetModulePropertiesForRepeat(mod));

                // clone and insert new action
                var cAction = PEUtils.CloneRepeatAction(request.Action, mod.AssignToId);
                cAction.CompletedBy = "CM";
                AddUniquePlanElementToProcessedList(cAction);

                // insert action update
                var action = NGUtils.UpdateProgramAction(request.Action, p);
                AddUniquePlanElementToProcessedList(request.Action);

                // insert action into module and update references
                ReplaceActionReferenceInModule(request.Action.Id, cAction, mod);
                strategy.Evoke();
                AddUniquePlanElementToProcessedList(mod);

                // save
                var pdetail = EndPointUtils.SaveAction(request, cAction.Id, p, true);

                // create element changed lists
                PEUtils.HydratePlanElementLists(ProcessedElements, response.PlanElems);

                response.PlanElems.Attributes = PEUtils.GetAttributes(pdetail.Attributes);
                response.RelatedChanges       = RelatedChanges;
                response.PatientId            = request.PatientId;
                response.Version = request.Version;

                return(response);
            }
            catch (Exception ex)
            {
                throw new Exception("AD:InterviewManager:ProcessActionResults()::" + ex.Message, ex.InnerException);
            }
        }
Exemplo n.º 13
0
 public void HandleResponseSpawnElements(Step s, Response r, PlanElementEventArg e, string userId)
 {
     try
     {
         if (r.SpawnElement != null)
         {
             if (PEUtils.ResponseSpawnAllowed(s, r))
             {
                 r.SpawnElement.ForEach(rse => HandlePlanElementActions(e, userId, rse));
             }
         }
     }
     catch (Exception ex)
     {
         throw new Exception("AD:StepPlanProcessor:HandleResponseSpawnElements()::" + ex.Message, ex.InnerException);
     }
 }
Exemplo n.º 14
0
        public override void PlanElementHandler(object sender, PlanElementEventArg e)
        {
            try
            {
                if (e.PlanElement.GetType() == typeof(Actions))
                {
                    Actions action = e.PlanElement as Actions;
                    //PlanElementUtil.SetProgramInformation(_programAttributes, e.Program);
                    _programAttributes.PlanElementId = e.Program.Id;

                    if (action != null && action.Completed)
                    {
                        action.CompletedBy    = e.UserId;
                        action.ElementState   = (int)ElementState.Completed;
                        action.DateCompleted  = DateTime.UtcNow;
                        action.StateUpdatedOn = DateTime.UtcNow;
                        PeUtils.DisableCompleteButtonForAction(action.Steps);

                        //2) look at spawnelement and trigger enabled state.
                        if (action.SpawnElement != null)
                        {
                            PEUtils.SpawnElementsInList(action.SpawnElement, e.Program, e.UserId, _programAttributes);
                            action.SpawnElement.ForEach(
                                rse => { if (rse.ElementType > 100)
                                         {
                                             HandlePlanElementActions(e, e.UserId, rse);
                                         }
                                });
                        }

                        // save any program attribute changes
                        PeUtils.SaveReportingAttributes(_programAttributes, e.DomainRequest);
                        OnProcessIdEvent(action);
                    }
                }
                else if (Successor != null)
                {
                    Successor.PlanElementHandler(this, e);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("AD:ActionPlanProcessor:PlanElementHandler()::" + ex.Message, ex.InnerException);
            }
        }
Exemplo n.º 15
0
        public void CreateApphostShellShim(FilePath entryPoint, FilePath shimPath)
        {
            string appHostSourcePath;

            if (OperatingSystem.IsWindows())
            {
                appHostSourcePath = Path.Combine(_appHostSourceDirectory, ApphostNameWithoutExtension + ".exe");
            }
            else
            {
                appHostSourcePath = Path.Combine(_appHostSourceDirectory, ApphostNameWithoutExtension);
            }

            var    appHostDestinationFilePath = Path.GetFullPath(shimPath.Value);
            string entryPointFullPath         = Path.GetFullPath(entryPoint.Value);
            var    appBinaryFilePath          = Path.GetRelativePath(Path.GetDirectoryName(appHostDestinationFilePath), entryPointFullPath);


            if (ResourceUpdater.IsSupportedOS())
            {
                var windowsGraphicalUserInterfaceBit = PEUtils.GetWindowsGraphicalUserInterfaceBit(entryPointFullPath);
                HostWriter.CreateAppHost(appHostSourceFilePath: appHostSourcePath,
                                         appHostDestinationFilePath: appHostDestinationFilePath,
                                         appBinaryFilePath: appBinaryFilePath,
                                         windowsGraphicalUserInterface: (windowsGraphicalUserInterfaceBit == WindowsGUISubsystem),
                                         assemblyToCopyResorcesFrom: entryPointFullPath);
            }
            else
            {
                // by passing null to assemblyToCopyResorcesFrom, it will skip copying resources,
                // which is only supported on Windows
                HostWriter.CreateAppHost(appHostSourceFilePath: appHostSourcePath,
                                         appHostDestinationFilePath: appHostDestinationFilePath,
                                         appBinaryFilePath: appBinaryFilePath,
                                         windowsGraphicalUserInterface: false,
                                         assemblyToCopyResorcesFrom: null,
                                         enableMacOSCodeSign: OperatingSystem.IsMacOS());
            }

            _filePermissionSetter.SetUserExecutionPermission(appHostDestinationFilePath);
        }
Exemplo n.º 16
0
        public void HandlePlanElementActions(PlanElementEventArg e, string userId, SpawnElement rse)
        {
            // handles the response spawnelements
            if (rse.ElementType < 10)
            {
                HandlePlanElementActivation(e, rse);
            }
            else if (rse.ElementType > 100)
            {
                //HandlePatientProblemRegistration(e, userId, rse);
                var type = ElementActivationStrategy.Run(e, rse, userId, ProgramAttributes);

                if (!string.IsNullOrEmpty(type.ToString()))
                {
                    OnSpawnElementEvent(type);
                }
            }
            else
            {
                PEUtils.SetProgramAttributes(rse, e.Program, e.UserId, ProgramAttributes);
            }
        }
Exemplo n.º 17
0
        public void WhenCallWithWpfDllItCanCreateShimWithWindowsGraphicalUserInterfaceBitSet()
        {
            string shimPath = CreateApphostAndReturnShimPath();

            PEUtils.GetWindowsGraphicalUserInterfaceBit(shimPath).Should().Be(WindowsGUISubsystem);
        }
Exemplo n.º 18
0
        public PostProcessActionResponse ProcessActionResults(PostProcessActionRequest request)
        {
            try
            {
                // need to refactor this into a mediator.
                RelatedChanges.Clear();
                ProcessedElements.Clear();
                PostProcessActionResponse response = new PostProcessActionResponse();
                response.PlanElems = new PlanElements();

                Program p = EndPointUtils.RequestPatientProgramDetail(request);

                Actions action = request.Action;

                if (action.Completed)
                {
                    // 1) pre-process
                    // set program starting date
                    if (IsInitialAction.IsSatisfiedBy(p))
                    {
                        p.AttrStartDate = DateTime.UtcNow;
                        //PlanElementUtil.SetStartDateForProgramAttributes(request.ProgramId, request);
                    }

                    // get module reference
                    Module mod = PEUtils.FindElementById(p.Modules, action.ModuleId);

                    // set module to in progress
                    if (mod.ElementState == (int)ElementState.NotStarted)  //!= 4
                    {
                        mod.ElementState   = (int)ElementState.InProgress; //4;
                        mod.StateUpdatedOn = DateTime.UtcNow;
                    }

                    // 2) set in progress state
                    //new ResponseSpawnAllowed<Step>().IsSatisfiedBy(s)
                    if (PEUtils.IsActionInitial(p))
                    //if (new IsActionInitialSpecification<Program>().IsSatisfiedBy(p))
                    {
                        // set program to in progress
                        if (p.ElementState == (int)ElementState.NotStarted)
                        {
                            p.ElementState   = (int)ElementState.InProgress; //4;
                            p.StateUpdatedOn = DateTime.UtcNow;
                        }
                    }

                    // 3) set action state to completed
                    action.ElementState   = (int)ElementState.Completed;
                    action.StateUpdatedOn = DateTime.UtcNow;

                    // 4) insert action update
                    var act = NGUtils.UpdateProgramAction(action, p);

                    //// create a responsibility chain to process each elemnt in the hierachy
                    ProgramPlanProcessor pChain = InitializeProgramChain();

                    // 5)  process steps
                    action.Steps.ForEach(
                        s =>
                        pChain.ProcessWorkflow((IPlanElement)s, p, request.UserId, request.PatientId, action,
                                               request));

                    // 6) process action
                    pChain.ProcessWorkflow((IPlanElement)action, p, request.UserId, request.PatientId, action, request);

                    // 7) process module
                    if (mod != null)
                    {
                        // set enabled status for action dependencies
                        PEUtils.SetEnabledStatusByPrevious(mod.Actions, mod.AssignToId, mod.Enabled);
                        // set enable/visibility of actions after action processing.
                        pChain.ProcessWorkflow((IPlanElement)mod, p, request.UserId, request.PatientId, action, request);
                        AddUniquePlanElementToProcessedList(mod);
                    }

                    // post processing //
                    // 8) set module visibility for modules
                    PEUtils.SetEnabledStatusByPrevious(p.Modules, p.AssignToId, p.Enabled);

                    // 9) evaluate program status
                    if (PEUtils.IsProgramCompleted(p, request.UserId))
                    {
                        p.Completed = true;
                        pChain.ProcessWorkflow((IPlanElement)p, p, request.UserId, request.PatientId, action, request);
                    }

                    // 10) register changed action
                    AddUniquePlanElementToProcessedList(action);
                }
                else
                {
                    // need to update this on the p level.
                    action.ElementState = (int)ElementState.InProgress; //4; // in progress
                }

                AddUniquePlanElementToProcessedList(p);

                // save
                var pdetail = EndPointUtils.SaveAction(request, action.Id, p, false);

                // create element changed lists
                PEUtils.HydratePlanElementLists(ProcessedElements, response.PlanElems);

                response.PlanElems.Attributes = PEUtils.GetAttributes(pdetail.Attributes);
                response.RelatedChanges       = RelatedChanges;
                response.PatientId            = request.PatientId;
                response.Version = request.Version;

                return(response);
            }
            catch (Exception ex)
            {
                throw new Exception("AD:InterviewManager:ProcessActionResults()::" + ex.Message, ex.InnerException);
            }
        }
Exemplo n.º 19
0
 public bool IsNativeBinary(string filePath)
 {
     return(IsLinux ? ElfUtils.IsElfImage(filePath) : IsOSX?MachOUtils.IsMachOImage(filePath) : PEUtils.IsPEImage(filePath));
 }
Exemplo n.º 20
0
        unsafe public void Read(BinaryReader reader)
        {
            filePos = reader.BaseStream.Position;

            sig = reader.ReadUInt32();
            if (sig != Sig)
            {
                throw new BadImageException("Invalid MetaData Signature.");
            }

            majVer   = reader.ReadInt16();
            minVer   = reader.ReadInt16();
            reserved = reader.ReadUInt32();

            // Length of version string.
            len = reader.ReadInt32();

            // Read version string.
            if (len != 0)
            {
                sbyte *pVer = stackalloc sbyte [len];
                sbyte *p    = pVer;

                long pos = reader.BaseStream.Position;
                int  i;
                for (i = len; --i >= 0;)
                {
                    sbyte c = reader.ReadSByte();
                    if (c == 0)
                    {
                        break;
                    }
                    *p++ = c;
                }

                verStr = PEUtils.GetString(pVer, 0, len - i - 1, Encoding.UTF8);

                // Round up to dword boundary, relative to header start.
                pos += len;
                pos -= filePos;
                pos += 3;
                pos &= ~3;
                pos += filePos;

                // Advance file pointer.
                reader.BaseStream.Position = pos;
            }
            else
            {
                VersionString = String.Empty;
            }

            flags    = reader.ReadInt16();
            nStreams = reader.ReadInt16();
            streams  = new Hashtable(nStreams);

            // load all streams into memory
            for (int i = nStreams; --i >= 0;)
            {
                MDStream s = new MDStream(this);
                s.Read(reader);
                // TODO: check for duplicated streams,
                // use Add instead of indexer.
                streams[s.Name] = s;
            }

            MDStream tabs = Streams["#~"] as MDStream;

            // Try uncompressed stream.
            if (tabs == null)
            {
                tabs = Streams["#-"] as MDStream;
            }
            if (tabs == null)
            {
                throw new BadMetaDataException("Missing #~ stream.");
            }

            TablesHeap tabsHeap = tabs.Heap as TablesHeap;

            // cache index sizes
            strIdx  = tabsHeap.StringsIndexSize;
            guidIdx = tabsHeap.GUIDIndexSize;
            blobIdx = tabsHeap.BlobIndexSize;
        }
    PETreeNode Add(GameObject go, PETreeNode parent, bool includeChildren = true)
    {
        var isExpanded = expandedDict[go];

        var node = new PETreeNode(isExpanded)
        {
            content = new GUIContent(go.name, PEResources.icon), UserData = go
        };

        parent.children.Add(node);
        node.OnExpandChanged += expanded => expandedDict[go] = expanded;

        var pi = go.GetComponent <PEPrefabScript>();

        if (pi)
        {
            var isRoot = PEUtils.FindRootPrefab(pi.gameObject) == pi.Prefab ||
                         PrefabUtility.GetPrefabParent(pi.gameObject) == pi.Prefab;
            if (isRoot)
            {
                node.color         = Color.green;
                node.content.text += " (Root)";
            }
            else
            {
                node.color         = Color.yellow;
                node.content.text += " (Nested)";
            }
        }
        if (prefabScript.Modifications.TransformParentChanges.Any(npo => npo.child == go.transform))
        {
            node.color         = Color.cyan;
            node.content.text += " (Parent Changed)";
        }
        else
        if (prefabScript.Modifications.NonPrefabObjects.Any(c => c.child == go.transform))
        {
            node.color         = Color.yellow;
            node.content.text += " (New)";
        }

        if (!includeChildren)
        {
            return(node);
        }

        foreach (var property in GetProperties(go))
        {
            Add(property, node);
        }

        foreach (Component component in go.GetComponents <Component>())
        {
            Add(component, node);
        }

        foreach (Transform transform in go.transform)
        {
            var nd = Add(transform.gameObject, node);
            if (nd.children.Count == 0 && nd.color == Color.white)
            {
                node.children.Remove(nd);
            }
        }

        foreach (var obj in GetRemovedObjects(go, prefabScript))
        {
            PETreeNode nd        = null;
            var        component = obj as Component;
            if (component != null)
            {
                nd = Add(component, node, false);
            }
            else
            {
                var gameObject = obj as GameObject;
                if (gameObject != null)
                {
                    nd = Add(gameObject, node, false);
                }
            }

            if (nd != null)
            {
                nd.color         = Color.red;
                nd.content.text += " (Removed)";
            }
        }

        return(node);
    }