public static void RegisterServer(SocketContext socketContext)
        {
            socketContext.AddPacketHandler<DownloadFileQuery>(
                async (packet) =>
                {
                    var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read);
                    var data = new byte[stream.Length];
                    await stream.ReadAsync(data, 0, data.Length);
                    stream.Close();
                    socketContext.Send(new DownloadFileAnswer { StreamId = packet.StreamId, Data = data });
                });

            socketContext.AddPacketHandler<UploadFilePacket>(
                async (packet) =>
                {
                    var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write);
                    await stream.WriteAsync(packet.Data, 0, packet.Data.Length);
                    stream.Close();
                });

            socketContext.AddPacketHandler<FileExistsQuery>(
                async (packet) =>
                    {
                        var fileExists = await VirtualFileSystem.FileExistsAsync(packet.Url);
                        socketContext.Send(new FileExistsAnswer { StreamId = packet.StreamId, FileExists = fileExists });
                    });
        }
Ejemplo n.º 2
0
        public static void RegisterServer(SocketContext socketContext)
        {
            socketContext.AddPacketHandler <DownloadFileQuery>(
                async(packet) =>
            {
                var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read);
                var data   = new byte[stream.Length];
                await stream.ReadAsync(data, 0, data.Length);
                stream.Close();
                socketContext.Send(new DownloadFileAnswer {
                    StreamId = packet.StreamId, Data = data
                });
            });

            socketContext.AddPacketHandler <UploadFilePacket>(
                async(packet) =>
            {
                var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write);
                await stream.WriteAsync(packet.Data, 0, packet.Data.Length);
                stream.Close();
            });

            socketContext.AddPacketHandler <FileExistsQuery>(
                async(packet) =>
            {
                var fileExists = await VirtualFileSystem.FileExistsAsync(packet.Url);
                socketContext.Send(new FileExistsAnswer {
                    StreamId = packet.StreamId, FileExists = fileExists
                });
            });
        }
Ejemplo n.º 3
0
 protected override void Dispose(bool disposing)
 {
     socketContext.Send(new UploadFilePacket {
         Url = url, Data = memoryStream.ToArray()
     });
     base.Dispose(disposing);
 }
Ejemplo n.º 4
0
        public async Task ProcessLoginResult(string id, string pass, int session)
        {
            m_AccountInfo            = new AccountInfo();
            m_AccountInfo.Characters = new List <Tuple <int, int> >();
            m_AccountInfo.StrUserID  = id;
            m_AccountInfo.Password   = pass;

            using (var reader = await Globals.ShardDB.ExecuteReaderAsync("exec _CertifyUser '{0}', '{1}', {2}", id, Utility.MD5Hash(pass, true), session))
            {
                await reader.ReadAsync();

                int type = await reader.GetFieldValueAsync <int>(0);

                if (type == 0)
                {
                    m_AccountInfo.SID = await reader.GetFieldValueAsync <int>(1);

                    m_AccountInfo.Auth = (AuthType)await reader.GetFieldValueAsync <byte>(2);

                    Packet resp = new Packet(SCommon.Opcode.Agent.Response.CONNECTION);
                    resp.WriteByte(1);
                    m_SocketContext.Send(resp);
                }
                else
                {
                    Disconnect();
                }
            }
        }
Ejemplo n.º 5
0
        private async void ShaderCompilerRequestHandler(SocketContext clientSocketContext, EffectLogStore recordedEffectCompile, EffectCompiler effectCompiler, ShaderCompilerRequest shaderCompilerRequest)
        {
            // Wait for a client to be connected
            await clientConnectedTCS.Task;

            // Yield so that this socket can continue its message loop to answer to shader file request.
            await Task.Yield();

            Console.WriteLine("Compiling shader");

            // A shader has been requested, compile it (asynchronously)!
            var precompiledEffectShaderPass = await effectCompiler.Compile(shaderCompilerRequest.MixinTree, null).AwaitResult();

            // Record compilation to asset file (only if parent)
            recordedEffectCompile[new EffectCompileRequest(shaderCompilerRequest.MixinTree.Name, shaderCompilerRequest.MixinTree.UsedParameters)] = true;

            // Send compiled shader
            clientSocketContext.Send(new ShaderCompilerAnswer {
                StreamId = shaderCompilerRequest.StreamId, EffectBytecode = precompiledEffectShaderPass.Bytecode
            });
        }
