示例#1
0
        private async Task <string> FindOnlineFriends(List <int> friendUserIds)
        {
            string output       = "";
            bool   foundSomeone = false;

            foreach (int friendUserid in friendUserIds)
            {
                if (foundSomeone)
                {
                    output += "; ";
                }

                List <int> channelIds = CreeperCarl.GetActiveChannelIds(friendUserid);
                if (channelIds != null && channelIds.Count > 0)
                {
                    foundSomeone = true;
                    output      += $"{await MixerUtils.GetUserName(friendUserid)} is currently watching ";
                    output      += await CommandUtils.FormatChannelIds(channelIds, 50);
                }
            }
            if (!foundSomeone)
            {
                output = "None of your friends are currently online.";
            }
            return(output);
        }
示例#2
0
        public void SendRemoveLookAtConstraint(GameObject gobject)
        {
            NetCommand command = MixerUtils.BuildSendRemoveLookAtConstraintCommand(gobject);

            AddCommand(command);
            SendTransform(gobject.transform);  // For Blender
        }
示例#3
0
        private async Task HandleAddOrRemove(ChatMessage msg, bool add)
        {
            // Get the target they want to add
            string friendUserName = CommandUtils.GetSecondSingleWordArgument(msg.Text);

            if (friendUserName == null)
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"Who are we {(add ? "adding" : "removing")} as a friend? Specify a user name after the command.", true);

                return;
            }
            int?friendUserId = await MixerUtils.GetUserId(friendUserName);

            if (!friendUserId.HasValue)
            {
                await CommandUtils.SendMixerUserNotFound(m_firehose, msg, friendUserName);

                return;
            }

            // Add the friend to their list
            bool addedToFriends   = UpdateList(msg.UserId, friendUserId.Value, add, true);
            bool addedToFollowers = UpdateList(friendUserId.Value, msg.UserId, add, false);
            await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"You're {(add ? (!addedToFriends && !addedToFollowers ? "still" : "now") : "no longer")} friends with @{await MixerUtils.GetProperUserName(friendUserName)}{(add ? "! ❤️" : ". 💔")}", true);

            SaveSettings();
        }
示例#4
0
        public void SendPlayerTransform(MixerUser info)
        {
            NetCommand command = MixerUtils.BuildSendPlayerTransform(info);

            if (null != command)
            {
                AddCommand(command);
            }
        }
示例#5
0
        public static async Task <string> FormatUserIds(List <int> userIds, int lengthLimit = int.MaxValue)
        {
            List <string> names = new List <string>();

            foreach (int i in userIds)
            {
                names.Add("@" + await MixerUtils.GetUserName(i));
            }
            return(FormatWordList(names, lengthLimit));
        }
示例#6
0
        static public async Task <int> GlobalWhisper(IFirehose firehose, int userId, string message)
        {
            string userName = await MixerUtils.GetUserName(userId);

            if (String.IsNullOrWhiteSpace(userName))
            {
                return(0);
            }
            return(await GlobalWhisper(firehose, userId, userName, message));
        }
示例#7
0
        static public async Task <int> GlobalWhisper(IFirehose firehose, string userName, string message)
        {
            int?userId = await MixerUtils.GetUserId(userName);

            if (!userId.HasValue)
            {
                return(0);
            }
            return(await GlobalWhisper(firehose, userId.Value, userName, message));
        }
示例#8
0
        public static void SendLight(GameObject gObject)
        {
            LightInfo lightInfo = new LightInfo
            {
                transform = gObject.transform
            };

            MixerClient.Instance.SendEvent <LightInfo>(MessageType.Light, lightInfo);
            MixerClient.Instance.SendEvent <Transform>(MessageType.Transform, gObject.transform);
            MixerUtils.AddObjectToScene(gObject);
        }
