Ejemplo n.º 1
0
        public static void ExecutePacketAndBroadcast(HaProtoImpl.Opcode op, HaProtoImpl.HaProtoPacket packet)
        {
            bool announceIndexChange = packet.ApplyToDatabase(Program.Core.DataSource);

            if (announceIndexChange)
            {
                Program.Core.AnnounceIndexChange();
            }
            Program.Server.BroadcastMessage(op, packet);
        }
Ejemplo n.º 2
0
 public async void Send(HaProtoImpl.Opcode type, byte[] data)
 {
     try
     {
         await HaProtoImpl.SendAsync(stream, type, data);
     }
     catch (Exception)
     {
         Kill();
     }
 }
Ejemplo n.º 3
0
        private void ExecutePacketAndBroadcast(HaProtoImpl.Opcode op, HaProtoImpl.HaProtoPacket packet)
        {
            bool announceIndexChange;

            lock (dataSource.Lock)
            {
                announceIndexChange = packet.ApplyToDatabase(dataSource);
            }
            if (announceIndexChange)
            {
                AnnounceIndexChange();
            }
            BroadcastMessage(op, packet);
        }
Ejemplo n.º 4
0
 public void BroadcastMessage(HaProtoImpl.Opcode type, HaProtoImpl.HaProtoPacket packet, Client exempt = null)
 {
     byte[] data = packet.Build();
     lock (clients)
     {
         for (int i = 0; i < clients.Count; i++)
         {
             Client c = clients[i];
             if (c == exempt)
             {
                 continue;
             }
             HaProtoImpl.Send(c.Socket, type, data);
         }
     }
 }
Ejemplo n.º 5
0
        private void SockProc(Socket sock)
        {
            try
            {
                HaProtoImpl.Send(sock, HaProtoImpl.Opcode.GETDB, new HaProtoImpl.GETDB());
                while (true)
                {
                    byte[]             buf;
                    HaProtoImpl.Opcode type = HaProtoImpl.Receive(sock, out buf);
                    bool foo;
                    Dispatcher.Invoke(delegate()
                    {
                        try
                        {
                            internalChanging = true;
                            switch (type)
                            {
                            case HaProtoImpl.Opcode.GETDB:
                                throw new NotSupportedException();

                            case HaProtoImpl.Opcode.SETDB:
                                HaProtoImpl.SETDB setdb = HaProtoImpl.SETDB.Parse(buf);
                                data.ServerDataSource   = setdb.dataSource;
                                BringSelectedItemIntoView();
                                break;

                            case HaProtoImpl.Opcode.LIBRARY_ADD:
                            case HaProtoImpl.Opcode.LIBRARY_REMOVE:
                            case HaProtoImpl.Opcode.LIBRARY_RESET:
                                // No selection eye candy for library because it's not worth the time it will take to implement
                                HaProtoImpl.ApplyPacketToDatabase(type, buf, data.ServerDataSource, out foo);

                                // For some reason this doesn't happen automatically and I'm too tired to search why
                                // mediaBrowser.InvalidateProperty(MediaBrowser.SelectedDataProperty);
                                // For some reason, .NET sucks and InvalidateProperty doesn't do what it says it does...
                                // BindingOperations.GetBindingExpression(mediaBrowser, MediaBrowser.SelectedDataProperty).UpdateTarget();
                                // For some reason, .NET sucks and GetBindingExpression only works with single bindings...
                                BindingOperations.GetMultiBindingExpression(mediaBrowser, MediaBrowser.SelectedDataProperty).UpdateTarget();
                                break;

                            case HaProtoImpl.Opcode.ADD:
                            case HaProtoImpl.Opcode.REMOVE:
                            case HaProtoImpl.Opcode.CLEAR:
                            case HaProtoImpl.Opcode.SETSONG:
                            case HaProtoImpl.Opcode.ADDPL:
                            case HaProtoImpl.Opcode.DELPL:
                            case HaProtoImpl.Opcode.RENPL:
                            case HaProtoImpl.Opcode.REORDER:
                            case HaProtoImpl.Opcode.INJECT:
                                // These opcodes might change the list selection, we need to back it up
                                // However, only do this for small selections - if the selection is large, we would rather take the UI
                                // inconsistency over multiple seconds of delay
                                List <PlaylistItem> selectedItems = data.SelectedPlaylistItems.ToList();
                                IInputElement element             = FocusManager.GetFocusedElement(this);
                                PlaylistItem focusItem            = null;
                                if (element is FrameworkElement && ((FrameworkElement)element).DataContext is PlaylistItem)
                                {
                                    focusItem = (PlaylistItem)((FrameworkElement)element).DataContext;
                                }
                                int firstIndex;
                                if (selectedItems.Count == 0)
                                {
                                    firstIndex = 0;
                                }
                                else if (selectedItems.Count < EyeCandyDisableThreshold)
                                {
                                    firstIndex = selectedItems.Select(x => data.SelectedPlaylist.PlaylistItems.IndexOf(x)).Min();
                                }
                                else
                                {
                                    firstIndex = data.SelectedPlaylist.PlaylistItems.IndexOf(selectedItems[0]);
                                }

                                HaProtoImpl.ApplyPacketToDatabase(type, buf, data.ServerDataSource, out foo);

                                // Check which items still exist
                                List <PlaylistItem> newSelectedItems = new List <PlaylistItem>();
                                foreach (PlaylistItem item in selectedItems)
                                {
                                    PlaylistItem newItem;
                                    if (data.SelectedPlaylist.PlaylistItems.FastTryGet(item.UID, out newItem))
                                    {
                                        // We could have added item and it would work, but for extra safety lets add the new item
                                        newSelectedItems.Add(newItem);
                                    }
                                }

                                // Special case for deletion
                                if (selectedItems.Count > 0 && newSelectedItems.Count == 0)
                                {
                                    int selectedIndex;
                                    if (firstIndex < data.SelectedPlaylist.PlaylistItems.Count)
                                    {
                                        selectedIndex = firstIndex;
                                    }
                                    else if (data.SelectedPlaylist.PlaylistItems.Count > 0)
                                    {
                                        selectedIndex = data.SelectedPlaylist.PlaylistItems.Count - 1;
                                    }
                                    else
                                    {
                                        selectedIndex = -1;
                                    }

                                    if (selectedIndex == -1)
                                    {
                                        focusItem = null;
                                    }
                                    else
                                    {
                                        newSelectedItems.Add(focusItem = data.SelectedPlaylist.PlaylistItems[selectedIndex]);
                                    }
                                }
                                if (newSelectedItems.Count < EyeCandyDisableThreshold && !IsSelectionEqual(data.SelectedPlaylistItems, newSelectedItems))
                                {
                                    data.SelectedPlaylistItems.Clear();
                                    newSelectedItems.ForEach(x => data.SelectedPlaylistItems.Add(x));

                                    if (focusItem != null)
                                    {
                                        SetFocusItem(focusItem);
                                    }
                                }
                                break;

                            case HaProtoImpl.Opcode.SETMOVE:
                                HaProtoImpl.ApplyPacketToDatabase(type, buf, data.ServerDataSource, out foo);
                                break;

                            case HaProtoImpl.Opcode.SKIP:
                                // We should not be receiving SKIP packets, the server should translate them to SETSONG
                                throw new NotSupportedException();

                            case HaProtoImpl.Opcode.SETVOL:
                                data.ServerDataSource.Volume = HaProtoImpl.SETVOL.Parse(buf).volume;
                                break;

                            case HaProtoImpl.Opcode.SEEK:
                                HaProtoImpl.SEEK seek          = HaProtoImpl.SEEK.Parse(buf);
                                data.ServerDataSource.Position = seek.pos;
                                data.ServerDataSource.Maximum  = seek.max;
                                break;

                            case HaProtoImpl.Opcode.SETPLAYING:
                                data.ServerDataSource.Playing = HaProtoImpl.SETPLAYING.Parse(buf).playing;
                                break;

                            default:
                                throw new NotSupportedException();
                            }
                        }
                        finally
                        {
                            internalChanging = false;
                        }
                    });
                }
            }
            catch (Exception e)
            {
                try
                {
                    // Try to close the socket, if it's already closed than w/e
                    sock.Shutdown(SocketShutdown.Both);
                    sock.Close();
                }
                catch { }
                try
                {
                    Dispatcher.Invoke(delegate()
                    {
                        SetEnabled(false);
                    });
                }
                catch { }
            }
        }
