├── .github
└── workflows
│ └── dotnet-core-desktop.yml
├── .gitignore
├── ChaturbatePlayer
├── ChaturbatePlayer.sln
└── ChaturbatePlayer
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── Base
│ ├── IMediator.cs
│ └── Mediator.cs
│ ├── ChaturbatePlayer.csproj
│ ├── Converters
│ ├── GenderToImageConverter.cs
│ ├── GenderToNameConverter.cs
│ ├── IntegerToVisibilityConverter.cs
│ ├── InverseBooleanConverter.cs
│ ├── InverseBooleanToVisibilityConverter.cs
│ ├── LiveStreamPlayerStateToVisibilityConverter.cs
│ └── PlayerMuteStateToImageSourceConverter.cs
│ ├── Icon.ico
│ ├── Images
│ ├── ApplicationExport.png
│ ├── ArrowBack.png
│ ├── ArrowCircle.png
│ ├── ArrowForward.png
│ ├── ArrowRefresh.png
│ ├── FolderOpen.png
│ ├── GenderCouple.png
│ ├── GenderFemale.png
│ ├── GenderMale.png
│ ├── GenderTrans.png
│ ├── Help.png
│ ├── Icon.ico
│ ├── Icon.png
│ ├── Lock.png
│ ├── Logo.png
│ ├── PlayerMute.png
│ ├── PlayerPause.png
│ ├── PlayerPlay.png
│ ├── PlayerStop.png
│ ├── PlayerUnmute.png
│ ├── Settings.png
│ ├── Star.png
│ ├── Unlock.png
│ └── Webcam.png
│ ├── Models
│ ├── ChatRoomModel.cs
│ ├── LicenseModel.cs
│ └── SettingsModel.cs
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── Shared.cs
│ ├── VLC.zip
│ ├── ViewModels
│ ├── ChatRoomsViewModel.cs
│ ├── LicenseKeyGeneratorViewModel.cs
│ ├── LiveStreamPlayerViewModel.cs
│ ├── MainWindowViewModel.cs
│ ├── SettingsViewModel.cs
│ └── SplashViewModel.cs
│ ├── Views
│ ├── ChatRoomsView.xaml
│ ├── ChatRoomsView.xaml.cs
│ ├── LicenseKeyGeneratorWindowView.xaml
│ ├── LicenseKeyGeneratorWindowView.xaml.cs
│ ├── LiveStreamPlayerView.xaml
│ ├── LiveStreamPlayerView.xaml.cs
│ ├── MainWindowView.xaml
│ ├── MainWindowView.xaml.cs
│ ├── SettingsView.xaml
│ ├── SettingsView.xaml.cs
│ ├── SplashWindowView.xaml
│ └── SplashWindowView.xaml.cs
│ ├── app.config
│ └── packages.config
├── README.md
└── Screenshots
├── Capture0.PNG
├── Capture1.PNG
└── Capture2.PNG
/.github/workflows/dotnet-core-desktop.yml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub.
2 | # They are provided by a third-party and are governed by
3 | # separate terms of service, privacy policy, and support
4 | # documentation.
5 |
6 | # This workflow will build, test, sign and package a WPF or Windows Forms desktop application
7 | # built on .NET Core.
8 | # To learn how to migrate your existing application to .NET Core,
9 | # refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework
10 | #
11 | # To configure this workflow:
12 | #
13 | # 1. Configure environment variables
14 | # GitHub sets default environment variables for every workflow run.
15 | # Replace the variables relative to your project in the "env" section below.
16 | #
17 | # 2. Signing
18 | # Generate a signing certificate in the Windows Application
19 | # Packaging Project or add an existing signing certificate to the project.
20 | # Next, use PowerShell to encode the .pfx file using Base64 encoding
21 | # by running the following Powershell script to generate the output string:
22 | #
23 | # $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte
24 | # [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'
25 | #
26 | # Open the output file, SigningCertificate_Encoded.txt, and copy the
27 | # string inside. Then, add the string to the repo as a GitHub secret
28 | # and name it "Base64_Encoded_Pfx."
29 | # For more information on how to configure your signing certificate for
30 | # this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing
31 | #
32 | # Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key".
33 | # See "Build the Windows Application Packaging project" below to see how the secret is used.
34 | #
35 | # For more information on GitHub Actions, refer to https://github.com/features/actions
36 | # For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,
37 | # refer to https://github.com/microsoft/github-actions-for-desktop-apps
38 |
39 | name: .NET Core Desktop
40 |
41 | on:
42 | push:
43 | branches: [ master ]
44 | pull_request:
45 | branches: [ master ]
46 |
47 | jobs:
48 |
49 | build:
50 |
51 | strategy:
52 | matrix:
53 | configuration: [Debug, Release]
54 |
55 | runs-on: windows-latest # For a list of available runner types, refer to
56 | # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on
57 |
58 | env:
59 | Solution_Name: your-solution-name # Replace with your solution name, i.e. MyWpfApp.sln.
60 | Test_Project_Path: your-test-project-path # Replace with the path to your test project, i.e. MyWpfApp.Tests\MyWpfApp.Tests.csproj.
61 | Wap_Project_Directory: your-wap-project-directory-name # Replace with the Wap project directory relative to the solution, i.e. MyWpfApp.Package.
62 | Wap_Project_Path: your-wap-project-path # Replace with the path to your Wap project, i.e. MyWpf.App.Package\MyWpfApp.Package.wapproj.
63 |
64 | steps:
65 | - name: Checkout
66 | uses: actions/checkout@v2
67 | with:
68 | fetch-depth: 0
69 |
70 | # Install the .NET Core workload
71 | - name: Install .NET Core
72 | uses: actions/setup-dotnet@v1
73 | with:
74 | dotnet-version: 3.1.101
75 |
76 | # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
77 | - name: Setup MSBuild.exe
78 | uses: microsoft/setup-msbuild@2008f912f56e61277eefaac6d1888b750582aa16
79 |
80 | # Execute all unit tests in the solution
81 | - name: Execute unit tests
82 | run: dotnet test
83 |
84 | # Restore the application to populate the obj folder with RuntimeIdentifiers
85 | - name: Restore the application
86 | run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
87 | env:
88 | Configuration: ${{ matrix.configuration }}
89 |
90 | # Decode the base 64 encoded pfx and save the Signing_Certificate
91 | - name: Decode the pfx
92 | run: |
93 | $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.Base64_Encoded_Pfx }}")
94 | $certificatePath = Join-Path -Path $env:Wap_Project_Directory -ChildPath GitHubActionsWorkflow.pfx
95 | [IO.File]::WriteAllBytes("$certificatePath", $pfx_cert_byte)
96 |
97 | # Create the app package by building and packaging the Windows Application Packaging project
98 | - name: Create the app package
99 | run: msbuild $env:Wap_Project_Path /p:Configuration=$env:Configuration /p:UapAppxPackageBuildMode=$env:Appx_Package_Build_Mode /p:AppxBundle=$env:Appx_Bundle /p:PackageCertificateKeyFile=GitHubActionsWorkflow.pfx /p:PackageCertificatePassword=${{ secrets.Pfx_Key }}
100 | env:
101 | Appx_Bundle: Always
102 | Appx_Bundle_Platforms: x86|x64
103 | Appx_Package_Build_Mode: StoreUpload
104 | Configuration: ${{ matrix.configuration }}
105 |
106 | # Remove the pfx
107 | - name: Remove the pfx
108 | run: Remove-Item -path $env:Wap_Project_Directory\$env:Signing_Certificate
109 |
110 | # Upload the MSIX package: https://github.com/marketplace/actions/upload-artifact
111 | - name: Upload build artifacts
112 | uses: actions/upload-artifact@v2
113 | with:
114 | name: MSIX Package
115 | path: ${{ env.Wap_Project_Directory }}\AppPackages
116 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 |
24 | # Visual Studio 2015 cache/options directory
25 | .vs/
26 | # Uncomment if you have tasks that create the project's static files in wwwroot
27 | #wwwroot/
28 |
29 | # MSTest test Results
30 | [Tt]est[Rr]esult*/
31 | [Bb]uild[Ll]og.*
32 |
33 | # NUNIT
34 | *.VisualState.xml
35 | TestResult.xml
36 |
37 | # Build Results of an ATL Project
38 | [Dd]ebugPS/
39 | [Rr]eleasePS/
40 | dlldata.c
41 |
42 | # DNX
43 | project.lock.json
44 | artifacts/
45 |
46 | *_i.c
47 | *_p.c
48 | *_i.h
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.tmp_proj
63 | *.log
64 | *.vspscc
65 | *.vssscc
66 | .builds
67 | *.pidb
68 | *.svclog
69 | *.scc
70 |
71 | # Chutzpah Test files
72 | _Chutzpah*
73 |
74 | # Visual C++ cache files
75 | ipch/
76 | *.aps
77 | *.ncb
78 | *.opendb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 | *.sap
88 |
89 | # TFS 2012 Local Workspace
90 | $tf/
91 |
92 | # Guidance Automation Toolkit
93 | *.gpState
94 |
95 | # ReSharper is a .NET coding add-in
96 | _ReSharper*/
97 | *.[Rr]e[Ss]harper
98 | *.DotSettings.user
99 |
100 | # JustCode is a .NET coding add-in
101 | .JustCode
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | _NCrunch_*
111 | .*crunch*.local.xml
112 | nCrunchTemp_*
113 |
114 | # MightyMoose
115 | *.mm.*
116 | AutoTest.Net/
117 |
118 | # Web workbench (sass)
119 | .sass-cache/
120 |
121 | # Installshield output folder
122 | [Ee]xpress/
123 |
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 | # NuGet v3's project.json files produces more ignoreable files
154 | *.nuget.props
155 | *.nuget.targets
156 |
157 | # Microsoft Azure Build Output
158 | csx/
159 | *.build.csdef
160 |
161 | # Microsoft Azure Emulator
162 | ecf/
163 | rcf/
164 |
165 | # Microsoft Azure ApplicationInsights config file
166 | ApplicationInsights.config
167 |
168 | # Windows Store app package directory
169 | AppPackages/
170 | BundleArtifacts/
171 |
172 | # Visual Studio cache files
173 | # files ending in .cache can be ignored
174 | *.[Cc]ache
175 | # but keep track of directories ending in .cache
176 | !*.[Cc]ache/
177 |
178 | # Others
179 | ClientBin/
180 | ~$*
181 | *~
182 | *.dbmdl
183 | *.dbproj.schemaview
184 | *.pfx
185 | *.publishsettings
186 | node_modules/
187 | orleans.codegen.cs
188 |
189 | # RIA/Silverlight projects
190 | Generated_Code/
191 |
192 | # Backup & report files from converting an old project file
193 | # to a newer Visual Studio version. Backup files are not needed,
194 | # because we have git ;-)
195 | _UpgradeReport_Files/
196 | Backup*/
197 | UpgradeLog*.XML
198 | UpgradeLog*.htm
199 |
200 | # SQL Server files
201 | *.mdf
202 | *.ldf
203 |
204 | # Business Intelligence projects
205 | *.rdl.data
206 | *.bim.layout
207 | *.bim_*.settings
208 |
209 | # Microsoft Fakes
210 | FakesAssemblies/
211 |
212 | # GhostDoc plugin setting file
213 | *.GhostDoc.xml
214 |
215 | # Node.js Tools for Visual Studio
216 | .ntvs_analysis.dat
217 |
218 | # Visual Studio 6 build log
219 | *.plg
220 |
221 | # Visual Studio 6 workspace options file
222 | *.opt
223 |
224 | # Visual Studio LightSwitch build output
225 | **/*.HTMLClient/GeneratedArtifacts
226 | **/*.DesktopClient/GeneratedArtifacts
227 | **/*.DesktopClient/ModelManifest.xml
228 | **/*.Server/GeneratedArtifacts
229 | **/*.Server/ModelManifest.xml
230 | _Pvt_Extensions
231 |
232 | # Paket dependency manager
233 | .paket/paket.exe
234 |
235 | # FAKE - F# Make
236 | .fake/
237 | /.gitattributes
238 |
239 | !VlcLib/*
240 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29123.88
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaturbatePlayer", "ChaturbatePlayer\ChaturbatePlayer.csproj", "{F9AFA7E1-F72A-4AA7-95B2-5813337B984F}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|x64 = Release|x64
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Debug|x64.ActiveCfg = Debug|x64
21 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Debug|x64.Build.0 = Debug|x64
22 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Debug|x86.ActiveCfg = Debug|x86
23 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Debug|x86.Build.0 = Debug|x86
24 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Release|x64.ActiveCfg = Release|x64
27 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Release|x64.Build.0 = Release|x64
28 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Release|x86.ActiveCfg = Release|x86
29 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}.Release|x86.Build.0 = Release|x86
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {008E0EBB-72BF-422E-9835-27BEBD89C217}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/App.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Views;
2 | using System.Diagnostics;
3 | using System.Windows;
4 | using WpfBindingErrors;
5 |
6 | namespace ChaturbatePlayer
7 | {
8 | public partial class App : Application
9 | {
10 | protected override void OnStartup(StartupEventArgs e)
11 | {
12 | base.OnStartup(e);
13 | if (Debugger.IsAttached)
14 | BindingExceptionThrower.Attach();
15 | }
16 |
17 | protected override void OnExit(ExitEventArgs e)
18 | {
19 | Shared.Instance.SaveSettings();
20 | base.OnExit(e);
21 | }
22 |
23 | void Application_Startup(object sender, StartupEventArgs e)
24 | {
25 | MainWindow = new MainWindowView();
26 | MainWindow.Show();
27 |
28 | var splash = new SplashWindowView();
29 | splash.Show();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Base/IMediator.cs:
--------------------------------------------------------------------------------
1 | namespace ChaturbatePlayer.Base
2 | {
3 | public enum NotificationType: byte
4 | {
5 | ChatRoomSelected,
6 | LicenseChanged,
7 | TabPageChanged,
8 | Initialized
9 | }
10 |
11 | interface IMediator
12 | {
13 | void NotificationReceived(NotificationType type, params object[] data);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Base/Mediator.cs:
--------------------------------------------------------------------------------
1 | using NullVoidCreations.WpfHelpers.Base;
2 | using System.Collections.Generic;
3 |
4 | namespace ChaturbatePlayer.Base
5 | {
6 | sealed class Mediator: NotificationBase
7 | {
8 | static Mediator _instance;
9 | static object _syncLock;
10 | readonly List _colleagues;
11 |
12 | #region constructor/destructor
13 |
14 | static Mediator()
15 | {
16 | _syncLock = new object();
17 | }
18 |
19 | private Mediator()
20 | {
21 | _colleagues = new List();
22 | }
23 |
24 | #endregion
25 |
26 | #region properties
27 |
28 | public static Mediator Instance
29 | {
30 | get
31 | {
32 | lock(_syncLock)
33 | {
34 | if (_instance == null)
35 | _instance = new Mediator();
36 |
37 | return _instance;
38 | }
39 | }
40 | }
41 |
42 | #endregion
43 |
44 | public bool RegisterColleague(IMediator colleague)
45 | {
46 | if (_colleagues.Contains(colleague))
47 | return false;
48 | else
49 | {
50 | _colleagues.Add(colleague);
51 | return true;
52 | }
53 | }
54 |
55 | public void UnregisterColleague(IMediator colleague)
56 | {
57 | var index = _colleagues.IndexOf(colleague);
58 | if (index > -1)
59 | _colleagues.RemoveAt(index);
60 | }
61 |
62 | public void RaiseNotification(IMediator sender, NotificationType type, params object[] data)
63 | {
64 | foreach (var colleague in _colleagues)
65 | {
66 | if (!colleague.Equals(sender))
67 | {
68 | colleague.NotificationReceived(type, data);
69 | }
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/ChaturbatePlayer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {F9AFA7E1-F72A-4AA7-95B2-5813337B984F}
8 | WinExe
9 | Properties
10 | ChaturbatePlayer
11 | ChaturbatePlayer
12 | v4.0
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 |
17 | false
18 | publish\
19 | true
20 | Disk
21 | false
22 | Foreground
23 | 7
24 | Days
25 | false
26 | false
27 | true
28 | 0
29 | 1.0.0.0
30 | false
31 | true
32 |
33 |
34 | x86
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | DEBUG;TRACE
40 | prompt
41 | 4
42 | false
43 |
44 |
45 | x86
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | false
53 |
54 |
55 | false
56 |
57 |
58 |
59 |
60 |
61 |
62 | Images\Icon.ico
63 |
64 |
65 | true
66 | bin\x86\Debug\
67 | DEBUG;TRACE
68 | full
69 | x86
70 | prompt
71 | MinimumRecommendedRules.ruleset
72 |
73 |
74 | bin\x86\Release\
75 | TRACE
76 | true
77 | pdbonly
78 | x86
79 | prompt
80 | MinimumRecommendedRules.ruleset
81 |
82 |
83 | true
84 | bin\x64\Debug\
85 | DEBUG;TRACE
86 | full
87 | x64
88 | prompt
89 | MinimumRecommendedRules.ruleset
90 |
91 |
92 | bin\x64\Release\
93 | TRACE
94 | true
95 | pdbonly
96 | x64
97 | prompt
98 | MinimumRecommendedRules.ruleset
99 |
100 |
101 | ChaturbatePlayer.App
102 |
103 |
104 | true
105 |
106 |
107 |
108 | ..\packages\HtmlAgilityPack.1.11.17\lib\Net40\HtmlAgilityPack.dll
109 |
110 |
111 | ..\packages\NullVoidCreations.WpfHelpers.19.8.7.1139\lib\net40\Microsoft.Expression.Interactions.dll
112 |
113 |
114 | ..\packages\NullVoidCreations.WpfHelpers.19.8.7.1139\lib\net40\NullVoidCreations.WpfHelpers.dll
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | ..\packages\NullVoidCreations.WpfHelpers.19.8.7.1139\lib\net40\System.Windows.Interactivity.dll
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 | 4.0
132 |
133 |
134 | ..\packages\Vlc.DotNet.Core.3.0.0\lib\net40\Vlc.DotNet.Core.dll
135 |
136 |
137 | ..\packages\Vlc.DotNet.Core.Interops.3.0.0\lib\net40\Vlc.DotNet.Core.Interops.dll
138 |
139 |
140 | ..\packages\Vlc.DotNet.Forms.3.0.0\lib\net40\Vlc.DotNet.Forms.dll
141 |
142 |
143 | ..\packages\Vlc.DotNet.Wpf.3.0.0\lib\net40\Vlc.DotNet.Wpf.dll
144 |
145 |
146 |
147 |
148 |
149 |
150 | ..\packages\WpfBindingErrors.1.1.0\lib\net40\WpfBindingErrors.dll
151 |
152 |
153 |
154 |
155 | MSBuild:Compile
156 | Designer
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | ChatRoomsView.xaml
176 |
177 |
178 | LiveStreamPlayerView.xaml
179 |
180 |
181 | SettingsView.xaml
182 |
183 |
184 | LicenseKeyGeneratorWindowView.xaml
185 |
186 |
187 | SplashWindowView.xaml
188 |
189 |
190 | MSBuild:Compile
191 | Designer
192 |
193 |
194 | App.xaml
195 | Code
196 |
197 |
198 |
199 |
200 |
201 | MainWindowView.xaml
202 | Code
203 |
204 |
205 | Designer
206 | MSBuild:Compile
207 |
208 |
209 | Designer
210 | MSBuild:Compile
211 |
212 |
213 | Designer
214 | MSBuild:Compile
215 |
216 |
217 | Designer
218 | MSBuild:Compile
219 |
220 |
221 | Designer
222 | MSBuild:Compile
223 |
224 |
225 |
226 |
227 | Code
228 |
229 |
230 |
231 |
232 |
233 | PreserveNewest
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 | False
304 | .NET Framework 3.5 SP1
305 | false
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 | REM xcopy "$(SolutionDir)VlcLib\*.*" "$(TargetDir)VlcLib" /Y/D/E/I
315 |
316 |
323 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Converters/GenderToImageConverter.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Models;
2 | using System;
3 | using System.Globalization;
4 | using System.Windows.Data;
5 |
6 | namespace ChaturbatePlayer.Converters
7 | {
8 | [ValueConversion(typeof(Gender), typeof(string))]
9 | public class GenderToImageConverter : IValueConverter
10 | {
11 | internal const string IMAGE_URL = "/ChaturbatePlayer;component/Images/{0}";
12 |
13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14 | {
15 | switch((Gender)value)
16 | {
17 | case Gender.Male:
18 | return string.Format(IMAGE_URL, "GenderMale.png");
19 |
20 | case Gender.Female:
21 | return string.Format(IMAGE_URL, "GenderFemale.png");
22 |
23 | case Gender.Couple:
24 | return string.Format(IMAGE_URL, "GenderCouple.png");
25 |
26 | case Gender.Trans:
27 | return string.Format(IMAGE_URL, "GenderTrans.png");
28 |
29 | default:
30 | return string.Format(IMAGE_URL, "Star.png");
31 | }
32 | }
33 |
34 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
35 | {
36 | throw new NotImplementedException();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Converters/GenderToNameConverter.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Models;
2 | using System;
3 | using System.Globalization;
4 | using System.Windows.Data;
5 |
6 | namespace ChaturbatePlayer.Converters
7 | {
8 | [ValueConversion(typeof(Gender), typeof(string))]
9 | public class GenderToNameConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | switch ((Gender)value)
14 | {
15 | case Gender.Male:
16 | return "MALE";
17 |
18 | case Gender.Female:
19 | return "FEMALE";
20 |
21 | case Gender.Couple:
22 | return "COUPLE";
23 |
24 | case Gender.Trans:
25 | return "TRANS";
26 |
27 | default:
28 | return "FEATURED";
29 | }
30 | }
31 |
32 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
33 | {
34 | throw new NotImplementedException();
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Converters/IntegerToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace ChaturbatePlayer.Converters
7 | {
8 | ///
9 | /// This converter returns Visibility.Visible if value passed is 0.
10 | ///
11 | [ValueConversion(typeof(int), typeof(Visibility))]
12 | public class IntegerToVisibilityConverter : IValueConverter
13 | {
14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
15 | {
16 | if (int.Parse(value.ToString()) > 0)
17 | return Visibility.Collapsed;
18 | else
19 | return Visibility.Visible;
20 | }
21 |
22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
23 | {
24 | throw new NotImplementedException();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Converters/InverseBooleanConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 |
5 | namespace ChaturbatePlayer.Converters
6 | {
7 | [ValueConversion(typeof(bool), typeof(bool))]
8 | public class InverseBooleanConverter : IValueConverter
9 | {
10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11 | {
12 | return !(bool)value;
13 | }
14 |
15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
16 | {
17 | throw new NotImplementedException();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Converters/InverseBooleanToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace ChaturbatePlayer.Converters
7 | {
8 | [ValueConversion(typeof(bool), typeof(Visibility))]
9 | public class InverseBooleanToVisibilityConverter : IValueConverter
10 | {
11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
12 | {
13 | return !(bool)value ? Visibility.Visible : Visibility.Collapsed;
14 | }
15 |
16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
17 | {
18 | throw new NotImplementedException();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Converters/LiveStreamPlayerStateToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.ViewModels;
2 | using System;
3 | using System.Globalization;
4 | using System.Windows;
5 | using System.Windows.Data;
6 |
7 | namespace ChaturbatePlayer.Converters
8 | {
9 | [ValueConversion(typeof(LiveStreamPlayerState), typeof(Visibility))]
10 | public class LiveStreamPlayerStateToVisibilityConverter : IValueConverter
11 | {
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | switch((LiveStreamPlayerState)value)
15 | {
16 | case LiveStreamPlayerState.Playing:
17 | return Visibility.Visible;
18 |
19 | default:
20 | return Visibility.Hidden;
21 | }
22 | }
23 |
24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
25 | {
26 | throw new NotImplementedException();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Converters/PlayerMuteStateToImageSourceConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 |
5 | namespace ChaturbatePlayer.Converters
6 | {
7 | [ValueConversion(typeof(bool), typeof(string))]
8 | public class PlayerMuteStateToImageSourceConverter : IValueConverter
9 | {
10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11 | {
12 | if ((bool)value)
13 | return string.Format(GenderToImageConverter.IMAGE_URL, "PlayerUnmute.png");
14 | else
15 | return string.Format(GenderToImageConverter.IMAGE_URL, "PlayerMute.png");
16 | }
17 |
18 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
19 | {
20 | throw new NotImplementedException();
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Icon.ico
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/ApplicationExport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/ApplicationExport.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowBack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowBack.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowCircle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowCircle.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowForward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowForward.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowRefresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/ArrowRefresh.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/FolderOpen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/FolderOpen.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/GenderCouple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/GenderCouple.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/GenderFemale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/GenderFemale.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/GenderMale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/GenderMale.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/GenderTrans.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/GenderTrans.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Help.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Icon.ico
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Icon.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Lock.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Logo.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerMute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerMute.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerPause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerPause.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerPlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerPlay.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerStop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerStop.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerUnmute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/PlayerUnmute.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Settings.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Star.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Unlock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Unlock.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Images/Webcam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/Images/Webcam.png
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Models/ChatRoomModel.cs:
--------------------------------------------------------------------------------
1 | using NullVoidCreations.WpfHelpers.Base;
2 |
3 | namespace ChaturbatePlayer.Models
4 | {
5 | public enum Gender : byte
6 | {
7 | Male,
8 | Female,
9 | Couple,
10 | Trans,
11 | NotSpecified
12 | }
13 |
14 | public class ChatRoomModel : NotificationBase
15 | {
16 | string _camsCount, _videoFeedUrl;
17 | bool _isVideoFeedHd;
18 |
19 | public ChatRoomModel(
20 | string name,
21 | int age,
22 | Gender gender,
23 | string roomTitle,
24 | string profileUrl,
25 | string profileImageUrl,
26 | int height,
27 | int width)
28 | {
29 | Name = name;
30 | Age = age;
31 | Gender = gender;
32 | RoomTitle = roomTitle;
33 | ProfileUrl = profileUrl;
34 | ProfileImageUrl = profileImageUrl;
35 | Height = height;
36 | Width = width;
37 | }
38 |
39 | #region properties
40 |
41 | public string Name { get; }
42 |
43 | public int Age { get; }
44 |
45 | public Gender Gender { get; }
46 |
47 | public string ProfileUrl { get; }
48 |
49 | public int Height { get; }
50 |
51 | public int Width { get; }
52 |
53 | public string ProfileImageUrl { get; }
54 |
55 | public string RoomTitle { get; }
56 |
57 | public string VideoFeedUrl
58 | {
59 | get => _videoFeedUrl;
60 | set => Set(nameof(VideoFeedUrl), ref _videoFeedUrl, value);
61 | }
62 |
63 | public bool IsVideoFeedHd
64 | {
65 | get => _isVideoFeedHd;
66 | set => Set(nameof(IsVideoFeedHd), ref _isVideoFeedHd, value);
67 | }
68 |
69 | public string CamsCount
70 | {
71 | get => _camsCount;
72 | set => Set(nameof(CamsCount), ref _camsCount, value);
73 | }
74 |
75 | #endregion
76 |
77 | #region methods
78 |
79 | public override string ToString()
80 | {
81 | return Name;
82 | }
83 |
84 | public override int GetHashCode()
85 | {
86 | return Name.GetHashCode();
87 | }
88 |
89 | public override bool Equals(object obj)
90 | {
91 | var compareWith = obj as ChatRoomModel;
92 | if (compareWith == null)
93 | return false;
94 |
95 | return compareWith.Name.Equals(Name);
96 | }
97 |
98 | #endregion
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Models/LicenseModel.cs:
--------------------------------------------------------------------------------
1 | using NullVoidCreations.WpfHelpers;
2 | using NullVoidCreations.WpfHelpers.Base;
3 | using System;
4 |
5 | namespace ChaturbatePlayer.Models
6 | {
7 | public class LicenseModel : NotificationBase
8 | {
9 | bool _isTrial;
10 | DateTime _issueDate, _expirationDate;
11 | string _registeredEmail, _licenseKey;
12 |
13 | public LicenseModel()
14 | {
15 | Rest();
16 | }
17 |
18 | internal void Rest()
19 | {
20 | IssueDate = new DateTime(1900, 1, 1);
21 | ExpirationDate = new DateTime(1900, 1, 1);
22 | IsTrial = true;
23 | }
24 |
25 | #region properties
26 |
27 | public string LicenseKey
28 | {
29 | get { return _licenseKey; }
30 | set
31 | {
32 | Set(nameof(LicenseKey), ref _licenseKey, value);
33 | }
34 | }
35 |
36 | public bool IsTrial
37 | {
38 | get { return _isTrial; }
39 | private set
40 | {
41 | Set(nameof(IsTrial), ref _isTrial, value);
42 | }
43 | }
44 |
45 | public string RegisteredEmail
46 | {
47 | get { return _registeredEmail; }
48 | set
49 | {
50 | Set(nameof(RegisteredEmail), ref _registeredEmail, value);
51 | }
52 | }
53 |
54 | public DateTime IssueDate
55 | {
56 | get { return _issueDate; }
57 | set
58 | {
59 | Set(nameof(IssueDate), ref _issueDate, value);
60 | }
61 | }
62 |
63 | public DateTime ExpirationDate
64 | {
65 | get { return _expirationDate; }
66 | private set
67 | {
68 | Set(nameof(ExpirationDate), ref _expirationDate, value);
69 | }
70 | }
71 |
72 | #endregion
73 |
74 | #region private methods
75 |
76 | bool IsExpired(LicenseModel license)
77 | {
78 | var currentDate = DateTime.Now;
79 | if (currentDate.Date < license.IssueDate.Date)
80 | return true;
81 | if (currentDate.Date > license.ExpirationDate.Date)
82 | return true;
83 |
84 | return false;
85 | }
86 |
87 | DateTime ExtractDate(string text, int startIndex)
88 | {
89 | var date = new DateTime(
90 | int.Parse(text.Substring(startIndex, 4)),
91 | int.Parse(text.Substring(startIndex + 4, 2)),
92 | int.Parse(text.Substring(startIndex + 6, 2)));
93 | return date;
94 | }
95 |
96 | #endregion
97 |
98 | internal void Generate(string registeredEmail, DateTime issueDate, int numberOfDays)
99 | {
100 | RegisteredEmail = registeredEmail;
101 | IssueDate = issueDate;
102 | ExpirationDate = IssueDate.AddDays(numberOfDays);
103 | LicenseKey = string.Format("{0:0000}{1:00}{2:00}{3:0000}{4:00}{5:00}{6}",
104 | IssueDate.Year,
105 | IssueDate.Month,
106 | IssueDate.Day,
107 | ExpirationDate.Year,
108 | ExpirationDate.Month,
109 | ExpirationDate.Day,
110 | RegisteredEmail);
111 | LicenseKey = LicenseKey.Encrypt(Shared.ENCRYPTION_KEY);
112 | }
113 |
114 | public bool Validate()
115 | {
116 | try
117 | {
118 | var key = LicenseKey.Decrypt(Shared.ENCRYPTION_KEY);
119 | IssueDate = ExtractDate(key, 0);
120 | ExpirationDate = ExtractDate(key, 8);
121 | RegisteredEmail = key.Substring(16, key.Length - 16);
122 | IsTrial = IsExpired(this);
123 | return true;
124 | }
125 | catch
126 | {
127 | Rest();
128 | }
129 |
130 | return false;
131 | }
132 | }
133 | }
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Models/SettingsModel.cs:
--------------------------------------------------------------------------------
1 | using NullVoidCreations.WpfHelpers;
2 | using NullVoidCreations.WpfHelpers.Base;
3 | using System.IO;
4 |
5 | namespace ChaturbatePlayer.Models
6 | {
7 | public class SettingsModel: NotificationBase
8 | {
9 | readonly SettingsManager _manager;
10 | LicenseModel _license;
11 |
12 | public SettingsModel(ref SettingsManager manager)
13 | {
14 | _manager = manager;
15 | }
16 |
17 | internal void Reset()
18 | {
19 | MediaPlayer = "VLC";
20 | RefreshInterval = 2;
21 | IsMinutesLiveShown = false;
22 | IsAutoRefreshEnabled = false;
23 | IsExternalMediaPlayerAllowed = false;
24 | IsExternalMediaPlayerControlsHidden = false;
25 | IsExternalMediaPlayerFullScreen = false;
26 | IsAutoPauseEnabled = false;
27 | IsAutoSaveVideosEnabled = false;
28 | AutoSaveDirectory = Shared.Instance.DataPath;
29 | IsUrlShown = false;
30 | }
31 |
32 | #region properties
33 |
34 | public string LicenseKey
35 | {
36 | get { return _manager.GetValue(nameof(LicenseKey)); }
37 | set
38 | {
39 | _manager.SetValue(nameof(LicenseKey), value);
40 | RaisePropertyChanged(nameof(LicenseKey));
41 | }
42 | }
43 |
44 | public LicenseModel License
45 | {
46 | get { return _license; }
47 | private set
48 | {
49 | _license = value;
50 | RaisePropertyChanged(nameof(License));
51 | }
52 | }
53 |
54 | public string MediaPlayer
55 | {
56 | get
57 | {
58 | var value = _manager.GetValue(nameof(MediaPlayer));
59 | if (default(string) == value)
60 | value = "VLC";
61 |
62 | return value;
63 | }
64 | set
65 | {
66 | _manager.SetValue(nameof(MediaPlayer), value);
67 | RaisePropertyChanged(nameof(MediaPlayer));
68 | }
69 | }
70 |
71 | public int RefreshInterval
72 | {
73 | get
74 | {
75 | var value = _manager.GetValue(nameof(RefreshInterval));
76 | if (default(int) == value)
77 | value = 2;
78 |
79 | return value;
80 | }
81 | set
82 | {
83 | _manager.SetValue(nameof(RefreshInterval), value);
84 | RaisePropertyChanged(nameof(RefreshInterval));
85 | }
86 | }
87 |
88 | public bool IsMinutesLiveShown
89 | {
90 | get { return _manager.GetValue(nameof(IsMinutesLiveShown)); }
91 | set
92 | {
93 | _manager.SetValue(nameof(IsMinutesLiveShown), value);
94 | RaisePropertyChanged(nameof(IsMinutesLiveShown));
95 | }
96 | }
97 |
98 | public bool IsAutoRefreshEnabled
99 | {
100 | get { return _manager.GetValue(nameof(IsAutoRefreshEnabled)); }
101 | set
102 | {
103 | _manager.SetValue(nameof(IsAutoRefreshEnabled), value);
104 | RaisePropertyChanged(nameof(IsAutoRefreshEnabled));
105 | }
106 | }
107 |
108 | public bool IsExternalMediaPlayerAllowed
109 | {
110 | get { return _manager.GetValue(nameof(IsExternalMediaPlayerAllowed)); }
111 | set
112 | {
113 | _manager.SetValue(nameof(IsExternalMediaPlayerAllowed), value);
114 | RaisePropertyChanged(nameof(IsExternalMediaPlayerAllowed));
115 | }
116 | }
117 |
118 | public bool IsExternalMediaPlayerControlsHidden
119 | {
120 | get { return _manager.GetValue(nameof(IsExternalMediaPlayerControlsHidden)); }
121 | set
122 | {
123 | _manager.SetValue(nameof(IsExternalMediaPlayerControlsHidden), value);
124 | RaisePropertyChanged(nameof(IsExternalMediaPlayerControlsHidden));
125 | }
126 | }
127 |
128 | public bool IsExternalMediaPlayerFullScreen
129 | {
130 | get { return _manager.GetValue(nameof(IsExternalMediaPlayerFullScreen)); }
131 | set
132 | {
133 | _manager.SetValue(nameof(IsExternalMediaPlayerFullScreen), value);
134 | RaisePropertyChanged(nameof(IsExternalMediaPlayerFullScreen));
135 | }
136 | }
137 |
138 | public bool IsAutoPauseEnabled
139 | {
140 | get { return _manager.GetValue(nameof(IsAutoPauseEnabled)); }
141 | set
142 | {
143 | _manager.SetValue(nameof(IsAutoPauseEnabled), value);
144 | RaisePropertyChanged(nameof(IsAutoPauseEnabled));
145 | }
146 | }
147 |
148 | public bool IsAutoSaveVideosEnabled
149 | {
150 | get { return _manager.GetValue(nameof(IsAutoSaveVideosEnabled)); }
151 | set
152 | {
153 | _manager.SetValue(nameof(IsAutoSaveVideosEnabled), value);
154 | RaisePropertyChanged(nameof(IsAutoSaveVideosEnabled));
155 | }
156 | }
157 |
158 | public string AutoSaveDirectory
159 | {
160 | get { return _manager.GetValue(nameof(AutoSaveDirectory)); }
161 | set
162 | {
163 | // always end directory name with '\'
164 | if (!string.IsNullOrEmpty(AutoSaveDirectory) && value[value.Length - 1] != (Path.DirectorySeparatorChar))
165 | value = string.Format("{0}{1}", value, Path.DirectorySeparatorChar);
166 |
167 | _manager.SetValue(nameof(AutoSaveDirectory), value);
168 | RaisePropertyChanged(nameof(AutoSaveDirectory));
169 | }
170 | }
171 |
172 | public bool IsUrlShown
173 | {
174 | get { return _manager.GetValue(nameof(IsUrlShown)); }
175 | set
176 | {
177 | _manager.SetValue(nameof(IsUrlShown), value);
178 | RaisePropertyChanged(nameof(IsUrlShown));
179 | }
180 | }
181 |
182 | #endregion
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Chaturbate Cams Viewer")]
9 | [assembly: AssemblyDescription("Enjoying Chaturbate Live Cams Redefined")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Chaturbate Cams Viewer")]
13 | [assembly: AssemblyCopyright("Copyright © 2018 Rubal Walia. All rights reserved.")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | //In order to begin building localizable applications, set
23 | //CultureYouAreCodingWith in your .csproj file
24 | //inside a . For example, if you are using US english
25 | //in your source files, set the to en-US. Then uncomment
26 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
27 | //the line below to match the UICulture setting in the project file.
28 |
29 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
30 |
31 |
32 | [assembly: ThemeInfo(
33 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
34 | //(used if a resource is not found in the page,
35 | // or application resource dictionaries)
36 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
37 | //(used if a resource is not found in the page,
38 | // app, or any theme specific resource dictionaries)
39 | )]
40 |
41 |
42 | // Version information for an assembly consists of the following four values:
43 | //
44 | // Major Version
45 | // Minor Version
46 | // Build Number
47 | // Revision
48 | //
49 | // You can specify all the values or you can default the Build and Revision Numbers
50 | // by using the '*' as shown below:
51 | // [assembly: AssemblyVersion("1.0.*")]
52 | [assembly: AssemblyVersion("0.0.0.0")]
53 | [assembly: AssemblyFileVersion("0.0.0.0")]
54 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Shared.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Models;
2 | using NullVoidCreations.WpfHelpers;
3 | using System;
4 | using System.IO;
5 | using System.Reflection;
6 |
7 | namespace ChaturbatePlayer
8 | {
9 | class Shared
10 | {
11 | public const string ENCRYPTION_KEY = "QFByb3Blcl9QYXRvbGEhMjAxNQ==";
12 |
13 | static object _syncRoot;
14 | static Shared _instance;
15 |
16 | SettingsManager _settingsManager;
17 | string _settingsFile, _libVlcPath, _dataPath;
18 | AssemblyInformation _info;
19 | SettingsModel _settings;
20 |
21 | #region constructor
22 |
23 | static Shared()
24 | {
25 | _syncRoot = new object();
26 | }
27 |
28 | private Shared()
29 | {
30 |
31 | }
32 |
33 | #endregion
34 |
35 | #region properties
36 |
37 | public static Shared Instance
38 | {
39 | get
40 | {
41 | lock(_syncRoot)
42 | {
43 | if (_instance == null)
44 | _instance = new Shared();
45 |
46 | return _instance;
47 | }
48 | }
49 | }
50 |
51 | public LicenseModel License { get; set; }
52 |
53 | public SettingsModel Settings
54 | {
55 | get
56 | {
57 | if (_settings == null)
58 | {
59 | _settingsManager = new SettingsManager();
60 | _settingsManager.Load(SettingsFile, ENCRYPTION_KEY);
61 |
62 | _settings = new SettingsModel(ref _settingsManager);
63 | }
64 |
65 | return _settings;
66 | }
67 | }
68 |
69 | public AssemblyInformation Information
70 | {
71 | get
72 | {
73 | if (_info == null)
74 | _info = new AssemblyInformation(Assembly.GetExecutingAssembly());
75 |
76 | return _info;
77 | }
78 | }
79 |
80 | string SettingsFile
81 | {
82 | get
83 | {
84 | if (_settingsFile == null)
85 | _settingsFile = Path.Combine(DataPath, string.Format("{0}.setting", Information.Product));
86 |
87 | return _settingsFile;
88 | }
89 | }
90 |
91 | public string LibVlcPath
92 | {
93 | get
94 | {
95 | if (_libVlcPath == null)
96 | _libVlcPath = Path.Combine(DataPath, "VLC");
97 |
98 | return _libVlcPath;
99 | }
100 | }
101 |
102 | public string DataPath
103 | {
104 | get
105 | {
106 | if (_dataPath == null)
107 | _dataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Information.Product);
108 |
109 | return _dataPath;
110 | }
111 | }
112 |
113 | #endregion
114 |
115 | public void SaveSettings()
116 | {
117 | _settingsManager.Save(SettingsFile, ENCRYPTION_KEY);
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/VLC.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/ChaturbatePlayer/ChaturbatePlayer/VLC.zip
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/ViewModels/ChatRoomsViewModel.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Base;
2 | using ChaturbatePlayer.Models;
3 | using HtmlAgilityPack;
4 | using NullVoidCreations.WpfHelpers.Base;
5 | using NullVoidCreations.WpfHelpers.Commands;
6 | using NullVoidCreations.WpfHelpers.Helpers;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.ComponentModel;
10 | using System.Net;
11 | using System.Timers;
12 | using System.Windows;
13 | using System.Windows.Input;
14 |
15 | namespace ChaturbatePlayer.ViewModels
16 | {
17 | public enum NavigationDirection: byte
18 | {
19 | Forward,
20 | Backward,
21 | Refresh
22 | }
23 |
24 | public class ChatRoomsViewModel: ViewModelBase, IMediator
25 | {
26 | ICommand _getChatRooms, _getVideoFeed;
27 |
28 | Gender _gender;
29 | IList _chatRooms;
30 | ChatRoomModel _selectedRoom;
31 | Timer _refreshTimer;
32 | volatile int _page;
33 |
34 | const string CHATURBATE = "https://www.chaturbate.com";
35 | const string HOST = "chaturbate.com";
36 |
37 | #region constructor/destructor
38 |
39 | public ChatRoomsViewModel()
40 | {
41 | _refreshTimer = new Timer();
42 | _refreshTimer.Elapsed += RefreshTimer_Elapsed;
43 |
44 | Settings.PropertyChanged += Settings_Changed;
45 |
46 | ResetRefreshTimer();
47 | }
48 |
49 | ~ChatRoomsViewModel()
50 | {
51 | _refreshTimer.Elapsed -= RefreshTimer_Elapsed;
52 | _refreshTimer.Dispose();
53 |
54 | Settings.PropertyChanged -= Settings_Changed;
55 | }
56 |
57 | #endregion
58 |
59 | #region properties
60 |
61 | public int Page
62 | {
63 | get { return _page; }
64 | private set
65 | {
66 | _page = value;
67 | RaisePropertyChanged(nameof(Page));
68 | }
69 | }
70 |
71 | public SettingsModel Settings
72 | {
73 | get { return Shared.Instance.Settings; }
74 | }
75 |
76 | public IList ChatRooms
77 | {
78 | get { return _chatRooms; }
79 | set
80 | {
81 | _chatRooms = value;
82 | RaisePropertyChanged(nameof(ChatRooms));
83 | }
84 | }
85 |
86 | public Gender RoomsGender
87 | {
88 | get { return _gender; }
89 | set
90 | {
91 | _gender = value;
92 | RaisePropertyChanged(nameof(RoomsGender));
93 | }
94 | }
95 |
96 | public ChatRoomModel SelectedRoom
97 | {
98 | get { return _selectedRoom; }
99 | set
100 | {
101 | _selectedRoom = value;
102 | RaisePropertyChanged(nameof(SelectedRoom));
103 | Mediator.Instance.RaiseNotification(this, NotificationType.ChatRoomSelected, SelectedRoom);
104 | }
105 | }
106 |
107 | #endregion
108 |
109 | #region commands
110 |
111 | public ICommand GetChatRoomsCommand
112 | {
113 | get
114 | {
115 | if (_getChatRooms == null)
116 | _getChatRooms = new RelayCommand>(GetChatRooms, GetChatRoomsCallback);
117 |
118 | return _getChatRooms;
119 | }
120 | }
121 |
122 | public ICommand GetVideoFeedUrlCommand
123 | {
124 | get
125 | {
126 | if (_getVideoFeed == null)
127 | _getVideoFeed = new RelayCommand(GetVideoFeedUrl);
128 |
129 | return _getVideoFeed;
130 | }
131 | }
132 |
133 | #endregion
134 |
135 | void RefreshTimer_Elapsed(object sender, ElapsedEventArgs e)
136 | {
137 | Application.Current.Dispatcher.BeginInvoke(new Action(() => GetChatRoomsCommand.Execute(NavigationDirection.Refresh)));
138 | }
139 |
140 | void ResetRefreshTimer()
141 | {
142 | if (_refreshTimer.Enabled)
143 | _refreshTimer.Stop();
144 |
145 | if (Shared.Instance.Settings.IsAutoRefreshEnabled)
146 | {
147 | _refreshTimer.Interval = Shared.Instance.Settings.RefreshInterval * 60 * 1000;
148 | _refreshTimer.Start();
149 | }
150 | }
151 |
152 | void Settings_Changed(object sender, PropertyChangedEventArgs e)
153 | {
154 | switch (e.PropertyName)
155 | {
156 | case "RefreshInterval":
157 | case "IsAutoRefreshEnabled":
158 | ResetRefreshTimer();
159 | break;
160 | }
161 |
162 | }
163 |
164 | void GetChatRoomsCallback(IList chatRooms)
165 | {
166 | ChatRooms = chatRooms;
167 | RaisePropertyChanged(nameof(Page));
168 | }
169 |
170 | IList GetChatRooms(NavigationDirection parameter)
171 | {
172 | var chatRooms = new List();
173 |
174 | switch (parameter)
175 | {
176 | case NavigationDirection.Forward:
177 | Page += 1;
178 | break;
179 |
180 | case NavigationDirection.Backward:
181 | if (Page > 1)
182 | Page -= 1;
183 | break;
184 |
185 | case NavigationDirection.Refresh:
186 | default:
187 | if (Page == 0)
188 | Page = 1;
189 | break;
190 | }
191 |
192 | var url = string.Format("{0}/?page={1}", CHATURBATE, Page);
193 | switch (RoomsGender)
194 | {
195 | case Gender.Male:
196 | url = string.Format("{0}/male-cams/?page={1}", CHATURBATE, Page);
197 | break;
198 |
199 | case Gender.Female:
200 | url = string.Format("{0}/female-cams/?page={1}", CHATURBATE, Page);
201 | break;
202 |
203 | case Gender.Couple:
204 | url = string.Format("{0}/couple-cams/?page={1}", CHATURBATE, Page);
205 | break;
206 |
207 | case Gender.Trans:
208 | url = string.Format("{0}/trans-cams/?page={1}", CHATURBATE, Page);
209 | break;
210 | }
211 |
212 | string html;
213 | using (var client = new ExtendedWebClient())
214 | {
215 | client.Host = HOST;
216 | try
217 | {
218 | html = client.DownloadString(new Uri(url, UriKind.Absolute));
219 | }
220 | catch (WebException)
221 | {
222 | return chatRooms;
223 | }
224 | }
225 |
226 | var parser = new HtmlDocument();
227 | parser.LoadHtml(html);
228 |
229 | HtmlNode tempNode;
230 | foreach (var node in parser.DocumentNode.SelectNodes("//ul[@class='list']/li"))
231 | {
232 | tempNode = node.SelectSingleNode("./a/img[@class='png']");
233 | var profileImageUrl = tempNode.Attributes["src"].Value;
234 | var profileImageHeight = int.Parse(tempNode.Attributes["height"].Value);
235 | var profileImageWidth = int.Parse(tempNode.Attributes["width"].Value);
236 |
237 | tempNode = node.SelectSingleNode("./div[contains(@class,'thumbnail_label')]");
238 | var isVideoFeedHd = tempNode.InnerText.Equals("HD", StringComparison.InvariantCultureIgnoreCase);
239 |
240 | tempNode = node.SelectSingleNode("./div/ul[@class='subject']/li");
241 | var title = tempNode.Attributes["title"].Value;
242 |
243 | tempNode = node.SelectSingleNode("./div[@class='details']/div[@class='title']/a");
244 | var name = tempNode.InnerText.Trim();
245 | var profileUrl = string.Format("{0}{1}", CHATURBATE, tempNode.Attributes["href"].Value);
246 |
247 | tempNode = node.SelectSingleNode("./div[@class='details']/div[@class='title']/span[contains(@class,'age')]");
248 | int.TryParse(tempNode.InnerText, out int age);
249 | var genderString = tempNode.Attributes["class"].Value;
250 | Gender gender;
251 | if (genderString.Contains("genderm"))
252 | gender = Gender.Male;
253 | else if (genderString.Contains("genderf"))
254 | gender = Gender.Female;
255 | else if (genderString.Contains("genderc"))
256 | gender = Gender.Couple;
257 | else
258 | gender = Gender.Trans;
259 |
260 | tempNode = node.SelectSingleNode("./div[@class='details']/ul[@class='sub-info']/li[@class='cams']");
261 | var cams = tempNode.InnerText;
262 |
263 | var chatRoom = new ChatRoomModel(name, age, gender, title, profileUrl, profileImageUrl, profileImageHeight, profileImageWidth);
264 | chatRoom.IsVideoFeedHd = isVideoFeedHd;
265 | chatRoom.CamsCount = cams;
266 | chatRooms.Add(chatRoom);
267 | }
268 |
269 | return chatRooms;
270 | }
271 |
272 | void GetVideoFeedUrl(ChatRoomModel parameter)
273 | {
274 | if (parameter == null)
275 | return;
276 |
277 | if (string.IsNullOrEmpty(parameter.VideoFeedUrl))
278 | {
279 | const string VIDEO_URL_START = "initHlsPlayer(jsplayer, '";
280 | const string VIDEO_URL_END = "');";
281 |
282 | using (var webClient = new ExtendedWebClient())
283 | {
284 | string html;
285 | try
286 | {
287 | html = webClient.DownloadString(new Uri(parameter.ProfileUrl, UriKind.Absolute));
288 | }
289 | catch (WebException)
290 | {
291 | return;
292 | }
293 |
294 | if (string.IsNullOrEmpty(html))
295 | return;
296 |
297 | var start = html.IndexOf(VIDEO_URL_START);
298 | if (start > -1)
299 | {
300 | var end = html.IndexOf(VIDEO_URL_END, start + VIDEO_URL_START.Length);
301 | var url = html.Substring(start + VIDEO_URL_START.Length, end - start - VIDEO_URL_START.Length);
302 | parameter.VideoFeedUrl = url;
303 | SelectedRoom = parameter;
304 | }
305 | }
306 | }
307 | else
308 | SelectedRoom = parameter;
309 |
310 | }
311 |
312 | public void NotificationReceived(NotificationType type, params object[] data)
313 | {
314 | // do nothing
315 | }
316 | }
317 | }
318 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/ViewModels/LicenseKeyGeneratorViewModel.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Models;
2 | using NullVoidCreations.WpfHelpers.Base;
3 | using NullVoidCreations.WpfHelpers.Commands;
4 | using System.Windows.Input;
5 |
6 | namespace ChaturbatePlayer.ViewModels
7 | {
8 | public class LicenseKeyGeneratorViewModel : ViewModelBase
9 | {
10 | LicenseModel _license;
11 | ICommand _generateLicense;
12 |
13 | #region properties
14 |
15 | public LicenseModel License
16 | {
17 | get
18 | {
19 | if (_license == null)
20 | _license = new LicenseModel();
21 |
22 | return _license;
23 | }
24 | }
25 |
26 | #endregion
27 |
28 | #region commands
29 |
30 | public ICommand GenerateLicenseCommand
31 | {
32 | get
33 | {
34 | if (_generateLicense == null)
35 | _generateLicense = new RelayCommand(GenerateLicense);
36 |
37 | return _generateLicense;
38 | }
39 | }
40 |
41 | #endregion
42 |
43 | void GenerateLicense(int daysToAdd)
44 | {
45 | if (License == null)
46 | return;
47 |
48 | License.Generate(License.RegisteredEmail, License.IssueDate, daysToAdd);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/ViewModels/LiveStreamPlayerViewModel.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Base;
2 | using ChaturbatePlayer.Models;
3 | using Microsoft.Win32;
4 | using NullVoidCreations.WpfHelpers.Base;
5 | using NullVoidCreations.WpfHelpers.Commands;
6 | using System;
7 | using System.Diagnostics;
8 | using System.IO;
9 | using System.Text;
10 | using System.Windows.Input;
11 |
12 | namespace ChaturbatePlayer.ViewModels
13 | {
14 | public enum LiveStreamPlayerState : byte
15 | {
16 | Play,
17 | Playing,
18 | Pause,
19 | Paused,
20 | Stop,
21 | Stopped,
22 | ExternalMediaPlayer
23 | }
24 |
25 | public class LiveStreamPlayerViewModel : ViewModelBase, IMediator
26 | {
27 | ICommand _toggleMute, _playerCommand;
28 | LiveStreamPlayerState _state;
29 | ChatRoomModel _selectedRoom;
30 | bool _isMuted;
31 |
32 | public LiveStreamPlayerViewModel()
33 | {
34 | Mediator.Instance.RegisterColleague(this);
35 | }
36 |
37 | #region commands
38 |
39 | public ICommand PlayerCommand
40 | {
41 | get
42 | {
43 | if (_playerCommand == null)
44 | _playerCommand = new RelayCommand(Player);
45 |
46 | return _playerCommand;
47 | }
48 | }
49 |
50 | public ICommand ToggleMuteCommand
51 | {
52 | get
53 | {
54 | if (_toggleMute == null)
55 | _toggleMute = new RelayCommand(ToggleMute);
56 |
57 | return _toggleMute;
58 | }
59 | }
60 |
61 | #endregion
62 |
63 | #region properties
64 |
65 | public LiveStreamPlayerState State
66 | {
67 | get { return _state; }
68 | set
69 | {
70 | _state = value;
71 | RaisePropertyChanged(nameof(State));
72 | }
73 | }
74 |
75 | public bool IsMuted
76 | {
77 | get { return _isMuted; }
78 | set
79 | {
80 | _isMuted = value;
81 | RaisePropertyChanged(nameof(IsMuted));
82 | }
83 | }
84 |
85 | public SettingsModel Settings
86 | {
87 | get { return Shared.Instance.Settings; }
88 | }
89 |
90 | public ChatRoomModel SelectedRoom
91 | {
92 | get { return _selectedRoom; }
93 | set
94 | {
95 | if (value == _selectedRoom)
96 | return;
97 |
98 | _selectedRoom = value;
99 | RaisePropertyChanged(nameof(SelectedRoom));
100 | State = LiveStreamPlayerState.Play;
101 | }
102 | }
103 |
104 | #endregion
105 |
106 | string GetWmpExecutablePath()
107 | {
108 | using (var view = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
109 | {
110 | using (var key = view.OpenSubKey(@"Software\Microsoft\Active Setup\Installed Components\{22d6f312-b0f6-11d0-94ab-0080c74c7e95}", false))
111 | {
112 | if ((int)key.GetValue("IsInstalled") == 1)
113 | return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Windows Media Player\wmplayer.exe");
114 | else
115 | return string.Empty;
116 | }
117 | }
118 | }
119 |
120 | string GetVlcExecutablePath()
121 | {
122 | using (var view = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32))
123 | {
124 | using (var key = view.OpenSubKey(@"Software\VideoLAN\VLC\", false))
125 | {
126 | if (key == null)
127 | return Path.Combine(Shared.Instance.LibVlcPath, "vlc.exe");
128 | else
129 | return key.GetValue(string.Empty).ToString();
130 | }
131 | }
132 | }
133 |
134 | void PlayVideoFeed(ChatRoomModel chatRoom)
135 | {
136 | string playerPath, arguments;
137 |
138 | var useVlc = "VLC".Equals(Settings.MediaPlayer);
139 | if (useVlc)
140 | {
141 | playerPath = GetVlcExecutablePath();
142 |
143 | var VlcArgumentsBuilder = new StringBuilder();
144 |
145 | // hide controls
146 | if (Settings.IsExternalMediaPlayerControlsHidden)
147 | VlcArgumentsBuilder.Append(" --qt-minimal-view");
148 |
149 | // full screen
150 | if (Settings.IsExternalMediaPlayerFullScreen)
151 | VlcArgumentsBuilder.Append(" --fullscreen");
152 |
153 | // show URL in title bar
154 | if (!Settings.IsUrlShown)
155 | VlcArgumentsBuilder.AppendFormat(" --meta-title=\"{0}\"", chatRoom.Name);
156 |
157 | // video feed URL
158 | VlcArgumentsBuilder.AppendFormat(" {0}", chatRoom.VideoFeedUrl);
159 |
160 | // recording options
161 | if (Settings.IsAutoSaveVideosEnabled)
162 | {
163 | var videoDirectory = Settings.AutoSaveDirectory;
164 | if (string.IsNullOrEmpty(videoDirectory))
165 | videoDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos);
166 | if (Directory.Exists(videoDirectory))
167 | VlcArgumentsBuilder.AppendFormat(" --sout=\"#duplicate{{dst=std{{access=file,dst='{0}{1}.mp4'}},dst=display}}\"", videoDirectory, chatRoom.Name);
168 | }
169 |
170 | arguments = VlcArgumentsBuilder.ToString().Trim();
171 | }
172 | else
173 | {
174 | playerPath = GetWmpExecutablePath();
175 | arguments = string.Format("\"{0}\"", chatRoom.VideoFeedUrl, chatRoom.Name);
176 | }
177 |
178 | if (string.IsNullOrEmpty(playerPath) || string.IsNullOrEmpty(arguments))
179 | return;
180 |
181 | var process = new Process();
182 | process.StartInfo.FileName = playerPath;
183 | process.StartInfo.Arguments = arguments;
184 | process.Start();
185 | }
186 |
187 | void Player(LiveStreamPlayerState state)
188 | {
189 | if (SelectedRoom == null)
190 | return;
191 |
192 | switch (state)
193 | {
194 | case LiveStreamPlayerState.Play:
195 | State = LiveStreamPlayerState.Play;
196 | break;
197 |
198 | case LiveStreamPlayerState.Pause:
199 | State = LiveStreamPlayerState.Pause;
200 | break;
201 |
202 | case LiveStreamPlayerState.Stop:
203 | State = LiveStreamPlayerState.Stop;
204 | break;
205 |
206 | case LiveStreamPlayerState.ExternalMediaPlayer:
207 | State = LiveStreamPlayerState.ExternalMediaPlayer;
208 | PlayVideoFeed(SelectedRoom);
209 | break;
210 | }
211 | }
212 |
213 | void ToggleMute()
214 | {
215 | IsMuted = !IsMuted;
216 | }
217 |
218 | public void NotificationReceived(NotificationType type, params object[] data)
219 | {
220 | switch(type)
221 | {
222 | case NotificationType.TabPageChanged:
223 | if (Shared.Instance.Settings.IsAutoPauseEnabled)
224 | {
225 | var index = (int)data[0];
226 | if (index == 5 && (State == LiveStreamPlayerState.Paused || State == LiveStreamPlayerState.Pause))
227 | State = LiveStreamPlayerState.Play;
228 | else if (index != 5 && State == LiveStreamPlayerState.Playing)
229 | State = LiveStreamPlayerState.Pause;
230 | }
231 | break;
232 |
233 | case NotificationType.ChatRoomSelected:
234 | SelectedRoom = (ChatRoomModel)data[0];
235 | break;
236 | }
237 | }
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/ViewModels/MainWindowViewModel.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Base;
2 | using ChaturbatePlayer.Models;
3 | using NullVoidCreations.WpfHelpers.Base;
4 |
5 | namespace ChaturbatePlayer.ViewModels
6 | {
7 | public class MainWindowViewModel: ViewModelBase, IMediator
8 | {
9 | ChatRoomModel _selectedRoom;
10 | int _selectedTabIndex;
11 |
12 | public MainWindowViewModel()
13 | {
14 | SelectedRoom = null;
15 | SelectedTabIndex = 0;
16 |
17 | Mediator.Instance.RegisterColleague(this);
18 | }
19 |
20 | #region properties
21 |
22 | public Gender Featured
23 | {
24 | get { return Gender.NotSpecified; }
25 | }
26 |
27 | public Gender Female
28 | {
29 | get { return Gender.Female; }
30 | }
31 |
32 | public Gender Male
33 | {
34 | get { return Gender.Male; }
35 | }
36 |
37 | public Gender Couple
38 | {
39 | get { return Gender.Couple; }
40 | }
41 |
42 | public Gender Trans
43 | {
44 | get { return Gender.Trans; }
45 | }
46 |
47 | public LicenseModel License
48 | {
49 | get { return Shared.Instance.License; }
50 | }
51 |
52 | public ChatRoomModel SelectedRoom
53 | {
54 | get { return _selectedRoom; }
55 | set
56 | {
57 | if (value == _selectedRoom)
58 | return;
59 |
60 | _selectedRoom = value;
61 | RaisePropertyChanged(nameof(SelectedRoom));
62 | SelectedTabIndex = 5;
63 | }
64 | }
65 |
66 | public int SelectedTabIndex
67 | {
68 | get { return _selectedTabIndex; }
69 | set
70 | {
71 | if (value == _selectedTabIndex)
72 | return;
73 |
74 | _selectedTabIndex = value;
75 | RaisePropertyChanged(nameof(SelectedTabIndex));
76 | Mediator.Instance.RaiseNotification(this, NotificationType.TabPageChanged, _selectedTabIndex);
77 | }
78 | }
79 |
80 | #endregion
81 |
82 | public void NotificationReceived(NotificationType type, params object[] data)
83 | {
84 | switch(type)
85 | {
86 | case NotificationType.ChatRoomSelected:
87 | SelectedRoom = (ChatRoomModel)data[0];
88 | break;
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/ViewModels/SettingsViewModel.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Models;
2 | using NullVoidCreations.WpfHelpers.Base;
3 | using NullVoidCreations.WpfHelpers.Commands;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Windows.Forms;
8 | using System.Windows.Input;
9 |
10 | namespace ChaturbatePlayer.ViewModels
11 | {
12 | public class SettingsViewModel: ViewModelBase
13 | {
14 | ICommand _selectDirectory;
15 |
16 | IEnumerable _mediaPlayers;
17 | IEnumerable _refreshIntervals;
18 |
19 | #region properties
20 |
21 | public IEnumerable MediaPlayers
22 | {
23 | get
24 | {
25 | if (_mediaPlayers == null)
26 | _mediaPlayers = new List { "VLC", "Windows" };
27 |
28 | return _mediaPlayers;
29 | }
30 | }
31 |
32 | public IEnumerable RefreshIntervals
33 | {
34 | get
35 | {
36 | if (_refreshIntervals == null)
37 | {
38 | var refreshIntervals = new List();
39 | for (var interval = 2; interval <= 15; interval += 2)
40 | refreshIntervals.Add(interval);
41 | _refreshIntervals = refreshIntervals;
42 | }
43 |
44 | return _refreshIntervals;
45 | }
46 |
47 | }
48 |
49 | public string ProductName
50 | {
51 | get { return Shared.Instance.Information.ProductTitle; }
52 | }
53 |
54 | public string ProductDescription
55 | {
56 | get { return Shared.Instance.Information.Description; }
57 | }
58 |
59 | public string ProductCopyright
60 | {
61 | get { return Shared.Instance.Information.Copyright; }
62 | }
63 |
64 | public Version ProductVersion
65 | {
66 | get { return Shared.Instance.Information.Version; }
67 | }
68 |
69 | public SettingsModel Settings
70 | {
71 | get { return Shared.Instance.Settings; }
72 | }
73 |
74 | public LicenseModel License
75 | {
76 | get { return Shared.Instance.License; }
77 | }
78 |
79 | #endregion
80 |
81 | #region commands
82 |
83 | public ICommand SelectDirectoryCommand
84 | {
85 | get
86 | {
87 | if (_selectDirectory == null)
88 | _selectDirectory = new RelayCommand(SelectDirectory) { IsSynchronous = true };
89 |
90 | return _selectDirectory;
91 |
92 | }
93 | }
94 |
95 | #endregion
96 |
97 | void SelectDirectory(string dialogDescription)
98 | {
99 | if (dialogDescription == null)
100 | dialogDescription = "Please select a directory below and click OK.";
101 |
102 | var dialog = new FolderBrowserDialog();
103 | dialog.Description = dialogDescription;
104 | dialog.ShowNewFolderButton = true;
105 | if (dialog.ShowDialog() == DialogResult.OK)
106 | Settings.AutoSaveDirectory = dialog.SelectedPath.EndsWith(Path.DirectorySeparatorChar.ToString()) ? dialog.SelectedPath : string.Format("{0}{1}", dialog.SelectedPath, Path.DirectorySeparatorChar);
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/ViewModels/SplashViewModel.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Base;
2 | using NullVoidCreations.WpfHelpers;
3 | using NullVoidCreations.WpfHelpers.Base;
4 | using NullVoidCreations.WpfHelpers.Commands;
5 | using System;
6 | using System.IO;
7 | using System.IO.Compression;
8 | using System.Windows;
9 | using System.Windows.Input;
10 |
11 | namespace ChaturbatePlayer.ViewModels
12 | {
13 | public class SplashViewModel: ViewModelBase, IMediator
14 | {
15 | ICommand _initialize;
16 | const string VLC_LIB_ARCHIVE = "VLC.zip";
17 |
18 | #region properties
19 |
20 | public string ProductName
21 | {
22 | get { return Shared.Instance.Information.Product; }
23 | }
24 |
25 | public string ProductDescription
26 | {
27 | get { return Shared.Instance.Information.Description; }
28 | }
29 |
30 | public string ProductCopyright
31 | {
32 | get { return Shared.Instance.Information.Copyright; }
33 | }
34 |
35 | public Version ProductVersion
36 | {
37 | get { return Shared.Instance.Information.Version; }
38 | }
39 |
40 | #endregion
41 |
42 | #region commands
43 |
44 | public ICommand InitializeCommand
45 | {
46 | get
47 | {
48 | if (_initialize == null)
49 | _initialize = new RelayCommand(Initialize);
50 |
51 | return _initialize;
52 | }
53 | }
54 |
55 | #endregion
56 |
57 | void Initialize()
58 | {
59 | if (Directory.Exists(Shared.Instance.LibVlcPath))
60 | {
61 | Mediator.Instance.RaiseNotification(this, NotificationType.Initialized);
62 | return;
63 | }
64 |
65 | var archivePath = Path.Combine(Application.Current.GetStartupDirectory(), VLC_LIB_ARCHIVE);
66 | if (!File.Exists(archivePath))
67 | {
68 | Application.Current.Shutdown(1);
69 | return;
70 | }
71 |
72 | if (!Directory.Exists(Shared.Instance.DataPath))
73 | Directory.CreateDirectory(Shared.Instance.DataPath);
74 |
75 | using (var zip = ZipStorer.Open(archivePath, FileAccess.Read))
76 | {
77 | foreach (ZipStorer.ZipFileEntry zipEntry in zip.ReadCentralDir())
78 | zip.ExtractFile(zipEntry, Path.Combine(Shared.Instance.DataPath, zipEntry.FilenameInZip));
79 | }
80 |
81 | Mediator.Instance.RaiseNotification(this, NotificationType.Initialized);
82 | }
83 |
84 | public void NotificationReceived(NotificationType type, params object[] data)
85 | {
86 | // do nothing
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/ChatRoomsView.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
50 |
51 |
52 |
53 |
58 |
59 |
64 |
65 |
66 |
70 |
75 |
76 |
82 |
88 |
94 |
95 |
96 |
97 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
200 |
201 |
206 |
207 |
208 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
226 |
231 |
232 |
233 |
234 |
240 |
241 |
245 |
249 |
253 |
254 |
255 |
261 |
262 |
268 |
269 |
275 |
276 |
277 |
278 |
279 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/ChatRoomsView.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ChaturbatePlayer.Views
2 | {
3 | ///
4 | /// Interaction logic for ChatRoomsView.xaml
5 | ///
6 | public partial class ChatRoomsView
7 | {
8 | public ChatRoomsView()
9 | {
10 | InitializeComponent();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/LicenseKeyGeneratorWindowView.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
31 |
37 |
42 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
69 |
70 |
71 |
76 |
77 |
78 |
83 |
84 |
88 |
95 |
96 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/LicenseKeyGeneratorWindowView.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ChaturbatePlayer.Views
2 | {
3 | ///
4 | /// Interaction logic for WindowLicenseKeyGenerator.xaml
5 | ///
6 | public partial class LicenseKeyGeneratorWindowView
7 | {
8 | public LicenseKeyGeneratorWindowView()
9 | {
10 | InitializeComponent();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/LiveStreamPlayerView.xaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
34 |
35 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
60 |
61 |
62 |
69 |
76 |
83 |
89 |
97 |
98 |
99 |
105 |
115 |
116 |
117 |
118 |
119 |
120 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/LiveStreamPlayerView.xaml.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Base;
2 | using ChaturbatePlayer.ViewModels;
3 | using System;
4 | using System.IO;
5 | using Vlc.DotNet.Core;
6 | using Vlc.DotNet.Core.Interops.Signatures;
7 |
8 | namespace ChaturbatePlayer.Views
9 | {
10 | public partial class LiveStreamPlayerView: IMediator
11 | {
12 | readonly LiveStreamPlayerViewModel _viewModel;
13 | string _currentVideoUrl;
14 |
15 | public LiveStreamPlayerView()
16 | {
17 | InitializeComponent();
18 |
19 | Mediator.Instance.RegisterColleague(this);
20 |
21 | _viewModel = DataContext as LiveStreamPlayerViewModel;
22 | _viewModel.State = LiveStreamPlayerState.Stopped;
23 | _viewModel.PropertyChanged += LiveStreamPlayerView_PropertyChanged;
24 | }
25 |
26 | ~LiveStreamPlayerView()
27 | {
28 | //Player.Dispose();
29 |
30 | _viewModel.PropertyChanged -= LiveStreamPlayerView_PropertyChanged;
31 | }
32 |
33 | void LiveStreamPlayerView_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
34 | {
35 | if (_viewModel.SelectedRoom == null || Player.SourceProvider.MediaPlayer == null)
36 | return;
37 |
38 | if (e.PropertyName.Equals("State"))
39 | {
40 | switch (_viewModel.State)
41 | {
42 | case LiveStreamPlayerState.Play:
43 | ChangePlayerState(_viewModel.SelectedRoom.VideoFeedUrl, LiveStreamPlayerState.Play);
44 | break;
45 |
46 | case LiveStreamPlayerState.Pause:
47 | ChangePlayerState(_viewModel.SelectedRoom.VideoFeedUrl, LiveStreamPlayerState.Pause);
48 | break;
49 |
50 | case LiveStreamPlayerState.Stop:
51 | case LiveStreamPlayerState.ExternalMediaPlayer:
52 | ChangePlayerState(_viewModel.SelectedRoom.VideoFeedUrl, LiveStreamPlayerState.Stop);
53 | break;
54 | }
55 | }
56 | else if (e.PropertyName.Equals("IsMuted"))
57 | {
58 | Player.SourceProvider.MediaPlayer.Audio.IsMute = _viewModel.IsMuted;
59 | }
60 | }
61 |
62 | void MediaPlayer_Stopped(object sender, VlcMediaPlayerStoppedEventArgs e)
63 | {
64 | _viewModel.State = LiveStreamPlayerState.Stopped;
65 | }
66 |
67 | void MediaPlayer_Buffering(object sender, VlcMediaPlayerBufferingEventArgs e)
68 | {
69 | _viewModel.State = LiveStreamPlayerState.Playing;
70 | }
71 |
72 | void MediaPlayer_Opening(object sender, VlcMediaPlayerOpeningEventArgs e)
73 | {
74 | _viewModel.State = LiveStreamPlayerState.Playing;
75 | }
76 |
77 | void MediaPlayer_Playing(object sender, VlcMediaPlayerPlayingEventArgs e)
78 | {
79 | _viewModel.State = LiveStreamPlayerState.Playing;
80 | }
81 |
82 | void MediaPlayer_EncounteredError(object sender, VlcMediaPlayerEncounteredErrorEventArgs e)
83 | {
84 | _viewModel.State = LiveStreamPlayerState.Stopped;
85 | }
86 |
87 | void MediaPlayer_Paused(object sender, VlcMediaPlayerPausedEventArgs e)
88 | {
89 | _viewModel.State = LiveStreamPlayerState.Paused;
90 | }
91 |
92 | void ChangePlayerState(string url, LiveStreamPlayerState state)
93 | {
94 | switch(state)
95 | {
96 | case LiveStreamPlayerState.Play:
97 | if (string.IsNullOrEmpty(url))
98 | {
99 | if (Player.SourceProvider.MediaPlayer.State == MediaStates.Playing)
100 | Player.SourceProvider.MediaPlayer.Stop();
101 | _currentVideoUrl = null;
102 | }
103 | else
104 | {
105 | if (_currentVideoUrl == url)
106 | {
107 | if (Player.SourceProvider.MediaPlayer.State == MediaStates.Paused)
108 | Player.SourceProvider.MediaPlayer.Play();
109 | }
110 | else
111 | {
112 | if (Player.SourceProvider.MediaPlayer.State == MediaStates.Playing)
113 | Player.SourceProvider.MediaPlayer.Stop();
114 |
115 | Player.SourceProvider.MediaPlayer.Play(new Uri(url, UriKind.Absolute));
116 | _currentVideoUrl = url;
117 | }
118 | }
119 |
120 | break;
121 |
122 | case LiveStreamPlayerState.ExternalMediaPlayer:
123 | if (Player.SourceProvider.MediaPlayer.State == MediaStates.Playing || Player.SourceProvider.MediaPlayer.State == MediaStates.Paused)
124 | Player.SourceProvider.MediaPlayer.Stop();
125 | break;
126 |
127 | case LiveStreamPlayerState.Stop:
128 | if (Player.SourceProvider.MediaPlayer.State == MediaStates.Playing || Player.SourceProvider.MediaPlayer.State == MediaStates.Paused)
129 | Player.SourceProvider.MediaPlayer.Stop();
130 | _currentVideoUrl = null;
131 | break;
132 |
133 | case LiveStreamPlayerState.Pause:
134 | if (Player.SourceProvider.MediaPlayer.State == MediaStates.Playing)
135 | Player.SourceProvider.MediaPlayer.Pause();
136 | break;
137 | }
138 | }
139 |
140 | public void NotificationReceived(NotificationType type, params object[] data)
141 | {
142 | switch(type)
143 | {
144 | case NotificationType.Initialized:
145 | Player.SourceProvider.CreatePlayer(new DirectoryInfo(Shared.Instance.LibVlcPath));
146 | Player.SourceProvider.MediaPlayer.Opening += MediaPlayer_Opening;
147 | Player.SourceProvider.MediaPlayer.Buffering += MediaPlayer_Buffering;
148 | Player.SourceProvider.MediaPlayer.Playing += MediaPlayer_Playing;
149 | Player.SourceProvider.MediaPlayer.EncounteredError += MediaPlayer_EncounteredError;
150 | Player.SourceProvider.MediaPlayer.Stopped += MediaPlayer_Stopped;
151 | Player.SourceProvider.MediaPlayer.Paused += MediaPlayer_Paused;
152 | break;
153 | }
154 | }
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/MainWindowView.xaml:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
52 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
191 |
192 |
193 |
194 |
195 |
196 |
200 |
201 |
202 |
203 |
204 |
205 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/MainWindowView.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ChaturbatePlayer.Views
2 | {
3 | ///
4 | /// Interaction logic for MainWindow.xaml
5 | ///
6 | public partial class MainWindowView
7 | {
8 | public MainWindowView()
9 | {
10 | InitializeComponent();
11 | }
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/SettingsView.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
47 |
48 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
74 |
75 |
80 |
81 |
82 |
83 |
87 |
91 |
94 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
144 |
145 |
146 |
147 |
148 |
149 |
156 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/SettingsView.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace ChaturbatePlayer.Views
2 | {
3 | ///
4 | /// Interaction logic for SettingsView.xaml
5 | ///
6 | public partial class SettingsView
7 | {
8 | public SettingsView()
9 | {
10 | InitializeComponent();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/SplashWindowView.xaml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
53 |
54 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
70 |
71 |
72 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/Views/SplashWindowView.xaml.cs:
--------------------------------------------------------------------------------
1 | using ChaturbatePlayer.Base;
2 | using System;
3 | using System.Windows;
4 |
5 | namespace ChaturbatePlayer.Views
6 | {
7 | ///
8 | /// Interaction logic for SplashWindowView.xaml
9 | ///
10 | public partial class SplashWindowView: IMediator
11 | {
12 | public SplashWindowView()
13 | {
14 | InitializeComponent();
15 | Mediator.Instance.RegisterColleague(this);
16 | }
17 |
18 | public void NotificationReceived(NotificationType type, params object[] data)
19 | {
20 | switch(type)
21 | {
22 | case NotificationType.Initialized:
23 | var action = (Action)(() => Close());
24 | Application.Current.Dispatcher.BeginInvoke(action);
25 | break;
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/app.config:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/ChaturbatePlayer/ChaturbatePlayer/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ChaturbatePlayer
2 | A redefined way to view live cam feeds from chaturbate.com without opening it in web browser.
3 |
--------------------------------------------------------------------------------
/Screenshots/Capture0.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/Screenshots/Capture0.PNG
--------------------------------------------------------------------------------
/Screenshots/Capture1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/Screenshots/Capture1.PNG
--------------------------------------------------------------------------------
/Screenshots/Capture2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/waliarubal/ChaturbatePlayer/eabc83518e59d49a019cdd24b5d3dfd13848c813/Screenshots/Capture2.PNG
--------------------------------------------------------------------------------