Ejemplo n.º 6
0
        public async static Task ProcessClient(EngineContext engineContext, SocketContext socketContext, SocketContext socketContextAsync)
        {
            socketContext.AddPacketHandler <DownloadFileQuery>(
                async(packet) =>
            {
                var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read);
                var data   = new byte[stream.Length];
                await stream.ReadAsync(data, 0, data.Length);
                stream.Close();
                socketContext.Send(new DownloadFileAnswer {
                    StreamId = packet.StreamId, Data = data
                });
            });

            socketContext.AddPacketHandler <UploadFilePacket>(
                async(packet) =>
            {
                var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write);
                await stream.WriteAsync(packet.Data, 0, packet.Data.Length);
                stream.Close();
            });

            var viewModelGlobalContext = new ViewModelGlobalContext();

            selectedEntitiesContext = new ViewModelContext(viewModelGlobalContext);
            selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EntityComponentEnumerator(engineContext));
            selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginEnumerator());
            selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            //selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EffectPropertyEnumerator(engineContext));

            var renderPassHierarchyContext = new ViewModelContext(viewModelGlobalContext);

            renderPassHierarchyContext.ChildrenPropertyEnumerators.Add(new RenderPassHierarchyEnumerator());
            renderPassHierarchyContext.Root = new ViewModelNode("Root", engineContext.RenderContext.RootRenderPass).GenerateChildren(renderPassHierarchyContext);

            var renderPassPluginsContext = new ViewModelContext(viewModelGlobalContext);

            renderPassPluginsContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginsEnumerator {
                SelectedRenderPassPluginContext = selectedEntitiesContext
            });
            renderPassPluginsContext.Root = new ViewModelNode("Root", new EnumerableViewModelContent <ViewModelReference>(
                                                                  () => engineContext.RenderContext.RenderPassPlugins.Select(x => new ViewModelReference(x, true))));


            var entityHierarchyEnumerator = new EntityHierarchyEnumerator(engineContext.EntityManager, selectedEntitiesContext);
            var entityHierarchyContext    = new ViewModelContext(viewModelGlobalContext);

            entityHierarchyContext.ChildrenPropertyEnumerators.Add(entityHierarchyEnumerator);
            entityHierarchyContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            entityHierarchyContext.Root = new ViewModelNode("EntityHierarchyRoot", new EnumerableViewModelContent <ViewModelReference>(
                                                                () => engineContext.EntityManager.Entities
                                                                .Where(x =>
            {
                var transformationComponent = x.Transformation;
                return(transformationComponent == null || transformationComponent.Parent == null);
            })
                                                                .Select(x => new ViewModelReference(x, true))));

            entityHierarchyEnumerator.SelectedEntities.CollectionChanged += (sender, args) =>
            {
                SelectEntity(entityHierarchyEnumerator.SelectedEntities);
            };
            //entityHierarchyContext.Root.Children.Add(new ViewModelNode("SelectedItems", EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, ViewModelReference>(new NullViewModelContent(),
            //    (x) => { return new[] { new ViewModelReference(pickingSystem.SelectedEntity) }; })));

            /*(value) =>
             *  {
             *      var entityModelView = value != null ? entityHierarchyContext.GetModelView(value.Guid) : null;
             *      var entity = entityModelView != null ? (Entity)entityModelView.NodeValue : null;
             *      SelectEntity(entity);
             *  })));*/
            entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropEntity", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) =>
            {
                var dropParameters = (DropCommandParameters)parameter;

                var movedItem = dropParameters.Data is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Data) : null;
                var newParent = dropParameters.Parent is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Parent) : null;

                if (newParent == null || movedItem == null)
                {
                    return;
                }

                var parent = ((Entity)newParent.NodeValue).Transformation;
                if (dropParameters.TargetIndex > parent.Children.Count)
                {
                    return;
                }

                var transformationComponent = ((Entity)movedItem.NodeValue).Transformation;
                transformationComponent.Parent = null;
                parent.Children.Insert(dropParameters.TargetIndex, transformationComponent);
            }))));

            entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropAsset", new RootViewModelContent((ExecuteCommand)(async(viewModel2, parameter) =>
            {
                var dropParameters = (DropCommandParameters)parameter;

                var assetUrl = (string)dropParameters.Data;

                /*var newParent = entityHierarchyContext.GetModelView((Guid)dropParameters.Parent);
                 *
                 * if (newParent == null || assetUrl == null)
                 *  return;
                 *
                 * var parent = ((Entity)newParent.NodeValue).Transformation;
                 * if (dropParameters.ItemIndex > parent.Children.Count)
                 *  return;*/

                engineContext.Scheduler.Add(async() =>
                {
                    // Load prefab entity
                    var loadedEntityPrefab = await engineContext.AssetManager.LoadAsync <Entity>(assetUrl + "#");

                    // Build another entity from prefab
                    var loadedEntity = Prefab.Inherit(loadedEntityPrefab);

                    // Add it to scene
                    engineContext.EntityManager.AddEntity(loadedEntity);

                    if (loadedEntity.ContainsKey(AnimationComponent.Key))
                    {
                        Scheduler.Current.Add(() => AnimScript.AnimateFBXModel(engineContext, loadedEntity));
                    }
                });
            }))));

            var scriptEngineContext = new ViewModelContext(viewModelGlobalContext);

            scriptEngineContext.ChildrenPropertyEnumerators.Add(new ScriptAssemblyEnumerator(engineContext));
            scriptEngineContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            scriptEngineContext.Root = new ViewModelNode(new EnumerableViewModelContent <ViewModelReference>(
                                                             () => engineContext.ScriptManager.ScriptAssemblies.Select(x => new ViewModelReference(x, true))));
            scriptEngineContext.Root.Children.Add(new ViewModelNode("RunScript", new RootViewModelContent((ExecuteCommand)(async(viewModel2, parameter) =>
            {
                var scriptName = (string)parameter;
                var matchingScript = engineContext.ScriptManager.Scripts.Where(x => x.TypeName + "." + x.MethodName == scriptName);
                if (matchingScript.Any())
                {
                    var scriptEntry = matchingScript.Single();
                    var microThread = engineContext.ScriptManager.RunScript(scriptEntry, null);
                }
            }))));

            var runningScriptsContext = new ViewModelContext(viewModelGlobalContext);

            runningScriptsContext.ChildrenPropertyEnumerators.Add(new MicroThreadEnumerator(selectedEntitiesContext));
            runningScriptsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            runningScriptsContext.Root = new ViewModelNode("MicroThreads", new EnumerableViewModelContent <ViewModelReference>(
                                                               () => engineContext.Scheduler.MicroThreads.Select(x => new ViewModelReference(x, true))
                                                               ));

            var effectsContext = new ViewModelContext(viewModelGlobalContext);

            effectsContext.ChildrenPropertyEnumerators.Add(new EffectEnumerator(selectedEntitiesContext));
            effectsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            effectsContext.Root = new ViewModelNode("Effects", new EnumerableViewModelContent <ViewModelReference>(
                                                        () => engineContext.RenderContext.Effects.Select(x => new ViewModelReference(x, true))
                                                        ));
            //effectsContext.Root.Children.Add(new ViewModelNode("PluginDefinitions", new RootViewModelContent()));

            var assetBrowserContext = new ViewModelContext(viewModelGlobalContext);

            assetBrowserContext.ChildrenPropertyEnumerators.Add(new AssetBrowserEnumerator(engineContext));
            assetBrowserContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            assetBrowserContext.Root = new ViewModelNode("Root", "Root").GenerateChildren(assetBrowserContext);

            var editorContext = new ViewModelContext(viewModelGlobalContext);

            editorContext.Root = new ViewModelNode("Root");
            editorContext.Root.Children.Add(new ViewModelNode("SwitchSelectionMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.None; })));
            editorContext.Root.Children.Add(new ViewModelNode("SwitchTranslationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Translation; })));
            editorContext.Root.Children.Add(new ViewModelNode("SwitchRotationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Rotation; })));

            var contexts = new Dictionary <string, Tuple <ViewModelContext, ViewModelState> >();

            contexts.Add("Editor", Tuple.Create(editorContext, new ViewModelState()));
            contexts.Add("RenderPassPlugins", Tuple.Create(renderPassPluginsContext, new ViewModelState()));
            contexts.Add("RenderPasses", Tuple.Create(renderPassHierarchyContext, new ViewModelState()));
            contexts.Add("SelectedEntities", Tuple.Create(selectedEntitiesContext, new ViewModelState()));
            contexts.Add("EntityHierarchy", Tuple.Create(entityHierarchyContext, new ViewModelState()));
            contexts.Add("ScriptEngine", Tuple.Create(scriptEngineContext, new ViewModelState()));
            contexts.Add("MicroThreads", Tuple.Create(runningScriptsContext, new ViewModelState()));
            contexts.Add("AssetBrowser", Tuple.Create(assetBrowserContext, new ViewModelState()));
            contexts.Add("Effects", Tuple.Create(effectsContext, new ViewModelState()));

            int lastAckPacket = 0;

            var entitiesChangePackets = new ConcurrentQueue <EntitiesChangePacket>();

            socketContext.AddPacketHandler <EntitiesChangePacket>(
                (packet) =>
            {
                entitiesChangePackets.Enqueue(packet);
                entitiesChangePacketEvent.Set();
            });

            Action asyncThreadStart = () =>
            {
                while (true)
                {
                    Thread.Sleep(100);
                    foreach (var context in contexts)
                    {
                        // Process async data
                        Guid[] path  = null;
                        object value = null;
                        lock (context.Value.Item1)
                        {
                            var pendingNode = context.Value.Item1.GetNextPendingAsyncNode();
                            if (pendingNode != null)
                            {
                                value = pendingNode.Value;
                                path  = ViewModelController.BuildPath(pendingNode);
                            }
                        }
                        if (path != null)
                        {
                            // Temporary encoding through our serializer (until our serializer are used for packets)
                            var memoryStream = new MemoryStream();
                            var writer       = new BinarySerializationWriter(memoryStream);
                            writer.SerializeExtended(null, value, ArchiveMode.Serialize);

                            var change = new NetworkChange {
                                Path = path.ToArray(), Type = NetworkChangeType.ValueUpdateAsync, Value = memoryStream.ToArray()
                            };
                            var packet = new EntitiesChangePacket {
                                GroupKey = context.Key, Changes = new NetworkChange[] { change }
                            };
                            socketContextAsync.Send(packet);
                            break;
                        }
                    }
                }
            };

            new Thread(new ThreadStart(asyncThreadStart)).Start();

            // TODO: Move some of this code directly inside ViewModelContext/Controller classes
            while (true)
            {
                await TaskEx.WhenAny(TaskEx.Delay(250), entitiesChangePacketEvent.WaitAsync());

                EntitiesChangePacket packet;
                while (entitiesChangePackets.TryDequeue(out packet))
                {
                    ViewModelController.NetworkApplyChanges(contexts[packet.GroupKey].Item1, packet.Changes);
                    lastAckPacket = packet.Index;
                }

                // Wait a single frame so that network updates get applied properly by all rendering systems for next update
                await Scheduler.Current.NextFrame();

                // If entity disappeared, try to replace it with new one (happen during file reload)
                // It's little bit cumbersome to test, need some simplification of this specific entity view model root.
                if (selectedEntitiesContext.Root != null &&
                    selectedEntitiesContext.Root.Parent != null &&
                    selectedEntitiesContext.Root.Parent.NodeValue is Entity)
                {
                    var entity = (Entity)selectedEntitiesContext.Root.Parent.NodeValue;
                    if (!engineContext.EntityManager.Entities.Contains(entity))
                    {
                        entity = engineContext.EntityManager.Entities.FirstOrDefault(x => x.Guid == entity.Guid);
                        if (entity != null)
                        {
                            selectedEntitiesContext.ViewModelByGuid.Clear();
                            selectedEntitiesContext.Root = selectedEntitiesContext.GetModelView(entity).Children.First(x => x.PropertyName == "Components");
                        }
                    }
                }

                var data = new Dictionary <string, byte[]>();
                foreach (var context in contexts)
                {
                    lock (context.Value.Item1)
                    {
                        if (context.Value.Item1.Root != null)
                        {
                            context.Value.Item1.AddModelView(context.Value.Item1.Root);
                        }
                        ViewModelController.UpdateReferences(context.Value.Item1, true);
                        data[context.Key] = ViewModelController.NetworkSerialize(context.Value.Item1, context.Value.Item2);
                    }
                }

                viewModelGlobalContext.UpdateObjects(contexts.Select(x => x.Value.Item1));

                //Console.WriteLine("DataSize: {0}", data.Sum(x => x.Value.Length));
                await Task.Factory.StartNew(() => socketContext.Send(new EntitiesUpdatePacket {
                    AckIndex = lastAckPacket, Data = data
                }));
            }
        }
Ejemplo n.º 7
0
        private async void ShaderCompilerRequestHandler(SocketContext clientSocketContext, EffectLogStore recordedEffectCompile, EffectCompiler effectCompiler, ShaderCompilerRequest shaderCompilerRequest)
        {
            // Wait for a client to be connected
            await clientConnectedTCS.Task;

            // Yield so that this socket can continue its message loop to answer to shader file request.
            await Task.Yield();

            Console.WriteLine("Compiling shader");

            // A shader has been requested, compile it (asynchronously)!
            var precompiledEffectShaderPass = await effectCompiler.Compile(shaderCompilerRequest.MixinTree, null).AwaitResult();

            // Record compilation to asset file (only if parent)
            recordedEffectCompile[new EffectCompileRequest(shaderCompilerRequest.MixinTree.Name, shaderCompilerRequest.MixinTree.UsedParameters)] = true;
            
            // Send compiled shader
            clientSocketContext.Send(new ShaderCompilerAnswer { StreamId = shaderCompilerRequest.StreamId, EffectBytecode = precompiledEffectShaderPass.Bytecode });
        }
Ejemplo n.º 8
0
        #pragma warning disable 1998, 4014
        public async Task ProcessLoginResult(Services._shard_item shard, string id, string password)
        {
            using (var reader = await Data.Globals.AccountDB.ExecuteReaderAsync("exec _CertifyTB_User '{0}', '{1}'", id, password))
            {
                await reader.ReadAsync();

                Packet resp = new Packet(SCommon.Opcode.Gateway.Response.LOGIN);

                int type = await reader.GetFieldValueAsync <int>(0);

                switch (type)
                {
                case 0:
                {
                    int sid = await reader.GetFieldValueAsync <int>(1);

                    byte sec_content = await reader.GetFieldValueAsync <byte>(2);

                    int session_id = -1;
                    lock (shard.m_lock)
                    {
                        if (shard.CurrentUsers < shard.MaxUsers)
                        {
                            session_id = Services.Session.Generate();
                        }
                    }

                    if (session_id != -1)
                    {
                        Data.Globals.GlobalDB.ExecuteCommandAsync("INSERT INTO _ActiveSessions (UserSID, SessionID, Processed) VALUES ({0}, {1}, 0)", sid, session_id);

                        resp.WriteByte(1);
                        resp.WriteInt32(session_id);
                        resp.WriteAscii(Data.Globals.GetConfigValue <string>("GameServerIPAddress"));
                        resp.WriteUInt16(Data.Globals.GetConfigValue <ushort>("GameServerPort"));
                    }
                    else
                    {
                        resp.WriteByte(2);
                        resp.WriteByte(5);
                    }
                }
                break;

                case 1:
                {
                    int sid = await reader.GetFieldValueAsync <int>(1);

                    string ban_reason = await reader.GetFieldValueAsync <string>(2);

                    DateTime ban_endTime = await reader.GetFieldValueAsync <DateTime>(3);

                    resp.WriteByte(2);
                    resp.WriteByte(2);
                    resp.WriteByte(1);
                    resp.WriteAscii(ban_reason);
                    resp.WriteUInt16(ban_endTime.Year);
                    resp.WriteUInt16(ban_endTime.Month);
                    resp.WriteUInt16(ban_endTime.Day);
                    resp.WriteUInt16(ban_endTime.Hour);
                    resp.WriteUInt16(ban_endTime.Minute);
                    resp.WriteUInt16(ban_endTime.Second);
                    resp.WriteInt32(ban_endTime.Millisecond);
                }
                break;

                case 2:
                {
                    resp.WriteByte(2);
                    resp.WriteByte(1);

                    if (Data.Globals.WrongPasswordTries.ContainsKey(id))
                    {
                        var wrong = Data.Globals.WrongPasswordTries[id];

                        resp.WriteInt32(++wrong.Tries);

                        wrong.LastTick = Environment.TickCount;
                        Data.Globals.WrongPasswordTries[id] = wrong;
                    }
                    else
                    {
                        var wrong = new Data._wrongpass_item
                        {
                            LastTick = Environment.TickCount,
                            Tries    = 1
                        };
                        Data.Globals.WrongPasswordTries.Add(id, wrong);

                        resp.WriteInt32(1);
                    }

                    resp.WriteInt32(Data.Globals.MAX_WRONG_PASSWORD);
                }
                break;

                case 3:
                {
                    //already in game packet
                }
                break;
                }

                m_SocketContext.Send(resp);
                Disconnect();
            }
        }
Ejemplo n.º 9
0
        public async static Task ProcessClient(EngineContext engineContext, SocketContext socketContext, SocketContext socketContextAsync)
        {
            socketContext.AddPacketHandler<DownloadFileQuery>(
                async (packet) =>
                {
                    var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Open, VirtualFileAccess.Read);
                    var data = new byte[stream.Length];
                    await stream.ReadAsync(data, 0, data.Length);
                    stream.Close();
                    socketContext.Send(new DownloadFileAnswer { StreamId = packet.StreamId, Data = data });
                });

            socketContext.AddPacketHandler<UploadFilePacket>(
                async (packet) =>
                {
                    var stream = await VirtualFileSystem.OpenStreamAsync(packet.Url, VirtualFileMode.Create, VirtualFileAccess.Write);
                    await stream.WriteAsync(packet.Data, 0, packet.Data.Length);
                    stream.Close();
                });

            var viewModelGlobalContext = new ViewModelGlobalContext();

            selectedEntitiesContext = new ViewModelContext(viewModelGlobalContext);
            selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EntityComponentEnumerator(engineContext));
            selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginEnumerator());
            selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            //selectedEntitiesContext.ChildrenPropertyEnumerators.Add(new EffectPropertyEnumerator(engineContext));

            var renderPassHierarchyContext = new ViewModelContext(viewModelGlobalContext);
            renderPassHierarchyContext.ChildrenPropertyEnumerators.Add(new RenderPassHierarchyEnumerator());
            renderPassHierarchyContext.Root = new ViewModelNode("Root", engineContext.RenderContext.RootRenderPass).GenerateChildren(renderPassHierarchyContext);

            var renderPassPluginsContext = new ViewModelContext(viewModelGlobalContext);
            renderPassPluginsContext.ChildrenPropertyEnumerators.Add(new RenderPassPluginsEnumerator { SelectedRenderPassPluginContext = selectedEntitiesContext });
            renderPassPluginsContext.Root = new ViewModelNode("Root", new EnumerableViewModelContent<ViewModelReference>(
                () => engineContext.RenderContext.RenderPassPlugins.Select(x => new ViewModelReference(x, true))));


            var entityHierarchyEnumerator = new EntityHierarchyEnumerator(engineContext.EntityManager, selectedEntitiesContext);
            var entityHierarchyContext = new ViewModelContext(viewModelGlobalContext);
            entityHierarchyContext.ChildrenPropertyEnumerators.Add(entityHierarchyEnumerator);
            entityHierarchyContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            entityHierarchyContext.Root = new ViewModelNode("EntityHierarchyRoot", new EnumerableViewModelContent<ViewModelReference>(
                        () => engineContext.EntityManager.Entities
                                           .Where(x =>
                                           {
                                               var transformationComponent = x.Transformation;
                                               return (transformationComponent == null || transformationComponent.Parent == null);
                                           })
                                           .Select(x => new ViewModelReference(x, true))));

            entityHierarchyEnumerator.SelectedEntities.CollectionChanged += (sender, args) =>
                {
                    SelectEntity(entityHierarchyEnumerator.SelectedEntities);
                };
            //entityHierarchyContext.Root.Children.Add(new ViewModelNode("SelectedItems", EnumerableViewModelContent.FromUnaryLambda<ViewModelReference, ViewModelReference>(new NullViewModelContent(),
            //    (x) => { return new[] { new ViewModelReference(pickingSystem.SelectedEntity) }; })));
                /*(value) =>
                    {
                        var entityModelView = value != null ? entityHierarchyContext.GetModelView(value.Guid) : null;
                        var entity = entityModelView != null ? (Entity)entityModelView.NodeValue : null;
                        SelectEntity(entity);
                    })));*/
            entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropEntity", new RootViewModelContent((ExecuteCommand)((viewModel2, parameter) =>
                {
                    var dropParameters = (DropCommandParameters)parameter;

                    var movedItem = dropParameters.Data is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Data) : null;
                    var newParent = dropParameters.Parent is Guid ? entityHierarchyContext.GetModelView((Guid)dropParameters.Parent) : null;

                    if (newParent == null || movedItem == null)
                        return;

                    var parent = ((Entity)newParent.NodeValue).Transformation;
                    if (dropParameters.TargetIndex > parent.Children.Count)
                        return;

                    var transformationComponent = ((Entity)movedItem.NodeValue).Transformation;
                    transformationComponent.Parent = null;
                    parent.Children.Insert(dropParameters.TargetIndex, transformationComponent);
                }))));

            entityHierarchyContext.Root.Children.Add(new ViewModelNode("DropAsset", new RootViewModelContent((ExecuteCommand)(async (viewModel2, parameter) =>
                {
                    var dropParameters = (DropCommandParameters)parameter;

                    var assetUrl = (string)dropParameters.Data;
                    /*var newParent = entityHierarchyContext.GetModelView((Guid)dropParameters.Parent);

                    if (newParent == null || assetUrl == null)
                        return;

                    var parent = ((Entity)newParent.NodeValue).Transformation;
                    if (dropParameters.ItemIndex > parent.Children.Count)
                        return;*/

                    engineContext.Scheduler.Add(async () =>
                    {
                        // Load prefab entity
                        var loadedEntityPrefab = await engineContext.AssetManager.LoadAsync<Entity>(assetUrl + "#");

                        // Build another entity from prefab
                        var loadedEntity = Prefab.Inherit(loadedEntityPrefab);

                        // Add it to scene
                        engineContext.EntityManager.AddEntity(loadedEntity);

                        if (loadedEntity.ContainsKey(AnimationComponent.Key))
                        {
                            Scheduler.Current.Add(() => AnimScript.AnimateFBXModel(engineContext, loadedEntity));
                        }
                    });
                }))));

            var scriptEngineContext = new ViewModelContext(viewModelGlobalContext);
            scriptEngineContext.ChildrenPropertyEnumerators.Add(new ScriptAssemblyEnumerator(engineContext));
            scriptEngineContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            scriptEngineContext.Root = new ViewModelNode(new EnumerableViewModelContent<ViewModelReference>(
                        () => engineContext.ScriptManager.ScriptAssemblies.Select(x => new ViewModelReference(x, true))));
            scriptEngineContext.Root.Children.Add(new ViewModelNode("RunScript", new RootViewModelContent((ExecuteCommand)(async (viewModel2, parameter) =>
                {
                    var scriptName = (string)parameter;
                    var matchingScript = engineContext.ScriptManager.Scripts.Where(x => x.TypeName + "." + x.MethodName == scriptName);
                    if (matchingScript.Any())
                    {
                        var scriptEntry = matchingScript.Single();
                        var microThread = engineContext.ScriptManager.RunScript(scriptEntry, null);
                    }
                }))));

            var runningScriptsContext = new ViewModelContext(viewModelGlobalContext);
            runningScriptsContext.ChildrenPropertyEnumerators.Add(new MicroThreadEnumerator(selectedEntitiesContext));
            runningScriptsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            runningScriptsContext.Root = new ViewModelNode("MicroThreads", new EnumerableViewModelContent<ViewModelReference>(
                    () => engineContext.Scheduler.MicroThreads.Select(x => new ViewModelReference(x, true))
                ));

            var effectsContext = new ViewModelContext(viewModelGlobalContext);
            effectsContext.ChildrenPropertyEnumerators.Add(new EffectEnumerator(selectedEntitiesContext));
            effectsContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            effectsContext.Root = new ViewModelNode("Effects", new EnumerableViewModelContent<ViewModelReference>(
                    () => engineContext.RenderContext.Effects.Select(x => new ViewModelReference(x, true))
                ));
            //effectsContext.Root.Children.Add(new ViewModelNode("PluginDefinitions", new RootViewModelContent()));

            var assetBrowserContext = new ViewModelContext(viewModelGlobalContext);
            assetBrowserContext.ChildrenPropertyEnumerators.Add(new AssetBrowserEnumerator(engineContext));
            assetBrowserContext.ChildrenPropertyEnumerators.Add(new ChildrenPropertyInfoEnumerator());
            assetBrowserContext.Root = new ViewModelNode("Root", "Root").GenerateChildren(assetBrowserContext);

            var editorContext = new ViewModelContext(viewModelGlobalContext);
            editorContext.Root = new ViewModelNode("Root");
            editorContext.Root.Children.Add(new ViewModelNode("SwitchSelectionMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.None; })));
            editorContext.Root.Children.Add(new ViewModelNode("SwitchTranslationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Translation; })));
            editorContext.Root.Children.Add(new ViewModelNode("SwitchRotationMode", new CommandViewModelContent((sender, parameters) => { pickingSystem.ActiveGizmoActionMode = PickingSystem.GizmoAction.Rotation; })));

            var contexts = new Dictionary<string, Tuple<ViewModelContext, ViewModelState>>();
            contexts.Add("Editor", Tuple.Create(editorContext, new ViewModelState()));
            contexts.Add("RenderPassPlugins", Tuple.Create(renderPassPluginsContext, new ViewModelState()));
            contexts.Add("RenderPasses", Tuple.Create(renderPassHierarchyContext, new ViewModelState()));
            contexts.Add("SelectedEntities", Tuple.Create(selectedEntitiesContext, new ViewModelState()));
            contexts.Add("EntityHierarchy", Tuple.Create(entityHierarchyContext, new ViewModelState()));
            contexts.Add("ScriptEngine", Tuple.Create(scriptEngineContext, new ViewModelState()));
            contexts.Add("MicroThreads", Tuple.Create(runningScriptsContext, new ViewModelState()));
            contexts.Add("AssetBrowser", Tuple.Create(assetBrowserContext, new ViewModelState()));
            contexts.Add("Effects", Tuple.Create(effectsContext, new ViewModelState()));

            int lastAckPacket = 0;

            var entitiesChangePackets = new ConcurrentQueue<EntitiesChangePacket>();
            socketContext.AddPacketHandler<EntitiesChangePacket>(
                (packet) =>
                    {
                        entitiesChangePackets.Enqueue(packet);
                        entitiesChangePacketEvent.Set();
                    });

            Action asyncThreadStart = () =>
                {
                    while (true)
                    {
                        Thread.Sleep(100);
                        foreach (var context in contexts)
                        {
                            // Process async data
                            Guid[] path = null;
                            object value = null;
                            lock (context.Value.Item1)
                            {
                                var pendingNode = context.Value.Item1.GetNextPendingAsyncNode();
                                if (pendingNode != null)
                                {
                                    value = pendingNode.Value;
                                    path = ViewModelController.BuildPath(pendingNode);
                                }
                            }
                            if (path != null)
                            {
                                // Temporary encoding through our serializer (until our serializer are used for packets)
                                var memoryStream = new MemoryStream();
                                var writer = new BinarySerializationWriter(memoryStream);
                                writer.SerializeExtended(null, value, ArchiveMode.Serialize);

                                var change = new NetworkChange { Path = path.ToArray(), Type = NetworkChangeType.ValueUpdateAsync, Value = memoryStream.ToArray() };
                                var packet = new EntitiesChangePacket { GroupKey = context.Key, Changes = new NetworkChange[] { change } };
                                socketContextAsync.Send(packet);
                                break;
                            }
                        }
                    }
                };

            new Thread(new ThreadStart(asyncThreadStart)).Start();

            // TODO: Move some of this code directly inside ViewModelContext/Controller classes
            while (true)
            {
                await TaskEx.WhenAny(TaskEx.Delay(250), entitiesChangePacketEvent.WaitAsync());

                EntitiesChangePacket packet;
                while (entitiesChangePackets.TryDequeue(out packet))
                {
                    ViewModelController.NetworkApplyChanges(contexts[packet.GroupKey].Item1, packet.Changes);
                    lastAckPacket = packet.Index;
                }

                // Wait a single frame so that network updates get applied properly by all rendering systems for next update
                await Scheduler.Current.NextFrame();

                // If entity disappeared, try to replace it with new one (happen during file reload)
                // It's little bit cumbersome to test, need some simplification of this specific entity view model root.
                if (selectedEntitiesContext.Root != null
                    && selectedEntitiesContext.Root.Parent != null
                    && selectedEntitiesContext.Root.Parent.NodeValue is Entity)
                {
                    var entity = (Entity)selectedEntitiesContext.Root.Parent.NodeValue;
                    if (!engineContext.EntityManager.Entities.Contains(entity))
                    {
                        entity = engineContext.EntityManager.Entities.FirstOrDefault(x => x.Guid == entity.Guid);
                        if (entity != null)
                        {
                            selectedEntitiesContext.ViewModelByGuid.Clear();
                            selectedEntitiesContext.Root = selectedEntitiesContext.GetModelView(entity).Children.First(x => x.PropertyName == "Components");
                        }
                    }
                }

                var data = new Dictionary<string, byte[]>();
                foreach (var context in contexts)
                {
                    lock (context.Value.Item1)
                    {
                        if (context.Value.Item1.Root != null)
                            context.Value.Item1.AddModelView(context.Value.Item1.Root);
                        ViewModelController.UpdateReferences(context.Value.Item1, true);
                        data[context.Key] = ViewModelController.NetworkSerialize(context.Value.Item1, context.Value.Item2);
                    }
                }

                viewModelGlobalContext.UpdateObjects(contexts.Select(x => x.Value.Item1));

                //Console.WriteLine("DataSize: {0}", data.Sum(x => x.Value.Length));
                await Task.Factory.StartNew(() => socketContext.Send(new EntitiesUpdatePacket { AckIndex = lastAckPacket, Data = data }));
            }
        }