示例#9
0
        public static void SendCamera(GameObject gObject)
        {
            CameraInfo cameraInfo = new CameraInfo
            {
                transform = gObject.transform
            };

            MixerClient.Instance.SendEvent <CameraInfo>(MessageType.Camera, cameraInfo);
            MixerClient.Instance.SendEvent <Transform>(MessageType.Transform, gObject.transform);
            MixerUtils.AddObjectToScene(gObject);
        }
示例#10
0
        public void ForceUpdate()
        {
            int mappedFrame = (int)(frame * data.frameScale) + data.frameOffset;

            if (data.hasCustomRange)
            {
                if (mappedFrame >= data.rangeStartFrame)
                {
                    mappedFrame = ((mappedFrame - data.rangeStartFrame) % (data.rangeEndFrame - data.rangeStartFrame + 1)) + data.rangeStartFrame;
                }
                else
                {
                    mappedFrame = data.rangeEndFrame - ((data.rangeStartFrame - mappedFrame - 1) % (data.rangeEndFrame - data.rangeStartFrame + 1));
                }
            }


            Tuple <Mesh, List <MaterialParameters> > meshData = findMesh(mappedFrame);

            if (null == meshData)
            {
                return;
            }

            MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>();

            if (null == meshFilter)
            {
                meshFilter = gameObject.AddComponent <MeshFilter>();
            }
            meshFilter.mesh      = meshData.Item1;
            meshFilter.mesh.name = gameObject.name;

            MeshCollider collider = gameObject.GetComponent <MeshCollider>();

            if (null != collider)
            {
                GameObject.Destroy(collider);
            }
            gameObject.AddComponent <MeshCollider>();

            MeshRenderer meshRenderer = gameObject.GetComponent <MeshRenderer>();

            if (null == meshRenderer)
            {
                meshRenderer = gameObject.AddComponent <MeshRenderer>();
            }

            MixerUtils.ApplyMaterialParameters(meshRenderer, meshData.Item2);
        }
示例#11
0
        public static GameObject CreateFullHierarchyPrefab(GameObject original)
        {
            string rootPath = Utils.GetPath(original.transform.parent);

            GameObject root = null;

            foreach (var originalTransform in original.GetComponentsInChildren <Transform>())
            {
                originalTransform.gameObject.name = Utils.CreateUniqueName(originalTransform.gameObject.name);
                string path = originalTransform.parent != null ? originalTransform.parent.name + "/" + originalTransform.name : originalTransform.name;
                if (rootPath.Length > 0 && path.StartsWith(rootPath))
                {
                    path = path.Substring(rootPath.Length + 1);
                }
                Transform prefabTransform = GetOrCreatePrefabPath(path);
                prefabTransform.localPosition = originalTransform.localPosition;
                prefabTransform.localRotation = originalTransform.localRotation;
                prefabTransform.localScale    = originalTransform.localScale;

                if (originalTransform.gameObject == original)
                {
                    root = prefabTransform.gameObject;
                }
                MeshFilter meshFilter = originalTransform.GetComponent <MeshFilter>();
                if (null != meshFilter && null != meshFilter.sharedMesh)
                {
                    MixerUtils.ConnectMesh(prefabTransform, meshFilter.sharedMesh);
                }

                MeshRenderer meshRenderer = originalTransform.GetComponent <MeshRenderer>();
                if (null != meshRenderer && null != meshRenderer.sharedMaterials)
                {
                    MeshRenderer dstMeshRenderer = prefabTransform.GetComponent <MeshRenderer>();
                    if (null != dstMeshRenderer)
                    {
                        dstMeshRenderer.sharedMaterials = meshRenderer.sharedMaterials;
                        dstMeshRenderer.material.name   = Utils.GetMaterialName(prefabTransform.gameObject);
                    }
                }
            }

            return(root);
        }
