diff --git a/ClientServerLib/ClientServerLib/CServer.cs b/ClientServerLib/ClientServerLib/CServer.cs index c6435566..57bbe01d 100644 --- a/ClientServerLib/ClientServerLib/CServer.cs +++ b/ClientServerLib/ClientServerLib/CServer.cs @@ -203,6 +203,18 @@ namespace ServerLib _Init(port, encrypted); } + public static string GetLocalAddress() + { + IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); + string IPAddress = ""; + foreach (IPAddress ip in ips) + { + if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) + IPAddress = ip.ToString(); + } + return IPAddress; + } + #region server control private void _Init(int port, bool encrypted) diff --git a/ClientServerLib/ClientServerLib/UserRoleControl.cs b/ClientServerLib/ClientServerLib/UserRoleControl.cs index 5af1a6ba..8bff242a 100644 --- a/ClientServerLib/ClientServerLib/UserRoleControl.cs +++ b/ClientServerLib/ClientServerLib/UserRoleControl.cs @@ -6,7 +6,7 @@ namespace ServerLib internal static class CUserRoleControl { private static readonly Dictionary _RoleRightsMapping = new Dictionary { - {EUserRoles.Administrator, + {EUserRoles.TR_USERROLE_ADMIN, (EUserRights.EditAllProfiles| EUserRights.UploadPhotos| EUserRights.ViewOtherProfiles| @@ -16,10 +16,23 @@ namespace ServerLib EUserRights.CreatePlaylists| EUserRights.DeletePlaylists| EUserRights.RemoveSongsFromPlaylists)}, - {EUserRoles.AuthenticatedUser, + {EUserRoles.TR_USERROLE_GUEST, + EUserRights.None}, + {EUserRoles.TR_USERROLE_NORMAL, (EUserRights.UploadPhotos| - EUserRights.ViewOtherProfiles| - EUserRights.UseKeyboard)} + EUserRights.ViewOtherProfiles)}, + {EUserRoles.TR_USERROLE_KEYBOARDUSER, + EUserRights.UseKeyboard}, + {EUserRoles.TR_USERROLE_ADDSONGSUSER, + EUserRights.AddSongToPlaylist}, + {EUserRoles.TR_USERROLE_PLAYLISTEDITOR, + (EUserRights.AddSongToPlaylist| + EUserRights.ReorderPlaylists| + EUserRights.CreatePlaylists| + EUserRights.DeletePlaylists| + EUserRights.RemoveSongsFromPlaylists)}, + {EUserRoles.TR_USERROLE_PROFILEEDITOR, + EUserRights.EditAllProfiles} }; diff --git a/ClientServerLib/ClientServerLib/UserRoles.cs b/ClientServerLib/ClientServerLib/UserRoles.cs index b352317c..bcdb0988 100644 --- a/ClientServerLib/ClientServerLib/UserRoles.cs +++ b/ClientServerLib/ClientServerLib/UserRoles.cs @@ -5,7 +5,12 @@ namespace ServerLib [Flags] internal enum EUserRoles { - AuthenticatedUser = 0, - Administrator = 1 + TR_USERROLE_GUEST = 0, + TR_USERROLE_NORMAL = 1, + TR_USERROLE_ADMIN = 2, + TR_USERROLE_KEYBOARDUSER = 4, + TR_USERROLE_ADDSONGSUSER = 8, + TR_USERROLE_PLAYLISTEDITOR = 16, + TR_USERROLE_PROFILEEDITOR = 32 } } diff --git a/Output/LICENSE QRCoder.txt b/Output/LICENSE QRCoder.txt new file mode 100644 index 00000000..5624f5cf --- /dev/null +++ b/Output/LICENSE QRCoder.txt @@ -0,0 +1,22 @@ +// QRCode.dll from https://github.com/codebude/QRCoder/ + +The MIT License (MIT) + +Copyright (c) 2013 Raffael Herrmann + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Output/Languages/English.xml b/Output/Languages/English.xml index 282cea99..128e9dd4 100644 --- a/Output/Languages/English.xml +++ b/Output/Languages/English.xml @@ -26,6 +26,9 @@ Wannabe Amateur Tone Deaf + Guest + Normal User + Administrator Software OpenGL Direct3D @@ -147,7 +150,7 @@ Player Name Game Difficulty Avatar - Guest Profile + User Role Active New Delete @@ -162,6 +165,7 @@ Video Lyrics Theme + Server address Game Options Language Debug Level @@ -204,4 +208,5 @@ Webcams Webcamcapabilities Volume + Server address diff --git a/Output/QRCoder.dll b/Output/QRCoder.dll new file mode 100644 index 00000000..5e9f62c3 Binary files /dev/null and b/Output/QRCoder.dll differ diff --git a/Output/Themes/Ambient/Screens/PopupScreenServerQR.xml b/Output/Themes/Ambient/Screens/PopupScreenServerQR.xml new file mode 100644 index 00000000..94038a48 --- /dev/null +++ b/Output/Themes/Ambient/Screens/PopupScreenServerQR.xml @@ -0,0 +1,285 @@ + + + + 1 + + + SongMenuBG + + 0 + 0 + -1,99 + 1280 + 720 + + + 1,00 + 1,00 + 1,00 + 0,80 + + + + + + + Menu + + 490 + 210 + -2,00 + 300 + 300 + + + Visible + + + + + + + Menu + + 25 + 25 + -2,00 + 200 + 200 + + + Visible + + + + + + + Menu + + 1055 + 25 + -2,00 + 200 + 200 + + + Visible + + + + + + + Menu + + 25 + 495 + -2,00 + 200 + 200 + + + Visible + + + + + + + Menu + + 1055 + 495 + -2,00 + 200 + 200 + + + Visible + + + + + + + 640 + 515 + + -2,00 + + 35 + + 300 + + + StaticColor + + + TextSColor + + Center + + Center + + + + Outline + + + + + + + + + 640 + 180 + + -2,00 + + 35 + + 300 + + + StaticColor + + + TextSColor + + Center + + Center + + + + Outline + + TR_SCREENPSERVERQR_ADDRESS + + + + + + + 125 + 230 + + -2,00 + + 27 + + 200 + + + StaticColor + + + TextSColor + + Center + + Center + + + + Outline + + Android + + + + + + + 1155 + 230 + + -2,00 + + 27 + + 200 + + + StaticColor + + + TextSColor + + Center + + Center + + + + Outline + + Symbian + + + + + + + 125 + 460 + + -2,00 + + 27 + + 200 + + + StaticColor + + + TextSColor + + Center + + Center + + + + Outline + + WebOS + + + + + + + 1155 + 460 + + -2,00 + + 27 + + 200 + + + StaticColor + + + TextSColor + + Center + + Center + + + + Outline + + Windows Phone + + + + + + diff --git a/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml b/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml index 6f758a46..49c9551a 100644 --- a/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml +++ b/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml @@ -1,7 +1,7 @@  - 1 + 2 Video @@ -385,6 +385,63 @@ 26 + + + Button + + Button + + 355 + 600 + 0,00 + 150 + 50 + + + ButtonColor + + + ButtonSColor + + + 75 + 12 + + 27 + + 142 + + + ButtonTextColor + + + ButtonTextSColor + + Center + + Center + + + + Outline + + TR_SCREENOGAME_BUTTON_SERVER + + + + + + 10 + 26 + + + + + + 10 + 26 + + Invisible @@ -788,4 +845,4 @@ 3 - \ No newline at end of file + diff --git a/Output/Themes/Ambient/Screens/ScreenProfiles.xml b/Output/Themes/Ambient/Screens/ScreenProfiles.xml index 919a580d..1fb4ce6f 100644 --- a/Output/Themes/Ambient/Screens/ScreenProfiles.xml +++ b/Output/Themes/Ambient/Screens/ScreenProfiles.xml @@ -1,7 +1,7 @@  - 2 + 3 Video @@ -265,7 +265,7 @@ Outline - TR_SCREENPROFILES_GUESTPROFILE + TR_SCREENPROFILES_USERROLE @@ -989,7 +989,7 @@ 3 - + Invisible @@ -1055,7 +1055,7 @@ Bold 2 - + Invisible diff --git a/Output/Themes/Changelog/Changelog_ScreenOptionsGame.txt b/Output/Themes/Changelog/Changelog_ScreenOptionsGame.txt new file mode 100644 index 00000000..e60b7e4a --- /dev/null +++ b/Output/Themes/Changelog/Changelog_ScreenOptionsGame.txt @@ -0,0 +1,8 @@ +ScreenOptionsGame + +++++++++++ +Version 2: + +Add: + +++++++++++ \ No newline at end of file diff --git a/Output/Themes/Changelog/Changelog_ScreenProfiles.txt b/Output/Themes/Changelog/Changelog_ScreenProfiles.txt index 65dae6e8..3c741fc1 100644 --- a/Output/Themes/Changelog/Changelog_ScreenProfiles.txt +++ b/Output/Themes/Changelog/Changelog_ScreenProfiles.txt @@ -1,4 +1,7 @@ ScreenProfiles +++++++++++ +Version 3: +Rename: to ++++++++++ Version 2: diff --git a/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs b/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs index 234d1ca1..b0975714 100644 --- a/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs +++ b/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs @@ -513,12 +513,18 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley return false; } + //Calc avarage sing-count + int totalCounts = 0; + foreach (CSong song in visibleSongs) + totalCounts += song.NumPlayedSession; + int averageCount = totalCounts / visibleSongs.Count; + // ReSharper disable LoopCanBeConvertedToQuery foreach (CSong song in visibleSongs) { foreach (EGameMode mode in song.AvailableGameModes) { - if (mode == EGameMode.TR_GAMEMODE_MEDLEY) + if (mode == EGameMode.TR_GAMEMODE_MEDLEY && song.NumPlayedSession <= averageCount) ids.Add(song.ID); } } diff --git a/Vocaluxe/Base/CGraphics.cs b/Vocaluxe/Base/CGraphics.cs index 5a7fdd54..91878e51 100644 --- a/Vocaluxe/Base/CGraphics.cs +++ b/Vocaluxe/Base/CGraphics.cs @@ -90,6 +90,7 @@ namespace Vocaluxe.Base _PopupScreens.Add(new CPopupScreenPlayerControl()); _PopupScreens.Add(new CPopupScreenVolumeControl()); + _PopupScreens.Add(new CPopupScreenServerQR()); CLog.StopBenchmark(1, "Build Screen List"); @@ -379,6 +380,14 @@ namespace Vocaluxe.Base _Cursor.FadeOut(); } + if (keyEvent.Key == Keys.F11) + { + if (_CurrentPopupScreen == EPopupScreens.NoPopup) + ShowPopup(EPopupScreens.PopupServerQR); + else + HidePopup(EPopupScreens.PopupServerQR); + } + if (popupPlayerControlAllowed && keyEvent.Key == Keys.Tab) { if (_CurrentPopupScreen == EPopupScreens.NoPopup && CConfig.BackgroundMusic == EOffOn.TR_CONFIG_ON) diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index dbf75632..ff9f0f5d 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -233,6 +233,16 @@ namespace Vocaluxe.Base { return CSettings.DataPath; } + + public float GetSlideShowImageTime() + { + return CSettings.SlideShowImageTime; + } + + public float GetSlideShowFadeTime() + { + return CSettings.SlideShowFadeTime; + } } class CBtheme : ITheme diff --git a/Vocaluxe/Base/CProfiles.cs b/Vocaluxe/Base/CProfiles.cs index 44f996fe..d77331ca 100644 --- a/Vocaluxe/Base/CProfiles.cs +++ b/Vocaluxe/Base/CProfiles.cs @@ -212,7 +212,7 @@ namespace Vocaluxe.Base public static void LoadProfiles() { - var change = new SChange {Action = EAction.LoadProfiles}; + var change = new SChange { Action = EAction.LoadProfiles }; lock (_QueueMutex) { @@ -222,7 +222,7 @@ namespace Vocaluxe.Base public static void LoadAvatars() { - var change = new SChange {Action = EAction.LoadAvatars}; + var change = new SChange { Action = EAction.LoadAvatars }; lock (_QueueMutex) { @@ -235,7 +235,7 @@ namespace Vocaluxe.Base if (newProfile == null) return; - var change = new SChange {Action = EAction.AddProfile, Profile = newProfile}; + var change = new SChange { Action = EAction.AddProfile, Profile = newProfile }; lock (_QueueMutex) { @@ -248,7 +248,7 @@ namespace Vocaluxe.Base if (editProfile == null) return; - var change = new SChange {Action = EAction.EditProfile, Profile = editProfile}; + var change = new SChange { Action = EAction.EditProfile, Profile = editProfile }; lock (_QueueMutex) { @@ -261,7 +261,7 @@ namespace Vocaluxe.Base if (!IsProfileIDValid(profileID)) return; - var change = new SChange {Action = EAction.DeleteProfile, ProfileID = profileID}; + var change = new SChange { Action = EAction.DeleteProfile, ProfileID = profileID }; lock (_QueueMutex) { @@ -274,7 +274,7 @@ namespace Vocaluxe.Base if (newAvatar == null) return; - var change = new SChange {Action = EAction.AddAvatar, Avatar = newAvatar}; + var change = new SChange { Action = EAction.AddAvatar, Avatar = newAvatar }; lock (_QueueMutex) { @@ -287,7 +287,7 @@ namespace Vocaluxe.Base if (editAvatar == null) return; - var change = new SChange {Action = EAction.EditAvatar, Avatar = editAvatar}; + var change = new SChange { Action = EAction.EditAvatar, Avatar = editAvatar }; lock (_QueueMutex) { @@ -310,9 +310,9 @@ namespace Vocaluxe.Base if (!IsProfileIDValid(profileID)) { return null; - } + } - return _Profiles[profileID]; + return _Profiles[profileID]; } public static IEnumerable GetAvatars() @@ -433,17 +433,19 @@ namespace Vocaluxe.Base _Profiles[profileID].Difficulty = difficulty; } - public static EOffOn GetGuestProfile(int profileID) + public static EUserRole GetUserRoleProfile(int profileID) { - return IsProfileIDValid(profileID) ? _Profiles[profileID].GuestProfile : EOffOn.TR_CONFIG_OFF; + return IsProfileIDValid(profileID) ? _Profiles[profileID].UserRole : EUserRole.TR_USERROLE_GUEST; } - public static void SetGuestProfile(int profileID, EOffOn option) + public static void SetUserRoleProfile(int profileID, EUserRole option) { if (!IsProfileIDValid(profileID)) return; - - _Profiles[profileID].GuestProfile = option; + //Only allow the change of TR_USERROLE_GUEST, TR_USERROLE_NORMAL and TR_USERROLE_ADMIN + const EUserRole mask = (EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL | EUserRole.TR_USERROLE_ADMIN); + option &= mask; + _Profiles[profileID].UserRole = (_Profiles[profileID].UserRole & ~mask) | option; } public static EOffOn GetActive(int profileID) @@ -464,7 +466,7 @@ namespace Vocaluxe.Base if (!IsProfileIDValid(profileID)) return true; // this will prevent from saving dummy profiles to highscore db - return _Profiles[profileID].GuestProfile == EOffOn.TR_CONFIG_ON; + return _Profiles[profileID].UserRole.HasFlag(EUserRole.TR_USERROLE_GUEST); } public static bool IsActive(int profileID) diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index 7f63c97e..bfd0aa35 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -116,6 +116,11 @@ namespace Vocaluxe.Base public const string FolderPartyModeLanguages = "Languages"; public const string FolderPartyModeFonts = "Fonts"; + public const string LinkAndroidApp = "https://build.phonegap.com/apps/639714/download/android/?qr_key=uY98ymvTr6K144RyTdhs"; + public const string LinkSymbianApp = "https://build.phonegap.com/apps/639714/download/symbian/?qr_key=uY98ymvTr6K144RyTdhs"; + public const string LinkWebOSApp = "https://build.phonegap.com/apps/639714/download/webos/?qr_key=uY98ymvTr6K144RyTdhs"; + public const string LinkWindowsPhoneApp = "https://build.phonegap.com/apps/639714/download/winphone/?qr_key=uY98ymvTr6K144RyTdhs"; + //public const String[] ToneStrings = new String[]{ "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; public const int ToneMin = -36; public const int ToneMax = 89; @@ -143,6 +148,9 @@ namespace Vocaluxe.Base public const float BackgroundMusicFadeTime = 0.5f; public const float PauseResetTime = 1f; + public const float SlideShowImageTime = 3500f; + public const float SlideShowFadeTime = 500f; + public static readonly List MusicFileTypes = new List { "*.mp3", diff --git a/Vocaluxe/Base/CSongs.cs b/Vocaluxe/Base/CSongs.cs index c031209c..86a2f482 100644 --- a/Vocaluxe/Base/CSongs.cs +++ b/Vocaluxe/Base/CSongs.cs @@ -217,7 +217,20 @@ namespace Vocaluxe.Base public static void UpdateRandomSongList() { _SongsForRandom.Clear(); - _SongsForRandom.AddRange(VisibleSongs); + //Calc avarage sing-count + int totalCounts = 0; + foreach (CSong song in VisibleSongs) + totalCounts += song.NumPlayedSession; + int averageCount = totalCounts / NumSongsVisible; + + foreach(CSong song in VisibleSongs) + { + if (song.NumPlayedSession <= averageCount) + _SongsForRandom.Add(song); + } + + if(_SongsForRandom.Count == 0) + _SongsForRandom.AddRange(VisibleSongs); } public static int GetRandomCategory() diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs index d64bbf4d..9358b954 100644 --- a/Vocaluxe/Base/Server/CVocaluxeServer.cs +++ b/Vocaluxe/Base/Server/CVocaluxeServer.cs @@ -184,7 +184,7 @@ namespace Vocaluxe.Base.Server AvatarFileName = existingProfile.AvatarFileName, Avatar = existingProfile.Avatar, Difficulty = existingProfile.Difficulty, - GuestProfile = existingProfile.GuestProfile, + UserRole = existingProfile.UserRole, PlayerName = existingProfile.PlayerName }; } @@ -193,7 +193,7 @@ namespace Vocaluxe.Base.Server newProfile = new CProfile { Active = EOffOn.TR_CONFIG_ON, - GuestProfile = EOffOn.TR_CONFIG_OFF + UserRole = EUserRole.TR_USERROLE_NORMAL }; } @@ -228,7 +228,10 @@ namespace Vocaluxe.Base.Server if (profile.Type >= 0 && profile.Type <= 1) { - newProfile.GuestProfile = (EOffOn)profile.Type; + var option = profile.Type == 0 ? EUserRole.TR_USERROLE_GUEST : EUserRole.TR_USERROLE_NORMAL; + //Only allow the change of TR_USERROLE_GUEST and TR_USERROLE_NORMAL + const EUserRole mask = EUserRole.TR_USERROLE_NORMAL; + newProfile.UserRole = (newProfile.UserRole & mask) | option; } if (!string.IsNullOrEmpty(profile.Password)) @@ -281,10 +284,11 @@ namespace Vocaluxe.Base.Server IsEditable = !isReadonly, ProfileId = profile.ID, PlayerName = profile.PlayerName, - Type = (int)profile.GuestProfile, + //Is TR_USERROLE_GUEST or TR_USERROLE_NORMAL? + Type = (profile.UserRole.HasFlag(EUserRole.TR_USERROLE_NORMAL)?1:0), Difficulty = (int)profile.Difficulty }; - + CAvatar avatar = profile.Avatar; if (avatar != null) { @@ -502,7 +506,7 @@ namespace Vocaluxe.Base.Server { throw new ArgumentException("invalid songId"); } - if (position < 0 || CPlaylists.Playlists[playlistId].Songs.Count <= position + if (position < 0 || CPlaylists.Playlists[playlistId].Songs.Count <= position || CPlaylists.Playlists[playlistId].Songs[position].SongID != songId) { throw new ArgumentException("invalid position"); @@ -521,7 +525,7 @@ namespace Vocaluxe.Base.Server { throw new ArgumentException("invalid songId"); } - + if (CPlaylists.Playlists[playlistId].Songs.Count < newPosition) { throw new ArgumentException("invalid newPosition"); @@ -673,7 +677,10 @@ namespace Vocaluxe.Base.Server throw new ArgumentException("Invalid profileId"); } - return profile.UserRoles; + //Hide TR_USERROLE_GUEST and TR_USERROLE_NORMAL + const EUserRole mask = (EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL); + + return (int)(profile.UserRole & ~mask); } private static void _SetUserRole(int profileId, int userRole) @@ -683,8 +690,14 @@ namespace Vocaluxe.Base.Server { throw new ArgumentException("Invalid profileId"); } - - profile.UserRoles = userRole; + + var option = (EUserRole)userRole; + + //Only allow the change of all options exept TR_USERROLE_GUEST and TR_USERROLE_NORMAL + const EUserRole mask = (EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL); + option &= ~mask; + + profile.UserRole = (profile.UserRole & mask) | option; CProfiles.EditProfile(profile); CProfiles.Update(); diff --git a/Vocaluxe/Screens/CPopupScreenServerQR.cs b/Vocaluxe/Screens/CPopupScreenServerQR.cs new file mode 100644 index 00000000..47400f17 --- /dev/null +++ b/Vocaluxe/Screens/CPopupScreenServerQR.cs @@ -0,0 +1,117 @@ +#region license +// This file is part of Vocaluxe. +// +// Vocaluxe is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Vocaluxe is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Vocaluxe. If not, see . +#endregion + +using ServerLib; +using Vocaluxe.Base; +using VocaluxeLib; +using VocaluxeLib.Menu; +using VocaluxeLib.Draw; +using QRCoder; + +namespace Vocaluxe.Screens +{ + class CPopupScreenServerQR : CMenu + { + // Version number for theme files. Increment it, if you've changed something on the theme files! + protected override int _ScreenVersion + { + get { return 1; } + } + + private CTexture _QRServerAddress; + private CTexture _QRAndroidLink; + private CTexture _QRSymbianLink; + private CTexture _QRWebOSLink; + private CTexture _QRWindowsPhoneLink; + + private const string _StaticQRServer = "StaticQRServer"; + private const string _StaticQRAndroid = "StaticQRAndroid"; + private const string _StaticQRSymbian = "StaticQRSymbian"; + private const string _StaticQRWebOS = "StaticQRWebOS"; + private const string _StaticQRWindowsPhone = "StaticQRWindowsPhone"; + + private const string _TextServerAddress = "TextServerAddress"; + + public override void Init() + { + base.Init(); + + _ThemeStatics = new string[] { _StaticQRServer, _StaticQRAndroid, _StaticQRSymbian, _StaticQRWebOS, _StaticQRWindowsPhone }; + _ThemeTexts = new string[] { _TextServerAddress }; + } + + public override void LoadTheme(string xmlPath) + { + base.LoadTheme(xmlPath); + _GenerateQRs(); + _Statics[_StaticQRServer].Texture = _QRServerAddress; + _Statics[_StaticQRAndroid].Texture = _QRAndroidLink; + _Statics[_StaticQRSymbian].Texture = _QRSymbianLink; + _Statics[_StaticQRWebOS].Texture = _QRWebOSLink; + _Statics[_StaticQRWindowsPhone].Texture = _QRWindowsPhoneLink; + _Texts[_TextServerAddress].Text = CServer.GetLocalAddress() + ":" + CConfig.ServerPort; + } + + public override bool HandleMouse(SMouseEvent mouseEvent) + { + if (mouseEvent.LB) + { + CGraphics.HidePopup(EPopupScreens.PopupServerQR); + return true; + } + return false; + } + + public override bool UpdateGame() + { + return true; + } + + public override bool Draw() + { + if (!_Active) + return false; + + return base.Draw(); + } + + private void _GenerateQRs() + { + QRCodeGenerator qr = new QRCodeGenerator(); + + //ServerAddress + QRCodeGenerator.QRCode qrcode = qr.CreateQrCode(CServer.GetLocalAddress() + ":" + CConfig.ServerPort, QRCodeGenerator.ECCLevel.H); + _QRServerAddress = CDraw.AddTexture(qrcode.GetGraphic(20)); + + //Android + qrcode = qr.CreateQrCode(CSettings.LinkAndroidApp, QRCodeGenerator.ECCLevel.H); + _QRAndroidLink = CDraw.AddTexture(qrcode.GetGraphic(20)); + + //Symbian + qrcode = qr.CreateQrCode(CSettings.LinkSymbianApp, QRCodeGenerator.ECCLevel.H); + _QRSymbianLink = CDraw.AddTexture(qrcode.GetGraphic(20)); + + //WebOS + qrcode = qr.CreateQrCode(CSettings.LinkWebOSApp, QRCodeGenerator.ECCLevel.H); + _QRWebOSLink = CDraw.AddTexture(qrcode.GetGraphic(20)); + + //WindowsPhone + qrcode = qr.CreateQrCode(CSettings.LinkWindowsPhoneApp, QRCodeGenerator.ECCLevel.H); + _QRWindowsPhoneLink = CDraw.AddTexture(qrcode.GetGraphic(20)); + } + } +} diff --git a/Vocaluxe/Screens/CScreenOptionsGame.cs b/Vocaluxe/Screens/CScreenOptionsGame.cs index 16d2f30e..4ed5c752 100644 --- a/Vocaluxe/Screens/CScreenOptionsGame.cs +++ b/Vocaluxe/Screens/CScreenOptionsGame.cs @@ -27,7 +27,7 @@ namespace Vocaluxe.Screens // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion { - get { return 1; } + get { return 2; } } private const string _SelectSlideLanguage = "SelectSlideLanguage"; @@ -38,12 +38,13 @@ namespace Vocaluxe.Screens private const string _SelectSlideTimerMode = "SelectSlideTimerMode"; private const string _ButtonExit = "ButtonExit"; + private const string _ButtonServer = "ButtonServer"; public override void Init() { base.Init(); - _ThemeButtons = new string[] {_ButtonExit}; + _ThemeButtons = new string[] {_ButtonExit, _ButtonServer}; _ThemeSelectSlides = new string[] {_SelectSlideLanguage, _SelectSlideDebugLevel, _SelectSlideSongMenu, _SelectSlideSongSorting, _SelectSlideTabs, _SelectSlideTimerMode}; } @@ -86,6 +87,8 @@ namespace Vocaluxe.Screens _SaveConfig(); CGraphics.FadeTo(EScreens.ScreenOptions); } + else if (_Buttons[_ButtonServer].Selected) + CGraphics.ShowPopup(EPopupScreens.PopupServerQR); break; case Keys.Left: @@ -112,9 +115,13 @@ namespace Vocaluxe.Screens if (mouseEvent.LB && _IsMouseOver(mouseEvent)) { - _SaveConfig(); if (_Buttons[_ButtonExit].Selected) + { CGraphics.FadeTo(EScreens.ScreenOptions); + _SaveConfig(); + } + else if (_Buttons[_ButtonServer].Selected) + CGraphics.ShowPopup(EPopupScreens.PopupServerQR); } return true; } diff --git a/Vocaluxe/Screens/CScreenProfiles.cs b/Vocaluxe/Screens/CScreenProfiles.cs index 24aef79b..7e567a38 100644 --- a/Vocaluxe/Screens/CScreenProfiles.cs +++ b/Vocaluxe/Screens/CScreenProfiles.cs @@ -40,13 +40,13 @@ namespace Vocaluxe.Screens // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion { - get { return 2; } + get { return 3; } } private const string _SelectSlideProfiles = "SelectSlideProfiles"; private const string _SelectSlideDifficulty = "SelectSlideDifficulty"; private const string _SelectSlideAvatars = "SelectSlideAvatars"; - private const string _SelectSlideGuestProfile = "SelectSlideGuestProfile"; + private const string _SelectSlideUserRole = "SelectSlideUserRole"; private const string _SelectSlideActive = "SelectSlideActive"; private const string _ButtonPlayerName = "ButtonPlayerName"; private const string _ButtonExit = "ButtonExit"; @@ -73,7 +73,7 @@ namespace Vocaluxe.Screens _ThemeButtons = new string[] {_ButtonPlayerName, _ButtonExit, _ButtonSave, _ButtonNew, _ButtonDelete, _ButtonWebcam, _ButtonSaveSnapshot, _ButtonDiscardSnapshot, _ButtonTakeSnapshot}; - _ThemeSelectSlides = new string[] {_SelectSlideProfiles, _SelectSlideDifficulty, _SelectSlideAvatars, _SelectSlideGuestProfile, _SelectSlideActive}; + _ThemeSelectSlides = new string[] {_SelectSlideProfiles, _SelectSlideDifficulty, _SelectSlideAvatars, _SelectSlideUserRole, _SelectSlideActive}; _ThemeStatics = new string[] {_StaticAvatar}; _EditMode = EEditMode.None; @@ -91,7 +91,7 @@ namespace Vocaluxe.Screens _Buttons[_ButtonTakeSnapshot].Visible = false; _Buttons[_ButtonWebcam].Visible = CWebcam.IsDeviceAvailable(); _SelectSlides[_SelectSlideDifficulty].SetValues(0); - _SelectSlides[_SelectSlideGuestProfile].SetValues(0); + _SelectSlides[_SelectSlideUserRole].SetValues(0); _SelectSlides[_SelectSlideActive].SetValues(0); _Statics[_StaticAvatar].Aspect = EAspect.Crop; } @@ -176,10 +176,10 @@ namespace Vocaluxe.Screens CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex, _SelectSlides[_SelectSlideAvatars].ValueIndex); } - else if (_SelectSlides[_SelectSlideGuestProfile].Selected) + else if (_SelectSlides[_SelectSlideUserRole].Selected) { - CProfiles.SetGuestProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex, - (EOffOn)_SelectSlides[_SelectSlideGuestProfile].Selection); + CProfiles.SetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex, + (EUserRole)_SelectSlides[_SelectSlideUserRole].Selection); } else if (_SelectSlides[_SelectSlideActive].Selected) { @@ -225,10 +225,10 @@ namespace Vocaluxe.Screens if (CWebcam.IsDeviceAvailable() && _WebcamTexture != null) _OnDiscardSnapshot(); } - else if (_SelectSlides[_SelectSlideGuestProfile].Selected) + else if (_SelectSlides[_SelectSlideUserRole].Selected) { - CProfiles.SetGuestProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex, - (EOffOn)_SelectSlides[_SelectSlideGuestProfile].Selection); + CProfiles.SetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex, + (EUserRole)_SelectSlides[_SelectSlideUserRole].Selection); } else if (_SelectSlides[_SelectSlideActive].Selected) { @@ -265,7 +265,7 @@ namespace Vocaluxe.Screens _Buttons[_ButtonPlayerName].Text.Text += "|"; _SelectSlides[_SelectSlideDifficulty].Selection = (int)CProfiles.GetDifficulty(_SelectSlides[_SelectSlideProfiles].ValueIndex); - _SelectSlides[_SelectSlideGuestProfile].Selection = (int)CProfiles.GetGuestProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex); + _SelectSlides[_SelectSlideUserRole].Selection = (int)CProfiles.GetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex); _SelectSlides[_SelectSlideActive].Selection = (int)CProfiles.GetActive(_SelectSlides[_SelectSlideProfiles].ValueIndex); int avatarID = CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].ValueIndex); @@ -428,7 +428,7 @@ namespace Vocaluxe.Screens if (!keep) { _SelectSlides[_SelectSlideDifficulty].Selection = (int)CProfiles.GetDifficulty(selectedProfileID); - _SelectSlides[_SelectSlideGuestProfile].Selection = (int)CProfiles.GetGuestProfile(selectedProfileID); + _SelectSlides[_SelectSlideUserRole].Selection = (int)CProfiles.GetUserRoleProfile(selectedProfileID); _SelectSlides[_SelectSlideActive].Selection = (int)CProfiles.GetActive(selectedProfileID); _SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(CProfiles.GetAvatarID(selectedProfileID)); } diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs index b1e06b1e..af7525f5 100644 --- a/Vocaluxe/Screens/CScreenScore.cs +++ b/Vocaluxe/Screens/CScreenScore.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Windows.Forms; using Vocaluxe.Base; +using Vocaluxe.Base.Server; using VocaluxeLib; using VocaluxeLib.Game; using VocaluxeLib.Menu; @@ -42,6 +43,8 @@ namespace Vocaluxe.Screens private const string _ScreenSettingShortDifficulty = "ScreenSettingShortDifficulty"; private const string _ScreenSettingAnimationDirection = "ScreenSettingAnimationDirection"; + private CBackground _SlideShowBG; + private string[,] _TextNames; private string[,] _TextScores; private string[,] _TextRatings; @@ -53,6 +56,7 @@ namespace Vocaluxe.Screens private int _Round; private CPoints _Points; private Stopwatch _Timer; + private bool _SlideShowBGAvailable; public override void Init() { @@ -72,6 +76,8 @@ namespace Vocaluxe.Screens _ThemeScreenSettings = new string[] {_ScreenSettingShortScore, _ScreenSettingShortRating, _ScreenSettingShortDifficulty, _ScreenSettingAnimationDirection}; _StaticPointsBarDrawnPoints = new double[CSettings.MaxNumPlayer]; + + _SlideShowBG = GetNewBackground(); } public override bool HandleInput(SKeyEvent keyEvent) @@ -125,6 +131,7 @@ namespace Vocaluxe.Screens _SetVisibility(); _UpdateRatings(); + _SlideShowBGAvailable = _UpdateBackground(); } public override bool UpdateGame() @@ -176,7 +183,11 @@ namespace Vocaluxe.Screens public override bool Draw() { - base.Draw(); + if (_SlideShowBGAvailable) + _SlideShowBG.Draw(); + else + base._DrawBG(); + base._DrawFG(); return true; } @@ -409,12 +420,22 @@ namespace Vocaluxe.Screens CSong song = CSongs.GetSong(players[p].SongID); CDataBase.IncreaseSongCounter(song.DataBaseSongID); song.NumPlayed++; + song.NumPlayedSession++; break; } } } } + private bool _UpdateBackground() + { + string[] photos = CVocaluxeServer.getPhotosOfThisRound(); + _SlideShowBG.RemoveSlideShowTextures(); + foreach (string photo in photos) + _SlideShowBG.AddSlideShowTexture(photo); + return photos.Length > 0; + } + private void _LeaveScreen() { CParty.LeavingScore(); diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index e792ba4e..e5c610d3 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -119,6 +119,8 @@ namespace Vocaluxe.Screens private bool _Pause; private bool _Webcam; + private CBackground _SlideShow; + public override void Init() { base.Init(); @@ -474,6 +476,8 @@ namespace Vocaluxe.Screens CDraw.DrawTexture(background, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, 0f), background.Color, new SRectF(bounds.X, bounds.Y, bounds.Width, bounds.Height, 0f)); } + else if (_SlideShow != null) + _SlideShow.Draw(); } _DrawBG(); @@ -557,6 +561,9 @@ namespace Vocaluxe.Screens } CDraw.RemoveTexture(ref _Background); + if(_SlideShow != null) + _SlideShow.RemoveSlideShowTextures(); + _Lyrics[_LyricMain].Clear(); _Lyrics[_LyricSub].Clear(); _Lyrics[_LyricMainDuet].Clear(); @@ -622,8 +629,18 @@ namespace Vocaluxe.Screens } CDraw.RemoveTexture(ref _Background); - if (!String.IsNullOrEmpty(song.BackgroundFileName)) - _Background = CDraw.AddTexture(Path.Combine(song.Folder, song.BackgroundFileName)); + if (song.BackgroundFileNames.Count > 1) + { + _SlideShow = GetNewBackground(); + foreach(string bgFile in song.BackgroundFileNames) + _SlideShow.AddSlideShowTexture(Path.Combine(song.Folder, bgFile)); + _Background = null; + } + else if (song.BackgroundFileNames.Count == 1) + { + if (!String.IsNullOrEmpty(song.BackgroundFileNames[0])) + _Background = CDraw.AddTexture(Path.Combine(song.Folder, song.BackgroundFileNames[0])); + } _SingNotes[_SingBars].Reset(); diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 2dec4b8e..69fdef19 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -1,4 +1,4 @@ - + DebugWin @@ -191,6 +191,10 @@ ..\Output\OpenTK.GLControl.dll + + False + ..\Output\QRCoder.dll + @@ -239,6 +243,7 @@ + diff --git a/Vocaluxe/Website/index.html b/Vocaluxe/Website/index.html index 256db6f1..987d8c49 100644 --- a/Vocaluxe/Website/index.html +++ b/Vocaluxe/Website/index.html @@ -329,10 +329,16 @@
- - - - + + + + + + + + + +
diff --git a/Vocaluxe/Website/js/main.js b/Vocaluxe/Website/js/main.js index bfc14a85..5334e726 100644 --- a/Vocaluxe/Website/js/main.js +++ b/Vocaluxe/Website/js/main.js @@ -7,34 +7,24 @@ var playlistRequestName = ""; var customSelectPlaylistSongCallback = null; var sessionId = ""; var serverBaseAddress = ""; -var tranlationLoaded; if (document.location.protocol == "file:") { if (typeof (window.deviceAndJqmLoaded) == "undefined") { window.deviceAndJqmLoaded = $.Deferred(); } window.deviceAndJqmLoaded.done(function () { - preStart(); + start(); }); } else { $(document).ready(function () { - preStart(); - }); -} - -function preStart() { - tranlationLoaded = $.Deferred(); - - initTranslation(); - - tranlationLoaded.done(function () { - translate(); start(); }); } + function start() { replaceTransitionHandler(); + initTranslation(); initPageLoadHandler(); initKeyboardPageHandler(); initMainPageHandler(); @@ -410,13 +400,28 @@ function initPageLoadHandler() { var promise = request({ url: "getUserRole?profileId=" + profileIdRequest }).done(function (result) { - $('#roleAdministrator').prop("checked", ((result & 0x01) != 0)).checkboxradio("refresh"); + var userRoles = { + TR_USERROLE_ADMIN: 2, + TR_USERROLE_KEYBOARDUSER: 4, + TR_USERROLE_ADDSONGSUSER: 8, + TR_USERROLE_PLAYLISTEDITOR: 16, + TR_USERROLE_PROFILEEDITOR: 32 + }; + + for (var roleName in userRoles) { + $('#' + roleName).prop("checked", ((result & userRoles[roleName]) != 0)).checkboxradio("refresh"); + } + $('#btnRoleSave').unbind('click').click(function () { var role = 0; - if ($('#roleAdministrator').prop("checked")) { - role = (role | 0x01); + + for (var roleName2 in userRoles) { + if ($('#' + roleName2).prop("checked")) { + role = (role | userRoles[roleName2]); + } } + request({ url: "setUserRole?profileId=" + profileIdRequest + "&userRole=" + role, headers: { "session": sessionId } @@ -1239,24 +1244,185 @@ function showWikipedia(artist) { } function initTranslation() { - $.i18n.init({ - resGetPath: 'locales/__lng__.json', - supportedLngs: ['en', 'de'], - fallbackLng: 'en', - keyseparator: '::', - nsseparator: ':::' - }).done(function () { - tranlationLoaded.resolve(); - }); -} + var translations = { + "en": { + translation: { + 'loginName': 'User:', + 'loginPassword': 'Password:', + 'loginButton': 'Login', + 'registerButton': 'Create Profile', + 'discoverReadQrButton': 'Scan QRCode', + 'mainPageYourProfileLink': 'Your Profile', + 'mainPageYourProfileLinkDesc': 'Edit your profile', + 'mainPageCurrentSongLink': 'Current Song', + 'mainPageCurrentSongLinkDesc': 'Display informations about the current song', + 'mainPageSelectSong': 'All songs', + 'mainPageSelectSongDesc': 'Lists all available songs', + 'mainPageSelectPlaylist': 'All playlists', + 'mainPageSelectPlaylistDesc': 'Lists all playlists', + 'mainPageSelectProfile': 'Profiles', + 'mainPageSelectProfileDesc': 'Shows all profiles', + 'mainPageTakePhotoLink': 'Take Photo', + 'mainPageTakePhotoLinkDesc': 'Takes a photo and displays it at the end of the current round', + 'mainPageKeyboard': 'Keyboard', + 'mainPageKeyboardDesc': 'Send keys', + 'mainPageSelectUserAdmin': 'Administration', + 'mainPageSelectUserAdminDesc': 'Configure user rights', + 'mainPageLogoutLink': 'Logout', + 'mainPageLogoutLinkDesc': 'Closes the session', + 'selectProfileHeader': 'All profiles', + 'displayProfileHeader': 'Profile', + 'displayProfileName': 'Name:', + 'displayProfilePlayerType': 'Player Type:', + 'displayProfilePlayerTypeNormal': 'Normal', + 'displayProfilePlayerTypeGuest': 'Guest', + 'displayProfilePlayerDifficulty': 'Difficulty:', + 'displayProfilePlayerDifficultyEasy': 'Easy', + 'displayProfilePlayerDifficultyNormal': 'Normal', + 'displayProfilePlayerDifficultyHard': 'Hard', + 'displayProfilePlayerPassword': 'New Password:', + 'displayProfilePlayerSaveButton': 'Save and upload', + 'displaySongHeader': 'No current song', + 'displaySongArtist': 'Artist:', + 'displaySongGenre': 'Genre:', + 'displaySongYear': 'Year:', + 'displaySongLanguage': 'Language:', + 'displaySongIsDuet': 'Duet:', + 'popupVideoClose': 'Close', + 'selectSongHeader': 'All songs', + 'keyboardHeader': 'Keyboard', + 'keyboardButtonUp': 'up', + 'keyboardButtonLeft': 'left', + 'keyboardButtonRight': 'right', + 'keyboardButtonDown': 'down', + 'keyboardButtonEscape': 'escape', + 'keyboardButtonTab': 'tab', + 'keyboardButtonReturn': 'return', + 'keyboardButtonKeys': 'To send other keys type here:', + 'selectUserAdminHeader': 'All profiles', + 'displayUserAdminHeader': 'Profile', + 'displayUserAdminContentSaveButton': 'Save', + 'selectPlaylistHeader': 'Select a playlist', + 'displayPlaylistHeader': 'Playlist', + 'displayPlaylistSaveButton': 'Save', + 'selectPlaylistAddPlaylistButton': 'Add', + 'Loading (external)...': 'Loading (external)...', + 'Loading...': 'Loading...', + 'Error...': 'Error...', + 'No connection': 'No connection', + 'No session': 'No session', + 'Uploading photo...': 'Uploading photo...', + 'Getting current song...': 'Getting current song...', + 'Login...': 'Login...', + 'Creating profile...': 'Creating profile...', + 'This is not a valid name.': 'This is not a valid name.', + 'Uploading profile...': 'Uploading profile...', + 'songs': 'songs', + 'YourName': 'YourName', + 'discoverConnectHeader': 'Connect to server', + 'discoverConnectServerAddress': 'Serveraddress:', + 'discoverConnectButton': 'Connect', + 'Checking...': 'Checking...', + 'timeout': 'Timeout' + } + }, + "de": { + translation: { + 'loginName': 'Benutzer:', + 'loginPassword': 'Passwort:', + 'loginButton': 'Einloggen', + 'registerButton': 'Erstelle Profil', + 'discoverReadQrButton': 'Fotografiere QRCode', + 'mainPageYourProfileLink': 'Dein Profil', + 'mainPageYourProfileLinkDesc': 'Bearbeite dein Profil', + 'mainPageCurrentSongLink': 'Aktuelles Lied', + 'mainPageCurrentSongLinkDesc': 'Zeigt Informationen über das aktuelle Lied an', + 'mainPageSelectSong': 'Alle Lieder', + 'mainPageSelectSongDesc': 'Listet alle verfügbaren Lieder auf', + 'mainPageSelectPlaylist': 'Alle Playlisten', + 'mainPageSelectPlaylistDesc': 'Listet alle verfügbaren Playlisten auf', + 'mainPageSelectProfile': 'Profile', + 'mainPageSelectProfileDesc': 'Listet alle Profile auf', + 'mainPageTakePhotoLink': 'Nehme Foto auf', + 'mainPageTakePhotoLinkDesc': 'Nimmt ein Foto auf und zeigt es am ende der Runde an', + 'mainPageKeyboard': 'Tastatur', + 'mainPageKeyboardDesc': 'Sende Tastatureingaben', + 'mainPageSelectUserAdmin': 'Administration', + 'mainPageSelectUserAdminDesc': 'Konfiguriere die Benutzerrechte', + 'mainPageLogoutLink': 'Abmelden', + 'mainPageLogoutLinkDesc': 'Beendet diese Sitzung', + 'selectProfileHeader': 'Alle Profile', + 'displayProfileHeader': 'Profile', + 'displayProfileName': 'Name:', + 'displayProfilePlayerType': 'Player Typ:', + 'displayProfilePlayerTypeNormal': 'Normal', + 'displayProfilePlayerTypeGuest': 'Gast', + 'displayProfilePlayerDifficulty': 'Schwierigkeit:', + 'displayProfilePlayerDifficultyEasy': 'Einfach', + 'displayProfilePlayerDifficultyNormal': 'Normal', + 'displayProfilePlayerDifficultyHard': 'Schwer', + 'displayProfilePlayerPassword': 'Neues Passwort:', + 'displayProfilePlayerSaveButton': 'Speichern und hochladen', + 'displaySongHeader': 'Kein aktuelles Lied', + 'displaySongArtist': 'Künstler:', + 'displaySongGenre': 'Genre:', + 'displaySongYear': 'Jahr:', + 'displaySongLanguage': 'Sprache:', + 'displaySongIsDuet': 'Duet:', + 'popupVideoClose': 'Schließen', + 'selectSongHeader': 'Alle Lieder', + 'keyboardHeader': 'Tastatur', + 'keyboardButtonUp': 'hoch', + 'keyboardButtonLeft': 'links', + 'keyboardButtonRight': 'rechts', + 'keyboardButtonDown': 'runter', + 'keyboardButtonEscape': 'Escape', + 'keyboardButtonTab': 'Tab', + 'keyboardButtonReturn': 'Enter', + 'keyboardButtonKeys': 'Um andere Zeichen zu senden, hier tippen:', + 'selectUserAdminHeader': 'Alle Profile', + 'displayUserAdminHeader': 'Profile', + 'displayUserAdminContentSaveButton': 'Speichern', + 'selectPlaylistHeader': 'Wähle eine Playlist', + 'displayPlaylistHeader': 'Playlist', + 'displayPlaylistSaveButton': 'Speichern', + 'selectPlaylistAddPlaylistButton': 'Hinzufügen', + 'Loading (external)...': 'Laden (extern)...', + 'Loading...': 'Laden...', + 'Error...': 'Fehler...', + 'No connection': 'Keine Verbindung', + 'No session': 'Keine Sitzung', + 'Uploading photo...': 'Foto hochladen...', + 'Getting current song...': 'Lade aktuelles Lied...', + 'Login...': 'Einloggen...', + 'Creating profile...': 'Erstelle Profil...', + 'This is not a valid name.': 'Dies ist kein gültiger Name.', + 'Uploading profile...': 'Profil hochladen...', + 'songs': 'Lieder', + 'YourName': 'DeinName', + 'discoverConnectHeader': 'Verbinde zum Server', + 'discoverConnectServerAddress': 'Serveradresse:', + 'discoverConnectButton': 'Verbinden', + 'Checking...': 'Prüfen...', + 'timeout': 'Zeitüberschreitung' + } + } + }; -function translate() { //repair broken buttons on the first page (get broken while translating) var repairButtons = function () { $($('#discoverConnect')[0].childNodes).wrap(' '); $($('#discoverReadQr')[0].childNodes).wrap(' '); }; - - $('body').i18n(); - repairButtons(); + + $.i18n.init({ + resStore: translations, + supportedLngs: ['en', 'de'], + fallbackLng: 'en', + keyseparator: '::', + nsseparator: ':::' + }).done(function () { + $('body').i18n(); + repairButtons(); + }); } \ No newline at end of file diff --git a/VocaluxeLib/Enums.cs b/VocaluxeLib/Enums.cs index 97e008a8..b3f78439 100644 --- a/VocaluxeLib/Enums.cs +++ b/VocaluxeLib/Enums.cs @@ -345,7 +345,20 @@ namespace VocaluxeLib { PopupPlayerControl = 0, PopupVolumeControl = 1, + PopupServerQR = 2, NoPopup = -1 } + + [Flags] + public enum EUserRole + { + TR_USERROLE_GUEST = 0, + TR_USERROLE_NORMAL = 1, + TR_USERROLE_ADMIN = 2, + TR_USERROLE_KEYBOARDUSER = 4, + TR_USERROLE_ADDSONGSUSER = 8, + TR_USERROLE_PLAYLISTEDITOR = 16, + TR_USERROLE_PROFILEEDITOR = 32 + } } \ No newline at end of file diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index b64e5e60..ac8ed878 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -86,6 +86,9 @@ namespace VocaluxeLib string GetFolderProfiles(); string GetDataPath(); + + float GetSlideShowImageTime(); + float GetSlideShowFadeTime(); } public interface ITheme diff --git a/VocaluxeLib/Menu/CBackground.cs b/VocaluxeLib/Menu/CBackground.cs index 2e77ffc7..7049bac9 100644 --- a/VocaluxeLib/Menu/CBackground.cs +++ b/VocaluxeLib/Menu/CBackground.cs @@ -18,6 +18,8 @@ using System; using System.Drawing; using System.Xml; +using System.Diagnostics; +using System.Collections.Generic; using VocaluxeLib.Draw; namespace VocaluxeLib.Menu @@ -27,6 +29,7 @@ namespace VocaluxeLib.Menu None, Color, Texture, + SlideShow, Video } @@ -36,6 +39,8 @@ namespace VocaluxeLib.Menu public EBackgroundTypes Type; + public List SlideShowTextures; + public string VideoName; public string TextureName; @@ -48,6 +53,10 @@ namespace VocaluxeLib.Menu private SThemeBackground _Theme; private bool _ThemeLoaded; + private int _SlideShowCurrent; + private Stopwatch _SlideShowTimer = new Stopwatch(); + private List _SlideShowTextures = new List(); + public SColorF Color; public string GetThemeName() @@ -61,6 +70,7 @@ namespace VocaluxeLib.Menu _PartyModeID = partyModeID; _ThemeLoaded = false; _Theme = new SThemeBackground(); + _Theme.SlideShowTextures = new List(); Color = new SColorF(0f, 0f, 0f, 1f); } @@ -92,6 +102,17 @@ namespace VocaluxeLib.Menu _ThemeLoaded &= success; } + string slideShow = ""; + int i = 1; + + while (xmlReader.ItemExists(item + "/SlideShow" + i)) + { + xmlReader.GetValue(item + "/SlideShow" + i, out slideShow, String.Empty); + if (slideShow != "") + _Theme.SlideShowTextures.Add(slideShow); + i++; + } + if (_ThemeLoaded) { _Theme.Name = elementName; @@ -115,6 +136,12 @@ namespace VocaluxeLib.Menu writer.WriteComment(": Background Texture name"); writer.WriteElementString("Skin", _Theme.TextureName); + writer.WriteComment(": Texture name for slide-show"); + for (int i = 0; i < _Theme.SlideShowTextures.Count; i++) + { + writer.WriteElementString("SlideShow" + (i + 1), _Theme.SlideShowTextures[i]); + } + writer.WriteComment(": Background color for type \"Color\" from ColorScheme (high priority)"); writer.WriteComment("or , , , (lower priority)"); if (!String.IsNullOrEmpty(_Theme.ColorName)) @@ -164,6 +191,11 @@ namespace VocaluxeLib.Menu ok = _DrawVideo(); } + if (_Theme.Type == EBackgroundTypes.SlideShow ) + { + ok = _DrawSlideShow(); + } + if (!String.IsNullOrEmpty(_Theme.TextureName) && (_Theme.Type == EBackgroundTypes.Texture || (_Theme.Type == EBackgroundTypes.Video && (CBase.Config.GetVideoBackgrounds() == EOffOn.TR_CONFIG_OFF || !ok)))) @@ -176,12 +208,36 @@ namespace VocaluxeLib.Menu return true; } - public void UnloadTextures() {} + public void UnloadTextures() { _SlideShowTextures.Clear(); } public void LoadTextures() { if (!String.IsNullOrEmpty(_Theme.ColorName)) Color = CBase.Theme.GetColor(_Theme.ColorName, _PartyModeID); + + foreach (string s in _Theme.SlideShowTextures) + _SlideShowTextures.Add(CBase.Theme.GetSkinTexture(s, _PartyModeID)); + } + + public void AddSlideShowTexture(string image) + { + _Theme.Type = EBackgroundTypes.SlideShow; + if (!String.IsNullOrEmpty(image)) + { + CTexture texture = CBase.Drawing.AddTexture(image); + if(texture != null) + _SlideShowTextures.Add(texture); + } + } + + public void RemoveSlideShowTextures() + { + foreach (CTexture tex in _SlideShowTextures) + { + CTexture texture = tex; + CBase.Drawing.RemoveTexture(ref texture); + } + _SlideShowTextures.Clear(); } public void ReloadTextures() @@ -214,6 +270,58 @@ namespace VocaluxeLib.Menu return false; } + private bool _DrawSlideShow() + { + if (_SlideShowTextures.Count > 0) + { + if (!_SlideShowTimer.IsRunning) + { + _SlideShowTimer.Start(); + _SlideShowCurrent = 0; + } + + if (_SlideShowTimer.ElapsedMilliseconds >= (CBase.Settings.GetSlideShowFadeTime() + CBase.Settings.GetSlideShowImageTime())) + { + _SlideShowTimer.Restart(); + if (_SlideShowCurrent + 1 < _SlideShowTextures.Count) + _SlideShowCurrent++; + else if (_SlideShowCurrent != 0) + _SlideShowCurrent = 0; + } + + CTexture texture = _SlideShowTextures[_SlideShowCurrent]; + + if (texture == null) + return false; + + var bounds = new RectangleF(0f, 0f, CBase.Settings.GetRenderW(), CBase.Settings.GetRenderH()); + RectangleF rect; + CHelper.SetRect(bounds, out rect, texture.OrigAspect, EAspect.Crop); + + CBase.Drawing.DrawTexture(texture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, CBase.Settings.GetZFar() / 4)); + + if (_SlideShowTimer.ElapsedMilliseconds >= CBase.Settings.GetSlideShowImageTime()) + { + if (_SlideShowCurrent + 1 < _SlideShowTextures.Count) + texture = _SlideShowTextures[_SlideShowCurrent + 1]; + else if (_SlideShowCurrent != 0) + texture = _SlideShowTextures[0]; + else + texture = null; + + if (texture != null) + { + float alpha = (_SlideShowTimer.ElapsedMilliseconds - CBase.Settings.GetSlideShowImageTime()) / CBase.Settings.GetSlideShowFadeTime(); + CHelper.SetRect(bounds, out rect, texture.OrigAspect, EAspect.Crop); + CBase.Drawing.DrawTexture(texture, new SRectF(rect.X, rect.Y, rect.Width, rect.Height, (CBase.Settings.GetZFar() / 4) - 1), new SColorF(1,1,1, alpha)); + } + } + + return true; + } + return false; + } + private bool _DrawVideo() { CTexture videoTexture = CBase.Theme.GetSkinVideoTexture(_Theme.VideoName, _PartyModeID); diff --git a/VocaluxeLib/Menu/CNameSelection.cs b/VocaluxeLib/Menu/CNameSelection.cs index d162d539..bb1df5b2 100644 --- a/VocaluxeLib/Menu/CNameSelection.cs +++ b/VocaluxeLib/Menu/CNameSelection.cs @@ -370,7 +370,7 @@ namespace VocaluxeLib.Menu _Player = player; _PlayerSelector.Color = CBase.Theme.GetPlayerColor(player); } - //Normal activation + //Normal activation else if (active) { Selection = 0; @@ -379,7 +379,7 @@ namespace VocaluxeLib.Menu _PlayerSelector.Color = CBase.Theme.GetPlayerColor(player); _PlayerSelector.Visible = true; } - //Deactivate + //Deactivate else { Selection = -1; @@ -456,7 +456,7 @@ namespace VocaluxeLib.Menu return new CStatic(_PartyModeID); } - public void UnloadTextures() {} + public void UnloadTextures() { } public void LoadTextures() { @@ -486,7 +486,7 @@ namespace VocaluxeLib.Menu for (int j = 0; j < _NumW; j++) { var rect = new SRectF(Rect.X + j * (_TileW + _SpaceW), Rect.Y + i * (_TileH + _SpaceH), _TileW, _TileH, Rect.Z); - var tileStatic = new CStatic(_PartyModeID, _TextureEmptyTile, ColorEmptyTile, rect) {Aspect = EAspect.Crop}; + var tileStatic = new CStatic(_PartyModeID, _TextureEmptyTile, ColorEmptyTile, rect) { Aspect = EAspect.Crop }; var tileText = new CText(rect.X + rect.W / 2, rect.Y + rect.H + _Theme.NameSpace, rect.Z, _Theme.NameHeight, rect.W, EAlignment.Center, _Theme.NameStyle, _Theme.NameFont, _Theme.NameColor, ""); _Tiles.Add(new CTile(tileStatic, tileText, -1)); @@ -508,7 +508,8 @@ namespace VocaluxeLib.Menu for (int p = 0; p < CBase.Game.GetNumPlayer(); p++) { //Don't show profile if is selected, but if selected and guest - if (CBase.Game.GetPlayers()[p].ProfileID == profile.ID && profile.GuestProfile == EOffOn.TR_CONFIG_OFF) + if (CBase.Game.GetPlayers()[p].ProfileID == profile.ID + && profile.UserRole.HasFlag(EUserRole.TR_USERROLE_GUEST)) visible = false; } } diff --git a/VocaluxeLib/Profile/CProfile.cs b/VocaluxeLib/Profile/CProfile.cs index 466de93f..21b10e03 100644 --- a/VocaluxeLib/Profile/CProfile.cs +++ b/VocaluxeLib/Profile/CProfile.cs @@ -32,7 +32,6 @@ namespace VocaluxeLib.Profile public string AvatarFileName; public byte[] PasswordHash; public byte[] PasswordSalt; - public int UserRoles; public EGameDifficulty Difficulty; @@ -47,7 +46,7 @@ namespace VocaluxeLib.Profile } } - public EOffOn GuestProfile; + public EUserRole UserRole; public EOffOn Active; public CProfile() @@ -55,7 +54,7 @@ namespace VocaluxeLib.Profile PlayerName = String.Empty; Difficulty = EGameDifficulty.TR_CONFIG_EASY; Avatar = new CAvatar(-1); - GuestProfile = EOffOn.TR_CONFIG_OFF; + UserRole = EUserRole.TR_USERROLE_NORMAL; Active = EOffOn.TR_CONFIG_ON; AvatarFileName = String.Empty; @@ -88,7 +87,7 @@ namespace VocaluxeLib.Profile xmlReader.TryGetEnumValue("//root/Info/Difficulty", ref Difficulty); xmlReader.GetValue("//root/Info/Avatar", out AvatarFileName, String.Empty); - xmlReader.TryGetEnumValue("//root/Info/GuestProfile", ref GuestProfile); + xmlReader.TryGetEnumValue("//root/Info/UserRole", ref UserRole); xmlReader.TryGetEnumValue("//root/Info/Active", ref Active); string passwordHash; xmlReader.GetValue("//root/Info/PasswordHash", out passwordHash, ""); @@ -96,9 +95,6 @@ namespace VocaluxeLib.Profile string passwordSalt; xmlReader.GetValue("//root/Info/PasswordSalt", out passwordSalt, ""); PasswordSalt = !string.IsNullOrEmpty(passwordSalt) ? Convert.FromBase64String(passwordSalt) : null; - string userRoles; - xmlReader.GetValue("//root/Info/UserRoles", out userRoles, "0"); - Int32.TryParse(userRoles, out UserRoles); return true; } @@ -157,7 +153,7 @@ namespace VocaluxeLib.Profile writer.WriteElementString("PlayerName", PlayerName); writer.WriteElementString("Difficulty", Enum.GetName(typeof(EGameDifficulty), Difficulty)); writer.WriteElementString("Avatar", Path.GetFileName(Avatar.FileName)); - writer.WriteElementString("GuestProfile", Enum.GetName(typeof(EOffOn), GuestProfile)); + writer.WriteElementString("UserRole", Enum.GetName(typeof(EUserRole), UserRole)); writer.WriteElementString("Active", Enum.GetName(typeof(EOffOn), Active)); if (PasswordHash != null) { @@ -167,7 +163,6 @@ namespace VocaluxeLib.Profile { writer.WriteElementString("PasswordSalt", Convert.ToBase64String(PasswordSalt)); } - writer.WriteElementString("UserRoles", UserRoles.ToString()); writer.WriteEndElement(); writer.WriteEndElement(); //end of root diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs index aa0ced4b..d2c393e8 100644 --- a/VocaluxeLib/Songs/CSong.cs +++ b/VocaluxeLib/Songs/CSong.cs @@ -97,7 +97,7 @@ namespace VocaluxeLib.Songs public string MP3FileName = String.Empty; public string CoverFileName = String.Empty; - public string BackgroundFileName = String.Empty; + public List BackgroundFileNames = new List(); public string VideoFileName = String.Empty; public EAspect VideoAspect = EAspect.Crop; @@ -174,6 +174,7 @@ namespace VocaluxeLib.Songs public int DataBaseSongID = -1; public string DateAdded = ""; public int NumPlayed; + public int NumPlayedSession; // Notes public readonly CNotes Notes = new CNotes(); @@ -226,7 +227,7 @@ namespace VocaluxeLib.Songs MP3FileName = song.MP3FileName; CoverFileName = song.CoverFileName; - BackgroundFileName = song.BackgroundFileName; + BackgroundFileNames = song.BackgroundFileNames; VideoFileName = song.VideoFileName; VideoAspect = song.VideoAspect; @@ -266,6 +267,7 @@ namespace VocaluxeLib.Songs DataBaseSongID = song.DataBaseSongID; DateAdded = song.DateAdded; NumPlayed = song.NumPlayed; + NumPlayedSession = song.NumPlayedSession; Notes = new CNotes(song.Notes); } @@ -328,7 +330,7 @@ namespace VocaluxeLib.Songs } } - if (BackgroundFileName == "") + if (BackgroundFileNames.Count == 0) { List files = CHelper.ListFiles(Folder, "*.jpg"); files.AddRange(CHelper.ListFiles(Folder, "*.jpeg")); @@ -338,7 +340,7 @@ namespace VocaluxeLib.Songs { if (file.ContainsIgnoreCase("[BG]") && (file.ContainsIgnoreCase(Title) || file.ContainsIgnoreCase(Artist))) - BackgroundFileName = file; + BackgroundFileNames.Add(file); } } } diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs index 597398d4..4556b776 100644 --- a/VocaluxeLib/Songs/CSongLoader.cs +++ b/VocaluxeLib/Songs/CSongLoader.cs @@ -243,7 +243,7 @@ namespace VocaluxeLib.Songs break; case "BACKGROUND": if (File.Exists(Path.Combine(_Song.Folder, value))) - _Song.BackgroundFileName = value; + _Song.BackgroundFileNames.Add(value); else _LogWarning("Can't find background file: " + Path.Combine(_Song.Folder, value)); break; diff --git a/VocaluxeLib/Songs/CSongWriter.cs b/VocaluxeLib/Songs/CSongWriter.cs index 906c358f..9d7328b7 100644 --- a/VocaluxeLib/Songs/CSongWriter.cs +++ b/VocaluxeLib/Songs/CSongWriter.cs @@ -74,7 +74,7 @@ namespace VocaluxeLib.Songs _WriteHeaderEntry("YEAR", _Song.Year); _WriteHeaderEntry("MP3", _Song.MP3FileName); _WriteHeaderEntry("COVER", _Song.CoverFileName); - _WriteHeaderEntry("BACKGROUND", _Song.BackgroundFileName); + _WriteHeaderEntrys("BACKGROUND", _Song.BackgroundFileNames); _WriteHeaderEntry("VIDEO", _Song.VideoFileName); _WriteHeaderEntry("VIDEOGAP", _Song.VideoGap); if (_Song.VideoAspect != EAspect.Crop)