- Integration of the server into the main project

- Made the webserver calls threadsafe (with Tasks)
- Removed some old and unused server classes
This commit is contained in:
lukeIam committed 2015-02-21 18:23:21 +01:00
1 parent 2b9a38ff0d
commit 86a98e7bf8
21 files changed
+417 -1030

No files matched your search

-129
View File
@@ -1,129 +0,0 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using Newtonsoft.Json;
namespace Vocaluxe.Base.Server
{
public static class CCommands
{
private static readonly UTF8Encoding _Encoder = new UTF8Encoding();
private static readonly SHA256Managed _Sha256 = new SHA256Managed();
public const string BroadcastKeyword = "I am a Vocaluxe Server";
#region Commands
// ReSharper disable UnusedMember.Global
public const int ResponseOK = 1;
public const int ResponseNOK = 2;
public const int CommandLogin = 20;
public const int ResponseLoginWrongPassword = 21;
public const int ResponseLoginFailed = 22;
public const int ResponseLoginOK = 23;
public const int CommandSendKeyStroke = 100;
public const int CommandSendKeyUp = 110;
public const int CommandSendKeyDown = 111;
public const int CommandSendKeyLeft = 112;
public const int CommandSendKeyRight = 113;
public const int CommandSendMouseMoveEvent = 200;
public const int CommandSendMouseLBDownEvent = 220;
public const int CommandSendMouseLBUpEvent = 221;
public const int CommandSendMouseRBDownEvent = 230;
public const int CommandSendMouseRBUpEvent = 231;
public const int ComamndSendMouseMBDownEvent = 240;
public const int ComamndSendMouseMBUpEvent = 241;
public const int CommandSendMouseWheelEvent = 250;
public const int CommandSendAvatarPicture = 500;
public const int CommandSendAvatarPictureJpg = 501;
public const int CommandSendProfile = 510;
// ReSharper restore UnusedMember.Global
#endregion Commands
#region General
public static byte[] CreateCommandWithoutParams(int command)
{
return BitConverter.GetBytes(command);
}
#endregion General
#region Login
public static byte[] CreateCommandLogin(string password)
{
var data = new SLoginData {Sha256 = _Sha256.ComputeHash(Encoding.UTF8.GetBytes(password))};
return _Serialize(CommandLogin, data);
}
public static bool DecodeCommandLogin(byte[] message, out SLoginData loginData)
{
return _TryDeserialize(message, out loginData);
}
#endregion Login
#region Serializing
private static byte[] _Serialize<T>(T obj)
{
return _Serialize(0, obj);
}
private static byte[] _Serialize<T>(int command, T obj)
{
byte[] cmd = BitConverter.GetBytes(command);
var stream = new MemoryStream();
stream.Write(cmd, 0, cmd.Length);
string json = JsonConvert.SerializeObject(obj);
byte[] data = _Encoder.GetBytes(json);
stream.Write(data, 0, data.Length);
return stream.ToArray();
}
private static bool _TryDeserialize<T>(byte[] message, out T obj)
{
obj = default(T);
if (message == null)
return false;
if (message.Length < 5)
return false;
var data = new byte[message.Length - 4];
Array.Copy(message, 4, data, 0, data.Length);
try
{
obj = JsonConvert.DeserializeObject<T>(_Encoder.GetString(data));
return true;
}
catch
{
return false;
}
}
#endregion Serializing
}
}
+232 -71
View File
@@ -17,14 +17,18 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security.Cryptography;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ServerLib;
using Vocaluxe.Lib.Input;
using Vocaluxe.Lib.Playlist;
using VocaluxeLib;
@@ -36,6 +40,11 @@ namespace Vocaluxe.Base.Server
{
static class CVocaluxeServer
{
private static ServiceHost _Host;
private static Uri _BaseAddress;
private static bool _Encrypted;
private static readonly Queue<Task> _ServerTaskQueue = new Queue<Task>();
private class CServerController : CControllerFramework
{
public override string GetName()
@@ -55,81 +64,232 @@ namespace Vocaluxe.Base.Server
public override void SetRumble(float duration) {}
}
private static CServer _Server;
//private static CDiscover _Discover;
public static readonly CControllerFramework Controller = new CServerController();
#region server control
public static void Init()
{
_Server = new CServer(CConfig.Config.Server.ServerPort, CConfig.Config.Server.ServerEncryption == EOffOn.TR_CONFIG_ON);
int port = CConfig.Config.Server.ServerPort;
bool encrypted = CConfig.Config.Server.ServerEncryption == EOffOn.TR_CONFIG_ON;
string hostname = Dns.GetHostName();
string protocol = (encrypted) ? "https" : "http";
_BaseAddress = new Uri(protocol + "://" + hostname + ":" + port + "/");
_Encrypted = encrypted;
_Host = new WebServiceHost(typeof(CWebservice), _BaseAddress);
CServer.SendKeyEvent = _SendKeyEvent;
CServer.SendKeyStringEvent = _sendKeyStringEvent;
CServer.GetProfileData = _GetProfileData;
CServer.SendProfileData = _SendProfileData;
CServer.GetProfileList = _GetProfileList;
CServer.SendPhoto = _SendPhoto;
CServer.GetSiteFile = _GetSiteFile;
CServer.GetServerVersion = _GetServerVersion;
CServer.GetSong = _GetSong;
CServer.GetAllSongs = _GetAllSongs;
CServer.GetCurrentSongId = _GetCurrentSongId;
CServer.GetMp3Path = _GetMp3Path;
CServer.ValidatePassword = _ValidatePassword;
CServer.GetUserRole = _GetUserRole;
CServer.SetUserRole = _SetUserRole;
CServer.GetUserIdFromUsername = _GetUserIdFromUsername;
CServer.GetDelayedImage = _GetDelayedImage;
CServer.GetPlaylists = _GetPlaylists;
CServer.GetPlaylist = _GetPlaylist;
CServer.AddSongToPlaylist = _AddSongToPlaylist;
CServer.RemoveSongFromPlaylist = _RemoveSongFromPlaylist;
CServer.MoveSongInPlaylist = _MoveSongInPlaylist;
CServer.PlaylistContainsSong = _PlaylistContainsSong;
CServer.GetPlaylistSongs = _GetPlaylistSongs;
CServer.RemovePlaylist = _RemovePlaylist;
CServer.AddPlaylist = _AddPlaylist;
WebHttpBinding wb = new WebHttpBinding
{
MaxReceivedMessageSize = 10485760,
MaxBufferSize = 10485760,
MaxBufferPoolSize = 10485760,
ReaderQuotas = { MaxStringContentLength = 10485760, MaxArrayLength = 10485760, MaxBytesPerRead = 10485760 }
};
if (encrypted)
{
wb.Security.Mode = WebHttpSecurityMode.Transport;
wb.Security.Transport = new HttpTransportSecurity { ClientCredentialType = HttpClientCredentialType.None };
}
_Host.AddServiceEndpoint(typeof(ICWebservice), wb, "");
Start();
//_Discover = new CDiscover(CConfig.ServerPort, CCommands.BroadcastKeyword);
}
public static void Start()
{
if (CConfig.Config.Server.ServerActive == EOffOn.TR_CONFIG_ON)
{
_Server.Start();
//_Discover.StartBroadcasting();
try
{
_RegisterUrlAndCert(_BaseAddress.Port, false);
_Host.Open();
}
catch (CommunicationException e)
{
if (e is AddressAccessDeniedException || e is AddressAlreadyInUseException)
{
_RegisterUrlAndCert(_BaseAddress.Port, true);
try
{
_Host.Abort();
Init();
_Host.Open();
}
catch (CommunicationException)
{
_Host.Abort();
MessageBox.Show("Problem while initialization of webserver. You may try a different port (Change it in config.xml)");
}
}
else
_Host.Abort();
}
}
}
public static void Close()
{
if (_Server != null)
if (_Host != null)
{
_Server.Stop();
_Server = null;
//_Discover.Stop();
try
{
_Host.Close();
}
catch (CommunicationException)
{
_Host.Abort();
}
}
}
private static void _RegisterUrlAndCert(int port, bool reserve)
{
#if WIN
ProcessStartInfo info = new ProcessStartInfo
{
FileName = "VocaluxeServerConfig.exe",
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
Arguments = AppDomain.CurrentDomain.FriendlyName + " " + port + " " + (_Encrypted ? "true" : "false") + (reserve ? " true" : ""),
UseShellExecute = true,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
};
try
{
using (Process p = Process.Start(info))
{
p.WaitForExit();
if (p.ExitCode != 0)
MessageBox.Show("Registering the Server failed (Code " + p.ExitCode + ")!\r\nThe Server might not work correctly.");
p.Close();
}
}
catch (Exception e)
{
MessageBox.Show("Registering the Server failed (" + e + ")!\r\nThe Server might not work correctly.");
}
#else
//Required?
#endif
}
public static string GetServerAddress()
{
return _Server == null ? "" : _Server.GetBaseAddress();
return _BaseAddress == null ? "" : _BaseAddress.AbsoluteUri;
}
public static bool IsServerRunning()
{
if (_Server == null)
if (_Host == null)
return false;
return _Server.IsRunning();
return _Host.State == CommunicationState.Opened;
}
private static bool _SendKeyEvent(string key)
#endregion
#region task control
public static void ProcessServerTasks()
{
//Serial processing - one by one
while (_ServerTaskQueue.Count > 0)
{
//Get a task from the queue
Task task = _ServerTaskQueue.Dequeue();
//Start the task
task.RunSynchronously(TaskScheduler.FromCurrentSynchronizationContext());
task.Wait();
}
}
public static TReturnType DoTask<TReturnType>(Func<TReturnType> action)
{
var task = new Task<TReturnType>(action);
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
return task.Result;
}
public static TReturnType DoTask<TReturnType, TParameterType>(Func<TParameterType, TReturnType> action, TParameterType parameter)
{
var task = new Task<TReturnType>(() => action(parameter));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
return task.Result;
}
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2>(Func<TParameterType1, TParameterType2, TReturnType> action, TParameterType1 parameter1, TParameterType2 parmaeter2)
{
var task = new Task<TReturnType>(() => action(parameter1, parmaeter2));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
return task.Result;
}
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2, TParameterType3>(Func<TParameterType1, TParameterType2, TParameterType3, TReturnType> action, TParameterType1 parameter1, TParameterType2 parmaeter2, TParameterType3 parmaeter3)
{
var task = new Task<TReturnType>(() => action(parameter1, parmaeter2, parmaeter3));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
return task.Result;
}
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2, TParameterType3, TParameterType4>(Func<TParameterType1, TParameterType2, TParameterType3, TParameterType4, TReturnType> action, TParameterType1 parameter1, TParameterType2 parmaeter2, TParameterType3 parmaeter3, TParameterType4 parmaeter4)
{
var task = new Task<TReturnType>(() => action(parameter1, parmaeter2, parmaeter3, parmaeter4));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
return task.Result;
}
public static void DoTaskWithoutReturn(Action action)
{
var task = new Task(action);
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
}
public static void DoTaskWithoutReturn<TParameterType>(Action<TParameterType> action, TParameterType parameter)
{
var task = new Task(() => action(parameter));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
}
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2>(Action<TParameterType1, TParameterType2> action, TParameterType1 parameter1, TParameterType2 parmaeter2)
{
var task = new Task(() => action(parameter1, parmaeter2));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
}
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2, TParameterType3>(Action<TParameterType1, TParameterType2, TParameterType3> action, TParameterType1 parameter1, TParameterType2 parmaeter2, TParameterType3 parmaeter3)
{
var task = new Task(() => action(parameter1, parmaeter2, parmaeter3));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
}
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2, TParameterType3, TParameterType4>(Action<TParameterType1, TParameterType2, TParameterType3, TParameterType4> action, TParameterType1 parameter1, TParameterType2 parmaeter2, TParameterType3 parmaeter3, TParameterType4 parmaeter4)
{
var task = new Task(() => action(parameter1, parmaeter2, parmaeter3, parmaeter4));
_ServerTaskQueue.Enqueue(task);
task.Wait(); //wait until the task is completed
}
#endregion
public static bool SendKeyEvent(string key)
{
bool result = false;
string lowerKey = key.ToLower();
@@ -192,7 +352,7 @@ namespace Vocaluxe.Base.Server
return result;
}
private static bool _sendKeyStringEvent(string keyString, bool isShiftPressed, bool isAltPressed, bool isCtrlPressed)
public static bool SendKeyStringEvent(string keyString, bool isShiftPressed, bool isAltPressed, bool isCtrlPressed)
{
bool result = false;
@@ -230,7 +390,7 @@ namespace Vocaluxe.Base.Server
}
#region profile
private static SProfileData _GetProfileData(int profileId, bool isReadonly)
public static SProfileData GetProfileData(int profileId, bool isReadonly)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
@@ -238,7 +398,7 @@ namespace Vocaluxe.Base.Server
return _CreateProfileData(profile, isReadonly);
}
private static bool _SendProfileData(SProfileData profile)
public static bool SendProfileData(SProfileData profile)
{
CProfile newProfile;
CProfile existingProfile = CProfiles.GetProfile(profile.ProfileId);
@@ -325,7 +485,7 @@ namespace Vocaluxe.Base.Server
return true;
}
private static SProfileData[] _GetProfileList()
public static SProfileData[] GetProfileList()
{
List<SProfileData> result = new List<SProfileData>(CProfiles.NumProfiles);
@@ -379,7 +539,7 @@ namespace Vocaluxe.Base.Server
#region photo
private static readonly List<string> _PhotosOfThisRound = new List<string>();
private static bool _SendPhoto(SPhotoData photoData)
public static bool SendPhoto(SPhotoData photoData)
{
if (photoData.Photo == null)
return false;
@@ -406,7 +566,7 @@ namespace Vocaluxe.Base.Server
#region website
private static readonly Dictionary<string, string> _DelayedImagePath = new Dictionary<string, string>();
private static byte[] _GetSiteFile(string filename)
public static byte[] GetSiteFile(string filename)
{
string path = "Website/" + filename;
path = path.Replace("..", "");
@@ -438,7 +598,7 @@ namespace Vocaluxe.Base.Server
return hashedFilename;
}
private static string _GetServerVersion()
public static string GetServerVersion()
{
var informationalVersion = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();
if (informationalVersion != null)
@@ -448,7 +608,7 @@ namespace Vocaluxe.Base.Server
return Assembly.GetExecutingAssembly().GetName().Version.ToString() + " (" + informationalVersion + ")";
}
private static CBase64Image _GetDelayedImage(string hashedFilename)
public static CBase64Image GetDelayedImage(string hashedFilename)
{
if (!_DelayedImagePath.ContainsKey(hashedFilename))
throw new FileNotFoundException("Image not found");
@@ -465,25 +625,26 @@ namespace Vocaluxe.Base.Server
#endregion
#region songs
private static SSongInfo _GetSong(int songId)
public static SSongInfo GetSong(int songId)
{
CSong song = CSongs.GetSong(songId);
return _GetSongInfo(song, true);
}
private static SSongInfo[] _GetAllSongs()
public static SSongInfo[] GetAllSongs()
{
List<CSong> songs = CSongs.Songs;
return (from s in songs
select _GetSongInfo(s, false)).ToArray<SSongInfo>();
}
private static string _GetMp3Path(int songId)
public static string GetMp3Path(int songId)
{
CSong song = CSongs.GetSong(songId);
return song.GetMP3();
}
private static int _GetCurrentSongId()
public static int GetCurrentSongId()
{
CSong song = CGame.GetSong();
if (song == null)
@@ -511,25 +672,25 @@ namespace Vocaluxe.Base.Server
#endregion
#region playlist
private static SPlaylistData[] _GetPlaylists()
public static SPlaylistData[] GetPlaylists()
{
return (from p in CPlaylists.Playlists
select _GetPlaylistInfo(p)).ToArray();
}
private static SPlaylistData _GetPlaylist(int playlistId)
public static SPlaylistData GetPlaylist(int playlistId)
{
if (CPlaylists.Get(playlistId) == null)
throw new ArgumentException("invalid playlistId");
return _GetPlaylistInfo(CPlaylists.Get(playlistId));
}
private static void _AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates)
public static void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates)
{
if (CPlaylists.Get(playlistId) == null)
throw new ArgumentException("invalid playlistId");
if (allowDuplicates || !_PlaylistContainsSong(songId, playlistId))
if (allowDuplicates || !PlaylistContainsSong(songId, playlistId))
{
CPlaylists.AddSong(playlistId, songId);
CPlaylists.Save(playlistId);
@@ -538,12 +699,12 @@ namespace Vocaluxe.Base.Server
throw new ArgumentException("song exists in this playlist");
}
private static void _RemoveSongFromPlaylist(int position, int playlistId, int songId)
public static void RemoveSongFromPlaylist(int position, int playlistId, int songId)
{
CPlaylistFile pl = CPlaylists.Get(playlistId);
if (pl == null)
throw new ArgumentException("invalid playlistId");
if (!_PlaylistContainsSong(songId, playlistId))
if (!PlaylistContainsSong(songId, playlistId))
throw new ArgumentException("invalid songId");
if (position < 0 || pl.Songs.Count <= position
|| pl.Songs[position].SongID != songId)
@@ -552,12 +713,12 @@ namespace Vocaluxe.Base.Server
pl.Save();
}
private static void _MoveSongInPlaylist(int newPosition, int playlistId, int songId)
public static void MoveSongInPlaylist(int newPosition, int playlistId, int songId)
{
CPlaylistFile pl = CPlaylists.Get(playlistId);
if (pl == null)
throw new ArgumentException("invalid playlistId");
if (!_PlaylistContainsSong(songId, playlistId))
if (!PlaylistContainsSong(songId, playlistId))
throw new ArgumentException("invalid songId");
if (pl.Songs.Count < newPosition)
@@ -568,7 +729,7 @@ namespace Vocaluxe.Base.Server
pl.Save();
}
private static bool _PlaylistContainsSong(int songId, int playlistId)
public static bool PlaylistContainsSong(int songId, int playlistId)
{
CPlaylistFile pl = CPlaylists.Get(playlistId);
if (pl == null)
@@ -576,7 +737,7 @@ namespace Vocaluxe.Base.Server
return pl.Songs.Any(s => s.SongID == songId);
}
private static SPlaylistSongInfo[] _GetPlaylistSongs(int playlistId)
public static SPlaylistSongInfo[] GetPlaylistSongs(int playlistId)
{
CPlaylistFile pl = CPlaylists.Get(playlistId);
if (pl == null)
@@ -617,14 +778,14 @@ namespace Vocaluxe.Base.Server
};
}
private static void _RemovePlaylist(int playlistId)
public static void RemovePlaylist(int playlistId)
{
if (CPlaylists.Get(playlistId) == null)
throw new ArgumentException("invalid playlistId");
CPlaylists.Delete(playlistId);
}
private static int _AddPlaylist(string playlistName)
public static int AddPlaylist(string playlistName)
{
int newPlaylistId = CPlaylists.NewPlaylist(playlistName);
CPlaylists.Save(newPlaylistId);
@@ -634,7 +795,7 @@ namespace Vocaluxe.Base.Server
#endregion
#region user management
private static bool _ValidatePassword(int profileId, string password)
public static bool ValidatePassword(int profileId, string password)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
@@ -651,7 +812,7 @@ namespace Vocaluxe.Base.Server
return _Hash((new UTF8Encoding()).GetBytes(password), salt).SequenceEqual(profile.PasswordHash);
}
private static bool _ValidatePassword(int profileId, byte[] hashedPassword)
public static bool ValidatePassword(int profileId, byte[] hashedPassword)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
@@ -680,7 +841,7 @@ namespace Vocaluxe.Base.Server
return profile.PasswordSalt;
}
private static int _GetUserRole(int profileId)
public static int GetUserRole(int profileId)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
@@ -692,7 +853,7 @@ namespace Vocaluxe.Base.Server
return (int)(profile.UserRole);
}
private static void _SetUserRole(int profileId, int userRole)
public static void SetUserRole(int profileId, int userRole)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
@@ -711,7 +872,7 @@ namespace Vocaluxe.Base.Server
CProfiles.SaveProfiles();
}
private static int _GetUserIdFromUsername(string username)
public static int GetUserIdFromUsername(string username)
{
IEnumerable<int> playerIds = (from p in CProfiles.GetProfiles()
where String.Equals(p.PlayerName, username, StringComparison.OrdinalIgnoreCase)
+560
View File
@@ -0,0 +1,560 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.IO;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
namespace Vocaluxe.Base.Server
{
class CWebservice : ICWebservice
{
private static Guid _GetSession()
{
Guid sessionKey = Guid.Empty;
string sessionHeader =
((HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties["httpRequest"]).Headers["session"];
if (string.IsNullOrEmpty(sessionHeader))
return sessionKey;
try
{
sessionKey = Guid.Parse(sessionHeader);
}
catch (Exception)
{ }
CSessionControl.ResetSessionTimeout(sessionKey);
return sessionKey;
}
public void SendKeyEvent(string key)
{
if (!_CheckRight(EUserRights.UseKeyboard))
return;
CVocaluxeServer.DoTask(CVocaluxeServer.SendKeyEvent,key);
}
public void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false)
{
if (!_CheckRight(EUserRights.UseKeyboard))
return;
CVocaluxeServer.DoTask(CVocaluxeServer.SendKeyStringEvent, keyString, isShiftPressed, isAltPressed, isCtrlPressed);
}
#region profile
public int GetOwnProfileId()
{
Guid sessionKey = _GetSession();
if (sessionKey == Guid.Empty)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session";
}
return -1;
}
int profileId = CSessionControl.GetUserIdFromSession(sessionKey);
if (profileId < 0)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session";
}
return -1;
}
return profileId;
}
public void SendProfile(SProfileData profile)
{
Guid sessionKey = _GetSession();
if (profile.ProfileId != -1) //-1 is the id for a new profile
{
if (CSessionControl.GetUserIdFromSession(sessionKey) != profile.ProfileId
&& !(_CheckRight(EUserRights.EditAllProfiles)))
return;
}
CVocaluxeServer.DoTask(CVocaluxeServer.SendProfileData, profile);
}
public SProfileData GetProfile(int profileId)
{
Guid sessionKey = _GetSession();
if (CSessionControl.GetUserIdFromSession(sessionKey) == profileId || _CheckRight(EUserRights.ViewOtherProfiles))
{
bool isReadonly = (!CSessionControl.RequestRight(sessionKey, EUserRights.EditAllProfiles) &&
CSessionControl.GetUserIdFromSession(sessionKey) != profileId);
return CVocaluxeServer.DoTask(CVocaluxeServer.GetProfileData,profileId, isReadonly);
}
return new SProfileData();
}
public SProfileData[] GetProfileList()
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetProfileList);
}
#endregion
#region photo
public void SendPhoto(SPhotoData photo)
{
if (_CheckRight(EUserRights.UploadPhotos))
CVocaluxeServer.DoTask(CVocaluxeServer.SendPhoto, photo);
}
#endregion
#region website
public Guid Login(string username, string password)
{
Guid sessionId = CSessionControl.OpenSession(username, password);
if (sessionId == Guid.Empty)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "Wrong username or password";
}
}
return sessionId;
}
public void Logout()
{
Guid sessionKey = _GetSession();
CSessionControl.InvalidateSessions(sessionKey);
}
public Stream Index()
{
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
return new MemoryStream(CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile,"index.html"));
}
public Stream GetJsFile(string filename)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/javascript";
WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow;
WebOperationContext.Current.OutgoingResponse.Headers.Add(
HttpResponseHeader.Expires,
DateTime.UtcNow.AddHours(4).ToString("r"));
}
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "js/" + filename);
if (data != null)
return new MemoryStream(data);
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
return null;
}
public Stream GetCssFile(string filename)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/css";
WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow;
WebOperationContext.Current.OutgoingResponse.Headers.Add(
HttpResponseHeader.Expires,
DateTime.UtcNow.AddHours(4).ToString("r"));
}
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css/" + filename);
if (data != null)
return new MemoryStream(data);
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
return null;
}
public Stream GetCssImageFile(string filename)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";
WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow;
WebOperationContext.Current.OutgoingResponse.Headers.Add(
HttpResponseHeader.Expires,
DateTime.UtcNow.AddYears(1).ToString("r"));
}
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css\\images\\" + filename);
if (data != null)
return new MemoryStream(data);
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
return null;
}
public Stream GetImgFile(string filename)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "image/png";
WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow;
WebOperationContext.Current.OutgoingResponse.Headers.Add(
HttpResponseHeader.Expires,
DateTime.UtcNow.AddYears(1).ToString("r"));
}
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "img/" + filename);
if (data != null)
return new MemoryStream(data);
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
return null;
}
public Stream GetLocaleFile(string filename)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/javascript";
WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow;
WebOperationContext.Current.OutgoingResponse.Headers.Add(
HttpResponseHeader.Expires,
DateTime.UtcNow.AddHours(4).ToString("r"));
}
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "locales/" + filename);
if (data != null)
return new MemoryStream(data);
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
return null;
}
public CBase64Image GetDelayedImage(string id)
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetDelayedImage, id);
}
public bool IsServerOnline()
{
_GetSession();
return true;
}
public string GetServerVersion()
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetServerVersion);
}
#endregion
#region songs
public SSongInfo GetSong(int songId)
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetSong, songId);
}
public int GetCurrentSongId()
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetCurrentSongId);
}
public SSongInfo[] GetAllSongs()
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetAllSongs);
}
public Stream GetMp3File(int songId)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.LastModified = DateTime.UtcNow;
WebOperationContext.Current.OutgoingResponse.Headers.Add(
HttpResponseHeader.Expires,
DateTime.UtcNow.AddYears(1).ToString("r"));
}
String path = CVocaluxeServer.DoTask(CVocaluxeServer.GetMp3Path,songId);
path = path.Replace("..", "");
if (!File.Exists(path)
|| !(path.EndsWith(".mp3", StringComparison.InvariantCulture)
|| path.EndsWith(".ogg", StringComparison.InvariantCulture)
|| path.EndsWith(".wav", StringComparison.InvariantCulture)
|| path.EndsWith(".webm", StringComparison.InvariantCulture)))
{
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
return null;
}
if (WebOperationContext.Current != null)
{
if (path.EndsWith(".mp3", StringComparison.InvariantCulture))
{
WebOperationContext.Current.OutgoingResponse.ContentType = "audio/mpeg";
}
else if (path.EndsWith(".ogg", StringComparison.InvariantCulture))
{
WebOperationContext.Current.OutgoingResponse.ContentType = "audio/ogg";
}
else if (path.EndsWith(".wav", StringComparison.InvariantCulture))
{
WebOperationContext.Current.OutgoingResponse.ContentType = "audio/wav";
}
else if (path.EndsWith(".webm", StringComparison.InvariantCulture))
{
WebOperationContext.Current.OutgoingResponse.ContentType = "audio/webm";
}
}
return File.OpenRead(path);
}
#endregion
#region playlist
public SPlaylistData[] GetPlaylists()
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetPlaylists);
}
public SPlaylistData GetPlaylist(int playlistId)
{
try
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetPlaylist, playlistId);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
return new SPlaylistData();
}
}
public void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates)
{
if (!_CheckRight(EUserRights.AddSongToPlaylist))
return;
try
{
CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.AddSongToPlaylist, songId, playlistId, allowDuplicates);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
}
}
public void RemoveSongFromPlaylist(int position, int playlistId, int songId)
{
if (!_CheckRight(EUserRights.RemoveSongsFromPlaylists))
return;
try
{
CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.RemoveSongFromPlaylist, position, playlistId, songId);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
}
}
public void MoveSongInPlaylist(int newPosition, int playlistId, int songId)
{
if (!_CheckRight(EUserRights.ReorderPlaylists))
return;
try
{
CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.MoveSongInPlaylist, newPosition, playlistId, songId);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
}
}
public bool PlaylistContainsSong(int songId, int playlistId)
{
try
{
return CVocaluxeServer.DoTask(CVocaluxeServer.PlaylistContainsSong, songId, playlistId);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
return false;
}
}
public SPlaylistSongInfo[] GetPlaylistSongs(int playlistId)
{
try
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetPlaylistSongs, playlistId);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
return new SPlaylistSongInfo[0];
}
}
public void RemovePlaylist(int playlistId)
{
if (!_CheckRight(EUserRights.DeletePlaylists))
return;
try
{
CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.RemovePlaylist, playlistId);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
}
}
public int AddPlaylist(string playlistName)
{
if (!_CheckRight(EUserRights.CreatePlaylists))
return -1;
try
{
return CVocaluxeServer.DoTask(CVocaluxeServer.AddPlaylist, playlistName);
}
catch (ArgumentException e)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
}
return -1;
}
}
#endregion
#region user management
public int GetUserRole(int profileId)
{
return CVocaluxeServer.DoTask(CVocaluxeServer.GetUserRole, profileId);
}
public void SetUserRole(int profileId, int userRole)
{
if (_CheckRight(EUserRights.EditAllProfiles))
CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.SetUserRole, profileId, userRole);
}
public bool HasUserRight(int right)
{
return _CheckRightWithNoErrorMessage((EUserRights)right);
}
private static bool _CheckRight(EUserRights requestedRight)
{
Guid sessionKey = _GetSession();
if (sessionKey == Guid.Empty)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session";
}
return false;
}
if (!CSessionControl.RequestRight(sessionKey, requestedRight))
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "Not allowed";
}
return false;
}
return true;
}
private static bool _CheckRightWithNoErrorMessage(EUserRights requestedRight)
{
Guid sessionKey = _GetSession();
if (sessionKey == Guid.Empty)
return false;
if (!CSessionControl.RequestRight(sessionKey, requestedRight))
return false;
return true;
}
#endregion
}
}
+211
View File
@@ -0,0 +1,211 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace Vocaluxe.Base.Server
{
[ServiceContract]
public interface ICWebservice
{
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/sendKeyEvent?key={key}")]
void SendKeyEvent(string key);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/sendKeyStringEvent?keyString={keyString}&shift={isShiftPressed}&alt={isAltPressed}&ctrl={isCtrlPressed}")]
void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false);
#region profile
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getOwnProfileId")]
int GetOwnProfileId();
[OperationContract, WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/sendProfile")]
void SendProfile(SProfileData profile);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getProfile?profileId={profileId}")]
SProfileData GetProfile(int profileId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getProfileList")]
SProfileData[] GetProfileList();
#endregion
#region photo
[OperationContract, WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/sendPhoto")]
void SendPhoto(SPhotoData photo);
#endregion
#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,
UriTemplate = "/logout")]
void Logout();
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "")]
Stream Index();
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/js/{filename}")]
Stream GetJsFile(String filename);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/css/{filename}")]
Stream GetCssFile(String filename);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/css/images/{filename}")]
Stream GetCssImageFile(String filename);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/img/{filename}")]
Stream GetImgFile(String filename);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/locales/{filename}")]
Stream GetLocaleFile(String filename);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/delayedImage?id={id}")]
CBase64Image GetDelayedImage(String id);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/isServerOnline")]
bool IsServerOnline();
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getServerVersion")]
String GetServerVersion();
#endregion
#region songs
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getSong?songId={songId}")]
SSongInfo GetSong(int songId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getCurrentSongId")]
int GetCurrentSongId();
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getAllSongs")]
SSongInfo[] GetAllSongs();
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getMp3?songId={songId}")]
Stream GetMp3File(int songId);
#endregion
#region playlist
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getPlaylists")]
SPlaylistData[] GetPlaylists();
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getPlaylist?id={playlistId}")]
SPlaylistData GetPlaylist(int playlistId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/addSongToPlaylist?songId={songId}&playlistId={playlistId}&duplicates={allowDuplicates}")]
void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/removeSongFromPlaylist?position={position}&playlistId={playlistId}&songId={songId}")]
void RemoveSongFromPlaylist(int position, int playlistId, int songId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/moveSongInPlaylist?newPosition={newPosition}&playlistId={playlistId}&songId={songId}")]
void MoveSongInPlaylist(int newPosition, int playlistId, int songId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/playlistContainsSong?songId={songId}&playlistId={playlistId}")]
bool PlaylistContainsSong(int songId, int playlistId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getPlaylistSongs?playlistId={playlistId}")]
SPlaylistSongInfo[] GetPlaylistSongs(int playlistId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/removePlaylist?playlistId={playlistId}")]
void RemovePlaylist(int playlistId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/addPlaylist?playlistName={playlistName}")]
int AddPlaylist(string playlistName);
#endregion
#region user management
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getUserRole?profileId={profileId}")]
int GetUserRole(int profileId);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/setUserRole?profileId={profileId}&userRole={userRole}")]
void SetUserRole(int profileId, int userRole);
[OperationContract, WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/hasUserRight?right={right}")]
bool HasUserRight(int right);
#endregion
}
}
+57
View File
@@ -0,0 +1,57 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
namespace Vocaluxe.Base.Server
{
class CSession
{
private readonly Guid _ID;
public Guid Id
{
get { return _ID; }
}
private readonly int _ProfileId;
public int ProfileId
{
get { return _ProfileId; }
}
private readonly EUserRoles _Roles;
internal EUserRoles Roles
{
get { return _Roles; }
}
private DateTime _LastSeen;
public DateTime LastSeen
{
get { return _LastSeen; }
internal set { _LastSeen = value; }
}
public CSession(Guid id, int profileId, EUserRoles roles)
{
_ID = id;
_ProfileId = profileId;
_Roles = roles;
_LastSeen = DateTime.Now;
}
}
}
+119
View File
@@ -0,0 +1,119 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Timers;
namespace Vocaluxe.Base.Server
{
static class CSessionControl
{
private static readonly Dictionary<Guid, CSession> _ActiveSessions;
private const int _UserTimeoutCheckIntervall = 120000;
private const int _UserTimeout = 120000;
static CSessionControl()
{
_ActiveSessions = new Dictionary<Guid, CSession>();
Timer timer = new Timer(_UserTimeoutCheckIntervall) {AutoReset = true, Enabled = true};
timer.Elapsed += _CheckForUserTimeouts;
timer.Start();
}
private static void _CheckForUserTimeouts(object sender, ElapsedEventArgs e)
{
var sessionIdsToRemove = _ActiveSessions.Where(pair => (DateTime.Now-pair.Value.LastSeen).TotalMilliseconds > _UserTimeout)
.Select(pair => pair.Key)
.ToList();
foreach (var sessionToRemove in sessionIdsToRemove)
{
InvalidateSessions(sessionToRemove);
}
}
public static Guid OpenSession(string userName, string password)
{
if (!_ValidateUserAndPassword(userName, password))
return Guid.Empty;
Guid newId = Guid.NewGuid();
int id = _GetProfileIdFormUsername(userName);
EUserRoles roles = _GetUserRoles(id);
CSession session = new CSession(newId, id, roles);
//InvalidateSessions(id);
_ActiveSessions.Add(newId, session);
return newId;
}
private static bool _ValidateUserAndPassword(string userName, string password)
{
return CVocaluxeServer.ValidatePassword(_GetProfileIdFormUsername(userName), password);
}
private static int _GetProfileIdFormUsername(string username)
{
return CVocaluxeServer.GetUserIdFromUsername(username);
}
private static EUserRoles _GetUserRoles(int profileId)
{
return (EUserRoles)CVocaluxeServer.GetUserRole(profileId);
}
internal static void InvalidateSessions(int profileId)
{
foreach (KeyValuePair<Guid, CSession> s in (from kv in _ActiveSessions
where kv.Value.ProfileId == profileId
select kv).ToList())
_ActiveSessions.Remove(s.Key);
}
internal static void InvalidateSessions(Guid sessionId)
{
if (_ActiveSessions.ContainsKey(sessionId))
{
_ActiveSessions.Remove(sessionId);
}
}
internal static bool RequestRight(Guid sessionId, EUserRights requestedRight)
{
return ((CUserRoleControl.GetUserRightsFromUserRole(_ActiveSessions[sessionId].Roles)
.HasFlag(requestedRight)));
}
internal static int GetUserIdFromSession(Guid sessionId)
{
if (!_ActiveSessions.ContainsKey(sessionId))
return -1;
return _ActiveSessions[sessionId].ProfileId;
}
internal static void ResetSessionTimeout(Guid sessionId)
{
CSession value;
if (_ActiveSessions.TryGetValue(sessionId, out value))
{
value.LastSeen = DateTime.Now;
}
}
}
}
@@ -15,17 +15,22 @@
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
namespace Vocaluxe.Base.Server
{
class CClientHandler
[Flags]
enum EUserRights
{
private int _ConnectionID;
public bool LoggedIn;
public CClientHandler(int connectionID)
{
_ConnectionID = connectionID;
LoggedIn = false;
}
None = 0,
EditAllProfiles = 1,
UploadPhotos = 2,
ViewOtherProfiles = 4,
UseKeyboard = 8,
ReorderPlaylists = 16,
AddSongToPlaylist = 32,
CreatePlaylists = 64,
DeletePlaylists = 128,
RemoveSongsFromPlaylists = 256
}
}
+77
View File
@@ -0,0 +1,77 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System.Collections.Generic;
using System.Linq;
namespace Vocaluxe.Base.Server
{
static class CUserRoleControl
{
private static readonly Dictionary<EUserRoles, EUserRights> _RoleRightsMapping = new Dictionary<EUserRoles, EUserRights>
{
{
EUserRoles.TR_USERROLE_ADMIN,
(EUserRights.EditAllProfiles |
EUserRights.UploadPhotos |
EUserRights.ViewOtherProfiles |
EUserRights.UseKeyboard |
EUserRights.AddSongToPlaylist |
EUserRights.ReorderPlaylists |
EUserRights.CreatePlaylists |
EUserRights.DeletePlaylists |
EUserRights.RemoveSongsFromPlaylists)
},
{
EUserRoles.TR_USERROLE_GUEST,
EUserRights.None
},
{
EUserRoles.TR_USERROLE_NORMAL,
(EUserRights.UploadPhotos |
EUserRights.ViewOtherProfiles)
},
{
EUserRoles.TR_USERROLE_KEYBOARDUSER,
EUserRights.UseKeyboard
},
{
EUserRoles.TR_USERROLE_ADDSONGSUSER,
EUserRights.AddSongToPlaylist
},
{
EUserRoles.TR_USERROLE_PLAYLISTEDITOR,
(EUserRights.AddSongToPlaylist |
EUserRights.ReorderPlaylists |
EUserRights.CreatePlaylists |
EUserRights.DeletePlaylists |
EUserRights.RemoveSongsFromPlaylists)
},
{
EUserRoles.TR_USERROLE_PROFILEEDITOR,
EUserRights.EditAllProfiles
}
};
internal static EUserRights GetUserRightsFromUserRole(EUserRoles userRole)
{
return _RoleRightsMapping.Where(role => userRole.HasFlag(role.Key))
.Select(role => role.Value)
.Aggregate(EUserRights.None, (current, r) => current | r);
}
}
}
+35
View File
@@ -0,0 +1,35 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
namespace Vocaluxe.Base.Server
{
[Flags]
enum EUserRoles
{
// ReSharper disable InconsistentNaming
TR_USERROLE_GUEST = 0,
TR_USERROLE_NORMAL = 1,
TR_USERROLE_ADMIN = 2,
TR_USERROLE_KEYBOARDUSER = 4,
TR_USERROLE_ADDSONGSUSER = 8,
TR_USERROLE_PLAYLISTEDITOR = 16,
TR_USERROLE_PROFILEEDITOR = 32
// ReSharper restore InconsistentNaming
}
}
+122
View File
@@ -15,6 +15,14 @@
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
namespace Vocaluxe.Base.Server
{
public struct SLoginData
@@ -35,4 +43,118 @@ namespace Vocaluxe.Base.Server
public string PlayerName;
public int Difficulty;
}
[DataContract]
public struct SProfileData
{
[DataMember]
public CBase64Image Avatar;
[DataMember]
public string PlayerName;
[DataMember]
public int Type;
[DataMember]
public int Difficulty;
[DataMember]
public int ProfileId;
[DataMember]
public bool IsEditable;
[DataMember]
public string Password;
}
[DataContract]
public struct SPhotoData
{
[DataMember]
public CBase64Image Photo;
//Add infomation about the user who took this image??
}
[DataContract]
public class CBase64Image
{
// ReSharper disable InconsistentNaming
[DataMember]
private string base64Data = "";
[DataMember]
private string imageId = "";
// ReSharper restore InconsistentNaming
public CBase64Image(Image img, ImageFormat format)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, format);
string formatString = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid).FilenameExtension.Replace("*.", "").ToLower();
base64Data = "data:image/" + formatString + ";base64," + Convert.ToBase64String(ms.ToArray());
}
public CBase64Image(string imageId)
{
this.imageId = imageId;
}
public Image GetImage()
{
string onlyBase64Data = base64Data.Substring(base64Data.IndexOf(";base64,") + (";base64,").Length);
byte[] imageData = Convert.FromBase64String(onlyBase64Data);
MemoryStream ms = new MemoryStream(imageData, 0, imageData.Length);
ms.Write(imageData, 0, imageData.Length);
Image image = Image.FromStream(ms, true);
return image;
}
public string GetImageType()
{
Match match = Regex.Match(base64Data, "(?<=data:image/)[a-zA-Z]+(?=;base64)");
return match.Success ? match.Groups[0].Value : "";
}
}
[DataContract]
public struct SSongInfo
{
[DataMember]
public string Title;
[DataMember]
public string Artist;
[DataMember]
public CBase64Image Cover;
[DataMember]
public string Genre { get; set; }
[DataMember]
public string Language { get; set; }
[DataMember]
public string Year { get; set; }
[DataMember]
public bool IsDuet { get; set; }
[DataMember]
public int SongId { get; set; }
}
[DataContract]
public struct SPlaylistSongInfo
{
[DataMember]
public SSongInfo Song;
[DataMember]
public int PlaylistId;
[DataMember]
public int PlaylistPosition;
[DataMember]
public int GameMode;
}
[DataContract]
public struct SPlaylistData
{
[DataMember]
public int PlaylistId;
[DataMember]
public string PlaylistName;
[DataMember]
public int SongCount;
[DataMember]
public string LastChanged;
}
}
+2
View File
@@ -21,6 +21,7 @@ using Vocaluxe.Base;
using VocaluxeLib;
using VocaluxeLib.Draw;
using System.Diagnostics;
using Vocaluxe.Base.Server;
namespace Vocaluxe.Lib.Draw
{
@@ -329,6 +330,7 @@ namespace Vocaluxe.Lib.Draw
while (_Run)
{
_CheckQueue();
CVocaluxeServer.ProcessServerTasks();
//We want to begin drawing
_OnBeforeDraw();
+10 -6
View File
@@ -210,6 +210,9 @@
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.XML" />
@@ -219,6 +222,13 @@
<Compile Include="Base\CCoverGenerator.cs" />
<Compile Include="Base\CPlaylistElement.cs" />
<Compile Include="Base\CRecord.cs" />
<Compile Include="Base\Server\CWebservice.cs" />
<Compile Include="Base\Server\ICWebservice.cs" />
<Compile Include="Base\Server\Session.cs" />
<Compile Include="Base\Server\SessionControl.cs" />
<Compile Include="Base\Server\UserRights.cs" />
<Compile Include="Base\Server\UserRoleControl.cs" />
<Compile Include="Base\Server\UserRoles.cs" />
<Compile Include="Base\ThemeSystem\CBaseTheme.cs" />
<Compile Include="Base\ThemeSystem\CPartySkin.cs" />
<Compile Include="Base\ThemeSystem\CBaseSkin.cs" />
@@ -274,8 +284,6 @@
<Compile Include="Base\CWebcam.cs" />
<Compile Include="Base\Fonts\CFonts.cs" />
<Compile Include="Base\Fonts\CGlyph.cs" />
<Compile Include="Base\Server\CClientHandler.cs" />
<Compile Include="Base\Server\CCommands.cs" />
<Compile Include="Base\Server\CVocaluxeServer.cs" />
<Compile Include="Base\Server\VocaluxeStructs.cs" />
<Compile Include="CProgrammHelper.cs" />
@@ -513,10 +521,6 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ServerLib\ServerLib.csproj">
<Project>{ec5167e4-ccfb-4cee-987c-cf816f1062a3}</Project>
<Name>ServerLib</Name>
</ProjectReference>
<ProjectReference Include="..\VocaluxeLib\VocaluxeLib.csproj">
<Project>{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}</Project>
<Name>VocaluxeLib</Name>