示例#12
0
        public static void SendMesh(GameObject gObject)
        {
            MeshInfos meshInfos = new MeshInfos
            {
                meshFilter    = gObject.GetComponent <MeshFilter>(),
                meshRenderer  = gObject.GetComponent <MeshRenderer>(),
                meshTransform = gObject.transform
            };

            foreach (Material mat in meshInfos.meshRenderer.materials)
            {
                MixerClient.Instance.SendEvent <Material>(MessageType.Material, mat);
            }

            MixerClient.Instance.SendEvent <MeshInfos>(MessageType.Mesh, meshInfos);
            MixerClient.Instance.SendEvent <Transform>(MessageType.Transform, gObject.transform);

            MixerUtils.AddObjectToScene(gObject);
        }
示例#13
0
        public void SendAddObjectToColleciton(AddToCollectionInfo addToCollectionInfo)
        {
            string collectionName = addToCollectionInfo.collectionName;

            if (!SyncData.collectionNodes.ContainsKey(collectionName))
            {
                NetCommand addCollectionCommand = MixerUtils.BuildAddCollecitonCommand(collectionName);
                AddCommand(addCollectionCommand);
            }

            NetCommand commandAddObjectToCollection = MixerUtils.BuildAddObjectToCollecitonCommand(addToCollectionInfo);

            AddCommand(commandAddObjectToCollection);
            if (!SyncData.sceneCollections.Contains(collectionName))
            {
                NetCommand commandAddCollectionToScene = MixerUtils.BuildAddCollectionToScene(collectionName);
                AddCommand(commandAddCollectionToScene);
            }
        }
示例#14
0
        private async Task HandleFindCommand(ChatMessage msg)
        {
            string userName = CommandUtils.GetSingleWordArgument(msg.Text);

            if (userName == null)
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"Find who? 🔍 You must specify a user name to find!", CommandUtils.ShouldForceIsWhisper(msg));

                return;
            }

            int?userId = await MixerUtils.GetUserId(userName);

            if (!userId.HasValue)
            {
                await CommandUtils.SendMixerUserNotFound(m_firehose, msg, userName);

                return;
            }

            // Find the user.
            List <int> channelIds = CreeperCarl.GetActiveChannelIds(userId.Value);

            if (channelIds == null)
            {
                await CommandUtils.SendCantFindUser(m_firehose, msg, userName);
            }
            else
            {
                // Go async to get the names.
                var _ignored = Task.Run(async() =>
                {
                    // Build the string.
                    string output = $"I found {await MixerUtils.GetProperUserName(userName)} in the following channels: " + await CommandUtils.FormatChannelIds(channelIds, 250) + ".";
                    await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, output, CommandUtils.ShouldForceIsWhisper(msg));
                }).ConfigureAwait(false);
            }
        }
示例#15
0
        public void SendAddObjectToScene(AddObjectToSceneInfo addObjectToScene)
        {
            NetCommand command = MixerUtils.BuildAddObjectToScene(addObjectToScene);

            AddCommand(command);
        }
示例#16
0
        public void SendClearAnimations(ClearAnimationInfo info)
        {
            NetCommand command = MixerUtils.BuildSendClearAnimations(info);

            AddCommand(command);
        }
示例#17
0
        public void SendShotManagerAction(ShotManagerActionInfo info)
        {
            NetCommand command = MixerUtils.BuildSendShotManagerAction(info);

            AddCommand(command);
        }
示例#18
0
        public void SendBlenderBank(BlenderBankInfo info)
        {
            NetCommand command = MixerUtils.BuildSendBlenderBank(info);

            AddCommand(command);
        }
示例#19
0
        public static async Task <bool> CheckForMutualFriendsAndMessageIfNot(IFirehose m_firehose, ChatMessage msg, int actionReceiverId, string action)
        {
            if (HasAdvancePermissions(msg.UserId) || FriendlyDan.AreMutualFriends(msg.UserId, actionReceiverId))
            {
                return(true);
            }
            else
            {
                await SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"You need to be mutual friends with {await MixerUtils.GetUserName(actionReceiverId)} before you can {action} them. You both need to friend each other with the \"^friends add\" command.", msg.IsWhisper);

                return(false);
            }
        }