Ejemplo n.º 6
0
 public void Send(HaProtoImpl.Opcode type, HaProtoImpl.HaProtoPacket packet)
 {
     Send(type, packet.Build());
 }
Ejemplo n.º 7
0
        public static HaProtoImpl.HaProtoPacket ApplyPacketToDatabase(HaProtoImpl.Opcode op, byte[] data, ServerDataSource dataSource, out bool result)
        {
            HaProtoPacket packet;

            switch (op)
            {
            case HaProtoImpl.Opcode.ADD:
                packet = HaProtoImpl.ADD.Parse(data);
                break;

            case HaProtoImpl.Opcode.REMOVE:
                packet = HaProtoImpl.REMOVE.Parse(data);
                break;

            case HaProtoImpl.Opcode.CLEAR:
                packet = HaProtoImpl.CLEAR.Parse(data);
                break;

            case HaProtoImpl.Opcode.SETSONG:
                packet = HaProtoImpl.SETSONG.Parse(data);
                break;

            case HaProtoImpl.Opcode.SKIP:
                packet = HaProtoImpl.SKIP.Parse(data);
                break;

            case HaProtoImpl.Opcode.ADDPL:
                packet = HaProtoImpl.ADDPL.Parse(data);
                break;

            case HaProtoImpl.Opcode.DELPL:
                packet = HaProtoImpl.DELPL.Parse(data);
                break;

            case HaProtoImpl.Opcode.RENPL:
                packet = HaProtoImpl.RENPL.Parse(data);
                break;

            case HaProtoImpl.Opcode.SETMOVE:
                packet = HaProtoImpl.SETMOVE.Parse(data);
                break;

            case HaProtoImpl.Opcode.REORDER:
                packet = HaProtoImpl.REORDER.Parse(data);
                break;

            case HaProtoImpl.Opcode.INJECT:
                packet = HaProtoImpl.INJECT.Parse(data);
                break;

            case HaProtoImpl.Opcode.LIBRARY_ADD:
                packet = HaProtoImpl.LIBRARY_ADD.Parse(data);
                break;

            case HaProtoImpl.Opcode.LIBRARY_REMOVE:
                packet = HaProtoImpl.LIBRARY_REMOVE.Parse(data);
                break;

            case HaProtoImpl.Opcode.LIBRARY_RESET:
                packet = HaProtoImpl.LIBRARY_RESET.Parse(data);
                break;

            default:
                throw new NotImplementedException();
            }
            result = packet.ApplyToDatabase(dataSource);
            return(packet);
        }
