├── Chimney.MPD ├── obj │ ├── Debug │ │ ├── layout.resfiles │ │ ├── pri.resfiles │ │ ├── qualifiers.txt │ │ ├── resources.resfiles │ │ ├── pri.resfiles.intermediate │ │ ├── layout.resfiles.intermediate │ │ ├── qualifiers.txt.intermediate │ │ ├── resources.resfiles.intermediate │ │ ├── MultipleQualifiersPerDimensionFound.txt │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ ├── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ ├── Chimney.MPD.dll │ │ ├── Chimney.MPD.pdb │ │ ├── MPD.csprojResolveAssemblyReference.cache │ │ ├── ChimneyMPD.csprojResolveAssemblyReference.cache │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── Chimney.MPD.csprojResolveAssemblyReference.cache │ │ ├── MPD.csproj.FileListAbsolute.txt │ │ ├── ChimneyMPD.csproj.FileListAbsolute.txt │ │ ├── priconfig.xml │ │ └── priconfig.xml.intermediate │ └── Release │ │ ├── pri.resfiles │ │ ├── qualifiers.txt │ │ ├── layout.resfiles │ │ ├── resources.resfiles │ │ ├── layout.resfiles.intermediate │ │ ├── pri.resfiles.intermediate │ │ ├── qualifiers.txt.intermediate │ │ ├── resources.resfiles.intermediate │ │ ├── MultipleQualifiersPerDimensionFound.txt │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ ├── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ ├── Chimney.MPD.dll │ │ ├── Chimney.MPD.pdb │ │ ├── ChimneyMPD.dll │ │ ├── ChimneyMPD.pdb │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── Chimney.MPD.csprojResolveAssemblyReference.cache │ │ ├── ChimneyMPD.csproj.FileListAbsolute.txt │ │ ├── Chimney.MPD.csproj.FileListAbsolute.txt │ │ ├── priconfig.xml │ │ └── priconfig.xml.intermediate ├── bin │ ├── Debug │ │ ├── Chimney.MPD.dll │ │ ├── Chimney.MPD.pdb │ │ └── Chimney.MPD.pri │ └── Release │ │ ├── Chimney.MPD.dll │ │ ├── Chimney.MPD.pdb │ │ ├── Chimney.MPD.pri │ │ ├── ChimneyMPD.dll │ │ ├── ChimneyMPD.pdb │ │ └── ChimneyMPD.pri ├── Classes │ ├── TagType.cs │ ├── QueueJob.cs │ ├── Channel.cs │ ├── Message.cs │ ├── StoredPlaylist.cs │ ├── Output.cs │ ├── Stats.cs │ ├── SongTag.cs │ └── Status.cs ├── Chimney.MPD.csproj.vspscc ├── Properties │ └── AssemblyInfo.cs ├── Net │ └── Connection.cs ├── Chimney.MPD.csproj ├── ChimneyMPDEvent.cs ├── MPDKeyWords.cs ├── ChimneyMPDBase.cs ├── ChimneyMPDClient.cs └── ChimneyMPDDirectClient.cs ├── .gitattributes ├── .gitignore ├── Chimney.Shared └── UserControls │ └── ChimneyServerUserControl.xaml └── license.txt /Chimney.MPD/obj/Debug/layout.resfiles: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/pri.resfiles: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/qualifiers.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/pri.resfiles: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/qualifiers.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/resources.resfiles: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/layout.resfiles: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/resources.resfiles: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/pri.resfiles.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/layout.resfiles.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/qualifiers.txt.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/resources.resfiles.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/layout.resfiles.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/pri.resfiles.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/qualifiers.txt.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/resources.resfiles.intermediate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/MultipleQualifiersPerDimensionFound.txt: -------------------------------------------------------------------------------- 1 | False -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/MultipleQualifiersPerDimensionFound.txt: -------------------------------------------------------------------------------- 1 | False -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Chimney.MPD/bin/Debug/Chimney.MPD.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Debug/Chimney.MPD.dll -------------------------------------------------------------------------------- /Chimney.MPD/bin/Debug/Chimney.MPD.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Debug/Chimney.MPD.pdb -------------------------------------------------------------------------------- /Chimney.MPD/bin/Debug/Chimney.MPD.pri: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Debug/Chimney.MPD.pri -------------------------------------------------------------------------------- /Chimney.MPD/bin/Release/Chimney.MPD.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Release/Chimney.MPD.dll -------------------------------------------------------------------------------- /Chimney.MPD/bin/Release/Chimney.MPD.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Release/Chimney.MPD.pdb -------------------------------------------------------------------------------- /Chimney.MPD/bin/Release/Chimney.MPD.pri: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Release/Chimney.MPD.pri -------------------------------------------------------------------------------- /Chimney.MPD/bin/Release/ChimneyMPD.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Release/ChimneyMPD.dll -------------------------------------------------------------------------------- /Chimney.MPD/bin/Release/ChimneyMPD.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Release/ChimneyMPD.pdb -------------------------------------------------------------------------------- /Chimney.MPD/bin/Release/ChimneyMPD.pri: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/bin/Release/ChimneyMPD.pri -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/Chimney.MPD.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Debug/Chimney.MPD.dll -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/Chimney.MPD.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Debug/Chimney.MPD.pdb -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/Chimney.MPD.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Release/Chimney.MPD.dll -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/Chimney.MPD.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Release/Chimney.MPD.pdb -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/ChimneyMPD.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Release/ChimneyMPD.dll -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/ChimneyMPD.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Release/ChimneyMPD.pdb -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/MPD.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Debug/MPD.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/ChimneyMPD.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Debug/ChimneyMPD.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/Chimney.MPD.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Debug/Chimney.MPD.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/Chimney.MPD.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengd/Chimney/HEAD/Chimney.MPD/obj/Release/Chimney.MPD.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /Chimney.MPD/Classes/TagType.cs: -------------------------------------------------------------------------------- 1 | namespace Chimney.MPD.Classes 2 | { 3 | public enum TagType 4 | { 5 | File, Directory, Playlist, Album, Genre, Artist, FileOrDirectory, Search, Alphabet, Empty 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Chimney.MPD/Chimney.MPD.csproj.vspscc: -------------------------------------------------------------------------------- 1 | "" 2 | { 3 | "FILE_VERSION" = "9237" 4 | "ENLISTMENT_CHOICE" = "NEVER" 5 | "PROJECT_FILE_RELATIVE_PATH" = "" 6 | "NUMBER_OF_EXCLUDED_FILES" = "0" 7 | "ORIGINAL_PROJECT_FILE_PATH" = "" 8 | "NUMBER_OF_NESTED_PROJECTS" = "0" 9 | "SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER" 10 | } 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/QueueJob.cs: -------------------------------------------------------------------------------- 1 | namespace Chimney.MPD.Classes 2 | { 3 | class QueueJob 4 | { 5 | public int id = -1; 6 | public string send = ""; 7 | public bool retry = true; 8 | public bool silent = false; 9 | public bool wait = true; 10 | public string response = ""; 11 | 12 | public QueueJob() 13 | { 14 | 15 | } 16 | 17 | public QueueJob(int id, string send, bool silent = false, bool retry = true, bool wait = true) 18 | { 19 | this.id = id; 20 | this.send = send; 21 | this.retry = retry; 22 | this.silent = silent; 23 | this.wait = wait; 24 | } 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /Chimney.Shared/UserControls/ChimneyServerUserControl.xaml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Erik Johansson chimneyapp@outlook.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chimney.MPD/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("ChimneyMPD")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ChimneyMPD")] 14 | [assembly: AssemblyCopyright("Copyright © 2015")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/Channel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Chimney.MPD.Classes 4 | { 5 | public class Channel 6 | { 7 | public string channel { get; set; } 8 | 9 | public Channel(List> keyValuePairList) 10 | { 11 | if (keyValuePairList == null) return; 12 | 13 | foreach (var kv in keyValuePairList) 14 | { 15 | switch (kv.Key) 16 | { 17 | case "channel": 18 | this.channel = kv.Value; 19 | break; 20 | default: 21 | break; 22 | } 23 | } 24 | } 25 | 26 | public Channel(Dictionary dictionary) 27 | { 28 | foreach (string key in dictionary.Keys) 29 | { 30 | switch (key) 31 | { 32 | case "channel": 33 | this.channel = dictionary[key]; 34 | break; 35 | default: 36 | break; 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/Message.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Chimney.MPD.Classes 4 | { 5 | public class Message 6 | { 7 | public string message { get; set; } 8 | public Channel channel { get; set; } 9 | 10 | public Message(List> keyValuePairList) 11 | { 12 | if (keyValuePairList == null) return; 13 | 14 | foreach (var kv in keyValuePairList) 15 | { 16 | switch (kv.Key) 17 | { 18 | case "message": 19 | this.message = kv.Value; 20 | break; 21 | case "channel": 22 | this.channel = new Channel(new List>() { new KeyValuePair ("channel", kv.Value ) }); 23 | break; 24 | default: 25 | break; 26 | } 27 | } 28 | } 29 | 30 | public Message(Dictionary dictionary) 31 | { 32 | foreach (string key in dictionary.Keys) 33 | { 34 | switch (key) 35 | { 36 | case "message": 37 | this.message = dictionary[key]; 38 | break; 39 | case "channel": 40 | this.channel = new Channel(new Dictionary() { { "channel", dictionary[key] } }); 41 | break; 42 | default: 43 | break; 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/ChimneyMPD.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Release\ChimneyMPD.dll 2 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Release\ChimneyMPD.pdb 3 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Release\ChimneyMPD.pri 4 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\ChimneyMPD.dll 5 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\ChimneyMPD.pdb 6 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\priconfig.xml 7 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\priconfig.xml.intermediate 8 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\layout.resfiles 9 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\layout.resfiles.intermediate 10 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\resources.resfiles 11 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\resources.resfiles.intermediate 12 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\pri.resfiles 13 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\pri.resfiles.intermediate 14 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\qualifiers.txt 15 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\qualifiers.txt.intermediate 16 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\MultipleQualifiersPerDimensionFound.txt 17 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/MPD.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\MPD.csprojResolveAssemblyReference.cache 2 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Debug\ChimneyMPD.dll 3 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Debug\ChimneyMPD.pdb 4 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Debug\ChimneyMPD.pri 5 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\ChimneyMPD.dll 6 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\ChimneyMPD.pdb 7 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\priconfig.xml 8 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\priconfig.xml.intermediate 9 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\layout.resfiles 10 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\layout.resfiles.intermediate 11 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\resources.resfiles 12 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\resources.resfiles.intermediate 13 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\pri.resfiles 14 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\pri.resfiles.intermediate 15 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\qualifiers.txt 16 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\qualifiers.txt.intermediate 17 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\MultipleQualifiersPerDimensionFound.txt 18 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/ChimneyMPD.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Debug\ChimneyMPD.dll 2 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Debug\ChimneyMPD.pdb 3 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Debug\ChimneyMPD.pri 4 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\ChimneyMPD.csprojResolveAssemblyReference.cache 5 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\ChimneyMPD.dll 6 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\ChimneyMPD.pdb 7 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\priconfig.xml 8 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\priconfig.xml.intermediate 9 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\layout.resfiles 10 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\layout.resfiles.intermediate 11 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\resources.resfiles 12 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\resources.resfiles.intermediate 13 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\pri.resfiles 14 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\pri.resfiles.intermediate 15 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\qualifiers.txt 16 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\qualifiers.txt.intermediate 17 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Debug\MultipleQualifiersPerDimensionFound.txt 18 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/Chimney.MPD.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Release\Chimney.MPD.dll 2 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Release\Chimney.MPD.pdb 3 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\bin\Release\Chimney.MPD.pri 4 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\Chimney.MPD.csprojResolveAssemblyReference.cache 5 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\Chimney.MPD.dll 6 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\Chimney.MPD.pdb 7 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\priconfig.xml 8 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\priconfig.xml.intermediate 9 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\layout.resfiles 10 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\layout.resfiles.intermediate 11 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\resources.resfiles 12 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\resources.resfiles.intermediate 13 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\pri.resfiles 14 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\pri.resfiles.intermediate 15 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\qualifiers.txt 16 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\qualifiers.txt.intermediate 17 | C:\Users\ejevi_000\Documents\Visual Studio 2013\Projects\Chimney\ChimneyMPD\obj\Release\MultipleQualifiersPerDimensionFound.txt 18 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/StoredPlaylist.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Chimney.MPD.Classes 5 | { 6 | public class StoredPlaylist 7 | { 8 | public string Playlist { get; set; } 9 | public string LastModified { get; set; } 10 | 11 | public override string ToString() 12 | { 13 | string storedplayliststring = string.Empty; 14 | 15 | storedplayliststring = storedplayliststring + "playlist: " + this.Playlist + "\n"; 16 | if (string.IsNullOrEmpty(this.LastModified)) storedplayliststring = storedplayliststring + "Last-Modified: " + this.LastModified + "\n"; 17 | else storedplayliststring = storedplayliststring + "Last-Modified: " + TimeSpan.FromSeconds(0) + "\n"; 18 | 19 | return storedplayliststring; 20 | } 21 | 22 | public StoredPlaylist() 23 | { 24 | 25 | } 26 | 27 | public StoredPlaylist(List> keyValuePairList) 28 | { 29 | foreach (var kv in keyValuePairList) 30 | { 31 | switch (kv.Key) 32 | { 33 | case "playlist": 34 | this.Playlist = kv.Value; 35 | break; 36 | case "Last-Modified": 37 | this.LastModified = kv.Value; 38 | break; 39 | default: 40 | break; 41 | } 42 | } 43 | } 44 | 45 | public StoredPlaylist(Dictionary dictionary) 46 | { 47 | foreach (string key in dictionary.Keys) 48 | { 49 | switch (key) 50 | { 51 | case "playlist": 52 | this.Playlist = dictionary[key]; 53 | break; 54 | case "Last-Modified": 55 | this.LastModified = dictionary[key]; 56 | break; 57 | default: 58 | break; 59 | } 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/priconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/priconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Debug/priconfig.xml.intermediate: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Chimney.MPD/obj/Release/priconfig.xml.intermediate: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/Output.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Chimney.MPD.Classes 5 | { 6 | public class Output 7 | { 8 | public string outputname { get; set; } 9 | public bool outputenabled { get; set; } 10 | public string outputid { get; set; } 11 | 12 | public Output() 13 | { 14 | 15 | } 16 | 17 | public Output(List> keyValuePair) 18 | { 19 | if (keyValuePair == null) return; 20 | 21 | foreach(var kv in keyValuePair) 22 | { 23 | switch (kv.Key) 24 | { 25 | case "outputname": 26 | this.outputname = kv.Value; 27 | break; 28 | case "outputenabled": 29 | this.outputenabled = Convert.ToBoolean(Convert.ToInt32(kv.Value)); 30 | break; 31 | case "outputid": 32 | this.outputid = kv.Value; 33 | break; 34 | default: 35 | break; 36 | } 37 | } 38 | } 39 | 40 | public Output(Dictionary dictionary) 41 | { 42 | foreach (string key in dictionary.Keys) 43 | { 44 | switch (key) 45 | { 46 | case "outputname": 47 | this.outputname = dictionary[key]; 48 | break; 49 | case "outputenabled": 50 | this.outputenabled = Convert.ToBoolean(Convert.ToInt32(dictionary[key])); 51 | break; 52 | case "outputid": 53 | this.outputid = dictionary[key]; 54 | break; 55 | default: 56 | break; 57 | } 58 | } 59 | } 60 | 61 | public override string ToString() 62 | { 63 | string returnstring = string.Empty; 64 | returnstring += "outputid: " + this.outputid + "\n"; 65 | returnstring += "outputname: " + this.outputname + "\n"; 66 | returnstring += "outputenabled: " + Convert.ToInt32(this.outputenabled) + "\n"; 67 | 68 | return returnstring; 69 | } 70 | 71 | public string ToJson() 72 | { 73 | return "{\n" + "\"outputname\": " + "\"" + this.outputname + "\"," + 74 | "\n\"outputenabled\": " + "\"" + this.outputname + "\"," + 75 | "\n\"outputid\": " + "\"" + this.outputid + "\"" + "\n}"; 76 | } 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /Chimney.MPD/Net/Connection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Windows.Networking; 9 | using Windows.Networking.Sockets; 10 | using Windows.Storage.Streams; 11 | 12 | namespace Chimney.MPD.Net 13 | { 14 | class Connection 15 | { 16 | private bool _Connected; 17 | public bool Connected 18 | { 19 | get 20 | { 21 | return _Connected; 22 | } 23 | } 24 | 25 | private StreamSocket _streamSocket; 26 | public StreamSocket Socket 27 | { 28 | get 29 | { 30 | return _streamSocket; 31 | } 32 | } 33 | 34 | private string _host; 35 | private string _port; 36 | 37 | public void Close() 38 | { 39 | try 40 | { 41 | _streamSocket.Dispose(); 42 | } 43 | catch (Exception ex) 44 | { 45 | Debug.WriteLine(ex.Message); 46 | } 47 | } 48 | 49 | public async Task Connect(string host, string port, int timeout = 0) 50 | { 51 | _streamSocket = new StreamSocket(); 52 | _streamSocket.Control.KeepAlive = true; 53 | _streamSocket.Control.QualityOfService = SocketQualityOfService.Normal; 54 | 55 | var cts = new CancellationTokenSource(); 56 | 57 | _host = host; 58 | _port = port; 59 | 60 | try 61 | { 62 | if(timeout > 0) 63 | { 64 | cts.CancelAfter(timeout); 65 | await _streamSocket.ConnectAsync(new HostName(host), port).AsTask(cts.Token); 66 | } 67 | else 68 | await _streamSocket.ConnectAsync(new HostName(host), port); 69 | 70 | _Connected = true; 71 | } 72 | catch (Exception ex) 73 | { 74 | Debug.WriteLine(ex.Message); 75 | 76 | Close(); 77 | 78 | _streamSocket = null; 79 | 80 | _host = null; 81 | _port = null; 82 | 83 | _Connected = false; 84 | } 85 | 86 | return _Connected; 87 | } 88 | 89 | public static async Task Recive(StreamSocket streamSocket, List orstarts, List orends, List andstarts, List andends) 90 | { 91 | string returnString = string.Empty; 92 | 93 | try 94 | { 95 | using (var dataReader = new DataReader(streamSocket.InputStream)) 96 | { 97 | dataReader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; 98 | dataReader.InputStreamOptions = InputStreamOptions.Partial; 99 | 100 | var end = false; 101 | 102 | while (!end && await dataReader.LoadAsync(64000) != 0) 103 | { 104 | string readString; 105 | var buffer = dataReader.ReadBuffer(dataReader.UnconsumedBufferLength); 106 | using (var dr = DataReader.FromBuffer(buffer)) 107 | { 108 | var bytes1251 = new Byte[buffer.Length]; 109 | dr.ReadBytes(bytes1251); 110 | 111 | readString = Encoding.GetEncoding("UTF-8").GetString(bytes1251, 0, bytes1251.Length); 112 | } 113 | 114 | if (!string.IsNullOrEmpty(readString)) 115 | returnString += readString; 116 | 117 | if (readString == null) 118 | { 119 | end = true; 120 | } 121 | else if (orstarts.FirstOrDefault(o => returnString.StartsWith(o)) != null) 122 | { 123 | end = true; 124 | } 125 | else if (orends.FirstOrDefault(o => returnString.EndsWith(o)) != null) 126 | { 127 | end = true; 128 | } 129 | else if (andstarts.FirstOrDefault(o => returnString.StartsWith(o)) != null 130 | && andends.FirstOrDefault(o => returnString.EndsWith(o)) != null) 131 | { 132 | end = true; 133 | } 134 | } 135 | 136 | dataReader.DetachStream(); 137 | } 138 | } 139 | catch(Exception ex) 140 | { 141 | Debug.WriteLine(ex.Message); 142 | returnString = string.Empty; 143 | } 144 | 145 | return returnString; 146 | } 147 | 148 | 149 | 150 | public static async Task Send(StreamSocket streamSocket, string send) 151 | { 152 | var bytearray = Encoding.GetEncoding("UTF-8").GetBytes(send); 153 | 154 | var success = true; 155 | try 156 | { 157 | using (var dataWriter = new DataWriter(streamSocket.OutputStream)) 158 | { 159 | dataWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; 160 | 161 | dataWriter.WriteBytes(bytearray); 162 | 163 | await dataWriter.StoreAsync(); 164 | 165 | await dataWriter.FlushAsync(); 166 | 167 | dataWriter.DetachStream(); 168 | } 169 | } 170 | catch (Exception ex) 171 | { 172 | Debug.WriteLine(ex.Message); 173 | success = false; 174 | } 175 | 176 | return success; 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /Chimney.MPD/Chimney.MPD.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FC9A0095-F01A-4A14-A16C-EDF6EFECF16C} 8 | Library 9 | Properties 10 | Chimney.MPD 11 | Chimney.MPD 12 | en-US 13 | UAP 14 | 10.0.10240.0 15 | 10.0.10240.0 16 | 14 17 | 512 18 | {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 19 | 20 | 21 | AnyCPU 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 27 | prompt 28 | 4 29 | 30 | 31 | AnyCPU 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE;NETFX_CORE;WINDOWS_UWP 36 | prompt 37 | 4 38 | 39 | 40 | ARM 41 | true 42 | bin\ARM\Debug\ 43 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 44 | ;2008 45 | full 46 | ARM 47 | false 48 | prompt 49 | true 50 | 51 | 52 | ARM 53 | bin\ARM\Release\ 54 | TRACE;NETFX_CORE;WINDOWS_UWP 55 | true 56 | ;2008 57 | pdbonly 58 | ARM 59 | false 60 | prompt 61 | true 62 | 63 | 64 | x64 65 | true 66 | bin\x64\Debug\ 67 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 68 | ;2008 69 | full 70 | x64 71 | false 72 | prompt 73 | true 74 | 75 | 76 | x64 77 | bin\x64\Release\ 78 | TRACE;NETFX_CORE;WINDOWS_UWP 79 | true 80 | ;2008 81 | pdbonly 82 | x64 83 | false 84 | prompt 85 | true 86 | 87 | 88 | x86 89 | true 90 | bin\x86\Debug\ 91 | DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP 92 | ;2008 93 | full 94 | x86 95 | false 96 | prompt 97 | true 98 | 99 | 100 | x86 101 | bin\x86\Release\ 102 | TRACE;NETFX_CORE;WINDOWS_UWP 103 | true 104 | ;2008 105 | pdbonly 106 | x86 107 | false 108 | prompt 109 | true 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 14.0 137 | 138 | 139 | 146 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/Stats.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Chimney.MPD.Classes 5 | { 6 | public class Stats 7 | { 8 | private string _albums; 9 | public string Albums 10 | { 11 | get 12 | { 13 | return (string.IsNullOrEmpty(this._albums)) ? "0" : this._albums; //string.Empty; 14 | } 15 | set 16 | { 17 | this._albums = value; 18 | } 19 | } 20 | 21 | private string _artists; 22 | public string Artists 23 | { 24 | get 25 | { 26 | return (string.IsNullOrEmpty(this._artists)) ? "0" : this._artists; 27 | } 28 | set 29 | { 30 | this._artists = value; 31 | } 32 | } 33 | 34 | private string _songs; 35 | public string Songs 36 | { 37 | get 38 | { 39 | return (string.IsNullOrEmpty(this._songs)) ? "0" : this._songs; 40 | } 41 | set 42 | { 43 | this._songs = value; 44 | } 45 | } 46 | private string _uptime; 47 | public string Uptime 48 | { 49 | get 50 | { 51 | if (string.IsNullOrEmpty(this._uptime)) return string.Empty; 52 | TimeSpan timeSpan = TimeSpan.FromSeconds(Convert.ToInt32(this._uptime)); 53 | return timeSpan.Days + "d " + timeSpan.Hours + "h " + 54 | timeSpan.Minutes + "m " + timeSpan.Seconds + "s"; 55 | } 56 | set 57 | { 58 | this._uptime = value; 59 | } 60 | } 61 | 62 | private string _db_playtime; 63 | public string DbPlaytime 64 | { 65 | get 66 | { 67 | if (string.IsNullOrEmpty(this._db_playtime)) return string.Empty; 68 | TimeSpan timeSpan = TimeSpan.FromSeconds(Convert.ToInt32(this._db_playtime)); 69 | return timeSpan.Days + "d " + timeSpan.Hours + "h " + 70 | timeSpan.Minutes + "m " + timeSpan.Seconds + "s"; 71 | } 72 | set 73 | { 74 | this._db_playtime = value; 75 | } 76 | } 77 | 78 | private string _db_update; 79 | public string DbUpdate 80 | { 81 | get 82 | { 83 | if (string.IsNullOrEmpty(this._db_update)) return string.Empty; 84 | DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); 85 | dateTime = dateTime.AddSeconds(Convert.ToDouble(this._db_update)).ToLocalTime(); 86 | TimeSpan timeSpan = DateTime.Now - dateTime; 87 | return timeSpan.Days + "d " + timeSpan.Hours + "h " + 88 | timeSpan.Minutes + "m " + timeSpan.Seconds + "s"; 89 | } 90 | set 91 | { 92 | this._db_update = value; 93 | } 94 | } 95 | 96 | public TimeSpan DbUpdateTimeSpan 97 | { 98 | get 99 | { 100 | if (string.IsNullOrEmpty(this._db_update)) return new TimeSpan(); 101 | DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0); 102 | dateTime = dateTime.AddSeconds(Convert.ToDouble(this._db_update)).ToLocalTime(); 103 | return DateTime.Now - dateTime; 104 | } 105 | } 106 | 107 | private string _playtime; 108 | public string Playtime 109 | { 110 | get 111 | { 112 | if (string.IsNullOrEmpty(this._playtime)) return string.Empty; 113 | TimeSpan timeSpan = TimeSpan.FromSeconds(Convert.ToInt32(this._playtime)); 114 | return timeSpan.Days + "d " + timeSpan.Hours + "h " + 115 | timeSpan.Minutes + "m " + timeSpan.Seconds + "s"; 116 | } 117 | set 118 | { 119 | this._playtime = value; 120 | } 121 | } 122 | 123 | public override string ToString() 124 | { 125 | string statstext = string.Empty; 126 | 127 | if(!string.IsNullOrEmpty(this.Artists)) statstext = statstext + "artists: " + this.Artists + "\n"; 128 | else statstext = statstext + "artists: 0\n"; 129 | 130 | if (!string.IsNullOrEmpty(this.Albums)) statstext = statstext + "albums: " + this.Albums + "\n"; 131 | else statstext = statstext + "albums: 0\n"; 132 | 133 | if (!string.IsNullOrEmpty(this.Songs)) statstext = statstext + "songs: " + this.Songs + "\n"; 134 | else statstext = statstext + "songs: 0\n"; 135 | 136 | if (!string.IsNullOrEmpty(this.Uptime)) statstext = statstext + "uptime: " + this.Uptime + "\n"; 137 | else statstext = statstext + "uptime: 0\n"; 138 | 139 | if (!string.IsNullOrEmpty(this.DbPlaytime)) statstext = statstext + "db_playtime: " + this._db_playtime + "\n"; 140 | else statstext = statstext + "db_playtime: 0\n"; 141 | 142 | if (!string.IsNullOrEmpty(this.DbUpdate)) statstext = statstext + "db_update: " + this.DbUpdate + "\n"; 143 | else statstext = statstext + "db_update: 0\n"; 144 | 145 | if (!string.IsNullOrEmpty(this.Playtime)) statstext = statstext + "playtime: " + this.Playtime + "\n"; 146 | else statstext = statstext + "playtime: 0\n"; 147 | 148 | return statstext; 149 | } 150 | 151 | public Stats() 152 | { 153 | } 154 | 155 | public Stats(List> keyValuePair) 156 | { 157 | if (keyValuePair == null) return; 158 | 159 | foreach (var kv in keyValuePair) 160 | { 161 | switch (kv.Key) 162 | { 163 | case "artists": 164 | this.Artists = kv.Value; 165 | break; 166 | case "albums": 167 | this.Albums = kv.Value; 168 | break; 169 | case "songs": 170 | this.Songs = kv.Value; 171 | break; 172 | case "uptime": 173 | this.Uptime = kv.Value; 174 | break; 175 | case "db_playtime": 176 | this.DbPlaytime = kv.Value; 177 | break; 178 | case "db_update": 179 | this.DbUpdate = kv.Value; 180 | break; 181 | case "playtime": 182 | this.Playtime = kv.Value; 183 | break; 184 | default: 185 | break; 186 | } 187 | } 188 | } 189 | 190 | public Stats(Dictionary dictionary) 191 | { 192 | foreach (string key in dictionary.Keys) 193 | { 194 | switch (key) 195 | { 196 | case "artists": 197 | this.Artists = dictionary[key]; 198 | break; 199 | case "albums": 200 | this.Albums = dictionary[key]; 201 | break; 202 | case "songs": 203 | this.Songs = dictionary[key]; 204 | break; 205 | case "uptime": 206 | this.Uptime = dictionary[key]; 207 | break; 208 | case "db_playtime": 209 | this.DbPlaytime = dictionary[key]; 210 | break; 211 | case "db_update": 212 | this.DbUpdate = dictionary[key]; 213 | break; 214 | case "playtime": 215 | this.Playtime = dictionary[key]; 216 | break; 217 | default: 218 | break; 219 | } 220 | } 221 | } 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /Chimney.MPD/ChimneyMPDEvent.cs: -------------------------------------------------------------------------------- 1 | using Chimney.MPD.Classes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Threading.Tasks; 5 | 6 | namespace Chimney.MPD 7 | { 8 | public class PlaylistEventArgs : EventArgs 9 | { 10 | public List playlist; 11 | public List playlistchanges; 12 | public Status status; 13 | public SongTag currentsong; 14 | 15 | public PlaylistEventArgs(List playlist, List playlistchanges, Status status, SongTag currentsong) 16 | { 17 | this.playlist = playlist; 18 | this.playlistchanges = playlistchanges; 19 | this.status = status; 20 | this.currentsong = currentsong; 21 | 22 | } 23 | } 24 | 25 | public class StoredPlaylistEventArgs : EventArgs 26 | { 27 | public List storedplaylists; 28 | 29 | public StoredPlaylistEventArgs(List storedplaylists) 30 | { 31 | this.storedplaylists = storedplaylists; 32 | } 33 | } 34 | 35 | public class StatusEventArgs : EventArgs 36 | { 37 | public Status status; 38 | 39 | public StatusEventArgs(Status status) 40 | { 41 | this.status = status; 42 | } 43 | } 44 | 45 | public class StatsEventArgs : EventArgs 46 | { 47 | public Stats stats; 48 | 49 | public StatsEventArgs(Stats stats) 50 | { 51 | this.stats = stats; 52 | } 53 | } 54 | 55 | public class UpdateEventArgs : EventArgs 56 | { 57 | public Status status; 58 | public bool IsUpdating; 59 | public Stats stats; 60 | 61 | public UpdateEventArgs(Status status, bool IsUpdating, Stats stats) 62 | { 63 | this.status = status; 64 | this.IsUpdating = IsUpdating; 65 | this.stats = stats; 66 | } 67 | } 68 | 69 | public class PlayerEventArgs : EventArgs 70 | { 71 | public SongTag currentsong; 72 | public Status status; 73 | 74 | public PlayerEventArgs(SongTag currentsong, Status status) 75 | { 76 | this.currentsong = currentsong; 77 | this.status = status; 78 | } 79 | } 80 | 81 | public class OutputEventArgs : EventArgs 82 | { 83 | public List outputs; 84 | public Status status; 85 | 86 | public OutputEventArgs(List outputs, Status status) 87 | { 88 | this.outputs = outputs; 89 | this.status = status; 90 | } 91 | } 92 | 93 | public class MessageEventArgs : EventArgs 94 | { 95 | public List messages; 96 | 97 | public MessageEventArgs(List messages) 98 | { 99 | this.messages = messages; 100 | } 101 | } 102 | 103 | public class ChimneyMPDEvent : ChimneyMPDClient 104 | { 105 | public delegate void PlaylistEventHandler(object sender, PlaylistEventArgs e); 106 | public delegate void StatusEventHandler(object sender, StatusEventArgs e); 107 | public delegate void PlayerEventHandler(object sender, PlayerEventArgs e); 108 | public delegate void OutputEventHandler(object sender, OutputEventArgs e); 109 | public delegate void StoredPlaylistEventHandler(object sender, StoredPlaylistEventArgs e); 110 | public delegate void UpdateEventHandler(object sender, UpdateEventArgs e); 111 | public delegate void StatsEventHandler(object sender, StatsEventArgs e); 112 | public delegate void MessageEventHandler(object sender, MessageEventArgs e); 113 | public event StatsEventHandler OnDatabase; 114 | public event UpdateEventHandler OnUpdate; 115 | public event StoredPlaylistEventHandler OnStoredPlaylist; 116 | public event PlaylistEventHandler OnPlaylist; 117 | public event PlayerEventHandler OnPlayer; 118 | public event StatusEventHandler OnMixer; 119 | public event OutputEventHandler OnOutput; 120 | public event StatusEventHandler OnOptions; 121 | public event EventHandler OnSticker; 122 | public event EventHandler OnSubscription; 123 | public event MessageEventHandler OnMessage; 124 | 125 | //private bool idle = true; 126 | 127 | // 128 | // Connect to MPD server 129 | // 130 | 131 | //ChimneyMPDClient actionChimeny; 132 | public bool silent = false; 133 | 134 | Status status; 135 | 136 | public async Task RefreshConnection(Status status = null) 137 | { 138 | //idle = false; 139 | await Stop(); 140 | bool suc = await Start(status, false); 141 | return suc; 142 | } 143 | 144 | public async Task Start(Status status = null, bool silent = false) 145 | { 146 | var success = await Connect(this.host, this.port, this.password, silent); 147 | 148 | if (success) 149 | { 150 | if (status == null) this.status = await GetStatus(); 151 | else this.status = status; 152 | 153 | idle = true; 154 | 155 | IdleEventLoop(); 156 | } 157 | else idle = false; 158 | 159 | return success; 160 | } 161 | 162 | void actionChimeny_ConnectionProblem(object sender, EventArgs e) 163 | { 164 | connectionproblem = true; 165 | SendConnectionProblem(); 166 | } 167 | 168 | public async Task Stop(bool connectionproblem = false) 169 | { 170 | this.connectionproblem = connectionproblem; 171 | idle = false; 172 | if(!this.connectionproblem) 173 | await this.NoIdle(); 174 | await this.Close(this.connectionproblem); 175 | } 176 | 177 | private async Task ActionOnEventLoop() 178 | { 179 | 180 | Status status = null; 181 | Stats stats = null; 182 | SongTag currentsong = null; 183 | 184 | for (int i = 0; i < responselist.Count; i++) 185 | { 186 | string response = responselist[i]; 187 | 188 | switch (response) 189 | { 190 | case ("database"): 191 | if (stats == null) stats = await this.Stats(); 192 | if (OnDatabase != null) OnDatabase(this, new StatsEventArgs(stats)); 193 | break; 194 | case ("update"): 195 | if (status == null) status = await this.GetStatus(); 196 | if (stats == null) stats = await this.Stats(); 197 | if (OnUpdate != null) OnUpdate(this, new UpdateEventArgs(status, status.IsDbUpdating, stats)); 198 | break; 199 | case ("stored_playlist"): 200 | if (OnStoredPlaylist != null) OnStoredPlaylist(this, new StoredPlaylistEventArgs(await this.ListPlaylists())); 201 | break; 202 | case ("playlist"): 203 | if (currentsong == null) currentsong = await this.CurrentSong(); 204 | if (status == null) status = await this.GetStatus(); 205 | List playlist = await this.Playlist(); 206 | List playlistchanges = await this.PlaylistChanges(this.status.Playlist); 207 | if (OnPlaylist != null) OnPlaylist(this, new PlaylistEventArgs(playlist, playlistchanges, status, currentsong)); 208 | break; 209 | case ("player"): 210 | if (currentsong == null) currentsong = await this.CurrentSong(); 211 | if (status == null) status = await this.GetStatus(); 212 | if (OnPlayer != null) OnPlayer(this, new PlayerEventArgs(currentsong, status)); 213 | break; 214 | case ("mixer"): 215 | if (status == null) status = await this.GetStatus(); 216 | if (OnMixer != null) OnMixer(this, new StatusEventArgs(status)); 217 | break; 218 | case ("output"): 219 | if (status == null) status = await this.GetStatus(); 220 | if (OnOutput != null) OnOutput(this, new OutputEventArgs(await this.Outputs(), status)); 221 | break; 222 | case ("options"): 223 | if (status == null) status = await this.GetStatus(); 224 | if (OnOptions != null) OnOptions(this, new StatusEventArgs(status)); 225 | break; 226 | case ("sticker"): 227 | if (OnSticker != null) OnSticker(this, new EventArgs()); 228 | break; 229 | case ("subscription"): 230 | //if (OnSubscription != null) OnSubscription(this, new EventArgs()); 231 | break; 232 | case ("message"): 233 | //if (OnMessage != null) OnMessage(this, new MessageEventArgs(await ReadMessages())); 234 | break; 235 | default: 236 | break; 237 | } 238 | } 239 | if (status != null) this.status = status; 240 | 241 | } 242 | 243 | List responselist; 244 | 245 | private async Task IdleEventLoop() 246 | { 247 | int attemps = 3; 248 | 249 | while(idle) 250 | { 251 | List tempresponselist = await Idle(); 252 | 253 | if (tempresponselist.Count > 0) 254 | { 255 | await NoIdle(); 256 | responselist = tempresponselist; 257 | await ActionOnEventLoop(); 258 | attemps = 3; 259 | idle = true; 260 | } 261 | else if (attemps > 0 && idle) 262 | { 263 | await Connect(this.host, this.port, this.password, false); 264 | attemps--; 265 | } 266 | else if(idle) 267 | { 268 | idle = false; 269 | attemps = 3; 270 | connectionproblem = true; 271 | SendConnectionProblem(); 272 | } 273 | } 274 | } 275 | 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/SongTag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | using Windows.Storage; 7 | 8 | namespace Chimney.MPD.Classes 9 | { 10 | public class SongTag 11 | { 12 | public TagType TagType { get; set; } 13 | 14 | private bool _isEmpty; 15 | 16 | public bool IsEmpty 17 | { 18 | get { return this._isEmpty; } 19 | set { _isEmpty = value; } 20 | } 21 | 22 | public int Hash 23 | { 24 | get 25 | { 26 | return (file + Title + Artist + Album + directory + playlist).GetHashCode(); 27 | } 28 | } 29 | 30 | private string _file; 31 | public string file 32 | { 33 | get 34 | { 35 | if (string.IsNullOrEmpty(_file)) return string.Empty; 36 | return _file; 37 | } 38 | set 39 | { 40 | _file = value; 41 | } 42 | } 43 | 44 | private string _directory; 45 | public string directory 46 | { 47 | get 48 | { 49 | if (string.IsNullOrEmpty(_directory)) return string.Empty; 50 | return _directory; 51 | } 52 | set 53 | { 54 | _directory = value; 55 | file = _directory; 56 | } 57 | } 58 | 59 | private string _playlist; 60 | public string playlist 61 | { 62 | get 63 | { 64 | if (string.IsNullOrEmpty(_playlist)) return string.Empty; 65 | return _playlist; 66 | } 67 | set 68 | { 69 | _playlist = value; 70 | } 71 | } 72 | 73 | private string _LastModified; 74 | public string LastModified 75 | { 76 | get 77 | { 78 | if (string.IsNullOrEmpty(_LastModified)) return string.Empty; 79 | return _LastModified; 80 | } 81 | set 82 | { 83 | _LastModified = value; 84 | } 85 | } 86 | 87 | private int _Time = 0; 88 | public int Time 89 | { 90 | get { return _Time; } 91 | set { _Time = value; } 92 | } 93 | 94 | public string TimeToString 95 | { 96 | get 97 | { 98 | if (Time == 0) return string.Empty; 99 | return (TimeSpan.FromSeconds(Time)).ToString(); 100 | } 101 | } 102 | 103 | private string _Artist; 104 | public string Artist 105 | { 106 | get 107 | { 108 | return (!string.IsNullOrEmpty(_Artist)) ? _Artist : string.Empty; 109 | } 110 | set 111 | { 112 | _Artist = value; 113 | } 114 | } 115 | 116 | private string _Title; 117 | public string Title 118 | { 119 | get 120 | { 121 | if (string.IsNullOrEmpty(_Title) && !string.IsNullOrEmpty(_file)) 122 | { 123 | string[] s = file.Split("/".ToCharArray()); 124 | return string.IsNullOrEmpty(s.Last()) ? _file : s.Last(); 125 | } 126 | else if (string.IsNullOrEmpty(_Title) && !string.IsNullOrEmpty(playlist)) return playlist; 127 | else if (string.IsNullOrEmpty(_Title)) return string.Empty; 128 | 129 | return _Title; 130 | } 131 | set 132 | { 133 | _Title = value; 134 | } 135 | } 136 | 137 | private string _Name; 138 | public string Name 139 | { 140 | get 141 | { return _Name; } 142 | set 143 | { 144 | _Name = value; 145 | } 146 | } 147 | 148 | private string _Album; 149 | public string Album 150 | { 151 | get 152 | { 153 | if (string.IsNullOrEmpty(_Album)) return string.Empty; 154 | return _Album; 155 | } 156 | set 157 | { 158 | _Album = value; 159 | } 160 | } 161 | 162 | private string _Date; 163 | public string Date 164 | { 165 | get 166 | { 167 | if (string.IsNullOrEmpty(_Date)) return string.Empty; 168 | return _Date; 169 | } 170 | set 171 | { 172 | _Date = value; 173 | } 174 | } 175 | 176 | private string _Genre; 177 | public string Genre 178 | { 179 | get 180 | { 181 | if (string.IsNullOrEmpty(_Genre)) return string.Empty; 182 | return _Genre; 183 | } 184 | set 185 | { 186 | _Genre = value; 187 | } 188 | } 189 | 190 | private string _Track; 191 | public string Track 192 | { 193 | get 194 | { 195 | if (string.IsNullOrEmpty(_Track)) return string.Empty; 196 | return _Track; 197 | } 198 | set 199 | { 200 | _Track = value; 201 | } 202 | } 203 | 204 | private string _AlbumArtist; 205 | public string AlbumArtist 206 | { 207 | get 208 | { 209 | if (string.IsNullOrEmpty(_AlbumArtist)) return string.Empty; 210 | return _AlbumArtist; 211 | } 212 | set 213 | { 214 | _AlbumArtist = value; 215 | } 216 | } 217 | 218 | private string _Disc; 219 | public string Disc 220 | { 221 | get 222 | { 223 | if (string.IsNullOrEmpty(_Disc)) return string.Empty; 224 | return _Disc; 225 | } 226 | set 227 | { 228 | _Disc = value; 229 | } 230 | } 231 | 232 | private int _pos = -1; 233 | public int Pos 234 | { 235 | get 236 | { 237 | return _pos; 238 | } 239 | set { 240 | _pos = value; 241 | } 242 | } 243 | public int Id = -1; 244 | public int Prio 245 | { 246 | get; set; 247 | } 248 | 249 | public List> SourceList { get; set; } 250 | 251 | public static SongTag Empty 252 | { 253 | get 254 | { 255 | return new SongTag(); 256 | } 257 | } 258 | 259 | public SongTag() 260 | { 261 | this._isEmpty = true; 262 | TagType = TagType.Empty; 263 | } 264 | 265 | public SongTag(TagType tagType, List> keyValuePairList, int pos) 266 | { 267 | Init(tagType, keyValuePairList, null); 268 | 269 | this.Pos = pos; 270 | } 271 | public SongTag(TagType tagType, List> keyValuePairList, int pos, string playlist) 272 | { 273 | Init(tagType, keyValuePairList, null); 274 | 275 | this.Pos = pos; 276 | this.playlist = playlist; 277 | } 278 | 279 | public SongTag(TagType tagType, List> keyValuePairList) 280 | { 281 | Init(tagType, keyValuePairList, null); 282 | } 283 | 284 | public SongTag(List> keyValuePairList, int Pos) 285 | { 286 | if (keyValuePairList == null) return; 287 | 288 | TagType tagType; 289 | 290 | var first = keyValuePairList.FirstOrDefault(); 291 | 292 | switch (first.Key) 293 | { 294 | case ("Artist"): 295 | tagType = TagType.Artist; 296 | break; 297 | case ("Album"): 298 | tagType = TagType.Album; 299 | break; 300 | case ("Genre"): 301 | tagType = TagType.Genre; 302 | break; 303 | default: 304 | tagType = TagType.FileOrDirectory; 305 | break; 306 | } 307 | 308 | Init(tagType, keyValuePairList, null); 309 | this.Pos = Pos; 310 | } 311 | 312 | private void Init(TagType tagType, List> list, List playlist = null) 313 | { 314 | if (list == null) list = new List>(); 315 | 316 | this.TagType = tagType; 317 | 318 | this.SourceList = list; 319 | 320 | this._isEmpty = (list.Count == 0) ? true : false; 321 | 322 | bool convsuc = false; 323 | int convi = 0; 324 | 325 | foreach (var keyValuePair in list) 326 | { 327 | switch (keyValuePair.Key) 328 | { 329 | case "file": 330 | this.file = keyValuePair.Value; 331 | if (tagType == TagType.FileOrDirectory) this.TagType = TagType.File; 332 | break; 333 | case "directory": 334 | this.directory = keyValuePair.Value; 335 | if (tagType == TagType.FileOrDirectory) this.TagType = TagType.Directory; 336 | break; 337 | case "playlist": 338 | this.playlist = keyValuePair.Value; 339 | this.TagType = TagType.Playlist; 340 | break; 341 | case "Last-Modified": 342 | this.LastModified = keyValuePair.Value; 343 | break; 344 | case "Time": 345 | convsuc = int.TryParse(keyValuePair.Value, out convi); 346 | this.Time = (convsuc) ? convi : 0; 347 | break; 348 | case "Artist": 349 | this.Artist = keyValuePair.Value; 350 | break; 351 | case "Title": 352 | this.Title = keyValuePair.Value; 353 | break; 354 | case "Album": 355 | this.Album = keyValuePair.Value; 356 | break; 357 | case "Date": 358 | this.Date = keyValuePair.Value; 359 | break; 360 | case "Genre": 361 | this.Genre = keyValuePair.Value; 362 | break; 363 | case "Track": 364 | this.Track = keyValuePair.Value; 365 | break; 366 | case "AlbumArtist": 367 | this.AlbumArtist = keyValuePair.Value; 368 | break; 369 | case "Disc": 370 | this.Disc = keyValuePair.Value; 371 | break; 372 | case "Name": 373 | this.Name = keyValuePair.Value; 374 | break; 375 | case "Pos": 376 | convsuc = int.TryParse(keyValuePair.Value, out convi); 377 | this.Pos = (convsuc) ? convi : 0; 378 | break; 379 | case "Id": 380 | convsuc = int.TryParse(keyValuePair.Value, out convi); 381 | this.Id = (convsuc) ? convi : 0; 382 | break; 383 | case "Prio": 384 | convsuc = int.TryParse(keyValuePair.Value, out convi); 385 | this.Prio = (convsuc) ? convi : 0; 386 | break; 387 | default: 388 | break; 389 | } 390 | } 391 | 392 | if (playlist != null) 393 | { 394 | foreach (SongTag st in playlist) 395 | { 396 | if (st.file.Equals(this.file)) 397 | { 398 | this.Pos = st.Pos; 399 | this.Id = st.Id; 400 | } 401 | } 402 | } 403 | 404 | if (this.TagType == TagType.File && string.IsNullOrEmpty(this.Title)) 405 | { 406 | string[] s = this.file.Split("/".ToCharArray()); 407 | if (s.Length > 0) this.Title = s.Last(); 408 | } 409 | } 410 | 411 | public override string ToString() 412 | { 413 | var songtagstring = string.Empty; 414 | 415 | if(!string.IsNullOrEmpty(this.file)) songtagstring = songtagstring + "file: " + this.file + "\n"; 416 | if(!string.IsNullOrEmpty(this.directory)) songtagstring = songtagstring + "directory: " + this.directory + "\n"; 417 | if(!string.IsNullOrEmpty(this.playlist)) songtagstring = songtagstring + "playlist: " + this.playlist + "\n"; 418 | if(!string.IsNullOrEmpty(this.LastModified)) songtagstring = songtagstring + "Last-Modified: " + this.LastModified + "\n"; 419 | if(this.Time > 0) songtagstring = songtagstring + "Time: " + this.Time + "\n"; 420 | if(!string.IsNullOrEmpty(this.Artist)) songtagstring = songtagstring + "Artist: " + this.Artist + "\n"; 421 | if(!string.IsNullOrEmpty(this.Title)) songtagstring = songtagstring + "Title: " + this.Title + "\n"; 422 | if(!string.IsNullOrEmpty(this.Album)) songtagstring = songtagstring + "Album: " + this.Album + "\n"; 423 | if(!string.IsNullOrEmpty(this.Date)) songtagstring = songtagstring + "Date: " + this.Date + "\n"; 424 | if(!string.IsNullOrEmpty(this.Genre)) songtagstring = songtagstring + "Genre: " + this.Genre + "\n"; 425 | if(!string.IsNullOrEmpty(this.Track)) songtagstring = songtagstring + "Track: " + this.Track + "\n"; 426 | if(!string.IsNullOrEmpty(this.AlbumArtist)) songtagstring = songtagstring + "AlbumArtist: " + this.AlbumArtist + "\n"; 427 | if(!string.IsNullOrEmpty(this.Disc)) songtagstring = songtagstring + "Disc: " + this.Disc + "\n"; 428 | if (!string.IsNullOrEmpty(this.Name)) songtagstring = songtagstring + "Name: " + this.Name + "\n"; 429 | if (this.Pos > -1) songtagstring = songtagstring + "Pos: " + this.Pos + "\n"; 430 | if(this.Id > -1) songtagstring = songtagstring + "Id: " + this.Id + "\n"; 431 | if(this.Prio > -1) songtagstring = songtagstring + "Prio: " + this.Prio + "\n"; 432 | 433 | return songtagstring; 434 | } 435 | 436 | public static async Task GetSongTagFromFile(StorageFile storageFile) 437 | { 438 | SongTag songTag = new SongTag(); 439 | Windows.Storage.FileProperties.MusicProperties mp = await storageFile.Properties.GetMusicPropertiesAsync(); 440 | //songTag.file = seekpath.Item2 + "/" + file.Name; 441 | songTag.Title = mp.Title; 442 | songTag.Artist = mp.Artist; 443 | songTag.Album = mp.Album; 444 | songTag.AlbumArtist = mp.AlbumArtist; 445 | songTag.Date = mp.Year.ToString(); 446 | songTag.Time = Convert.ToInt32(mp.Duration.TotalSeconds); 447 | if (mp.Genre.Count > 0) songTag.Genre = mp.Genre.First(); 448 | 449 | return songTag; 450 | } 451 | } 452 | } 453 | -------------------------------------------------------------------------------- /Chimney.MPD/MPDKeyWords.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Threading.Tasks; 5 | 6 | namespace Chimney.MPD 7 | { 8 | public static class MPDKeyWords 9 | { 10 | public static class Send 11 | { 12 | public const string SEPERATION = " "; 13 | public const string QUOTATION_MARK = "\""; 14 | 15 | public static string Encode(string cmd) 16 | { 17 | return Encode(cmd, new List(), new List()); 18 | } 19 | 20 | public static string Encode(string cmd, string args) 21 | { 22 | return Encode(cmd, new List() { args }, new List()); 23 | } 24 | 25 | public static string Encode(string cmd, List args) 26 | { 27 | return Encode(cmd, args, new List()); 28 | } 29 | 30 | public static string Encode(string cmd, List args, List quoted_args, bool reversarguments = false) 31 | { 32 | string send = cmd; 33 | 34 | var args_send = string.Empty; 35 | var quoted_args_send = string.Empty; 36 | 37 | if (args.Count > 0) 38 | { 39 | for (var i = 0; i < args.Count; i++) 40 | { 41 | args_send += args[i]; 42 | if (i < args.Count - 1) 43 | args_send += MPDKeyWords.Send.SEPERATION; 44 | } 45 | } 46 | 47 | if (quoted_args.Count > 0) 48 | { 49 | for (var i = 0; i < quoted_args.Count; i++) 50 | { 51 | quoted_args_send += MPDKeyWords.Send.QUOTATION_MARK 52 | + quoted_args[i] 53 | + MPDKeyWords.Send.QUOTATION_MARK; 54 | if (i < quoted_args.Count - 1) 55 | quoted_args_send += MPDKeyWords.Send.SEPERATION; 56 | } 57 | } 58 | 59 | if(reversarguments) 60 | { 61 | if(quoted_args.Count > 0) 62 | send += MPDKeyWords.Send.SEPERATION + quoted_args_send; 63 | if(args.Count > 0) 64 | send += MPDKeyWords.Send.SEPERATION + args_send; 65 | } 66 | else 67 | { 68 | if (args.Count > 0) 69 | send += MPDKeyWords.Send.SEPERATION + args_send; 70 | if (quoted_args.Count > 0) 71 | send += MPDKeyWords.Send.SEPERATION + quoted_args_send; 72 | } 73 | 74 | return send + MPDKeyWords.Response.END; 75 | } 76 | } 77 | 78 | public static class Response 79 | { 80 | public const string KEYVALUESEPERATION = ":"; 81 | public const string SPACE = " "; 82 | public const string OK = "OK"; 83 | public const string OK_LINEBREAK = MPDKeyWords.Response.OK + MPDKeyWords.Response.LINEBREAK; 84 | public const string ACK = "ACK"; 85 | public const string LIST_OK = "list_OK"; 86 | 87 | public const string SUCCESS_CONNECT = "OK"; 88 | public const string RESPONSE_SUCCESS_CONNECT = "OK MPD 1.0 Chimney" + END; 89 | 90 | public const string LINEBREAK = "\n"; 91 | 92 | public const string END = "\n"; 93 | 94 | public const string UPDATING_DB = "updating_db"; 95 | 96 | public struct Sections 97 | { 98 | public struct Outer 99 | { 100 | public const string PLAYLIST = "playlist"; 101 | public const string DIRECTORY = "directory"; 102 | public const string FILE = "file"; 103 | public const string OUTPUTID = "outputid"; 104 | } 105 | 106 | public struct Inner 107 | { 108 | public const string ARTIST = "Artist"; 109 | public const string ALBUM = "Album"; 110 | public const string GENRE = "Genre"; 111 | } 112 | } 113 | 114 | public static async Task>>> Encode(string value) 115 | { 116 | return GetResponseObjects(await GetResponseKeyValuePairList(value)); 117 | } 118 | 119 | private static async Task>> GetResponseKeyValuePairList(string responseString) 120 | { 121 | var list = new List>(); 122 | 123 | if (!string.IsNullOrEmpty(responseString)) 124 | { 125 | using (var stringReader = new StringReader(responseString)) 126 | { 127 | string line = string.Empty; 128 | while (!string.IsNullOrEmpty(line = await stringReader.ReadLineAsync()) 129 | && !line.Equals(MPDKeyWords.Response.OK)) 130 | { 131 | var pair = line.Split(MPDKeyWords.Response.KEYVALUESEPERATION.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 132 | 133 | var key = (pair.Length > 0) 134 | ? pair[0] 135 | : string.Empty; 136 | 137 | if (pair.Length > 1) 138 | pair[1] = pair[1].TrimStart(MPDKeyWords.Response.SPACE.ToCharArray()); 139 | 140 | var value = string.Empty; 141 | 142 | for(var i = 1; i < pair.Length; i++) 143 | { 144 | value += pair[i]; 145 | if(i != pair.Length - 1) value += MPDKeyWords.Response.KEYVALUESEPERATION; 146 | } 147 | 148 | list.Add(new KeyValuePair(key, value)); 149 | } 150 | } 151 | } 152 | 153 | return list; 154 | } 155 | 156 | private static List>> GetResponseObjects(List> keyValuePairList) 157 | { 158 | var outerList = new List>>(); 159 | 160 | if (keyValuePairList != null) 161 | { 162 | var innerList = new List>(); 163 | var outer = false; 164 | var i = 0; 165 | foreach (var keyValuePair in keyValuePairList) 166 | { 167 | if ((i == 0 || outer) 168 | && (keyValuePair.Key.Equals(MPDKeyWords.Response.Sections.Outer.DIRECTORY) 169 | || keyValuePair.Key.Equals(MPDKeyWords.Response.Sections.Outer.FILE) 170 | || keyValuePair.Key.Equals(MPDKeyWords.Response.Sections.Outer.PLAYLIST) 171 | || keyValuePair.Key.Equals(MPDKeyWords.Response.Sections.Outer.OUTPUTID))) 172 | { 173 | outer = true; 174 | if (innerList.Count > 0) 175 | outerList.Add(innerList); 176 | innerList = new List>(); 177 | } 178 | else if (!outer && 179 | (keyValuePair.Key.Equals(MPDKeyWords.Response.Sections.Inner.ARTIST) 180 | || keyValuePair.Key.Equals(MPDKeyWords.Response.Sections.Inner.ALBUM) 181 | || keyValuePair.Key.Equals(MPDKeyWords.Response.Sections.Inner.GENRE))) 182 | { 183 | outer = false; 184 | if (innerList.Count > 0) 185 | outerList.Add(innerList); 186 | innerList = new List>(); 187 | } 188 | 189 | innerList.Add(keyValuePair); 190 | i++; 191 | 192 | } 193 | if (innerList.Count > 0) 194 | outerList.Add(innerList); 195 | } 196 | 197 | return outerList; 198 | } 199 | } 200 | 201 | public static class Client 202 | { 203 | public struct Connection 204 | { 205 | public const string CLOSE = "close"; 206 | public const string KILL = "kill"; 207 | public const string PASSWORD = "password"; 208 | public const string PING = "ping"; 209 | } 210 | 211 | public struct CommandList 212 | { 213 | public const string COMMAND_LIST_OK_BEGIN = "command_list_ok_begin"; 214 | public const string COMMAND_LIST_BEGIN = "command_list_begin"; 215 | public const string COMMAND_LIST_END = "command_list_end"; 216 | } 217 | 218 | public struct Status 219 | { 220 | public const string CLEARERROR = "clearerror"; 221 | public const string CURRENTSONG = "currentsong"; 222 | public const string IDLE = "idle"; 223 | public const string NOIDLE = "noidle"; 224 | public const string STATUS = "status"; 225 | public const string STATS = "stats"; 226 | } 227 | 228 | public struct Playback 229 | { 230 | public const string CONSUME = "consume"; 231 | public const string CROSSFADE = "crossfade"; 232 | public const string MIXRAMPDB = "mixrampdb"; 233 | public const string MIXRAMPDELAY = "mixrampdelay"; 234 | public const string RANDOM = "random"; 235 | public const string REPEAT = "repeat"; 236 | public const string SETVOL = "setvol"; 237 | public const string SINGLE = "single"; 238 | public const string REPLAY_GAIN_MODE = "replay_gain_mode"; 239 | public const string REPLAY_GAIN_STATUS = "replay_gain_status"; 240 | public const string VOLUME = "volume"; // DO NOT USE 241 | 242 | public const string NEXT = "next"; 243 | public const string PAUSE = "pause"; 244 | public const string PLAY = "play"; 245 | public const string PLAYID = "playid"; 246 | public const string PREVIOUS = "previous"; 247 | public const string SEEK = "seek"; 248 | public const string SEEKID = "seekid"; 249 | public const string SEEKCUR = "seekcur"; 250 | public const string STOP = "stop"; 251 | } 252 | 253 | public struct Playlist 254 | { 255 | public const string ADD = "add"; 256 | public const string ADDID = "addid"; 257 | public const string CLEAR = "clear"; 258 | public const string DELETE = "delete"; 259 | public const string DELETEID = "deleteid"; 260 | public const string MOVE = "move"; 261 | public const string MOVEID = "moveid"; 262 | public const string PLAYLIST = "playlist"; //DO NOT USE 263 | public const string PLAYLISTFIND = "playlistfind"; 264 | public const string PLAYLISTID = "playlistid"; 265 | public const string PLAYLISTINFO = "playlistinfo"; 266 | public const string PLAYLISTSEARCH = "playlistsearch"; 267 | public const string PLCHANGES = "plchanges"; 268 | public const string PLCHANGESPOSID = "plchangesposid"; 269 | public const string PRIO = "prio"; 270 | public const string PRIOID = "prioid"; 271 | public const string SHUFFLE = "shuffle"; 272 | public const string SWAP = "swap"; 273 | public const string SWAPID = "swapid"; 274 | } 275 | 276 | public struct StoredPlaylist 277 | { 278 | public const string LISTPLAYLIST = "listplaylist"; 279 | public const string LISTPLAYLISTINFO = "listplaylistinfo"; 280 | public const string LISTPLAYLISTS = "listplaylists"; 281 | public const string LOAD = "load"; 282 | public const string PLAYLISTADD = "playlistadd"; 283 | public const string PLAYLISTCLEAR = "playlistclear"; 284 | public const string PLAYLISTDELETE = "playlistdelete"; 285 | public const string PLAYLISTMOVE = "playlistmove"; 286 | public const string RENAME = "rename"; 287 | public const string RM = "rm"; 288 | public const string SAVE = "save"; 289 | } 290 | 291 | public struct Database 292 | { 293 | public const string COUNT = "count"; 294 | public const string FIND = "find"; 295 | public const string FINDIN = "findin"; 296 | public const string FINDADD = "findadd"; 297 | public const string LIST = "list"; 298 | public const string LISTALL = "listall"; 299 | public const string LISTALLINFO = "listallinfo"; 300 | public const string LSINFO = "lsinfo"; 301 | public const string READCOMMENTS = "readcomments"; 302 | public const string SEARCH = "search"; 303 | public const string SEARCHIN = "searchin"; 304 | public const string SEARCHADD = "searchadd"; 305 | public const string SEARCHADDPL = "searchaddpl"; 306 | public const string UPDATE = "update"; 307 | public const string RESCAN = "rescan"; 308 | } 309 | 310 | public struct Stickers 311 | { 312 | public const string STICKER_GET = "sticker get"; 313 | public const string STICKER_SET = "sticker set"; 314 | public const string STICKER_DELETE = "sticker delete"; 315 | public const string STICKER_LIST = "sticker list"; 316 | public const string STICKER_FIND = "sticker find"; 317 | } 318 | 319 | public struct Outputs 320 | { 321 | public const string DISABLEOUTPUT = "disableoutput"; 322 | public const string ENABLEOUTPUT = "enableoutput"; 323 | public const string TOGGLEOUTPUT = "toggleoutput"; 324 | public const string OUTPUTS = "outputs"; 325 | } 326 | 327 | public struct Reflection 328 | { 329 | public const string CONFIG = "config"; 330 | public const string COMMANDS = "commands"; 331 | public const string NOTCOMMANDS = "notcommands"; 332 | public const string TAGTYPES = "tagtypes"; 333 | public const string URLHANDLERS = "urlhandlers"; 334 | public const string DECODERS = "decoders"; 335 | } 336 | 337 | public struct ClientToClient 338 | { 339 | public const string SUBSCRIBE = "subscribe"; 340 | public const string UNSUBSCRIBE = "unsubscribe"; 341 | public const string CHANNELS = "channels"; 342 | public const string READMESSAGES = "readmessages"; 343 | public const string SENDMESSAGE = "sendmessage"; 344 | } 345 | } 346 | } 347 | } 348 | -------------------------------------------------------------------------------- /Chimney.MPD/Classes/Status.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Chimney.MPD.Classes 5 | { 6 | public class Status 7 | { 8 | private int _volume; 9 | public int Volume 10 | { 11 | get 12 | { 13 | return _volume; 14 | } 15 | set 16 | { 17 | _volume = value; 18 | } 19 | } 20 | 21 | public bool IsVolumeEnable 22 | { 23 | get 24 | { 25 | return (_volume != -1) ? true : false; 26 | } 27 | } 28 | 29 | public bool Repeat { get; set; } 30 | public bool Random { get; set; } 31 | public bool Single { get; set; } 32 | public bool Consume { get; set; } 33 | public int Playlist { get; set; } 34 | public int PlaylistLength { get; set; } 35 | 36 | private string _state; 37 | public string State 38 | { 39 | get 40 | { 41 | return (!string.IsNullOrEmpty(_state)) ? _state : "stop"; 42 | } 43 | set 44 | { 45 | _state = value; 46 | } 47 | } 48 | 49 | public bool CanPlay 50 | { 51 | get 52 | { 53 | if (State.Equals("play")) return false; 54 | return true; 55 | } 56 | } 57 | 58 | 59 | public bool CanPause 60 | { 61 | get 62 | { 63 | if (State.Equals("pause") || State.Equals("stop")) return false; 64 | return true; 65 | } 66 | } 67 | 68 | public bool CanStop 69 | { 70 | get 71 | { 72 | //if (State.Equals("stop")) return true; 73 | return true; 74 | } 75 | } 76 | 77 | public bool IsStopped 78 | { 79 | get 80 | { 81 | if (State.Equals("stop")) return true; 82 | return false; 83 | } 84 | } 85 | 86 | public int Song { get; set; } 87 | public int SongId { get; set; } 88 | public int NextSong { get; set; } 89 | public int NextSongId { get; set; } 90 | public double Time { get; set; } 91 | public double Elapsed { get; set; } 92 | public int Bitrate { get; set; } 93 | public int XFade { get; set; } 94 | 95 | private string _mixrampdb; 96 | public string MixRampDb 97 | { 98 | get 99 | { 100 | if (string.IsNullOrEmpty(_mixrampdb)) return string.Empty; 101 | return _mixrampdb; 102 | } 103 | set 104 | { 105 | _mixrampdb = value; 106 | } 107 | } 108 | 109 | private string _mixrampdelay; 110 | public string MixRampDelay 111 | { 112 | get 113 | { 114 | if (string.IsNullOrEmpty(_mixrampdelay)) return string.Empty; 115 | return _mixrampdelay; 116 | } 117 | set 118 | { 119 | _mixrampdelay = value; 120 | } 121 | } 122 | 123 | private string _audio; 124 | public string Audio 125 | { 126 | get 127 | { 128 | if (string.IsNullOrEmpty(_audio)) return string.Empty; 129 | else if (_audio.Equals("0:?:0")) return string.Empty; 130 | return _audio; 131 | } 132 | set 133 | { 134 | _audio = value; 135 | } 136 | } 137 | 138 | private string _updating_db; 139 | public string UpdatingDb 140 | { 141 | get 142 | { 143 | if (string.IsNullOrEmpty(_updating_db)) return string.Empty; 144 | return _updating_db; 145 | } 146 | set 147 | { 148 | _updating_db = value; 149 | } 150 | } 151 | 152 | public bool IsDbUpdating 153 | { 154 | get 155 | { 156 | return (!string.IsNullOrEmpty(UpdatingDb)) ? true : false; 157 | } 158 | } 159 | 160 | private string _error; 161 | public string Error 162 | { 163 | get 164 | { 165 | return (!string.IsNullOrEmpty(_error)) ? _error : string.Empty; 166 | } 167 | set 168 | { 169 | _error = value; 170 | } 171 | } 172 | 173 | public bool IsError 174 | { 175 | get 176 | { 177 | return (!string.IsNullOrEmpty(_error)) ? true : false; 178 | } 179 | } 180 | 181 | public Status() 182 | { 183 | 184 | } 185 | 186 | public override string ToString() 187 | { 188 | string statusstring = string.Empty; 189 | 190 | statusstring = statusstring + "volume: " + this.Volume + "\n"; 191 | statusstring = statusstring + "repeat: " + Convert.ToInt32(this.Repeat) + "\n"; 192 | statusstring = statusstring + "random: " + Convert.ToInt32(this.Random) + "\n"; 193 | statusstring = statusstring + "single: " + Convert.ToInt32(this.Single) + "\n"; 194 | statusstring = statusstring + "consume: " + Convert.ToInt32(this.Consume) + "\n"; 195 | statusstring = statusstring + "playlist: " + this.Playlist + "\n"; 196 | statusstring = statusstring + "playlistlength: " + this.PlaylistLength + "\n"; 197 | statusstring = statusstring + "xfade: " + this.XFade + "\n"; 198 | 199 | if (!string.IsNullOrEmpty(this.MixRampDb)) statusstring = statusstring + "mixrampdb: " + this.MixRampDb + "\n"; 200 | else statusstring = statusstring + "mixrampdb: 0.00000\n"; 201 | 202 | if (!string.IsNullOrEmpty(this.MixRampDelay)) statusstring = statusstring + "mixrampdelay: " + this.MixRampDelay + "\n"; 203 | else statusstring = statusstring + "mixrampdelay: nan\n"; 204 | 205 | if (string.IsNullOrEmpty(this.State)) statusstring = statusstring + "state: stop\n"; 206 | else statusstring = statusstring + "state: " + this.State + "\n"; 207 | 208 | bool stop = false; 209 | if (this.State.Equals("stop") || string.IsNullOrEmpty(this.State)) stop = true; 210 | 211 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "song: " + this.Song + "\n"; 212 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "songid: " + this.SongId + "\n"; 213 | 214 | int a = 0; 215 | a = (int)this.Time; 216 | //int b = Convert.ToInt32(this.Time*100); 217 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "time: " + a + ":123" + "\n"; 218 | 219 | a = (int)this.Elapsed; 220 | 221 | //b = Convert.ToInt32(this.Elapsed * 100); 222 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "elapsed: " + a + ".122" + "\n"; 223 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "bitrate: " + this.Bitrate + "\n"; 224 | 225 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "audio: " + "44100:16:2" + "\n"; // this.Audio + "\n"; 226 | 227 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "nextsong: " + this.NextSong + "\n"; 228 | if (this.PlaylistLength > 0 && !stop) statusstring = statusstring + "nextsongid: " + this.NextSongId + "\n"; 229 | 230 | if(!string.IsNullOrEmpty(this.UpdatingDb)) statusstring = statusstring + "updating_db: " + this.UpdatingDb + "\n"; 231 | if(!string.IsNullOrEmpty(this.Error)) statusstring = statusstring + "error: " + this.Error + "\n"; 232 | 233 | return statusstring; 234 | } 235 | 236 | public Status (List> keyValuePairList) 237 | { 238 | if (keyValuePairList == null) return; 239 | 240 | bool succonvert = false; 241 | 242 | int convi = 0; 243 | bool convb = false; 244 | double convd = 0; 245 | 246 | foreach (var kv in keyValuePairList) 247 | { 248 | switch (kv.Key) 249 | { 250 | case "volume": 251 | succonvert = int.TryParse(kv.Value, out convi); 252 | this.Volume = (succonvert) ? convi : -1; 253 | break; 254 | case "repeat": 255 | succonvert = int.TryParse(kv.Value, out convi); 256 | this.Repeat = (succonvert && convi > 0) ? true : false; 257 | break; 258 | case "random": 259 | succonvert = int.TryParse(kv.Value, out convi); 260 | this.Random = (succonvert && convi > 0) ? true : false; 261 | break; 262 | case "single": 263 | succonvert = int.TryParse(kv.Value, out convi); 264 | this.Single = (succonvert && convi > 0) ? true : false; 265 | break; 266 | case "consume": 267 | succonvert = int.TryParse(kv.Value, out convi); 268 | this.Consume = (succonvert && convi > 0) ? true : false; 269 | break; 270 | case "playlist": 271 | succonvert = int.TryParse(kv.Value, out convi); 272 | this.Playlist = (succonvert) ? convi : 0; 273 | break; 274 | case "playlistlength": 275 | succonvert = int.TryParse(kv.Value, out convi); 276 | this.PlaylistLength = (succonvert) ? convi : 0; 277 | break; 278 | case "state": 279 | this.State = kv.Value; 280 | break; 281 | case "song": 282 | succonvert = int.TryParse(kv.Value, out convi); 283 | this.Song = (succonvert) ? convi : 0; 284 | break; 285 | case "songid": 286 | succonvert = int.TryParse(kv.Value, out convi); 287 | this.SongId = (succonvert) ? convi : 0; 288 | break; 289 | case "nextsong": 290 | succonvert = int.TryParse(kv.Value, out convi); 291 | this.NextSong = (succonvert) ? convi : 0; 292 | break; 293 | case "nextsongid": 294 | succonvert = int.TryParse(kv.Value, out convi); 295 | this.NextSongId = (succonvert) ? convi : 0; 296 | break; 297 | case "time": 298 | succonvert = double.TryParse(kv.Value.Replace(":", "."), out convd); 299 | this.Time = (succonvert) ? convd : 0; 300 | break; 301 | case "elapsed": 302 | succonvert = double.TryParse(kv.Value, out convd); 303 | this.Elapsed = (succonvert) ? convd : 0; 304 | break; 305 | case "bitrate": 306 | succonvert = int.TryParse(kv.Value, out convi); 307 | this.Bitrate = (succonvert) ? convi : 0; 308 | break; 309 | case "xfade": 310 | succonvert = int.TryParse(kv.Value, out convi); 311 | this.XFade = (succonvert) ? convi : 0; 312 | break; 313 | case "mixrampdb": 314 | this.MixRampDb = kv.Value; 315 | break; 316 | case "mixrampdelay": 317 | this.MixRampDelay = kv.Value; 318 | break; 319 | case "audio": 320 | this.Audio = kv.Value; 321 | break; 322 | case "updating_db": 323 | this.UpdatingDb = kv.Value; 324 | break; 325 | case "error": 326 | this.Error = kv.Value; 327 | break; 328 | default: 329 | break; 330 | } 331 | } 332 | } 333 | 334 | 335 | public Status(Dictionary dictionary) 336 | { 337 | bool succonvert = false; 338 | 339 | int convi = 0; 340 | bool convb = false; 341 | double convd = 0; 342 | 343 | foreach (string key in dictionary.Keys) 344 | { 345 | switch (key) 346 | { 347 | case "volume": 348 | succonvert = int.TryParse(dictionary[key], out convi); 349 | this.Volume = (succonvert) ? convi : -1; 350 | break; 351 | case "repeat": 352 | succonvert = int.TryParse(dictionary[key], out convi); 353 | this.Repeat = (succonvert && convi > 0) ? true : false; 354 | break; 355 | case "random": 356 | succonvert = int.TryParse(dictionary[key], out convi); 357 | this.Random = (succonvert && convi > 0) ? true : false; 358 | break; 359 | case "single": 360 | succonvert = int.TryParse(dictionary[key], out convi); 361 | this.Single = (succonvert && convi > 0) ? true : false; 362 | break; 363 | case "consume": 364 | succonvert = int.TryParse(dictionary[key], out convi); 365 | this.Consume = (succonvert && convi > 0) ? true : false; 366 | break; 367 | case "playlist": 368 | succonvert = int.TryParse(dictionary[key], out convi); 369 | this.Playlist = (succonvert) ? convi : 0; 370 | break; 371 | case "playlistlength": 372 | succonvert = int.TryParse(dictionary[key], out convi); 373 | this.PlaylistLength = (succonvert) ? convi : 0; 374 | break; 375 | case "state": 376 | this.State = dictionary[key]; 377 | break; 378 | case "song": 379 | succonvert = int.TryParse(dictionary[key], out convi); 380 | this.Song = (succonvert) ? convi : 0; 381 | break; 382 | case "songid": 383 | succonvert = int.TryParse(dictionary[key], out convi); 384 | this.SongId = (succonvert) ? convi : 0; 385 | break; 386 | case "nextsong": 387 | succonvert = int.TryParse(dictionary[key], out convi); 388 | this.NextSong = (succonvert) ? convi : 0; 389 | break; 390 | case "nextsongid": 391 | succonvert = int.TryParse(dictionary[key], out convi); 392 | this.NextSongId = (succonvert) ? convi : 0; 393 | break; 394 | case "time": 395 | succonvert = double.TryParse(dictionary[key].Replace(":", "."), out convd); 396 | this.Time = (succonvert) ? convd : 0; 397 | break; 398 | case "elapsed": 399 | succonvert = double.TryParse(dictionary[key], out convd); 400 | this.Elapsed = (succonvert) ? convd : 0; 401 | break; 402 | case "bitrate": 403 | succonvert = int.TryParse(dictionary[key], out convi); 404 | this.Bitrate = (succonvert) ? convi : 0; 405 | break; 406 | case "xfade": 407 | succonvert = int.TryParse(dictionary[key], out convi); 408 | this.XFade = (succonvert) ? convi : 0; 409 | break; 410 | case "mixrampdb": 411 | this.MixRampDb = dictionary[key]; 412 | break; 413 | case "mixrampdelay": 414 | this.MixRampDelay = dictionary[key]; 415 | break; 416 | case "audio": 417 | this.Audio = dictionary[key]; 418 | break; 419 | case "updating_db": 420 | this.UpdatingDb = dictionary[key]; 421 | break; 422 | case "error": 423 | this.Error = dictionary[key]; 424 | break; 425 | default: 426 | break; 427 | } 428 | } 429 | } 430 | } 431 | } 432 | -------------------------------------------------------------------------------- /Chimney.MPD/ChimneyMPDBase.cs: -------------------------------------------------------------------------------- 1 | using Chimney.MPD.Classes; 2 | using Chimney.MPD.Net; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Runtime.CompilerServices; 9 | using System.Threading.Tasks; 10 | using Windows.Networking.Sockets; 11 | 12 | namespace Chimney.MPD 13 | { 14 | public class ChimneyMPDBase : INotifyPropertyChanged 15 | { 16 | public event PropertyChangedEventHandler PropertyChanged; 17 | 18 | protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 19 | { 20 | if (PropertyChanged != null) 21 | { 22 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 23 | } 24 | } 25 | 26 | public StreamSocketListener streamSocketListner; 27 | 28 | protected bool idle = false; 29 | 30 | public delegate void EventHandler(object sender, EventArgs e); 31 | public event EventHandler ConnectionProblem; 32 | public event EventHandler ConnectionConnected; 33 | public event EventHandler CouldNotConnect; 34 | 35 | private Chimney.MPD.Net.Connection _connection; 36 | 37 | protected bool connectionproblem = true; 38 | 39 | public string host = ""; 40 | public string port = ""; 41 | public string password = ""; 42 | 43 | public string name = ""; 44 | 45 | bool queueInUse = false; 46 | bool runQue = false; 47 | 48 | List sendQueue = new List(); 49 | 50 | int queueId = -1; 51 | 52 | enum ConnectionErrors 53 | { 54 | Connection, Permission 55 | }; 56 | 57 | private Object add_send_lock = new object(); 58 | 59 | private bool _Connected = false; 60 | public bool Connected 61 | { 62 | get 63 | { 64 | return _Connected; 65 | } 66 | set 67 | { 68 | _Connected = value; 69 | NotifyPropertyChanged("Connected"); 70 | } 71 | } 72 | 73 | private bool _Connecting = false; 74 | public bool Connecting 75 | { 76 | get 77 | { 78 | return _Connecting; 79 | } 80 | set 81 | { 82 | _Connecting = value; 83 | NotifyPropertyChanged("Connecting"); 84 | } 85 | } 86 | 87 | protected void SendConnectionProblem() 88 | { 89 | connectionproblem = true; 90 | if (ConnectionProblem != null) ConnectionProblem(this, new EventArgs()); 91 | } 92 | 93 | public async Task Password(string password, bool closesocket = true) 94 | { 95 | if (_connection == null) return false; 96 | 97 | var success = await Connection.Send(_connection.Socket, 98 | MPDKeyWords.Send.Encode(MPDKeyWords.Client.Connection.PASSWORD, "\"" + password + "\"")); 99 | 100 | if (!success) return false; 101 | 102 | var response = await Connection.Recive(_connection.Socket, 103 | new List() { MPDKeyWords.Response.SUCCESS_CONNECT }, 104 | new List() { MPDKeyWords.Response.OK + MPDKeyWords.Response.LINEBREAK }, 105 | new List() { MPDKeyWords.Response.ACK }, 106 | new List() { MPDKeyWords.Response.LINEBREAK }); 107 | 108 | return (response.Equals(MPDKeyWords.Response.OK_LINEBREAK)) 109 | ? true 110 | : false; 111 | } 112 | 113 | public async Task Ping(bool silent = true, bool retry = false) 114 | { 115 | if (idle) await NoIdle(); 116 | 117 | var qId = await Send(MPDKeyWords.Send.Encode( MPDKeyWords.Client.Connection.PING ), silent, retry, true); 118 | 119 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 120 | ? true 121 | : false; 122 | } 123 | 124 | public async Task CheckConnection(bool silent = true, bool retry = false) 125 | { 126 | return await Ping(silent); 127 | } 128 | 129 | public async Task> TestPermission() 130 | { 131 | //var qId = await Send(MPDKeyWords.Send.Encode( MPDKeyWords.Client.Status.STATS ), true, false, true); 132 | 133 | bool success = await Connection.Send(_connection.Socket, 134 | MPDKeyWords.Send.Encode(MPDKeyWords.Client.Status.STATS)); 135 | 136 | if (!success) 137 | return null; 138 | 139 | string response = await Connection.Recive(_connection.Socket, 140 | new List() { MPDKeyWords.Response.SUCCESS_CONNECT }, 141 | new List() { MPDKeyWords.Response.OK + MPDKeyWords.Response.LINEBREAK }, 142 | new List() { MPDKeyWords.Response.ACK }, 143 | new List() { MPDKeyWords.Response.LINEBREAK }); 144 | 145 | //var response = await Response(qId); 146 | 147 | if (string.IsNullOrEmpty(response) || response.Contains(MPDKeyWords.Response.ACK)) 148 | return null; 149 | 150 | var stats = new Stats((await MPDKeyWords.Response.Encode(response)).FirstOrDefault()); 151 | 152 | //qId = await Send(MPDKeyWords.Send.Encode( MPDKeyWords.Client.Status.STATUS ), true, false, true); 153 | 154 | //response = await Response(qId); 155 | 156 | success = await Connection.Send(_connection.Socket, 157 | MPDKeyWords.Send.Encode(MPDKeyWords.Client.Status.STATUS)); 158 | 159 | if (!success) 160 | return null; 161 | 162 | response = await Connection.Recive(_connection.Socket, 163 | new List() { MPDKeyWords.Response.SUCCESS_CONNECT }, 164 | new List() { MPDKeyWords.Response.OK + MPDKeyWords.Response.LINEBREAK }, 165 | new List() { MPDKeyWords.Response.ACK }, 166 | new List() { MPDKeyWords.Response.LINEBREAK }); 167 | 168 | if (string.IsNullOrEmpty(response) || response.Contains(MPDKeyWords.Response.ACK)) 169 | return null; 170 | 171 | var status = new Status((await MPDKeyWords.Response.Encode(response)).FirstOrDefault()); 172 | 173 | return new Tuple(stats, status); 174 | } 175 | 176 | public async Task> Idle(string subsystems = "") 177 | { 178 | this.idle = true; 179 | 180 | //var qId = 181 | // ? await Send(MPDKeyWords.Client.Status.IDLE) 182 | // : await Send(MPDKeyWords.Client.Status.IDLE); 183 | 184 | var success = (string.IsNullOrEmpty(subsystems)) 185 | ? await Connection.Send(_connection.Socket, 186 | MPDKeyWords.Send.Encode(MPDKeyWords.Client.Status.IDLE)) 187 | : await Connection.Send(_connection.Socket, 188 | MPDKeyWords.Send.Encode(MPDKeyWords.Client.Status.IDLE, subsystems.Split(new char[] { ' ' }).ToList())); 189 | 190 | if (!success) return new List(); 191 | 192 | var response = await Connection.Recive(_connection.Socket, 193 | new List() { MPDKeyWords.Response.SUCCESS_CONNECT }, 194 | new List() { MPDKeyWords.Response.OK_LINEBREAK }, 195 | new List() { MPDKeyWords.Response.ACK }, 196 | new List() { MPDKeyWords.Response.LINEBREAK }); 197 | 198 | var responselist = (await MPDKeyWords.Response.Encode(response)).FirstOrDefault(); 199 | 200 | return (from kv in responselist select kv.Value).ToList(); 201 | } 202 | 203 | public async Task NoIdle() 204 | { 205 | await Connection.Send(_connection.Socket, 206 | MPDKeyWords.Send.Encode(MPDKeyWords.Client.Status.NOIDLE)); 207 | //await Send(MPDKeyWords.Send.Encode( MPDKeyWords.Client.Status.NOIDLE ), false, true, false); 208 | 209 | idle = false; 210 | } 211 | 212 | public async Task Close(bool connectionproblem = false) 213 | { 214 | Debug.WriteLine(name + " : CLOSE"); 215 | 216 | queueInUse = idle = runQue = false; 217 | 218 | sendQueue.Clear(); 219 | responseDictionary.Clear(); 220 | 221 | this.connectionproblem = connectionproblem; 222 | 223 | if (_connection != null && !this.connectionproblem) 224 | //await Send( MPDKeyWords.Send.Encode( MPDKeyWords.Client.Connection.CLOSE), false, true, false); 225 | await Connection.Send(_connection.Socket, 226 | MPDKeyWords.Send.Encode(MPDKeyWords.Client.Connection.CLOSE)); 227 | 228 | Connected = Connecting = false; 229 | 230 | return true; 231 | } 232 | 233 | public virtual async Task RefreshConnection() 234 | { 235 | /* 236 | bool suc = false; 237 | int i = 3; 238 | while (i > 0 || !suc) 239 | { 240 | suc = await Connection.Send(_connection.Socket, "CLOSE"); 241 | i--; 242 | } 243 | */ 244 | 245 | bool suc = await Connect(this.host, this.port, this.password, true); 246 | 247 | return suc; 248 | } 249 | 250 | public async Task Disconnect() 251 | { 252 | return await Close(false); 253 | } 254 | 255 | // 256 | // Connect to MPD server 257 | // 258 | public async Task Connect(string host, string port, string password = null, bool silent = false, int timeout = 0) 259 | { 260 | 261 | connectionproblem = false; 262 | 263 | this.host = host; 264 | this.port = port; 265 | this.password = password; 266 | 267 | if (!silent) 268 | { 269 | Connected = false; 270 | Connecting = true; 271 | } 272 | 273 | if (_connection != null) 274 | { 275 | _connection.Close(); 276 | Debug.WriteLine(this.name + " : CLOSE CONNECTION"); 277 | 278 | } 279 | 280 | _connection = new Connection(); 281 | 282 | bool success = await _connection.Connect(host, port, timeout); 283 | 284 | Debug.WriteLine(this.name + " : NEW CONNECTION : " + success); 285 | 286 | 287 | if (success) 288 | { 289 | var response = await Connection.Recive(_connection.Socket, 290 | new List() { MPDKeyWords.Response.SUCCESS_CONNECT }, 291 | new List() { MPDKeyWords.Response.OK + MPDKeyWords.Response.LINEBREAK }, 292 | new List() { MPDKeyWords.Response.ACK }, 293 | new List() { MPDKeyWords.Response.LINEBREAK }); 294 | 295 | if (string.IsNullOrEmpty(response) || !response.StartsWith(MPDKeyWords.Response.SUCCESS_CONNECT)) 296 | success = false; 297 | 298 | Debug.WriteLine(this.name + " : NEW CONNECTION : RESPONSE : " + success); 299 | 300 | //if (!string.IsNullOrEmpty(password) && !await Password(password, false)) 301 | // return false; 302 | 303 | //if (!await Password(password, false)) 304 | // return false; 305 | 306 | if (success) 307 | { 308 | await Password(password, false); 309 | 310 | if (await TestPermission() == null) 311 | success = false; 312 | } 313 | 314 | Debug.WriteLine(this.name + " : NEW CONNECTION : PERMISSION : " + success); 315 | } 316 | 317 | if (!success) 318 | { 319 | Connected = false; 320 | Connecting = false; 321 | _connection.Close(); 322 | 323 | if (CouldNotConnect != null) 324 | CouldNotConnect(this, new EventArgs()); 325 | } 326 | else if (success && !silent) 327 | { 328 | Connected = true; 329 | Connecting = false; 330 | 331 | if (ConnectionConnected != null) 332 | ConnectionConnected(this, new EventArgs()); 333 | } 334 | 335 | Debug.WriteLine(this.name + " : NEW CONNECTION : RETURN : " + success); 336 | 337 | return success; 338 | } 339 | 340 | public async Task> TestConnect(string host, string port, string password = null, bool silent = false, int timeout = 0) 341 | { 342 | this.host = host; 343 | this.port = port; 344 | this.password = password; 345 | 346 | if (_connection != null) 347 | { 348 | _connection.Close(); 349 | Debug.WriteLine(this.name + " : CLOSE CONNECTION"); 350 | } 351 | 352 | _connection = new Connection(); 353 | 354 | var permission = true; 355 | 356 | bool success = await _connection.Connect(host, port, timeout); 357 | 358 | Debug.WriteLine(this.name + " : NEW CONNECTION : " + success); 359 | 360 | if (success) 361 | { 362 | var response = await Connection.Recive(_connection.Socket, 363 | new List() { MPDKeyWords.Response.SUCCESS_CONNECT }, 364 | new List() { MPDKeyWords.Response.OK + MPDKeyWords.Response.LINEBREAK }, 365 | new List() { MPDKeyWords.Response.ACK }, 366 | new List() { MPDKeyWords.Response.LINEBREAK }); 367 | 368 | if (string.IsNullOrEmpty(response) || !response.StartsWith(MPDKeyWords.Response.SUCCESS_CONNECT)) 369 | success = false; 370 | 371 | Debug.WriteLine(this.name + " : NEW CONNECTION : RESPONSE : " + success); 372 | 373 | if (success) 374 | { 375 | await Password(password, false); 376 | 377 | if (await TestPermission() == null) 378 | permission = false; 379 | } 380 | 381 | Debug.WriteLine(this.name + " : NEW CONNECTION : PERMISSION : " + permission); 382 | } 383 | 384 | _connection.Close(); 385 | 386 | Debug.WriteLine(this.name + " : NEW CONNECTION : RETURN : " + success + " " + permission); 387 | 388 | return new Tuple(success, permission); 389 | } 390 | 391 | // Send and recive data to MPD server 392 | // 393 | private async Task RunQueue() 394 | { 395 | runQue = true; 396 | 397 | while (runQue) 398 | { 399 | if (sendQueue.Count > 0) 400 | { 401 | if (!queueInUse) 402 | { 403 | queueInUse = true; 404 | 405 | QueueJob queueJob = sendQueue[0]; 406 | 407 | int attemps = (queueJob.retry) ? 5 : 1; 408 | 409 | int readAttemps = 2; 410 | 411 | bool suc = false; 412 | bool readsuc = false; 413 | string responseString = string.Empty; 414 | 415 | while (!suc && attemps > 0) 416 | { 417 | Debug.WriteLine(this.name + " : SEND : queueJob.id: " + queueJob.id + " queueJob.send: " + queueJob.send); 418 | suc = await Connection.Send(_connection.Socket, queueJob.send); 419 | 420 | if (suc && queueJob.wait) 421 | { 422 | responseString = string.Empty; 423 | readAttemps = 3; 424 | while (string.IsNullOrEmpty(responseString) && readAttemps > 0) 425 | { 426 | responseString = await Connection.Recive(_connection.Socket, 427 | new List() { MPDKeyWords.Response.SUCCESS_CONNECT }, 428 | new List() { MPDKeyWords.Response.OK_LINEBREAK }, 429 | new List() { MPDKeyWords.Response.ACK }, 430 | new List() { MPDKeyWords.Response.LINEBREAK }); 431 | 432 | if (responseString.EndsWith(MPDKeyWords.Response.OK_LINEBREAK) 433 | || (responseString.StartsWith(MPDKeyWords.Response.ACK))) 434 | { 435 | queueJob.response = responseString; 436 | 437 | this.responseDictionary.Add(queueJob.id, queueJob); 438 | readsuc = true; 439 | Debug.WriteLine(this.name + " : RECIVE : queueJob.id: " + queueJob.id + " queueJob.send: " + queueJob.send); 440 | 441 | } 442 | 443 | readAttemps--; 444 | } 445 | 446 | if (string.IsNullOrEmpty(responseString)) 447 | readsuc = false; 448 | } 449 | 450 | attemps--; 451 | 452 | if ((!suc || !readsuc) && attemps > 0 && queueJob.wait) 453 | { 454 | Debug.WriteLine(this.name + " : RECONNECT"); 455 | await Connect(this.host, this.port, this.password, true); 456 | suc = false; 457 | //attemps--; 458 | 459 | 460 | } 461 | } 462 | 463 | if (readsuc == false && suc == true && string.IsNullOrEmpty(responseString)) 464 | { 465 | queueJob.response = responseString; 466 | this.responseDictionary.Add(queueJob.id, queueJob); 467 | Debug.WriteLine(this.name + " : EMPTY RECIVE : queueJob.id: " + queueJob.id + " queueJob.send: " + queueJob.send); 468 | 469 | } 470 | 471 | sendQueue.RemoveAt(0); 472 | queueInUse = false; 473 | 474 | if (attemps == 0 && !suc && !this.connectionproblem && !queueJob.silent) 475 | { 476 | this.connectionproblem = true; 477 | if (ConnectionProblem != null) 478 | ConnectionProblem(this, new EventArgs()); 479 | } 480 | 481 | } 482 | 483 | } 484 | else runQue = false; 485 | } 486 | } 487 | 488 | public async Task Send(string cmd) 489 | { 490 | return await Send(MPDKeyWords.Send.Encode(cmd), false, true, true); 491 | } 492 | 493 | public async Task Send(string cmd, List args) 494 | { 495 | return await Send(MPDKeyWords.Send.Encode(cmd, args, new List()), false, true, true); 496 | } 497 | 498 | public async Task Send(string cmd, List args, List quoted_args, bool reversarguments = false) 499 | { 500 | return await Send(MPDKeyWords.Send.Encode(cmd, args, quoted_args, reversarguments), false, true, true); 501 | } 502 | 503 | private async Task Send(string send, bool silent, bool retry, bool wait) 504 | { 505 | if (_connection == null) 506 | { 507 | Debug.WriteLine("connection null"); 508 | return -1; 509 | } 510 | 511 | lock(add_send_lock) 512 | { 513 | queueId++; 514 | 515 | Debug.WriteLine(this.name + " : ADD : queueId: " + queueId + " send: " + send); 516 | 517 | sendQueue.Add(new QueueJob(queueId, send, silent, retry, wait)); 518 | 519 | if (!runQue) RunQueue(); 520 | } 521 | return queueId; 522 | } 523 | 524 | private Dictionary responseDictionary = new Dictionary(); 525 | 526 | public async Task Response(int qId) 527 | { 528 | QueueJob queueJob = new QueueJob(); 529 | 530 | while (responseDictionary.ContainsKey(qId) == false 531 | && (responseDictionary.Count > 0 532 | || sendQueue.Count > 0)) 533 | { 534 | await Task.Delay(1); 535 | } 536 | 537 | if (responseDictionary.ContainsKey(qId)) 538 | { 539 | queueJob = responseDictionary[qId]; 540 | 541 | Debug.WriteLine(this.name + " : RETRIVE : qId: " + qId + " queueJob: " + queueJob.id); 542 | responseDictionary.Remove(qId); 543 | } 544 | 545 | return queueJob.response; 546 | } 547 | } 548 | } 549 | -------------------------------------------------------------------------------- /Chimney.MPD/ChimneyMPDClient.cs: -------------------------------------------------------------------------------- 1 | using Chimney.MPD.Classes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace Chimney.MPD 8 | { 9 | public class ChimneyMPDClient : ChimneyMPDBase 10 | { 11 | public async Task Start() 12 | { 13 | return await Connect(this.host, this.port, this.password); 14 | } 15 | 16 | public async Task> Outputs() 17 | { 18 | int qId = await Send(MPDKeyWords.Client.Outputs.OUTPUTS); 19 | 20 | var outputs = new List(); 21 | 22 | foreach (var d in await MPDKeyWords.Response.Encode(await Response(qId))) 23 | outputs.Add(new Output(d)); 24 | 25 | return outputs; 26 | } 27 | 28 | public async Task EnableOutput(string outputid = "0") 29 | { 30 | int qId = await Send(MPDKeyWords.Client.Outputs.ENABLEOUTPUT, 31 | new List() { outputid }); 32 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 33 | ? true 34 | : false; 35 | } 36 | 37 | public async Task SavePlaylist(string playlist) 38 | { 39 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.SAVE, 40 | new List(), 41 | new List() { playlist }); 42 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 43 | ? true 44 | : false; 45 | } 46 | 47 | public async Task RemovePlaylist(string playlist) 48 | { 49 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.RM, 50 | new List(), 51 | new List() { playlist }); 52 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 53 | ? true 54 | : false; 55 | } 56 | 57 | public async Task RenamePlaylist(string oldplaylistname, string newplaylistname) 58 | { 59 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.RENAME, 60 | new List(), 61 | new List() { oldplaylistname, newplaylistname }); 62 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 63 | ? true 64 | : false; 65 | } 66 | 67 | public async Task> ListPlaylists() 68 | { 69 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.LISTPLAYLISTS); 70 | 71 | List playlists = new List(); 72 | 73 | foreach (var d in await MPDKeyWords.Response.Encode(await Response(qId))) 74 | playlists.Add(new StoredPlaylist(d)); 75 | 76 | return playlists; 77 | } 78 | 79 | public async Task LoadPlaylist(string playlist) 80 | { 81 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.LOAD, 82 | new List(), 83 | new List() { playlist }); 84 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 85 | ? true 86 | : false; 87 | } 88 | 89 | public async Task LoadPlaylist(string playlist, int start, int end) 90 | { 91 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.LOAD, 92 | new List() { playlist }, 93 | new List() { start.ToString() + ":" + end.ToString() }, 94 | true); 95 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 96 | ? true 97 | : false; 98 | } 99 | 100 | public async Task DisableOutput(string outputid = "0") 101 | { 102 | int qId = await Send(MPDKeyWords.Client.Outputs.DISABLEOUTPUT, 103 | new List() { outputid } ); 104 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 105 | ? true 106 | : false; 107 | } 108 | 109 | public async Task Play(int songposition) 110 | { 111 | int qId = await Send(MPDKeyWords.Client.Playback.PLAY, 112 | new List() { songposition.ToString() }); 113 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 114 | ? true 115 | : false; 116 | } 117 | 118 | public async Task PlayId(int songid) 119 | { 120 | int qId = await Send(MPDKeyWords.Client.Playback.PLAYID, 121 | new List() { songid.ToString() }); 122 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 123 | ? true 124 | : false; 125 | } 126 | 127 | public async Task Stop() 128 | { 129 | int qId = await Send(MPDKeyWords.Client.Playback.STOP); 130 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 131 | ? true 132 | : false; 133 | } 134 | 135 | public async Task Pause() 136 | { 137 | int qId = await Send(MPDKeyWords.Client.Playback.PAUSE); 138 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 139 | ? true 140 | : false; 141 | } 142 | 143 | public async Task Next() 144 | { 145 | int qId = await Send(MPDKeyWords.Client.Playback.NEXT); 146 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 147 | ? true 148 | : false; 149 | } 150 | 151 | public async Task Previous() 152 | { 153 | int qId = await Send(MPDKeyWords.Client.Playback.PREVIOUS); 154 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 155 | ? true 156 | : false; 157 | } 158 | 159 | public async Task Volume(double volume) 160 | { 161 | int qId = await Send(MPDKeyWords.Client.Playback.SETVOL, 162 | new List() { volume.ToString() }); 163 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 164 | ? true 165 | : false; 166 | } 167 | 168 | public async Task Shuffle() 169 | { 170 | int qId = await Send(MPDKeyWords.Client.Playlist.SHUFFLE); 171 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 172 | ? true 173 | : false; 174 | } 175 | 176 | public async Task Prio(int id, int prio) 177 | { 178 | int qId = await Send(MPDKeyWords.Client.Playlist.PRIOID, 179 | new List() { prio.ToString(), id.ToString() }); 180 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 181 | ? true 182 | : false; 183 | } 184 | 185 | public async Task PrioRange(int from, int to, int prio) 186 | { 187 | int qId = await Send(MPDKeyWords.Client.Playlist.PRIO, 188 | new List() { prio.ToString(), from.ToString() + ":" + to.ToString() }); 189 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 190 | ? true 191 | : false; 192 | } 193 | 194 | public async Task UpdateDb(string URI = "") 195 | { 196 | int qId = await Send(MPDKeyWords.Client.Database.UPDATE, 197 | new List(), 198 | new List() { URI }); 199 | return ((await Response(qId)).Contains(MPDKeyWords.Response.UPDATING_DB)) 200 | ? true 201 | : false; 202 | } 203 | 204 | public async Task IsDbUpdating() 205 | { 206 | Status status = await GetStatus(); 207 | return (string.IsNullOrEmpty(status.UpdatingDb)) 208 | ? false 209 | : true; 210 | } 211 | 212 | public async Task> Playlist() 213 | { 214 | int qId = await Send(MPDKeyWords.Client.Playlist.PLAYLISTINFO); 215 | 216 | var playlist = new List(); 217 | 218 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 219 | 220 | for (int i = 0; i < response.Count; i++) 221 | playlist.Add(new SongTag(TagType.File, response[i])); 222 | 223 | return playlist; 224 | } 225 | 226 | public async Task> ListAll() 227 | { 228 | int qId = await Send(MPDKeyWords.Client.Database.LISTALL); 229 | 230 | var list = new List(); 231 | 232 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 233 | 234 | for (int i = 0; i < response.Count; i++) 235 | list.Add(new SongTag(TagType.File, response[i])); 236 | 237 | return list; 238 | } 239 | 240 | public async Task> ListAllInfo() 241 | { 242 | int qId = await Send(MPDKeyWords.Client.Database.LISTALLINFO); 243 | 244 | var list = new List(); 245 | 246 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 247 | 248 | for (int i = 0; i < response.Count; i++) 249 | list.Add(new SongTag(TagType.FileOrDirectory, response[i])); 250 | 251 | return list; 252 | } 253 | 254 | public async Task FindFile(string file) 255 | { 256 | int qId = await Send(MPDKeyWords.Client.Database.FIND, 257 | new List() { "file" }, 258 | new List() { file }); 259 | 260 | var reponse = await MPDKeyWords.Response.Encode(await Response(qId)); 261 | 262 | return (reponse.Count == 1) 263 | ? new SongTag(TagType.File, reponse[0]) 264 | : SongTag.Empty; 265 | } 266 | 267 | public async Task> PlaylistChanges(int version) 268 | { 269 | int qId = await Send(MPDKeyWords.Client.Playlist.PLCHANGES, 270 | new List(), 271 | new List() { version.ToString() }); 272 | 273 | var list = new List(); 274 | 275 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 276 | 277 | for (int i = 0; i < response.Count; i++) 278 | list.Add(new SongTag(TagType.File, response[i])); 279 | 280 | return list; 281 | } 282 | 283 | public async Task> Playlist(string playlistname) 284 | { 285 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.LISTPLAYLISTINFO, 286 | new List(), 287 | new List() { playlistname.ToString() }); 288 | 289 | var list = new List(); 290 | 291 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 292 | 293 | for (int i = 0; i < response.Count; i++) 294 | list.Add(new SongTag(TagType.File, response[i], i, playlistname)); 295 | 296 | return list; 297 | } 298 | 299 | public async Task PlaylistMoveItem(int id, int pos) 300 | { 301 | int qId = await Send(MPDKeyWords.Client.Playlist.MOVEID, 302 | new List(), 303 | new List() { id.ToString(), pos.ToString() }); 304 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 305 | ? true 306 | : false; 307 | } 308 | 309 | public async Task PlaylistMoveItem(int id, int pos, string playlistname) 310 | { 311 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.PLAYLISTMOVE, 312 | new List(), 313 | new List() { playlistname, id.ToString(), pos.ToString() }); 314 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 315 | ? true 316 | : false; 317 | } 318 | 319 | public async Task PlaylistClear() 320 | { 321 | int qId = await Send(MPDKeyWords.Client.Playlist.CLEAR); 322 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 323 | ? true 324 | : false; 325 | } 326 | 327 | public async Task PlaylistClear(string playlistname) 328 | { 329 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.PLAYLISTCLEAR, 330 | new List(), 331 | new List() { playlistname }); 332 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 333 | ? true 334 | : false; 335 | } 336 | 337 | public async Task AddToPlaylist(string file) 338 | { 339 | int qId = await Send(MPDKeyWords.Client.Playlist.ADD, 340 | new List(), 341 | new List() { file }); 342 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 343 | ? true 344 | : false; 345 | } 346 | 347 | public async Task AddIdToPlaylist(string file) 348 | { 349 | if (string.IsNullOrEmpty(file)) return string.Empty; 350 | 351 | int qId = await Send(MPDKeyWords.Client.Playlist.ADDID, 352 | new List(), 353 | new List() { file } ); 354 | 355 | string response = await Response(qId); 356 | 357 | if (response.EndsWith(MPDKeyWords.Response.OK_LINEBREAK)) 358 | { 359 | var list = await MPDKeyWords.Response.Encode(response); 360 | 361 | if (list.Count > 0) 362 | return list.FirstOrDefault().FirstOrDefault().Value; 363 | } 364 | return string.Empty; 365 | } 366 | 367 | public async Task SubscribeToChannel(string channel) 368 | { 369 | int qId = await Send(MPDKeyWords.Client.ClientToClient.SUBSCRIBE, 370 | new List() { channel }); 371 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 372 | ? true 373 | : false; 374 | } 375 | 376 | public async Task UnsubscribeToChannel(string channel) 377 | { 378 | int qId = await Send(MPDKeyWords.Client.ClientToClient.UNSUBSCRIBE, 379 | new List() { channel }); 380 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 381 | ? true 382 | : false; 383 | } 384 | 385 | public async Task SendMessage(string channel, string message) 386 | { 387 | int qId = await Send(MPDKeyWords.Client.ClientToClient.SENDMESSAGE, 388 | new List() { channel }, 389 | new List() { message }); 390 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 391 | ? true 392 | : false; 393 | } 394 | 395 | 396 | public async Task> Channels() 397 | { 398 | int qId = await Send(MPDKeyWords.Client.ClientToClient.CHANNELS); 399 | 400 | var list = new List(); 401 | 402 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 403 | 404 | for (int i = 0; i < response.Count; i++) 405 | list.Add(new Channel(response[i])); 406 | 407 | return list; 408 | } 409 | 410 | public async Task> ReadMessages() 411 | { 412 | int qId = await Send(MPDKeyWords.Client.ClientToClient.READMESSAGES); 413 | 414 | var list = new List(); 415 | 416 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 417 | 418 | for (int i = 0; i < response.Count; i++) 419 | list.Add(new Message(response[i])); 420 | 421 | return list; 422 | } 423 | 424 | public async Task AddToPlaylist(string file, string playlistname) 425 | { 426 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.PLAYLISTADD, 427 | new List(), 428 | new List() { playlistname, file }); 429 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 430 | ? true 431 | : false; 432 | } 433 | 434 | public async Task PlaybackSettingsRandom(bool settings) 435 | { 436 | int qId = await Send(MPDKeyWords.Client.Playback.RANDOM, 437 | new List() { Convert.ToInt32(settings).ToString() }); 438 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 439 | ? true 440 | : false; 441 | } 442 | 443 | public async Task PlaybackSettingsConsume(bool settings) 444 | { 445 | int qId = await Send(MPDKeyWords.Client.Playback.CONSUME, 446 | new List() { Convert.ToInt32(settings).ToString() }); 447 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 448 | ? true 449 | : false; 450 | } 451 | 452 | public async Task PlaybackSettingsRepeat(bool settings) 453 | { 454 | int qId = await Send(MPDKeyWords.Client.Playback.REPEAT, 455 | new List() { Convert.ToInt32(settings).ToString() }); 456 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 457 | ? true 458 | : false; 459 | } 460 | 461 | public async Task PlaybackSettingsSingle(bool settings) 462 | { 463 | int qId = await Send(MPDKeyWords.Client.Playback.SINGLE, 464 | new List() { Convert.ToInt32(settings).ToString() }); 465 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 466 | ? true 467 | : false; 468 | } 469 | 470 | public async Task PlaybackSettingsCrossfade(int seconds) 471 | { 472 | int qId = await Send(MPDKeyWords.Client.Playback.CROSSFADE, 473 | new List() { seconds.ToString() }); 474 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 475 | ? true 476 | : false; 477 | } 478 | 479 | public async Task RemoveIdFromPlaylist(int id) 480 | { 481 | int qId = await Send(MPDKeyWords.Client.Playlist.DELETEID, 482 | new List() { id.ToString() }); 483 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 484 | ? true 485 | : false; 486 | } 487 | 488 | public async Task RemoveFromPlaylist(int position) 489 | { 490 | int qId = await Send(MPDKeyWords.Client.Playlist.DELETE, 491 | new List() { position.ToString() }); 492 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 493 | ? true 494 | : false; 495 | } 496 | 497 | public async Task RemoveFromPlaylist(int position, string playlistname) 498 | { 499 | int qId = await Send(MPDKeyWords.Client.StoredPlaylist.PLAYLISTDELETE, 500 | new List() { position.ToString() }, 501 | new List() { playlistname }, 502 | true); 503 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 504 | ? true 505 | : false; 506 | } 507 | 508 | public async Task SeekCurrent(int time) 509 | { 510 | int qId = await Send(MPDKeyWords.Client.Playback.SEEKCUR, 511 | new List() { time.ToString() }); 512 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 513 | ? true 514 | : false; 515 | } 516 | 517 | public async Task SeekId(int time, int id) 518 | { 519 | int qId = await Send(MPDKeyWords.Client.Playback.SEEKID, 520 | new List() { id.ToString(), time.ToString() }); 521 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 522 | ? true 523 | : false; 524 | } 525 | 526 | public async Task ClearError() 527 | { 528 | int qId = await Send(MPDKeyWords.Client.Status.CLEARERROR); 529 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 530 | ? true 531 | : false; 532 | } 533 | 534 | public async Task DebugSend(string s) 535 | { 536 | int qId = await Send(s); 537 | string responseString = await Response(qId); 538 | return responseString; 539 | } 540 | 541 | public async Task> Search(string type, string searchstring) 542 | { 543 | int qId = await Send(MPDKeyWords.Client.Database.SEARCH, 544 | new List(), 545 | new List() { type, searchstring }); 546 | 547 | var list = new List(); 548 | 549 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 550 | 551 | for (int i = 0; i < response.Count; i++) 552 | list.Add(new SongTag(TagType.FileOrDirectory, response[i], i)); 553 | 554 | return list; 555 | } 556 | 557 | public async Task SearchAddToPlaylist(string playlist, string type, string searchstring) 558 | { 559 | var qId = (!string.IsNullOrEmpty(playlist)) 560 | ? await Send(MPDKeyWords.Client.Database.SEARCHADDPL, 561 | new List(), 562 | new List() { playlist, type, searchstring }) 563 | : await Send(MPDKeyWords.Client.Database.SEARCHADD, 564 | new List(), 565 | new List() { type, searchstring }); 566 | 567 | return ((await Response(qId)).Equals(MPDKeyWords.Response.OK_LINEBREAK)) 568 | ? true 569 | : false; 570 | } 571 | 572 | public async Task> Songlist(string URI = "", string ordertype ="", List currentPlaylist = null) 573 | { 574 | string command = string.Empty; 575 | var arguments = new List(); 576 | var special = new List(); 577 | 578 | switch(ordertype) 579 | { 580 | case ("artist"): 581 | command = MPDKeyWords.Client.Database.LIST; 582 | arguments.Add("artist"); 583 | break; 584 | case ("album"): 585 | command = MPDKeyWords.Client.Database.LIST; 586 | arguments.Add("album"); 587 | if(!string.IsNullOrEmpty(URI)) 588 | { 589 | arguments.Add("artist"); 590 | special.Add(URI); 591 | } 592 | break; 593 | case ("genre"): 594 | arguments.Add("genre"); 595 | if(string.IsNullOrEmpty(URI)) 596 | command = MPDKeyWords.Client.Database.LIST; 597 | else 598 | { 599 | command = MPDKeyWords.Client.Database.FIND; 600 | special.Add(URI); 601 | } 602 | break; 603 | case ("find"): 604 | command = MPDKeyWords.Client.Database.FIND; 605 | arguments.Add("album"); 606 | special.Add(URI); 607 | break; 608 | case ("search"): 609 | command = MPDKeyWords.Client.Database.SEARCH; 610 | arguments.Add("any"); 611 | special.Add(URI); 612 | break; 613 | default: 614 | command = MPDKeyWords.Client.Database.LSINFO; 615 | special.Add(URI); 616 | break; 617 | } 618 | 619 | var qId = await Send(command, arguments, special); 620 | 621 | var response = await MPDKeyWords.Response.Encode(await Response(qId)); 622 | 623 | var songlist = new List(); 624 | 625 | for (int i = 0; i < response.Count; i++ ) 626 | songlist.Add(new SongTag(response[i], i)); 627 | 628 | return songlist; 629 | } 630 | 631 | public async Task GetStatus() 632 | { 633 | int qId = await Send(MPDKeyWords.Client.Status.STATUS); 634 | var response = await Response(qId); 635 | return new Status( (await MPDKeyWords.Response.Encode(response)).FirstOrDefault() ); 636 | } 637 | 638 | public async Task Stats() 639 | { 640 | int qId = await Send(MPDKeyWords.Client.Status.STATS); 641 | return new Stats((await MPDKeyWords.Response.Encode(await Response(qId))).FirstOrDefault()); 642 | } 643 | 644 | public async Task CurrentSong() 645 | { 646 | var qId = await Send(MPDKeyWords.Client.Status.CURRENTSONG); 647 | 648 | var response = await Response(qId); 649 | var list = await MPDKeyWords.Response.Encode(response); 650 | 651 | return new SongTag(TagType.File, list.FirstOrDefault()); 652 | } 653 | 654 | public async Task PlaylistId(int Id) 655 | { 656 | int qId = await Send(MPDKeyWords.Client.Playlist.PLAYLISTID, 657 | new List() { Id.ToString() }); 658 | return new SongTag(TagType.File, (await MPDKeyWords.Response.Encode(await Response(qId))).FirstOrDefault()); 659 | } 660 | } 661 | } 662 | -------------------------------------------------------------------------------- /Chimney.MPD/ChimneyMPDDirectClient.cs: -------------------------------------------------------------------------------- 1 | using Chimney.MPD.Classes; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.UI.Xaml; 8 | 9 | namespace Chimney.MPD 10 | { 11 | /* 12 | public class ChimneyMPDDirectClient : ChimneyMPDBase 13 | { 14 | 15 | public bool idle = false; 16 | 17 | DispatcherTimer holdConnectionTimer; 18 | 19 | 20 | private bool silent; 21 | public bool Silent 22 | { 23 | get { return silent; } 24 | set { silent = value; } 25 | } 26 | 27 | public ChimneyMPDDirectClient(string host, string port, string password = null, bool silent = false, int timeout = 5) 28 | { 29 | if (!string.IsNullOrEmpty(host)) this.host = host; 30 | if (!string.IsNullOrEmpty(port)) this.port = port; 31 | if(!string.IsNullOrEmpty(password)) this.password = password; 32 | this.silent = silent; 33 | 34 | holdConnectionTimer = new DispatcherTimer(); 35 | holdConnectionTimer.Interval = new TimeSpan(0, 0, timeout); 36 | holdConnectionTimer.Tick += holdConnectionTimer_Tick; 37 | } 38 | 39 | async void holdConnectionTimer_Tick(object sender, object e) 40 | { 41 | await Close(false); 42 | holdConnectionTimer.Stop(); 43 | } 44 | 45 | 46 | public async Task Ping(bool silent = true) 47 | { 48 | await Connect(silent); 49 | bool suc = await Send(CLIENT_PING, streamSocket, "", silent); 50 | if (suc) 51 | { 52 | string responseString = await Response(); 53 | await Disconnect(); 54 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 55 | } 56 | return false; 57 | } 58 | 59 | public async Task Connect(bool silent = false) 60 | { 61 | if (holdConnectionTimer.IsEnabled) 62 | { 63 | holdConnectionTimer.Stop(); 64 | holdConnectionTimer.Start(); 65 | return true; 66 | } 67 | 68 | bool suc = await Connect(this.host, this.port, this.password, silent); 69 | if(suc) holdConnectionTimer.Start(); 70 | return suc; 71 | } 72 | 73 | public async Task Disconnect(bool silent = false) 74 | { 75 | //return await Close(false); 76 | return true; 77 | } 78 | 79 | public async Task CheckConnection(bool silent = true, bool retry = false) 80 | { 81 | await Connect(silent); 82 | bool suc = await Send(CLIENT_PING, streamSocket, "", silent, retry); 83 | if (suc) 84 | { 85 | string responseString = await Response(); 86 | await Disconnect(); 87 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 88 | } 89 | return false; 90 | } 91 | 92 | public async Task> Outputs() 93 | { 94 | await Connect(this.silent); 95 | await Send(CLIENT_OUTPUTS, streamSocket); 96 | string responseString = await Response(); 97 | await Disconnect(); 98 | 99 | List> respons = GetResponseOrder(responseString); 100 | 101 | List outputs = new List(); 102 | 103 | foreach (Dictionary d in respons) 104 | { 105 | outputs.Add(new Output(d)); 106 | } 107 | 108 | return outputs; 109 | } 110 | 111 | public async Task EnableOutput(string outputid = "0") 112 | { 113 | await Connect(this.silent); 114 | await Send(CLIENT_ENABLEOUTPUT, streamSocket, outputid); 115 | string responseString = await Response(); 116 | await Disconnect(); 117 | 118 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 119 | return false; 120 | } 121 | 122 | public async Task SavePlaylist(string playlist) 123 | { 124 | await Connect(this.silent); 125 | await Send(CLIENT_SAVE, streamSocket, "\"" + playlist + "\""); 126 | string responseString = await Response(); 127 | await Disconnect(); 128 | 129 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 130 | return false; 131 | } 132 | 133 | public async Task RemovePlaylist(string playlist) 134 | { 135 | await Connect(this.silent); 136 | await Send(CLIENT_RM, streamSocket, "\"" + playlist + "\""); 137 | string responseString = await Response(); 138 | await Disconnect(); 139 | 140 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 141 | return false; 142 | } 143 | 144 | public async Task> ListPlaylists() 145 | { 146 | await Connect(this.silent); 147 | await Send(CLIENT_LISTPLAYLISTS, streamSocket); 148 | string responseString = await Response(); 149 | await Disconnect(); 150 | 151 | List> responseList = GetResponseOrder(responseString); 152 | 153 | List playlists = new List(); 154 | 155 | foreach (Dictionary d in responseList) 156 | { 157 | playlists.Add(new StoredPlaylist(d)); 158 | } 159 | 160 | return playlists; 161 | } 162 | 163 | public async Task LoadPlaylist(string playlist) 164 | { 165 | await Connect(this.silent); 166 | await Send(CLIENT_LOAD, streamSocket, "\"" + playlist + "\""); 167 | string responseString = await Response(); 168 | await Disconnect(); 169 | 170 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 171 | return false; 172 | } 173 | 174 | public async Task LoadPlaylist(string playlist, int start, int end) 175 | { 176 | await Connect(this.silent); 177 | await Send(CLIENT_LOAD, streamSocket, "\"" + playlist + "\" " + start.ToString() + ":" + end.ToString()); 178 | string responseString = await Response(); 179 | await Disconnect(); 180 | 181 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 182 | return false; 183 | } 184 | 185 | public async Task DisableOutput(string outputid = "0") 186 | { 187 | await Connect(this.silent); 188 | await Send(CLIENT_DISABLEOUTPUT, streamSocket, outputid); 189 | string responseString = await Response(); 190 | await Disconnect(); 191 | 192 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 193 | return false; 194 | } 195 | 196 | public async Task Play(int songid) 197 | { 198 | await Connect(this.silent); 199 | await Send(CLIENT_PLAY, streamSocket, songid.ToString()); 200 | string responseString = await Response(); 201 | await Disconnect(); 202 | 203 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 204 | return false; 205 | } 206 | 207 | public async Task PlayId(int songid) 208 | { 209 | await Connect(this.silent); 210 | await Send(CLIENT_PLAYID, streamSocket, songid.ToString()); 211 | string responseString = await Response(); 212 | await Disconnect(); 213 | 214 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 215 | return false; 216 | } 217 | 218 | public async Task Stop() 219 | { 220 | await Connect(this.silent); 221 | await Send(CLIENT_STOP, streamSocket); 222 | string responseString = await Response(); 223 | await Disconnect(); 224 | 225 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 226 | return false; 227 | } 228 | 229 | public async Task Pause() 230 | { 231 | await Connect(this.silent); 232 | await Send(CLIENT_PAUSE, streamSocket); 233 | string responseString = await Response(); 234 | await Disconnect(); 235 | 236 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 237 | return false; 238 | } 239 | 240 | public async Task Next() 241 | { 242 | await Connect(this.silent); 243 | await Send(CLIENT_NEXT, streamSocket); 244 | string responseString = await Response(); 245 | await Disconnect(); 246 | 247 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 248 | return false; 249 | } 250 | 251 | public async Task Previous() 252 | { 253 | await Connect(this.silent); 254 | await Send(CLIENT_PREVIOUS, streamSocket); 255 | string responseString = await Response(); 256 | await Disconnect(); 257 | 258 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 259 | return false; 260 | } 261 | 262 | public async Task Volume(double volume) 263 | { 264 | await Connect(this.silent); 265 | await Send(CLIENT_SETVOL, streamSocket, volume.ToString()); 266 | string responseString = await Response(); 267 | await Disconnect(); 268 | 269 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 270 | return false; 271 | } 272 | 273 | public async Task Shuffle() 274 | { 275 | await Connect(this.silent); 276 | await Send(CLIENT_SHUFFLE, streamSocket); 277 | string responseString = await Response(); 278 | await Disconnect(); 279 | 280 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 281 | return false; 282 | } 283 | 284 | public async Task Prio(int id, int prio) 285 | { 286 | await Connect(this.silent); 287 | await Send(CLIENT_PRIOID, streamSocket, prio + " " + id); 288 | string responseString = await Response(); 289 | await Disconnect(); 290 | 291 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 292 | return false; 293 | } 294 | 295 | public async Task UpdateDb(string URI = "") 296 | { 297 | await Connect(this.silent); 298 | await Send(CLIENT_UPDATE, streamSocket, "\"" + URI + "\""); 299 | string responseString = await Response(); 300 | await Disconnect(); 301 | 302 | if (responseString.Contains("updating_db")) return true; 303 | else return false; 304 | } 305 | 306 | public async Task IsDbUpdating() 307 | { 308 | Status status = await GetStatus(); 309 | if (string.IsNullOrEmpty(status.UpdatingDb)) return false; 310 | else return true; 311 | } 312 | 313 | public async Task> Playlist() 314 | { 315 | await Connect(this.silent); 316 | await Send(CLIENT_PLAYLISTINFO, streamSocket); 317 | string responseString = await Response(); 318 | await Disconnect(); 319 | 320 | List> responseList = GetResponseLists(responseString); 321 | 322 | List playlist = new List(); 323 | 324 | foreach (Dictionary d in responseList) 325 | { 326 | playlist.Add(new SongTag(TagTypes.File, d)); 327 | } 328 | 329 | return playlist; 330 | } 331 | 332 | public async Task> PlaylistChanges(int version) 333 | { 334 | await Connect(this.silent); 335 | await Send(CLIENT_PLCHANGES, streamSocket, "\"" + version + "\""); 336 | string responseString = await Response(); 337 | await Disconnect(); 338 | 339 | List> responseList = GetResponseLists(responseString); 340 | 341 | List playlist = new List(); 342 | 343 | foreach (Dictionary d in responseList) 344 | { 345 | playlist.Add(new SongTag(TagTypes.File, d)); 346 | } 347 | 348 | return playlist; 349 | } 350 | 351 | public async Task> Playlist(string playlistname) 352 | { 353 | await Connect(this.silent); 354 | await Send(CLIENT_LISTPLAYLISTINFO, streamSocket, "\"" + playlistname + "\""); 355 | string responseString = await Response(); 356 | await Disconnect(); 357 | 358 | List> responseList = GetResponseLists(responseString); 359 | 360 | List playlist = new List(); 361 | 362 | int i = 0; 363 | foreach (Dictionary d in responseList) 364 | { 365 | playlist.Add(new SongTag(TagTypes.File, d, i, playlistname)); 366 | i++; 367 | } 368 | 369 | return playlist; 370 | } 371 | 372 | public async Task PlaylistMoveItem(int id, int pos) 373 | { 374 | await Connect(this.silent); 375 | await Send(CLIENT_MOVEID, streamSocket, "\"" + id + "\" \"" + pos + "\""); 376 | string responseString = await Response(); 377 | await Disconnect(); 378 | 379 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 380 | return false; 381 | } 382 | 383 | public async Task PlaylistMoveItem(int id, int pos, string playlistname) 384 | { 385 | await Connect(this.silent); 386 | await Send(CLIENT_PLAYLISTMOVE, streamSocket, "\"" + playlistname + "\" " + "\"" + id + "\" \"" + pos + "\""); 387 | string responseString = await Response(); 388 | await Disconnect(); 389 | 390 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 391 | return false; 392 | } 393 | 394 | public async Task PlaylistClear() 395 | { 396 | await Connect(this.silent); 397 | await Send(CLIENT_CLEAR, streamSocket); 398 | string responseString = await Response(); 399 | await Disconnect(); 400 | 401 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 402 | return false; 403 | } 404 | 405 | public async Task PlaylistClear(string playlistname) 406 | { 407 | await Connect(this.silent); 408 | await Send(CLIENT_PLAYLISTCLEAR, streamSocket, "\"" + playlistname + "\""); 409 | string responseString = await Response(); 410 | await Disconnect(); 411 | 412 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 413 | return false; 414 | } 415 | 416 | public async Task AddToPlaylist(string file) 417 | { 418 | await Connect(this.silent); 419 | await Send(CLIENT_ADD, streamSocket, "\"" + file + "\""); 420 | string responseString = await Response(); 421 | await Disconnect(); 422 | 423 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 424 | return false; 425 | } 426 | 427 | public async Task AddIdToPlaylist(string file) 428 | { 429 | await Connect(this.silent); 430 | await Send(CLIENT_ADDID, streamSocket, "\"" + file + "\""); 431 | string responseString = await Response(); 432 | await Disconnect(); 433 | 434 | if (responseString.EndsWith(LINEBREAK + RESPONSE_OK + LINEBREAK)) 435 | { 436 | responseString = responseString.Replace(LINEBREAK + RESPONSE_OK + LINEBREAK, ""); 437 | responseString = responseString.Replace(" ", ""); 438 | string[] responseList = responseString.Split(":".ToCharArray()); 439 | if (responseList.Length > 1) return responseList[1]; 440 | } 441 | return string.Empty; 442 | } 443 | 444 | public async Task SubscribeToChannel(string channel) 445 | { 446 | await Connect(this.silent); 447 | await Send(CLIENT_SUBSCRIBE, streamSocket, channel); 448 | string responseString = await Response(); 449 | await Disconnect(); 450 | 451 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 452 | return false; 453 | } 454 | 455 | public async Task UnsubscribeToChannel(string channel) 456 | { 457 | await Connect(this.silent); 458 | await Send(CLIENT_UNSUBSCRIBE, streamSocket, channel); 459 | string responseString = await Response(); 460 | await Disconnect(); 461 | 462 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 463 | return false; 464 | } 465 | 466 | public async Task SendMessage(string channel, string message) 467 | { 468 | await Connect(this.silent); 469 | await Send(CLIENT_SENDMESSAGE, streamSocket, channel + " \"" + message + "\""); 470 | string responseString = await Response(); 471 | await Disconnect(); 472 | 473 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 474 | return false; 475 | } 476 | 477 | 478 | public async Task> Channels() 479 | { 480 | await Connect(this.silent); 481 | await Send(CLIENT_CHANNELS, streamSocket); 482 | string responseString = await Response(); 483 | await Disconnect(); 484 | 485 | List> responseList = GetResponseOrder(responseString); 486 | 487 | List channels = new List(); 488 | 489 | foreach (Dictionary d in responseList) 490 | { 491 | channels.Add(new Channel(d)); 492 | } 493 | return channels; 494 | } 495 | 496 | public async Task> ReadMessages() 497 | { 498 | await Connect(this.silent); 499 | await Send(CLIENT_CHANNELS, streamSocket); 500 | string responseString = await Response(); 501 | await Disconnect(); 502 | 503 | List> responseList = GetResponseOrder(responseString); 504 | 505 | List messages = new List(); 506 | 507 | foreach (Dictionary d in responseList) 508 | { 509 | messages.Add(new Message(d)); 510 | } 511 | return messages; 512 | } 513 | 514 | public async Task AddToPlaylist(string file, string playlistname) 515 | { 516 | await Connect(this.silent); 517 | await Send(CLIENT_PLAYLISTADD, streamSocket, "\"" + playlistname + "\" " + "\"" + file + "\""); 518 | string responseString = await Response(); 519 | await Disconnect(); 520 | 521 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 522 | return false; 523 | } 524 | 525 | public async Task PlaybackSettingsRandom(bool settings) 526 | { 527 | await Connect(this.silent); 528 | await Send(CLIENT_RANDOM, streamSocket, Convert.ToInt32(settings).ToString()); 529 | string responseString = await Response(); 530 | await Disconnect(); 531 | 532 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 533 | return false; 534 | } 535 | 536 | public async Task PlaybackSettingsConsume(bool settings) 537 | { 538 | await Connect(this.silent); 539 | await Send(CLIENT_CONSUME, streamSocket, Convert.ToInt32(settings).ToString()); 540 | string responseString = await Response(); 541 | await Disconnect(); 542 | 543 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 544 | return false; 545 | } 546 | 547 | public async Task PlaybackSettingsRepeat(bool settings) 548 | { 549 | await Connect(this.silent); 550 | await Send(CLIENT_REPEAT, streamSocket, Convert.ToInt32(settings).ToString()); 551 | string responseString = await Response(); 552 | await Disconnect(); 553 | 554 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 555 | return false; 556 | } 557 | 558 | public async Task PlaybackSettingsSingle(bool settings) 559 | { 560 | await Connect(this.silent); 561 | await Send(CLIENT_SINGLE, streamSocket, Convert.ToInt32(settings).ToString()); 562 | string responseString = await Response(); 563 | await Disconnect(); 564 | 565 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 566 | return false; 567 | } 568 | 569 | public async Task PlaybackSettingsCrossfade(int seconds) 570 | { 571 | await Connect(this.silent); 572 | await Send(CLIENT_CROSSFADE, streamSocket, seconds.ToString()); 573 | string responseString = await Response(); 574 | await Disconnect(); 575 | 576 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 577 | return false; 578 | } 579 | 580 | public async Task RemoveFromPlaylist(int id) 581 | { 582 | await Connect(this.silent); 583 | await Send(CLIENT_DELETEID, streamSocket, "" + id); 584 | string responseString = await Response(); 585 | await Disconnect(); 586 | 587 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 588 | return false; 589 | } 590 | 591 | public async Task RemoveFromPlaylist(int id, string playlistname) 592 | { 593 | await Connect(this.silent); 594 | await Send(CLIENT_PLAYLISTDELETE, streamSocket, "\"" + playlistname + "\" " + id); 595 | string responseString = await Response(); 596 | await Disconnect(); 597 | 598 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 599 | return false; 600 | } 601 | 602 | public async Task SeekCurrent(int time) 603 | { 604 | await Connect(this.silent); 605 | await Send(CLIENT_SEEKCUR, streamSocket, "" + time); 606 | string responseString = await Response(); 607 | await Disconnect(); 608 | 609 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 610 | return false; 611 | } 612 | 613 | public async Task SeekId(int time, int id) 614 | { 615 | await Connect(this.silent); 616 | await Send(CLIENT_SEEKID, streamSocket, id + " " + time); 617 | string responseString = await Response(); 618 | await Disconnect(); 619 | 620 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 621 | return false; 622 | } 623 | 624 | public async Task ClearError() 625 | { 626 | await Connect(this.silent); 627 | await Send(CLIENT_CLEARERROR, streamSocket); 628 | string responseString = await Response(); 629 | await Disconnect(); 630 | 631 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 632 | return false; 633 | } 634 | 635 | public async Task DebugSend(string s) 636 | { 637 | await Connect(this.silent); 638 | await Send(s, streamSocket); 639 | string responseString = await Response(); 640 | await Disconnect(); 641 | 642 | return responseString; 643 | } 644 | 645 | public async Task> Search(string type, string searchstring) 646 | { 647 | await Connect(this.silent); 648 | List songlist = new List(); 649 | List> responsList = new List>(); 650 | TagType tagType; 651 | 652 | await Send(CLIENT_SEARCH, streamSocket, "\"" + type + "\" \"" + searchstring + "\""); 653 | string responseString = await Response(); 654 | await Disconnect(); 655 | 656 | responsList = GetResponseLists(responseString); 657 | tagType = TagTypes.FileOrDirectory; 658 | 659 | int i = 0; 660 | foreach (Dictionary d in responsList) 661 | { 662 | //songlist.Add(new SongTag(tagType, d, currentPlaylist)); 663 | songlist.Add(new SongTag(tagType, d, i)); 664 | i++; 665 | } 666 | 667 | return songlist; 668 | } 669 | 670 | public async Task SearchAddToPlaylist(string playlist, string type, string searchstring) 671 | { 672 | await Connect(this.silent); 673 | if (!string.IsNullOrEmpty(playlist)) 674 | { 675 | await Send(CLIENT_SEARCHADDPL, streamSocket, "\"" + playlist + "\" \"" + type + "\" \"" + searchstring + "\""); 676 | } 677 | else 678 | { 679 | await Send(CLIENT_SEARCHADD, streamSocket, "\"" + type + "\" \"" + searchstring + "\""); 680 | } 681 | string responseString = await Response(); 682 | await Disconnect(); 683 | 684 | if (responseString.Equals(RESPONSE_OK + LINEBREAK)) return true; 685 | return false; 686 | } 687 | 688 | public async Task> Songlist(string URI = "", string ordertype ="", List currentPlaylist = null) 689 | { 690 | await Connect(this.silent); 691 | List songlist = new List(); 692 | List> responsList = new List>(); 693 | 694 | TagType tagType; 695 | 696 | if (ordertype.Equals("artist")) 697 | { 698 | await Send(CLIENT_LIST, streamSocket, "artist"); 699 | string responseString = await Response(); 700 | await Disconnect(); 701 | 702 | responsList = GetResponseOrder(responseString); 703 | 704 | responsList.Sort(delegate(Dictionary d1, Dictionary d2) { return d1["Artist"].CompareTo(d2["Artist"]); }); 705 | 706 | tagType = TagTypes.Artist; 707 | } 708 | else if(ordertype.Equals("album")) 709 | { 710 | if(URI.Equals("")) await Send(CLIENT_LIST, streamSocket, "album"); 711 | else await Send(CLIENT_LIST, streamSocket, "album " + "\"" + URI + "\""); 712 | string responseString = await Response(); 713 | await Disconnect(); 714 | 715 | responsList = GetResponseOrder(responseString); 716 | 717 | responsList.Sort(delegate(Dictionary d1, Dictionary d2) { return d1["Album"].CompareTo(d2["Album"]); }); 718 | 719 | tagType = TagTypes.Album; 720 | } 721 | else if (ordertype.Equals("genre")) 722 | { 723 | if (URI.Equals("")) 724 | { 725 | await Send(CLIENT_LIST, streamSocket, "genre"); 726 | string responseString = await Response(); 727 | await Disconnect(); 728 | 729 | responsList = GetResponseOrder(responseString); 730 | 731 | responsList.Sort(delegate(Dictionary d1, Dictionary d2) { return d1["Genre"].CompareTo(d2["Genre"]); }); 732 | 733 | tagType = TagTypes.Genre; 734 | } 735 | else 736 | { 737 | await Send(CLIENT_FIND, streamSocket, "genre " + "\"" + URI + "\""); 738 | string responseString = await Response(); 739 | await Disconnect(); 740 | 741 | responsList = GetResponseLists(responseString); 742 | 743 | //responsList.Sort(delegate(Dictionary d1, Dictionary d2) { return d1["file"].CompareTo(d2["file"]); }); 744 | 745 | tagType = TagTypes.FileOrDirectory; 746 | } 747 | } 748 | else if(ordertype.Equals("find")) 749 | { 750 | await Send(CLIENT_FIND, streamSocket, "album " + "\"" + URI + "\""); 751 | string responseString = await Response(); 752 | await Disconnect(); 753 | 754 | responsList = GetResponseLists(responseString); 755 | 756 | //responsList.Sort(delegate(Dictionary d1, Dictionary d2) { return d1["file"].CompareTo(d2["file"]); }); 757 | 758 | tagType = TagTypes.FileOrDirectory; 759 | } 760 | else if (ordertype.Equals("search")) 761 | { 762 | await Send(CLIENT_SEARCH, streamSocket, "any " + "\"" + URI + "\""); 763 | string responseString = await Response(); 764 | await Disconnect(); 765 | 766 | responsList = GetResponseLists(responseString); 767 | 768 | //responsList.Sort(delegate(Dictionary d1, Dictionary d2) { return d1["file"].CompareTo(d2["file"]); }); 769 | 770 | tagType = TagTypes.FileOrDirectory; 771 | 772 | } 773 | else 774 | { 775 | await Send(CLIENT_LSINFO, streamSocket, "\"" + URI + "\""); 776 | string responseString = await Response(); 777 | await Disconnect(); 778 | 779 | responsList = GetResponseLists(responseString); 780 | 781 | tagType = TagTypes.FileOrDirectory; 782 | 783 | } 784 | 785 | int i = 0; 786 | foreach(Dictionary d in responsList) 787 | { 788 | songlist.Add(new SongTag(tagType, d, i)); 789 | i++; 790 | } 791 | 792 | return songlist; 793 | } 794 | 795 | public async Task GetStatus() 796 | { 797 | await Connect(this.silent); 798 | await Send(CLIENT_STATUS, streamSocket); 799 | string responseString = await Response(); 800 | await Disconnect(); 801 | 802 | Dictionary responseList = GetResponseDictionary(responseString); 803 | return new Status(responseList); 804 | } 805 | 806 | public async Task Stats() 807 | { 808 | await Connect(this.silent); 809 | await Send(CLIENT_STATS, streamSocket); 810 | string responseString = await Response(); 811 | await Disconnect(); 812 | 813 | Dictionary stats = GetResponseDictionary(responseString); 814 | return new Stats(stats); 815 | } 816 | 817 | public async Task CurrentSong() 818 | { 819 | await Connect(this.silent); 820 | await Send(CLIENT_CURRENTSONG, streamSocket); 821 | string responseString = await Response(); 822 | await Disconnect(); 823 | 824 | Dictionary responseList = GetResponseDictionary(responseString); 825 | return new SongTag(TagTypes.File, responseList); 826 | } 827 | 828 | public async Task PlaylistId(int Id) 829 | { 830 | await Connect(this.silent); 831 | await Send(CLIENT_PLAYLISTID, streamSocket, Id.ToString()); 832 | string responseString = await Response(); 833 | await Disconnect(); 834 | 835 | Dictionary responseList = GetResponseDictionary(responseString); 836 | return new SongTag(TagTypes.File, responseList); 837 | } 838 | 839 | 840 | 841 | 842 | } 843 | */ 844 | } 845 | --------------------------------------------------------------------------------