示例#20
0
        public void SendBlenderSave()
        {
            NetCommand command = MixerUtils.BuildSendBlenderSave();

            AddCommand(command);
        }
示例#21
0
        public async void OnUserActivity(AdvanceUserActivity activity)
        {
            // Only look at joins.
            if (!activity.IsJoin)
            {
                return;
            }

            // See if we have a notification setup for this user.
            Relationships relation;

            if (m_currentSettings.Users.TryGetValue(activity.UserId, out relation))
            {
                // Only send out notifications every so often.
                bool doFriendsCheck   = (DateTime.Now - relation.LastFriendsCheckTime) > c_minTimeBetweenFriendsCheck;
                bool doOnlineAnnounce = !relation.IsLurking && (DateTime.Now - relation.LastOnlineAnnounceTime) > c_minTimeBetweenOnlineAnnounce;
                if (!doFriendsCheck && !doOnlineAnnounce)
                {
                    return;
                }
                relation.LastFriendsCheckTime = relation.LastOnlineAnnounceTime = DateTime.Now;

                // Get the user data
                string userName = await MixerUtils.GetUserName(activity.UserId);

                if (userName == null)
                {
                    return;
                }
                string channelName = await MixerUtils.GetChannelName(activity.ChannelId);

                if (channelName == null)
                {
                    return;
                }

                if (doOnlineAnnounce)
                {
                    // Send notifications that the user is now online
                    List <int> notifiy = null;
                    lock (relation.UsersWhoFriended)
                    {
                        notifiy = relation.UsersWhoFriended.ToList <int>();
                    }
                    foreach (var userId in notifiy)
                    {
                        await CommandUtils.GlobalWhisper(m_firehose, userId, $"@{userName} has become active in @{channelName}");
                    }
                }

                if (doFriendsCheck)
                {
                    // Tell them what friends they have online.
                    List <int> friends;
                    lock (relation.Friends)
                    {
                        friends = relation.Friends.ToList <int>();
                    }
                    if (friends.Count > 0)
                    {
                        await CommandUtils.GlobalWhisper(m_firehose, activity.UserId, userName, await FindOnlineFriends(friends));
                    }
                }
            }
        }
示例#22
0
        public void SendToTrash(SendToTrashInfo sendToTrash)
        {
            NetCommand command = MixerUtils.BuildSendToTrashCommand(root, sendToTrash);

            AddCommand(command);
        }
示例#23
0
        private async Task HandleSummon(ChatMessage msg)
        {
            string summonUserName = CommandUtils.GetSingleWordArgument(msg.Text);

            if (summonUserName == null)
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"Let me know who you want so summon. Give me a user name after the command.", msg.IsWhisper);

                return;
            }
            string channelName = await MixerUtils.GetChannelName(msg.ChannelId);

            if (channelName == null)
            {
                await CommandUtils.SendMixerUserNotFound(m_firehose, msg, summonUserName, true);

                return;
            }

            // Get the summon user's id.
            int?actionReceiverId = await MixerUtils.GetUserId(summonUserName);

            if (!actionReceiverId.HasValue)
            {
                await CommandUtils.SendCantFindUser(m_firehose, msg, summonUserName);

                return;
            }

            // Make sure they are friends, otherwise we don't want to do this.
            if (!(await CommandUtils.CheckForMutualFriendsAndMessageIfNot(m_firehose, msg, actionReceiverId.Value, "summon")))
            {
                return;
            }

            // Check to see if the user is running the extension.
            //if (await CheckIfUserHasAnActiveExtension(summonUserName))
            //{
            //    // The user has an active extension
            //    if (await PostSummonToExtension(summonUserName, msg.UserName, channelName))
            //    {
            //        await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"I send an extension summon to {summonUserName}", msg.IsWhisper);
            //    }
            //    else
            //    {
            //        await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"That's not right... I failed to send extension summon to {summonUserName}.", msg.IsWhisper);
            //    }
            //}
            //else
            //{
            // The user doesn't have the extension! Whisper them.
            string properChannelName = await MixerUtils.GetProperUserName(channelName);

            int whispers = await CommandUtils.GlobalWhisper(m_firehose, summonUserName, $"{msg.UserName} summons you to @{properChannelName}'s channel! https://mixer.com/{properChannelName}");

            if (whispers == 0)
            {
                await CommandUtils.SendCantFindUser(m_firehose, msg, summonUserName);
            }
            else
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"I summoned {await MixerUtils.GetUserName(actionReceiverId.Value)} in {whispers} channel{(whispers > 1 ? "s" : "")}.", msg.IsWhisper);
            }
            //}
        }