Ejemplo n.º 8
0
        private void Proc()
        {
            try
            {
                log(string.Format("{0} Connected", id));
                while (true)
                {
                    bool               announceIndexChanges = false;
                    byte[]             data;
                    HaProtoImpl.Opcode type = HaProtoImpl.Receive(s, out data);
                    log(string.Format("{0}: {1}", id, type.ToString()));
                    HaProtoImpl.HaProtoPacket packet;
                    switch (type)
                    {
                    case HaProtoImpl.Opcode.GETDB:
                        lock (mainForm.DataSource.Lock)
                        {
                            HaProtoImpl.Send(s, HaProtoImpl.Opcode.SETDB, new HaProtoImpl.SETDB()
                            {
                                dataSource = mainForm.DataSource
                            });
                        }
                        break;

                    case HaProtoImpl.Opcode.SETDB:
                    case HaProtoImpl.Opcode.LIBRARY_ADD:
                    case HaProtoImpl.Opcode.LIBRARY_REMOVE:
                    case HaProtoImpl.Opcode.LIBRARY_RESET:
                        throw new NotSupportedException();

                    case HaProtoImpl.Opcode.ADD:
                    case HaProtoImpl.Opcode.REMOVE:
                    case HaProtoImpl.Opcode.CLEAR:
                    case HaProtoImpl.Opcode.SETSONG:
                    case HaProtoImpl.Opcode.ADDPL:
                    case HaProtoImpl.Opcode.DELPL:
                    case HaProtoImpl.Opcode.RENPL:
                    case HaProtoImpl.Opcode.SETMOVE:
                    case HaProtoImpl.Opcode.REORDER:
                    case HaProtoImpl.Opcode.INJECT:
                        packet = HaProtoImpl.ApplyPacketToDatabase(type, data, mainForm.DataSource, out announceIndexChanges);
                        mainForm.BroadcastMessage(type, packet);
                        break;

                    case HaProtoImpl.Opcode.SKIP:
                        long uid;
                        lock (mainForm.DataSource.Lock)
                        {
                            mainForm.DataSource.CurrentItem = mainForm.Mover.Next();
                            uid = mainForm.DataSource.CurrentItem == null ? -1 : mainForm.DataSource.CurrentItem.UID;
                        }
                        mainForm.BroadcastMessage(HaProtoImpl.Opcode.SETSONG, new HaProtoImpl.SETSONG()
                        {
                            uid = uid
                        });
                        announceIndexChanges = true;
                        break;

                    case HaProtoImpl.Opcode.SETVOL:
                        HaProtoImpl.SETVOL setvol = HaProtoImpl.SETVOL.Parse(data);
                        lock (mainForm.DataSource.Lock)
                        {
                            mainForm.DataSource.Volume = setvol.volume;
                        }
                        mainForm.SetVolume(setvol.volume);
                        mainForm.BroadcastMessage(type, setvol, this);
                        break;

                    case HaProtoImpl.Opcode.SEEK:
                        HaProtoImpl.SEEK seek = HaProtoImpl.SEEK.Parse(data);
                        lock (mainForm.DataSource.Lock)
                        {
                            mainForm.DataSource.Position = seek.pos;
                            seek.max = mainForm.DataSource.Maximum;
                        }
                        mainForm.SetPosition(seek.pos);
                        mainForm.BroadcastMessage(type, seek, this);
                        break;

                    case HaProtoImpl.Opcode.SETPLAYING:
                        HaProtoImpl.SETPLAYING setplaying = HaProtoImpl.SETPLAYING.Parse(data);
                        lock (mainForm.DataSource.Lock)
                        {
                            mainForm.DataSource.Playing = setplaying.playing;
                        }
                        mainForm.SetPlaying(setplaying.playing);
                        mainForm.BroadcastMessage(type, setplaying);
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                    if (announceIndexChanges)
                    {
                        mainForm.AnnounceIndexChange();
                    }
                }
            }
            catch (Exception e)
            {
                if (e is SocketException && ((SocketException)e).ErrorCode == 0)
                {
                    log(string.Format("{0} exited normally", id));
                }
                else
                {
                    log(string.Format("Exception in {0} : {1}", id, Program.GetErrorException(e)));
                }
                try
                {
                    // Try to close the socket, if it's already closed then w/e
                    s.Close();
                }
                catch { }
                mainForm.OnThreadExit(this);
                return;
            }
        }