User/Roles for webserver
This commit is contained in:
1 parent
c41af99536
commit
3126d5aaf0
13 files changed
+1134
-604
No files matched your search
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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,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
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user