示例#24
0
        private async Task HandleMockToggle(ChatMessage msg, bool isPrivate)
        {
            if (!CommandUtils.HasAdvancePermissions(msg.UserId))
            {
                await CommandUtils.SendAccessDenied(m_firehose, msg.ChannelId, msg.UserName);

                return;
            }

            // Find the user name.
            string userName = CommandUtils.GetSingleWordArgument(msg.Text);

            if (userName == null)
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, "I need a user name.", true);

                return;
            }

            // Get the user id.
            int?userId = await MixerUtils.GetUserId(userName);

            if (!userId.HasValue || userName.Length == 0)
            {
                await CommandUtils.SendMixerUserNotFound(m_firehose, msg, userName);

                return;
            }

            // Update the map.
            bool removed = false;
            bool currentValue;

            if (m_mockDict.TryGetValue(userId.Value, out currentValue))
            {
                // Remove if it's the same toggle.
                if (currentValue == isPrivate)
                {
                    removed = true;
                    m_mockDict.TryRemove(userId.Value, out currentValue);
                }
                // Otherwise, toggle it
                else
                {
                    m_mockDict.TryUpdate(userId.Value, isPrivate, currentValue);
                    currentValue = isPrivate;
                }
            }
            else
            {
                // If they are not in the map, add them.
                m_mockDict.TryAdd(userId.Value, isPrivate);
                currentValue = isPrivate;
            }

            string output;

            if (removed)
            {
                output = $"I'm no longer mocking {await MixerUtils.GetProperUserName(userName)}. Lucky them.";
            }
            else
            {
                output = $"I'm now {(currentValue ? "privately" : "publically")} mocking {await MixerUtils.GetProperUserName(userName)} 😮";
            }
            await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, output, msg.IsWhisper);

            return;
        }
示例#25
0
        private async Task HandleWhisperCommand(ChatMessage msg)
        {
            string userName = CommandUtils.GetSingleWordArgument(msg.Text);

            if (userName == null)
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, "I can globally whisper anyone on Mixer for you - they will get it no matter what channel they are watching. Give me a user name and the message you want to send.", true);

                return;
            }
            string message = CommandUtils.GetStringAfterFirstTwoWords(msg.Text);

            if (message == null)
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, "What do you want to say? Give me a user name and the message you want to send.", true);

                return;
            }

            int whispers = await CommandUtils.GlobalWhisper(m_firehose, userName, $"{msg.UserName} says: {message}");

            if (whispers == 0)
            {
                await CommandUtils.SendCantFindUser(m_firehose, msg, userName);
            }
            else
            {
                await CommandUtils.SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"I sent your message to {await MixerUtils.GetProperUserName(userName)} in {whispers} channels", true);
            }
        }
示例#26
0
 public static async Task <bool> SendCantFindUser(IFirehose m_firehose, ChatMessage msg, string failedToFindUserName)
 {
     return(await SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"It doesn't look like {await MixerUtils.GetProperUserName(failedToFindUserName)} is active on Mixer right now. Maybe they're lurking? 🙈", msg.IsWhisper));
 }
