User/Roles for webserver

This commit is contained in:
lukeIam committed 2013-12-13 17:43:13 +01:00
1 parent c41af99536
commit 3126d5aaf0
13 files changed
+1134 -604

No files matched your search

+47 -3
View File
@@ -94,6 +94,45 @@ namespace ServerLib
}
#endregion
#region user management
private static SetPasswordDelegate setPassword;
public static SetPasswordDelegate SetPassword
{
internal get { return CServer.setPassword; }
set { CServer.setPassword = value; }
}
private static ValidatePasswordDelegate validatePassword;
public static ValidatePasswordDelegate ValidatePassword
{
internal get { return CServer.validatePassword; }
set { CServer.validatePassword = value; }
}
private static GetUserRoleDelegate getUserRole;
public static GetUserRoleDelegate GetUserRole
{
internal get { return CServer.getUserRole; }
set { CServer.getUserRole = value; }
}
private static SetUserRoleDelegate setUserRole;
public static SetUserRoleDelegate SetUserRole
{
internal get { return CServer.setUserRole; }
set { CServer.setUserRole = value; }
}
private static GetUserIdFromUsernameDelegate getUserIdFromUsername;
public static GetUserIdFromUsernameDelegate GetUserIdFromUsername
{
internal get { return CServer.getUserIdFromUsername; }
set { CServer.getUserIdFromUsername = value; }
}
#endregion
public CServer(int port, bool encrypted)
@@ -101,6 +140,8 @@ namespace ServerLib
init(port, encrypted);
}
#region server control
private void init(int port, bool encrypted)
{
string hostname = Dns.GetHostName();
@@ -178,7 +219,7 @@ namespace ServerLib
private void registerUrlAndCert(int port)
{
#if WIN
#if WIN
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "WebserverInitalConfig.exe";
@@ -194,11 +235,14 @@ namespace ServerLib
p.Close();
}
#else
#else
//Required?
#endif
#endif
}
#endregion
}
}
+95 -3
View File
@@ -6,6 +6,7 @@ using System.Text;
using System.ServiceModel.Web;
using System.Web.Services;
using System.IO;
using System.ServiceModel.Channels;
namespace ServerLib
{
@@ -20,6 +21,12 @@ namespace ServerLib
#region profile
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getOwnProfileId")]
int getOwnProfileId();
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
@@ -53,6 +60,12 @@ namespace ServerLib
#region website
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/login?username={username}&password={password}")]
Guid login(string username, string password);
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
@@ -114,8 +127,35 @@ namespace ServerLib
{
}
private static Guid getSession()
{
Guid sessionKey = Guid.Empty;
string sessionHeader =
((HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties["httpRequest"]).Headers["session"];
if (sessionHeader == null || sessionHeader == "")
{
return sessionKey;
}
try
{
sessionKey = Guid.Parse(sessionHeader);
}
catch (Exception e)
{
}
return sessionKey;
}
public bool sendKeyEvent(string key)
{
Guid sessionKey = getSession();
if (sessionKey == Guid.Empty || !SessionControl.requestRight(sessionKey, UserRights.UseKeyboard))
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Forbidden;
return false;
}
if (CServer.SendKeyEvent == null)
{
return false;
@@ -125,22 +165,58 @@ namespace ServerLib
#region profile
public int getOwnProfileId()
{
Guid sessionKey = getSession();
if (sessionKey == Guid.Empty)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Forbidden;
return -1;
}
return SessionControl.getUserIdFromSession(sessionKey);
}
public bool sendProfile(ProfileData profile)
{
if (CServer.SendProfileData == null)
Guid sessionKey = getSession();
if (sessionKey == Guid.Empty || (!SessionControl.requestRight(sessionKey, UserRights.EditAllProfiles) &&
SessionControl.getUserIdFromSession(sessionKey) != profile.ProfileId))
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Forbidden;
return false;
}
if (CServer.SendProfileData == null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
return false;
}
return CServer.SendProfileData(profile);
}
public ProfileData getProfile(int profileId)
{
Guid sessionKey = getSession();
if (sessionKey == Guid.Empty || (!SessionControl.requestRight(sessionKey, UserRights.ViewOtherProfiles) &&
SessionControl.getUserIdFromSession(sessionKey) != profileId))
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Forbidden;
return new ProfileData();
}
if (CServer.GetProfileData == null)
{
return new ProfileData();
}
return CServer.GetProfileData(profileId);
bool isReadonly = (!SessionControl.requestRight(sessionKey, UserRights.EditAllProfiles) &&
SessionControl.getUserIdFromSession(sessionKey) != profileId);
return CServer.GetProfileData(profileId, isReadonly);
}
public ProfileData[] getProfileList()
@@ -158,6 +234,13 @@ namespace ServerLib
public bool sendPhoto(PhotoData photo)
{
Guid sessionKey = getSession();
if (!SessionControl.requestRight(sessionKey, UserRights.UploadPhotos))
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Forbidden;
return false;
}
return CServer.SendPhoto(photo);
}
@@ -165,6 +248,16 @@ namespace ServerLib
#region website
public Guid login(string username, string password)
{
Guid sessionId = SessionControl.openSession(username, password);
if (sessionId == Guid.Empty)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Forbidden;
}
return sessionId;
}
public Stream Index()
{
if (WebOperationContext.Current != null)
@@ -277,6 +370,5 @@ namespace ServerLib
}
#endregion
}
}
+15 -1
View File
@@ -15,7 +15,7 @@ namespace ServerLib
#region profile
public delegate ProfileData GetProfileDataDelegate(int profileId);
public delegate ProfileData GetProfileDataDelegate(int profileId, bool isReadonly);
public delegate bool SendProfileDataDelegate(ProfileData profile);
public delegate ProfileData[] GetProfileListDelegate();
@@ -121,4 +121,18 @@ namespace ServerLib
}
#endregion
#region user management
public delegate void SetPasswordDelegate(int profileId, string newPassword);
public delegate bool ValidatePasswordDelegate(int profileId, string password);
public delegate int GetUserRoleDelegate(int profileId);
public delegate void SetUserRoleDelegate(int profileId, int userRole);
public delegate int GetUserIdFromUsernameDelegate(string username);
#endregion
}
@@ -52,6 +52,11 @@
<Compile Include="CWebservice.cs" />
<Compile Include="DataStructs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Session.cs" />
<Compile Include="SessionControl.cs" />
<Compile Include="UserRights.cs" />
<Compile Include="UserRoleControl.cs" />
<Compile Include="UserRoles.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ServerLib
{
internal class Session
{
Guid id;
public Guid Id
{
get { return id; }
}
int profileId;
public int ProfileId
{
get { return profileId; }
}
UserRoles roles;
internal UserRoles Roles
{
get { return roles; }
}
public Session(Guid id, int profileId, UserRoles roles)
{
this.id = id;
this.profileId = profileId;
this.roles = roles;
}
}
}
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ServerLib
{
internal static class SessionControl
{
private static Dictionary<Guid, Session> activeSessions = new Dictionary<Guid, Session>();
public static Guid openSession(string userName, string password)
{
if (!validateUserAndPassword(userName, password))
{
return Guid.Empty;
}
Guid newId = Guid.NewGuid();
int id = getProfileIdFormUsername(userName);
UserRoles roles = getUserRoles(id);
Session session = new Session(newId, id, roles);
invalidateSessions(id);
activeSessions.Add(newId, session);
return newId;
}
private static bool validateUserAndPassword(string userName, string password)
{
return CServer.ValidatePassword(getProfileIdFormUsername(userName), password);
}
private static int getProfileIdFormUsername(string username)
{
return CServer.GetUserIdFromUsername(username);
}
private static UserRoles getUserRoles(int profileId)
{
return (UserRoles)CServer.GetUserRole(profileId);
}
internal static void invalidateSessions(int profileId)
{
foreach (var s in (from kv in activeSessions
where kv.Value.ProfileId == profileId
select kv).ToList())
{
activeSessions.Remove(s.Key);
}
}
internal static bool requestRight(Guid sessionId, UserRights requestedRight)
{
return ((UserRoleControl.getUserRightsFromUserRole(activeSessions[sessionId].Roles) & requestedRight) != 0);
}
internal static int getUserIdFromSession(Guid sessionId)
{
return activeSessions[sessionId].ProfileId;
}
}
}
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ServerLib
{
[Flags]
internal enum UserRights
{
None = 0x00,
EditAllProfiles = 0x01,
UploadPhotos = 0x02,
ViewOtherProfiles = 0x04,
UseKeyboard = 0x08
}
}
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ServerLib
{
internal static class UserRoleControl
{
private static Dictionary<UserRoles, UserRights> roleRightsMapping = new Dictionary<UserRoles, UserRights> {
{UserRoles.Administrator,
(UserRights.EditAllProfiles|
UserRights.UploadPhotos|
UserRights.ViewOtherProfiles)|
UserRights.UseKeyboard},
{UserRoles.AuthenticatedUser,
(UserRights.UploadPhotos|
UserRights.ViewOtherProfiles|
UserRights.UseKeyboard)}
};
internal static UserRights getUserRightsFromUserRole(UserRoles userRole)
{
UserRights resultRights = UserRights.None;
foreach (UserRights r in roleRightsMapping.Where(role => userRole.HasFlag(role.Key)).Select(role => role.Value))
{
resultRights |= r;
}
return resultRights;
}
}
}
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ServerLib
{
[Flags]
internal enum UserRoles
{
AuthenticatedUser = 0x00,
Administrator = 0x01
}
}
+148 -7
View File
@@ -29,6 +29,7 @@ using Vocaluxe.Lib.Input;
using VocaluxeLib;
using VocaluxeLib.Profile;
using VocaluxeLib.Songs;
using System.Security.Cryptography;
namespace Vocaluxe.Base.Server
{
@@ -44,9 +45,9 @@ namespace Vocaluxe.Base.Server
{
_Clients = new Dictionary<int, CClientHandler>();
_Server = new CServer(CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON);
_Server = new CServer(CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON);
//_Server = new CServer(RequestHandler, CConfig.ServerPort, CConfig.ServerPassword);
CServer.SendKeyEvent = sendKeyEvent;
CServer.GetProfileData = getProfileData;
CServer.SendProfileData = sendProfileData;
@@ -56,6 +57,11 @@ namespace Vocaluxe.Base.Server
CServer.GetSong = getSong;
CServer.GetAllSongs = getAllSongs;
CServer.GetCurrentSongId = getCurrentSongId;
CServer.SetPassword = setPassword;
CServer.ValidatePassword = validatePassword;
CServer.GetUserRole = getUserRole;
CServer.SetUserRole = setUserRole;
CServer.GetUserIdFromUsername = getUserIdFromUsername;
_Discover = new CDiscover(CConfig.ServerPort, CCommands.BroadcastKeyword);
Controller.Init();
@@ -148,14 +154,14 @@ namespace Vocaluxe.Base.Server
#region profile
private static ProfileData getProfileData(int profileId)
private static ProfileData getProfileData(int profileId, bool isReadonly)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
return new ProfileData();
}
return CreateProfileData(profile); ;
return CreateProfileData(profile, isReadonly); ;
}
private static bool sendProfileData(ProfileData profile)
@@ -226,17 +232,17 @@ namespace Vocaluxe.Base.Server
foreach (CProfile profile in CProfiles.GetProfiles())
{
result.Add(CreateProfileData(profile));
result.Add(CreateProfileData(profile, true));
}
return result.ToArray();
}
private static ProfileData CreateProfileData(CProfile profile)
private static ProfileData CreateProfileData(CProfile profile, bool isReadonly)
{
ProfileData profileData = new ProfileData();
profileData.IsEditable = true; //TODO: set correctly
profileData.IsEditable = !isReadonly;
profileData.ProfileId = profile.ID;
profileData.PlayerName = profile.PlayerName;
profileData.Type = (int)profile.GuestProfile;
@@ -369,6 +375,141 @@ namespace Vocaluxe.Base.Server
#endregion
#region user management
private static void setPassword(int profileId, string newPassword)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
throw new ArgumentException("Invalid profileId");
}
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buffer = new byte[128];
rng.GetNonZeroBytes(buffer);
byte[] salt = buffer;
byte[] hashedPassword = hash((new System.Text.UTF8Encoding()).GetBytes(newPassword), salt);
profile.PasswordSalt = salt;
profile.PasswordHash = hashedPassword;
}
private static bool validatePassword(int profileId, string password)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
throw new ArgumentException("Invalid profileId");
}
if (profile.PasswordHash == null)
{
if (password == "" || password == null)
{
return true; //Allow emty passwords
}
else
{
return false;
}
}
byte[] salt = profile.PasswordSalt;
return hash((new System.Text.UTF8Encoding()).GetBytes(password), salt).SequenceEqual(profile.PasswordHash);
}
private static bool validatePassword(int profileId, byte[] hashedPassword)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
throw new ArgumentException("Invalid profileId");
}
if (profile.PasswordHash == null)
{
if (hashedPassword == null)
{
return true; //Allow emty passwords
}
else
{
return false;
}
}
byte[] salt = profile.PasswordSalt;
return hashedPassword.SequenceEqual(profile.PasswordHash);
}
private static byte[] getPassowordSalt(int profileId)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
throw new ArgumentException("Invalid profileId");
}
if (profile.PasswordHash == null)
{
throw new ArgumentException("Emty password");
}
return profile.PasswordSalt;
}
private static int getUserRole(int profileId)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
throw new ArgumentException("Invalid profileId");
}
return profile.UserRoles;
}
private static void setUserRole(int profileId, int userRole)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
throw new ArgumentException("Invalid profileId");
}
profile.UserRoles = userRole;
}
private static int getUserIdFromUsername(string username)
{
var playerIds = (from p in CProfiles.GetProfiles()
where String.Equals(p.PlayerName, username,StringComparison.OrdinalIgnoreCase)
select p.ID);
if (playerIds.Count() == 0)
{
throw new ArgumentException("Invalid playername");
}
return playerIds.First();
}
private static byte[] hash(byte[] password, byte[] salt)
{
HashAlgorithm hashAlgo = new SHA256Managed();
byte[] data = new byte[password.Length + salt.Length];
password.CopyTo(data, 0);
salt.CopyTo(data, password.Length);
return hashAlgo.ComputeHash(data);
}
#endregion
private static string _SaveImage(Base64Image imageDate, string name, string folder)
{
Image avatarImage = imageDate.getImage();
+230 -228
View File
@@ -1,228 +1,230 @@
<!DOCTYPE html>
<html>
<head>
<title>Vocaluxe</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/jquery.mobile-1.3.2.min.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/jquery.mobile-1.3.2.min.js"></script>
<script src="js/main.js"></script>
</head>
<body>
<div id="login" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>Login</h1>
</div>
<!-- /header -->
<div id="loginContent" data-role="content">
<label for="playerName" class="input">Id:</label>
<input type="text" id="playerId" name="playerId" data-mini="true">
<br />
<a data-role="button" id="loginButton">Login</a>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="main" data-role="page" data-content-theme="a">
<div data-role="header">
<h1>Volcaluxe</h1>
</div>
<!-- /header -->
<div id="mainContent" data-role="content" data-add-back-btn="true">
<ul data-role="listview">
<li>
<a id="yourProfileLink" href="#" data-transition="slidefade">
<img src="img/profile.png">
<h2>Your Profile</h2>
<p>Edit your profile</p>
</a>
</li>
<li>
<a id="currentSongLink" href="#" data-transition="slidefade">
<img src="img/music.png">
<h2>Current Song</h2>
<p>Display informations about the current song</p>
</a>
</li>
<li>
<a href="#selectSong" data-transition="slidefade">
<img src="img/playlist.png">
<h2>All songs</h2>
<p>List all available songs</p>
</a>
</li>
<li>
<a href="#selectProfile" data-transition="slidefade">
<img src="img/profiles.png">
<h2>Profiles</h2>
<p>Shows all profiles</p>
</a>
</li>
<li>
<a id="mainPageTakePhotoLink" href="#" data-transition="slidefade">
<img src="img/photo.png">
<h2>Take Photo</h2>
<p>Takes a photo and displays it at the end of the current round</p>
</a>
</li>
<li>
<a href="#keyboard" data-transition="slidefade">
<img src="img/keyboard.png">
<h2>Keyboard</h2>
<p>Send keys</p>
</a>
</li>
<li>
<a href="#" data-transition="slidefade">
<img src="img/admin.png">
<h2>Administration</h2>
<p>Configure options and rights</p>
</a>
</li>
</ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="selectProfile" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>All profiles</h1>
</div>
<!-- /header -->
<div id="selectProfileContent" data-role="content">
<ul id="selectProfileList" data-role="listview"></ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="displayProfile" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>Profile</h1>
</div>
<!-- /header -->
<div id="displayProfileContent" data-role="content">
<img id="playerAvatar" src="img/profile.png" alt="Avatar">
<label for="playerName" class="input">Name:</label>
<input type="text" id="playerName" name="playerName" data-mini="true" value="Your Name">
<label for="playerType" class="select">Player Type:</label>
<select name="playerType" id="playerType">
<option value="0">Normal</option>
<option value="1">Guest</option>
</select>
<label for="playerDifficulty" class="select">Difficulty:</label>
<select name="playerDifficulty" id="playerDifficulty">
<option value="0">Easy</option>
<option value="1">Normal</option>
<option value="2">Hard</option>
</select>
<br />
<a data-role="button" id="playerSaveButton">Save and upload</a>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="displaySong" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1 id="displaySongTitle">No current song</h1>
</div>
<!-- /header -->
<div id="displaySongContent" data-role="content">
<img id="displaySongCover" src="img/noCover.png" alt="Cover">
<br />
<br />
<br />
<label for="displaySongArtist" class="input">Artist:</label>
<span id="displaySongArtist" data-mini="true">-</span>
<br />
<label for="displaySongGenre" class="input">Genre:</label>
<span id="displaySongGenre" data-mini="true">-</span>
<br />
<label for="displaySongYear" class="input">Year:</label>
<span id="displaySongYear" data-mini="true">-</span>
<br />
<label for="displaySongLanguage" class="input">Language:</label>
<span id="displaySongLanguage" data-mini="true">-</span>
<br />
<label for="displaySongIsDuet" class="input">Duet:</label>
<span id="displaySongIsDuet" data-mini="true">-</span>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="selectSong" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>All songs</h1>
</div>
<!-- /header -->
<div id="selectSongContent" data-role="content">
<ul id="selectSongList" data-role="listview" data-filter="true" data-autodividers="true"></ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="keyboard" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>Keyboard</h1>
</div>
<!-- /header -->
<div id="keyboardContent" data-role="content">
<div class="ui-grid-b">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonUp">up</a>
</div>
<div class="ui-block-c"></div>
<div class="ui-block-a">
<a data-role="button" id="keyboardButtonLeft">left</a>
</div>
<div class="ui-block-b">
</div>
<div class="ui-block-c">
<a data-role="button" id="keyboardButtonRight">right</a>
</div>
<div class="ui-block-a"></div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonDown">down</a>
</div>
<div class="ui-block-c"></div>
</div>
<div class="ui-grid-b">
<div class="ui-block-a">
<a data-role="button" id="keyboardButtonEscape">escape</a>
</div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonTab">tab</a>
</div>
<div class="ui-block-c">
<a data-role="button" id="keyboardButtonReturn">return</a>
</div>
</div>
<div>
<label for="keyboardButtonKeys">To send other keys type here:</label>
<input type="text" id="keyboardButtonKeys" data-mini="true">
</div>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div class="ui-loader-background"></div>
</body>
</html>
<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<title>Vocaluxe</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/jquery.mobile-1.3.2.min.css" />
<link rel="stylesheet" href="css/style.css" />
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/jquery.mobile-1.3.2.min.js"></script>
<script src="js/main.js"></script>
</head>
<body>
<div id="login" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>Login</h1>
</div>
<!-- /header -->
<div id="loginContent" data-role="content">
<label for="loginName" class="input">User:</label>
<input type="text" id="loginName" name="loginName" data-mini="true">
<label for="loginPassword" class="input">Password:</label>
<input type="text" id="loginPassword" name="loginPassword" data-mini="true">
<br />
<a data-role="button" id="loginButton">Login</a>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="main" data-role="page" data-content-theme="a">
<div data-role="header">
<h1>Volcaluxe</h1>
</div>
<!-- /header -->
<div id="mainContent" data-role="content" data-add-back-btn="true">
<ul data-role="listview">
<li>
<a id="yourProfileLink" href="#" data-transition="slidefade">
<img src="img/profile.png">
<h2>Your Profile</h2>
<p>Edit your profile</p>
</a>
</li>
<li>
<a id="currentSongLink" href="#" data-transition="slidefade">
<img src="img/music.png">
<h2>Current Song</h2>
<p>Display informations about the current song</p>
</a>
</li>
<li>
<a href="#selectSong" data-transition="slidefade">
<img src="img/playlist.png">
<h2>All songs</h2>
<p>List all available songs</p>
</a>
</li>
<li>
<a href="#selectProfile" data-transition="slidefade">
<img src="img/profiles.png">
<h2>Profiles</h2>
<p>Shows all profiles</p>
</a>
</li>
<li>
<a id="mainPageTakePhotoLink" href="#" data-transition="slidefade">
<img src="img/photo.png">
<h2>Take Photo</h2>
<p>Takes a photo and displays it at the end of the current round</p>
</a>
</li>
<li>
<a href="#keyboard" data-transition="slidefade">
<img src="img/keyboard.png">
<h2>Keyboard</h2>
<p>Send keys</p>
</a>
</li>
<li>
<a href="#" data-transition="slidefade">
<img src="img/admin.png">
<h2>Administration</h2>
<p>Configure options and rights</p>
</a>
</li>
</ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="selectProfile" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>All profiles</h1>
</div>
<!-- /header -->
<div id="selectProfileContent" data-role="content">
<ul id="selectProfileList" data-role="listview"></ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="displayProfile" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>Profile</h1>
</div>
<!-- /header -->
<div id="displayProfileContent" data-role="content">
<img id="playerAvatar" src="img/profile.png" alt="Avatar">
<label for="playerName" class="input">Name:</label>
<input type="text" id="playerName" name="playerName" data-mini="true" value="Your Name">
<label for="playerType" class="select">Player Type:</label>
<select name="playerType" id="playerType">
<option value="0">Normal</option>
<option value="1">Guest</option>
</select>
<label for="playerDifficulty" class="select">Difficulty:</label>
<select name="playerDifficulty" id="playerDifficulty">
<option value="0">Easy</option>
<option value="1">Normal</option>
<option value="2">Hard</option>
</select>
<br />
<a data-role="button" id="playerSaveButton">Save and upload</a>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="displaySong" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1 id="displaySongTitle">No current song</h1>
</div>
<!-- /header -->
<div id="displaySongContent" data-role="content">
<img id="displaySongCover" src="img/noCover.png" alt="Cover">
<br />
<br />
<br />
<label for="displaySongArtist" class="input">Artist:</label>
<span id="displaySongArtist" data-mini="true">-</span>
<br />
<label for="displaySongGenre" class="input">Genre:</label>
<span id="displaySongGenre" data-mini="true">-</span>
<br />
<label for="displaySongYear" class="input">Year:</label>
<span id="displaySongYear" data-mini="true">-</span>
<br />
<label for="displaySongLanguage" class="input">Language:</label>
<span id="displaySongLanguage" data-mini="true">-</span>
<br />
<label for="displaySongIsDuet" class="input">Duet:</label>
<span id="displaySongIsDuet" data-mini="true">-</span>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="selectSong" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>All songs</h1>
</div>
<!-- /header -->
<div id="selectSongContent" data-role="content">
<ul id="selectSongList" data-role="listview" data-filter="true" data-autodividers="true"></ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="keyboard" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>Keyboard</h1>
</div>
<!-- /header -->
<div id="keyboardContent" data-role="content">
<div class="ui-grid-b">
<div class="ui-block-a"></div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonUp">up</a>
</div>
<div class="ui-block-c"></div>
<div class="ui-block-a">
<a data-role="button" id="keyboardButtonLeft">left</a>
</div>
<div class="ui-block-b">
</div>
<div class="ui-block-c">
<a data-role="button" id="keyboardButtonRight">right</a>
</div>
<div class="ui-block-a"></div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonDown">down</a>
</div>
<div class="ui-block-c"></div>
</div>
<div class="ui-grid-b">
<div class="ui-block-a">
<a data-role="button" id="keyboardButtonEscape">escape</a>
</div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonTab">tab</a>
</div>
<div class="ui-block-c">
<a data-role="button" id="keyboardButtonReturn">return</a>
</div>
</div>
<div>
<label for="keyboardButtonKeys">To send other keys type here:</label>
<input type="text" id="keyboardButtonKeys" data-mini="true">
</div>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div class="ui-loader-background"></div>
</body>
</html>
<!DOCTYPE html>
+423 -360
View File
@@ -1,360 +1,423 @@
var ownProfileId = -1;
var profileIdRequest = -1;
var songIdRequest = -1
var allSongsCache = null;
$(document).ready(function () {
replaceTransitionHandler();
initPageLoadHandler();
initKeyboardPageHandler();
initMainPageHandler();
initLoginPageHandler();
});
function replaceTransitionHandler() {
//Thx to http://stackoverflow.com/a/14096311
var oldDefaultTransitionHandler = $.mobile.defaultTransitionHandler;
$.mobile.defaultTransitionHandler = function (name, reverse, $to, $from) {
var promise = $to.data('promise');
if (promise) {
$to.removeData('promise');
$.mobile.loading('show');
return promise.then(function () {
$.mobile.loading('hide');
return oldDefaultTransitionHandler(name, reverse, $to, $from);
});
}
return oldDefaultTransitionHandler(name, reverse, $to, $from);
};
}
function initPageLoadHandler() {
//pageLoadHandler for displayProfile
$(document).on('pagebeforeshow', '#displayProfile', function () {
var promise = $.ajax({
url: "getProfile?profileId=" + profileIdRequest
}).done(function (result) {
$('#playerName').prop("value", result.PlayerName);
if (result.Avatar && result.Avatar.base64Data) {
$('#playerAvatar').prop("src", result.Avatar.base64Data);
}
$('#playerType').prop("value", result.Type);
$('#playerDifficulty').prop("value", result.Difficulty);
if (result.IsEditable) {
$('#playerAvatar').click(function () {
if ($('#captureContainer').length > 0) {
$('#captureContainer').remove();
}
$(document.body).append('<div id="captureContainer" style="height: 0px;width:0px; overflow:hidden;"> <input type="file" accept="image/*" id="capture" capture> </div>');
$('#capture').change(function (eventData) {
if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) {
var file = eventData.target.files[0];
var reader = new FileReader();
reader.onloadend = function (e) {
$('#playerAvatar').prop("src", e.target.result);
$('#playerAvatar').data("changed", true);
$('#captureContainer').remove();
};
reader.readAsDataURL(file);
}
});
$('#capture').click();
});
$('#playerSaveButton').click(function () {
var dataToUpload = {};
dataToUpload["ProfileId"] = profileIdRequest;
dataToUpload["PlayerName"] = $('#playerName').prop("value");
dataToUpload["Type"] = $('#playerType').prop("value");
dataToUpload["Difficulty"] = $('#playerDifficulty').prop("value");
dataToUpload["Avatar"] = $('#playerAvatar').data("changed") ? { "base64Data": $('#playerAvatar').prop("src") } : null;
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Uploading profile...',
textVisible: true
});
$.ajax({
url: "sendProfile",
dataType: "json",
contentType: "application/json;charset=utf-8",
type: "POST",
data: JSON.stringify(dataToUpload),
success: function (msg) {
}
}).always(function () {
$.mobile.loading('hide');
$('#content').unwrap();
});
});
}
else {
$('#playerName').prop('disabled', true);
$('#playerType').prop('disabled', true);
$('#playerDifficulty').prop('disabled', true);
$('#playerSaveButton').hide();
$('#playerAvatar').unbind("click");
}
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
});
//pageLoadHandler for selectProfile
$(document).on('pagebeforeshow', '#selectProfile', function () {
var promise = $.ajax({
url: "getProfileList"
}).done(function (data) {
$('#selectProfileList').children().remove();
function handleProfileSelectLineClick(e) {
profileIdRequest = parseInt(e.currentTarget.id.replace("ProfileSelectLine_", ""));
$.mobile.changePage("#displayProfile", { transition: "slidefade" });
}
for (var profile in data) {
$('<li id="ProfileSelectLine_' + data[profile].ProfileId + '"> <a href="#"> <img src="' + ((data[profile].Avatar && data[profile].Avatar.base64Data) ? data[profile].Avatar.base64Data : "img/profile.png") + '"> <h2>' + data[profile].PlayerName + '</h2> <p>Click here to show the profile of ' + data[profile].PlayerName + '</p> </a> </li>')
.appendTo('#selectProfileList')
.click(handleProfileSelectLineClick);
}
$('#selectProfileList').listview('refresh');
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
});
//pageLoadHandler for displaySong
$(document).on('pagebeforeshow', '#displaySong', function () {
var promise = $.ajax({
url: "getSong?songId=" + songIdRequest
}).done(function (result) {
if (result.Title != null) {
$('#displaySongTitle').text(result.Title);
}
else {
$('#displaySongTitle').text("No current song");
}
if (result.Cover && result.Cover.base64Data) {
$('#displaySongCover').prop("src", result.Cover.base64Data);
}
else {
$('#displaySongCover').prop("src", "img/noCover.png");
}
if (result.Artist != null) {
$('#displaySongArtist').text(result.Artist);
}
else {
$('#displaySongArtist').text("-");
}
if (result.Genre != null) {
$('#displaySongGenre').text(result.Genre);
}
else {
$('#displaySongGenre').text("-");
}
if (result.Year != null && result.Year != "") {
$('#displaySongYear').text(result.Year);
}
else {
$('#displaySongYear').text("-");
}
if (result.Language != null) {
$('#displaySongLanguage').text(result.Language);
}
else {
$('#displaySongLanguage').text("-");
}
$('#displaySongIsDuet').text(result.IsDuet ? "Yes" : "No");
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
});
//pageLoadHandler for selectSong
$(document).on('pagebeforeshow', '#selectSong', function () {
function handleGetAllSongs() {
$('#selectSongList').children().remove();
function handleSelectSongLineClick(e) {
songIdRequest = parseInt(e.currentTarget.id.replace("selectSongLine_", ""));
$.mobile.changePage("#displaySong", { transition: "slidefade" });
}
for (var id in allSongsCache) {
$('<li id="selectSongLine_' + allSongsCache[id].SongId + '"> <a href="#"> '/*+'<img src="' + ((data[profile].Avatar && data[profile].Avatar.base64Data) ? data[id].Avatar.base64Data : "img/profile.png") + '"> '*/ + ' <h2>' + allSongsCache[id].Artist + '</h2> <p>' + allSongsCache[id].Title + '</p> </a> </li>')
.appendTo('#selectSongList')
.click(handleSelectSongLineClick);
}
$('#selectSongList').listview('refresh');
}
if (allSongsCache == null) {
var promise = $.ajax({
url: "getAllSongs"
}).done(function (data) {
allSongsCache = data;
handleGetAllSongs()
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
}
else {
handleGetAllSongs()
}
});
}
function initLoginPageHandler() {
$('#loginButton').click(function () {
ownProfileId = parseInt($('#playerId').prop("value"));
if (ownProfileId != "NaN") {
$.mobile.changePage("#main", { transition: "slidefade" });
}
});
}
function initMainPageHandler() {
$('#yourProfileLink').click(function () {
profileIdRequest = ownProfileId;
$.mobile.changePage("#displayProfile", { transition: "slidefade" });
});
$('#currentSongLink').click(function () {
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Getting current song...',
textVisible: true
});
$.ajax({
url: "getCurrentSongId"
}).done(function (result) {
songIdRequest = parseInt(result);
$.mobile.loading('hide');
$('#content').unwrap();
$.mobile.changePage("#displaySong", { transition: "slidefade" });
}).fail(function (result) {
$.mobile.loading('hide');
$('#content').unwrap();
});
});
$('#mainPageTakePhotoLink').click(function () {
if ($('#captureContainer').length > 0) {
$('#captureContainer').remove();
}
$(document.body).append('<div id="captureContainer" style="height: 0px;width:0px; overflow:hidden;"> <input type="file" accept="image/*" id="capture" capture="camera"> </div>');
$('#capture').change(function (eventData) {
if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) {
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Uploading photo...',
textVisible: true
});
var file = eventData.target.files[0];
var reader = new FileReader();
reader.onloadend = function (e) {
$.ajax({
url: "sendPhoto",
dataType: "json",
contentType: "application/json;charset=utf-8",
type: "POST",
data: JSON.stringify({ Photo: { base64Data: e.target.result } }),
success: function (msg) {
}
}).always(function () {
$.mobile.loading('hide');
$('#content').unwrap();
});
};
reader.readAsDataURL(file);
}
});
$('#capture').click();
});
}
function initKeyboardPageHandler() {
$('#keyboardButtonUp').click(function () {
$.ajax({
url: "sendKeyEvent?key=up"
})
});
$('#keyboardButtonDown').click(function () {
$.ajax({
url: "sendKeyEvent?key=down"
})
});
$('#keyboardButtonLeft').click(function () {
$.ajax({
url: "sendKeyEvent?key=left"
})
});
$('#keyboardButtonRight').click(function () {
$.ajax({
url: "sendKeyEvent?key=right"
})
});
$('#keyboardButtonEscape').click(function () {
$.ajax({
url: "sendKeyEvent?key=escape"
})
});
$('#keyboardButtonkeyboardButtonTab').click(function () {
$.ajax({
url: "sendKeyEvent?key=tab"
})
});
$('#keyboardButtonReturn').click(function () {
$.ajax({
url: "sendKeyEvent?key=return"
})
});
$('#keyboardButtonKeys').keyup(function (e) {
var c = String.fromCharCode(e.keyCode);
if (c.match(/\w/)) {
c = e.keyCode >= 65 ? c.toLowerCase() : c;
$.ajax({
url: "sendKeyEvent?key=" + c
})
}
var oldText = $('#keyboardButtonKeys')[0].value;
if (oldText.length > 0) {
$('#keyboardButtonKeys')[0].value = oldText.slice(1);
}
});
}
var ownProfileId = -1;
var profileIdRequest = -1;
var songIdRequest = -1
var allSongsCache = null;
var sessionId = "";
$(document).ready(function () {
replaceTransitionHandler();
initPageLoadHandler();
initKeyboardPageHandler();
initMainPageHandler();
initLoginPageHandler();
});
function replaceTransitionHandler() {
//Thx to http://stackoverflow.com/a/14096311
var oldDefaultTransitionHandler = $.mobile.defaultTransitionHandler;
$.mobile.defaultTransitionHandler = function (name, reverse, $to, $from) {
var promise = $to.data('promise');
if (promise) {
$to.removeData('promise');
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Loading data...',
textVisible: true
});
return promise.then(function () {
$.mobile.loading('hide');
$('#content').unwrap();
return oldDefaultTransitionHandler(name, reverse, $to, $from);
});
}
return oldDefaultTransitionHandler(name, reverse, $to, $from);
};
}
function initPageLoadHandler() {
//pageLoadHandler for displayProfile
$(document).on('pagebeforeshow', '#displayProfile', function () {
var promise = $.ajax({
url: "getProfile?profileId=" + profileIdRequest,
headers: { "session": sessionId }
}).done(function (result) {
$('#playerName').prop("value", result.PlayerName);
if (result.Avatar && result.Avatar.base64Data) {
$('#playerAvatar').prop("src", result.Avatar.base64Data);
}
$('#playerType').prop("value", result.Type);
$('#playerDifficulty').prop("value", result.Difficulty);
if (result.IsEditable) {
$('#playerName').prop('disabled', false);
$('#playerType').prop('disabled', false);
$('#playerDifficulty').prop('disabled', false);
$('#playerSaveButton').show();
$('#playerAvatar').unbind("click");
$('#playerAvatar').click(function () {
if ($('#captureContainer').length > 0) {
$('#captureContainer').remove();
}
$(document.body).append('<div id="captureContainer" style="height: 0px;width:0px; overflow:hidden;"> <input type="file" accept="image/*" id="capture" capture> </div>');
$('#capture').change(function (eventData) {
if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) {
var file = eventData.target.files[0];
var reader = new FileReader();
reader.onloadend = function (e) {
$('#playerAvatar').prop("src", e.target.result);
$('#playerAvatar').data("changed", true);
$('#captureContainer').remove();
};
reader.readAsDataURL(file);
}
});
$('#capture').click();
});
$('#playerSaveButton').click(function () {
var dataToUpload = {};
dataToUpload["ProfileId"] = profileIdRequest;
dataToUpload["PlayerName"] = $('#playerName').prop("value");
dataToUpload["Type"] = $('#playerType').prop("value");
dataToUpload["Difficulty"] = $('#playerDifficulty').prop("value");
dataToUpload["Avatar"] = $('#playerAvatar').data("changed") ? { "base64Data": $('#playerAvatar').prop("src") } : null;
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Uploading profile...',
textVisible: true
});
$.ajax({
url: "sendProfile",
dataType: "json",
contentType: "application/json;charset=utf-8",
type: "POST",
headers: { "session": sessionId },
data: JSON.stringify(dataToUpload),
success: function (msg) {
}
}).always(function () {
$.mobile.loading('hide');
$('#content').unwrap();
});
});
}
else {
$('#playerName').prop('disabled', true);
$('#playerType').prop('disabled', true);
$('#playerDifficulty').prop('disabled', true);
$('#playerSaveButton').hide();
$('#playerAvatar').unbind("click");
}
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
});
//pageLoadHandler for selectProfile
$(document).on('pagebeforeshow', '#selectProfile', function () {
var promise = $.ajax({
url: "getProfileList",
headers: { "session": sessionId }
}).done(function (data) {
$('#selectProfileList').children().remove();
function handleProfileSelectLineClick(e) {
profileIdRequest = parseInt(e.currentTarget.id.replace("ProfileSelectLine_", ""));
$.mobile.changePage("#displayProfile", { transition: "slidefade" });
}
for (var profile in data) {
$('<li id="ProfileSelectLine_' + data[profile].ProfileId + '"> <a href="#"> <img src="' + ((data[profile].Avatar && data[profile].Avatar.base64Data) ? data[profile].Avatar.base64Data : "img/profile.png") + '"> <h2>' + data[profile].PlayerName + '</h2> <p>Click here to show the profile of ' + data[profile].PlayerName + '</p> </a> </li>')
.appendTo('#selectProfileList')
.click(handleProfileSelectLineClick);
}
$('#selectProfileList').listview('refresh');
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
});
//pageLoadHandler for displaySong
$(document).on('pagebeforeshow', '#displaySong', function () {
var promise = $.ajax({
url: "getSong?songId=" + songIdRequest,
headers: { "session": sessionId }
}).done(function (result) {
if (result.Title != null) {
$('#displaySongTitle').text(result.Title);
}
else {
$('#displaySongTitle').text("No current song");
}
if (result.Cover && result.Cover.base64Data) {
$('#displaySongCover').prop("src", result.Cover.base64Data);
}
else {
$('#displaySongCover').prop("src", "img/noCover.png");
}
if (result.Artist != null) {
$('#displaySongArtist').text(result.Artist);
}
else {
$('#displaySongArtist').text("-");
}
if (result.Genre != null) {
$('#displaySongGenre').text(result.Genre);
}
else {
$('#displaySongGenre').text("-");
}
if (result.Year != null && result.Year != "") {
$('#displaySongYear').text(result.Year);
}
else {
$('#displaySongYear').text("-");
}
if (result.Language != null) {
$('#displaySongLanguage').text(result.Language);
}
else {
$('#displaySongLanguage').text("-");
}
$('#displaySongIsDuet').text(result.IsDuet ? "Yes" : "No");
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
});
//pageLoadHandler for selectSong
$(document).on('pagebeforeshow', '#selectSong', function () {
function handleGetAllSongs() {
$('#selectSongList').children().remove();
function handleSelectSongLineClick(e) {
songIdRequest = parseInt(e.currentTarget.id.replace("selectSongLine_", ""));
$.mobile.changePage("#displaySong", { transition: "slidefade" });
}
for (var id in allSongsCache) {
$('<li id="selectSongLine_' + allSongsCache[id].SongId + '"> <a href="#"> '/*+'<img src="' + ((data[profile].Avatar && data[profile].Avatar.base64Data) ? data[id].Avatar.base64Data : "img/profile.png") + '"> '*/ + ' <h2>' + allSongsCache[id].Artist + '</h2> <p>' + allSongsCache[id].Title + '</p> </a> </li>')
.appendTo('#selectSongList')
.click(handleSelectSongLineClick);
}
$('#selectSongList').listview('refresh');
}
if (allSongsCache == null) {
var promise = $.ajax({
url: "getAllSongs",
headers: { "session": sessionId }
}).done(function (data) {
allSongsCache = data;
handleGetAllSongs()
});
// Save promise on page so the transition handler can find it.
$(this).data('promise', promise);
}
else {
handleGetAllSongs()
}
});
}
function initLoginPageHandler() {
var keyPressed = function (e) {
if (e.which == 13) {
$('#loginButton').click();
}
};
$('#loginName').keypress(keyPressed)
$('#loginPassword').keypress(keyPressed);
$('#loginButton').click(function () {
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Login...',
textVisible: true
});
username = $('#loginName').prop("value");
password = $('#loginPassword').prop("value");
$.ajax({
url: "login?username=" + username + "&password=" + password
}).done(function (result) {
sessionId = result;
$.ajax({
url: "getOwnProfileId",
headers: { "session": sessionId }
}).done(function (result) {
ownProfileId = result;
$.mobile.loading('hide');
$('#content').unwrap();
$.mobile.changePage("#main", { transition: "slidefade" });
}).fail(function (result) {
$.mobile.loading('hide');
$('#content').unwrap();
});
}).fail(function (result) {
$.mobile.loading('hide');
$('#content').unwrap();
});
});
}
function initMainPageHandler() {
$('#yourProfileLink').click(function () {
profileIdRequest = ownProfileId;
$.mobile.changePage("#displayProfile", { transition: "slidefade" });
});
$('#currentSongLink').click(function () {
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Getting current song...',
textVisible: true
});
$.ajax({
url: "getCurrentSongId",
headers: { "session": sessionId }
}).done(function (result) {
songIdRequest = parseInt(result);
$.mobile.loading('hide');
$('#content').unwrap();
$.mobile.changePage("#displaySong", { transition: "slidefade" });
}).fail(function (result) {
$.mobile.loading('hide');
$('#content').unwrap();
});
});
$('#mainPageTakePhotoLink').click(function () {
if ($('#captureContainer').length > 0) {
$('#captureContainer').remove();
}
$(document.body).append('<div id="captureContainer" style="height: 0px;width:0px; overflow:hidden;"> <input type="file" accept="image/*" id="capture" capture="camera"> </div>');
$('#capture').change(function (eventData) {
if (eventData && eventData.target && eventData.target.files && eventData.target.files.length == 1) {
$('#content').wrap('<div class="overlay" />');
$.mobile.loading('show', {
text: 'Uploading photo...',
textVisible: true
});
var file = eventData.target.files[0];
var reader = new FileReader();
reader.onloadend = function (e) {
$.ajax({
url: "sendPhoto",
dataType: "json",
contentType: "application/json;charset=utf-8",
type: "POST",
headers: { "session": sessionId },
data: JSON.stringify({ Photo: { base64Data: e.target.result } }),
success: function (msg) {
}
}).always(function () {
$.mobile.loading('hide');
$('#content').unwrap();
});
};
reader.readAsDataURL(file);
}
});
$('#capture').click();
});
}
function initKeyboardPageHandler() {
$('#keyboardButtonUp').click(function () {
$.ajax({
url: "sendKeyEvent?key=up",
headers: { "session": sessionId }
})
});
$('#keyboardButtonDown').click(function () {
$.ajax({
url: "sendKeyEvent?key=down",
headers: { "session": sessionId }
})
});
$('#keyboardButtonLeft').click(function () {
$.ajax({
url: "sendKeyEvent?key=left",
headers: { "session": sessionId }
})
});
$('#keyboardButtonRight').click(function () {
$.ajax({
url: "sendKeyEvent?key=right",
headers: { "session": sessionId }
})
});
$('#keyboardButtonEscape').click(function () {
$.ajax({
url: "sendKeyEvent?key=escape",
headers: { "session": sessionId }
})
});
$('#keyboardButtonkeyboardButtonTab').click(function () {
$.ajax({
url: "sendKeyEvent?key=tab",
headers: { "session": sessionId }
})
});
$('#keyboardButtonReturn').click(function () {
$.ajax({
url: "sendKeyEvent?key=return",
headers: { "session": sessionId }
})
});
$('#keyboardButtonKeys').keyup(function (e) {
var c = String.fromCharCode(e.keyCode);
if (c.match(/\w/)) {
c = e.keyCode >= 65 ? c.toLowerCase() : c;
$.ajax({
url: "sendKeyEvent?key=" + c,
headers: { "session": sessionId }
})
}
var oldText = $('#keyboardButtonKeys')[0].value;
if (oldText.length > 0) {
$('#keyboardButtonKeys')[0].value = oldText.slice(1);
}
});
}
+5 -2
View File
@@ -30,6 +30,9 @@ namespace VocaluxeLib.Profile
public string FilePath;
public string FileName;
public string AvatarFileName;
public byte[] PasswordHash;
public byte[] PasswordSalt;
public int UserRoles;
public EGameDifficulty Difficulty;
@@ -56,7 +59,7 @@ namespace VocaluxeLib.Profile
Active = EOffOn.TR_CONFIG_ON;
AvatarFileName = String.Empty;
FileName = String.Empty;
FileName = String.Empty;
}
public bool LoadProfile()
@@ -104,7 +107,7 @@ namespace VocaluxeLib.Profile
string filename = string.Empty;
// ReSharper disable LoopCanBeConvertedToQuery
foreach (char chr in PlayerName)
// ReSharper restore LoopCanBeConvertedToQuery
// ReSharper restore LoopCanBeConvertedToQuery
{
if (char.IsLetter(chr))
filename += chr.ToString();