示例#27
0
 public static void SendEmpty(GameObject gObject)
 {
     MixerClient.Instance.SendEmpty(gObject.transform);
     MixerClient.Instance.SendTransform(gObject.transform);
     MixerUtils.AddObjectToScene(gObject);
 }
示例#28
0
 public static async Task <bool> SendMixerUserNotFound(IFirehose m_firehose, ChatMessage msg, string failedToFindUserName, bool isChannel = false)
 {
     return(await SendResponse(m_firehose, msg.ChannelId, msg.UserName, $"I can't find a {(isChannel ? "channel" : "user")} named {await MixerUtils.GetProperUserName(failedToFindUserName)} on Mixer. Is that spelled correctly? 😕", msg.IsWhisper));
 }
示例#29
0
        public void RestoreFromTrash(RestoreFromTrashInfo restoreFromTrash)
        {
            NetCommand command = MixerUtils.BuildRestoreFromTrashCommand(root, restoreFromTrash);

            AddCommand(command);
        }
示例#30
0
        IEnumerator ProcessIncomingCommands()
        {
            while (true)
            {
                lock (this)
                {
                    commands.AddRange(receivedCommands);
                    receivedCommands.Clear();
                }

                if (commands.Count == 0)
                {
                    yield return(null);

                    continue;
                }

                // don't process commands on play/record
                if (GlobalState.Animation.IsAnimating())
                {
                    yield return(null);

                    continue;
                }

                DateTime before         = DateTime.Now;
                bool     prematuredExit = false;
                foreach (NetCommand command in commands)
                {
                    commandProcessedCount++;

                    //Debug.Log($"Receiving command: {command.messageType}");

                    try
                    {
                        bool sceneModified = true;
                        switch (command.messageType)
                        {
                        case MessageType.ClientId:
                        {
                            MixerScene mixerScene = new MixerScene();
                            SceneManager.SetSceneImpl(mixerScene);

                            MixerUtils.BuildClientId(command.data);
                            sceneModified = false;
                        }
                        break;

                        case MessageType.Mesh:
                            MixerUtils.BuildMesh(command.data);
                            break;

                        case MessageType.Transform:
                            MixerUtils.BuildTransform(command.data);
                            break;

                        case MessageType.Empty:
                            MixerUtils.BuildEmpty(prefab, command.data);
                            break;

                        case MessageType.ObjectVisibility:
                            MixerUtils.BuildObjectVisibility(root, command.data);
                            break;

                        case MessageType.Material:
                            MixerUtils.BuildMaterial(command.data);
                            break;

                        case MessageType.AssignMaterial:
                            MixerUtils.BuildAssignMaterial(command.data);
                            break;

                        case MessageType.Camera:
                            MixerUtils.BuildCamera(prefab, command.data);
                            break;

                        case MessageType.Animation:
                            MixerUtils.BuildAnimation(command.data);
                            break;

                        case MessageType.AddKeyframe:
                            MixerUtils.BuildAddKeyframe(command.data);
                            break;

                        case MessageType.RemoveKeyframe:
                            MixerUtils.BuildRemoveKeyframe(command.data);
                            break;

                        case MessageType.MoveKeyframe:
                            MixerUtils.BuildMoveKeyframe(command.data);
                            break;

                        case MessageType.ClearAnimations:
                            MixerUtils.BuildClearAnimations(command.data);
                            break;

                        case MessageType.Light:
                            MixerUtils.BuildLight(prefab, command.data);
                            break;

                        case MessageType.Sky:
                            MixerUtils.BuildSky(command.data);
                            break;

                        case MessageType.AddConstraint:
                            MixerUtils.ReceiveAddConstraint(command.data);
                            break;

                        case MessageType.RemoveConstraint:
                            MixerUtils.ReceiveRemoveConstraint(command.data);
                            break;

                        case MessageType.Delete:
                            MixerUtils.Delete(prefab, command.data);
                            break;

                        case MessageType.Rename:
                            MixerUtils.Rename(prefab, command.data);
                            break;

                        case MessageType.Duplicate:
                            MixerUtils.Duplicate(prefab, command.data);
                            break;

                        case MessageType.SendToTrash:
                            MixerUtils.BuildSendToTrash(root, command.data);
                            break;

                        case MessageType.RestoreFromTrash:
                            MixerUtils.BuildRestoreFromTrash(root, command.data);
                            break;

                        case MessageType.Texture:
                            MixerUtils.BuildTexture(command.data);
                            break;

                        case MessageType.Collection:
                            MixerUtils.BuildCollection(command.data);
                            break;

                        case MessageType.CollectionRemoved:
                            MixerUtils.BuildCollectionRemoved(command.data);
                            break;

                        case MessageType.AddCollectionToCollection:
                            MixerUtils.BuildAddCollectionToCollection(prefab, command.data);
                            break;

                        case MessageType.RemoveCollectionFromCollection:
                            MixerUtils.BuildRemoveCollectionFromCollection(prefab, command.data);
                            break;

                        case MessageType.AddObjectToCollection:
                            MixerUtils.BuildAddObjectToCollection(prefab, command.data);
                            break;

                        case MessageType.RemoveObjectFromCollection:
                            MixerUtils.BuildRemoveObjectFromCollection(prefab, command.data);
                            break;

                        case MessageType.CollectionInstance:
                            MixerUtils.BuildCollectionInstance(command.data);
                            break;

                        case MessageType.AddObjectToDocument:
                            MixerUtils.BuildAddObjectToDocument(root, command.data);
                            break;

                        case MessageType.AddCollectionToScene:
                            MixerUtils.BuilAddCollectionToScene(command.data);
                            break;

                        case MessageType.SetScene:
                            MixerUtils.BuilSetScene(command.data);
                            break;

                        case MessageType.GreasePencilMaterial:
                            MixerUtils.BuildGreasePencilMaterial(command.data);
                            break;

                        case MessageType.GreasePencilMesh:
                            MixerUtils.BuildGreasePencilMesh(command.data);
                            break;

                        case MessageType.GreasePencilConnection:
                            MixerUtils.BuildGreasePencilConnection(command.data);
                            break;

                        case MessageType.GreasePencilTimeOffset:
                            MixerUtils.BuildGreasePencilTimeOffset(command.data);
                            break;

                        case MessageType.FrameStartEnd:
                            MixerUtils.BuildFrameStartEnd(command.data);
                            break;

                        case MessageType.CurrentCamera:
                            MixerUtils.BuildCurrentCamera(command.data);
                            break;

                        case MessageType.ShotManagerContent:
                            MixerUtils.BuildShotManager(command.data);
                            break;

                        case MessageType.ShotManagerAction:
                            MixerUtils.BuildShotManagerAction(command.data);
                            break;

                        case MessageType.BlenderBank:
                            MixerUtils.ReceiveBlenderBank(command.data);
                            break;

                        case MessageType.ClientUpdate:
                            MixerUtils.BuildClientAttribute(command.data);
                            sceneModified = false;
                            break;

                        case MessageType.ListAllClients:
                            MixerUtils.BuildListAllClients(command.data);
                            sceneModified = false;
                            break;
                        }
                        if (sceneModified)
                        {
                            CommandManager.SetSceneDirty(true);
                        }
                    }
                    catch (Exception e)
                    {
                        string message = $"Network exception (Command#{i}) Type {command.messageType}\n{e}";
                        Debug.LogError(message);
                    }
                    i++;

                    DateTime after    = DateTime.Now;
                    TimeSpan duration = after.Subtract(before);
                    if (duration.Milliseconds > 20)
                    {
                        commands.RemoveRange(0, commandProcessedCount);
                        prematuredExit = true;
                        break;
                    }
                }


                if (!prematuredExit)
                {
                    commands.Clear();
                }
                commandProcessedCount = 0;
                yield return(null);
            }
        }