Merge pull request #84 from lukeIam/WSRebaseTry

Webserver and App
This commit is contained in:
Stephan Sundermann committed 2013-12-16 11:45:36 -08:00
commit 355fa08599
82 files changed
+6347 -4499

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
+2
View File
@@ -52,5 +52,7 @@ AndroidRemote.dll.mdb
/ClientServerLib/AndroidRemote/bin/AndroidRemote.dll
/ClientServerLib/ClientTest/bin/Debug/Newtonsoft.Json.dll
*.apk
/Output/ClientServerLib.dll
Installer/VocaluxeSetup_0.3.0Beta.exe
Output/Vocaluxe_x64.exe
/WebserverInitalConfig/bin/Release
-405
View File
@@ -1,405 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace ClientServerLib
{
public class CClient
{
private bool doConnect;
private bool connected;
private bool running;
private int bufferLength = 8192;
private Thread clientThread;
private IPEndPoint serverEndPoint;
private string ip;
private int port;
private CConnection connection;
private List<SRequest> requests;
private List<SRequest> responses;
private Object mutexRequests = new Object();
private OnConnectionChanged onConnectionChanged;
private OnSend onSend;
private OnReceived onReceived;
private byte[] data;
public bool Connected
{
get { return connected; }
}
public CClient()
{
doConnect = false;
connected = false;
running = true;
requests = new List<SRequest>();
responses = new List<SRequest>();
data = new byte[bufferLength];
connection = new CConnection(new TcpClient(), -1);
}
public void Connect(string IP = "127.0.0.1", int Port = 3000, string Password = null,
OnConnectionChanged OnConnectionChanged = null,
OnSend OnSend = null,
OnReceived OnReceived = null)
{
if (!doConnect)
{
onConnectionChanged = OnConnectionChanged;
onSend = OnSend;
onReceived = OnReceived;
ip = IP;
port = Port;
connection.Password = Password;
doConnect = true;
if (clientThread == null)
{
running = true;
clientThread = new Thread(new ThreadStart(Runner));
clientThread.Start();
}
}
}
public void Disconnect()
{
if (doConnect)
{
doConnect = false;
lock (mutexRequests)
{
requests.Clear();
}
lock (responses)
{
responses.Clear();
}
}
}
public void Close()
{
running = false;
if (clientThread != null)
clientThread.Join(100);
clientThread = null;
DoDisconnect();
}
public void SendMessage(byte[] Message, ResponseCallback Callback)
{
SRequest req = new SRequest();
req.Command = Message;
req.Callback = Callback;
req.Response = null;
lock (mutexRequests)
{
requests.Add(req);
}
}
private void Runner()
{
while (running)
{
if (!connected && doConnect)
{
try
{
IPAddress resolvedIP;
if (TryResolveIPAddress(ip, out resolvedIP))
{
serverEndPoint = new IPEndPoint(resolvedIP, port);
connection.TcpClient.Connect(serverEndPoint);
connected = true;
RaiseOnConnectionChanged();
}
}
catch
{
DoDisconnect();
for (int i = 0; i < 500; i++)
{
if (running && doConnect)
Thread.Sleep(10);
else
break;
}
}
}
if (connected && !doConnect)
{
DoDisconnect();
}
if (doConnect && connected)
{
try
{
Communicate();
Thread.Sleep(10);
}
catch
{
DoDisconnect();
}
}
if (!doConnect && !connected)
{
for (int i = 0; i < 500; i++)
{
if (running && !doConnect)
Thread.Sleep(10);
else
break;
}
}
}
}
public bool TryResolveIPAddress(string serverNameOrURL, out IPAddress resolvedIPAddress)
{
bool isResolved = false;
IPHostEntry hostEntry = null;
IPAddress resolvIP = null;
try
{
if (!IPAddress.TryParse(serverNameOrURL, out resolvIP))
{
hostEntry = Dns.GetHostEntry(serverNameOrURL);
if (hostEntry != null && hostEntry.AddressList != null && hostEntry.AddressList.Length > 0)
{
if (hostEntry.AddressList.Length == 1)
{
resolvIP = hostEntry.AddressList[0];
isResolved = true;
}
else
{
foreach (IPAddress var in hostEntry.AddressList)
{
if (var.AddressFamily == AddressFamily.InterNetwork)
{
resolvIP = var;
isResolved = true;
break;
}
}
}
}
}
else
isResolved = true;
}
catch (Exception) {}
finally
{
resolvedIPAddress = resolvIP;
}
return isResolved;
}
private void DoDisconnect()
{
try
{
connection.TcpClient.Close();
}
catch { }
connection = new CConnection(new TcpClient(), -1);
connected = false;
doConnect = false;
RaiseOnConnectionChanged();
}
private void Communicate()
{
if (connection.TcpClient == null || !connection.TcpClient.Connected)
DoDisconnect();
NetworkStream clientStream = connection.TcpClient.GetStream();
int bytesRead;
if (!connection.KeySet)
{
bytesRead = 0;
try
{
bytesRead = clientStream.Read(data, 0, bufferLength);
}
catch
{
return;
}
if (bytesRead == 0)
return;
byte[] serverParam = new byte[bytesRead];
Array.Copy(data, serverParam, bytesRead);
RaiseOnReceived(serverParam);
byte[] clientResponse = connection.CreateClientKey(serverParam);
RaiseOnSend(clientResponse);
clientStream.Write(clientResponse, 0, clientResponse.Length);
clientStream.Flush();
}
else
{
try
{
while (requests.Count > 0)
{
SRequest res = HandleRequest(requests[0]);
lock (responses)
{
responses.Add(res);
}
lock (mutexRequests)
{
requests.RemoveAt(0);
}
}
}
catch { };
lock (responses)
{
while (responses.Count > 0)
{
try
{
if (responses[0].Callback != null)
responses[0].Callback(responses[0].Response);
}
finally
{
responses.RemoveAt(0);
}
}
}
}
}
private SRequest HandleRequest(SRequest request)
{
SRequest response = new SRequest();
response.Command = request.Command;
response.Callback = request.Callback;
response.Response = null;
NetworkStream clientStream = connection.TcpClient.GetStream();
RaiseOnSend(request.Command);
byte[] encrypted = connection.Encrypt(request.Command);
int sendBytes = 0;
while(sendBytes < encrypted.Length)
{
int bytesToSend = encrypted.Length - sendBytes;
if (bytesToSend > bufferLength)
bytesToSend = bufferLength;
clientStream.Write(encrypted, sendBytes, bytesToSend);
sendBytes += bytesToSend;
}
clientStream.Flush();
byte[] data = new byte[bufferLength];
int bytesRead = 0;
try
{
bytesRead = clientStream.Read(data, 0, bufferLength);
}
catch
{
return response;
}
if (bytesRead == 0)
return response;
int messageLength = BitConverter.ToInt32(data, 0);
while (messageLength > bytesRead)
{
if (data.Length < messageLength + bufferLength)
Array.Resize<byte>(ref data, messageLength + bufferLength);
bytesRead += clientStream.Read(data, bytesRead, bufferLength);
}
encrypted = new byte[bytesRead];
Array.Copy(data, encrypted, bytesRead);
response.Response = connection.Decrypt(encrypted);
RaiseOnReceived(response.Response);
return response;
}
private void RaiseOnConnectionChanged()
{
if (onConnectionChanged == null)
return;
try
{
onConnectionChanged(connected);
}
catch (Exception e)
{
Console.WriteLine (e.Message);
}
}
private void RaiseOnSend(byte[] Message)
{
if (onSend == null)
return;
try
{
onSend(Message);
}
catch { }
}
private void RaiseOnReceived(byte[] Message)
{
if (onReceived == null)
return;
try
{
onReceived(Message);
}
catch { }
}
}
}
@@ -1,307 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Text;
using DiffieHellman;
namespace ClientServerLib
{
internal class CConnection
{
private bool keySet;
private byte[] key;
private bool encryption;
private string password;
private CDiffieHellman dh;
private UTF8Encoding encoder;
private int connectionID;
private static SHA256Managed SHA256 = new SHA256Managed();
public TcpClient TcpClient;
public bool KeySet
{
get { return keySet; }
}
public int ConnectionID
{
get { return connectionID; }
}
public string Password
{
set
{
password = value;
encryption = value != null;
keySet = false;
}
}
public CConnection(TcpClient client, int ConnectionID, string Password = null)
{
TcpClient = client;
client.NoDelay = true;
keySet = false;
encryption = Password != null;
password = Password;
connectionID = ConnectionID;
encoder = new UTF8Encoding();
key = null;
}
public byte[] GetKeyParams()
{
if (!encryption)
{
return encoder.GetBytes("NO ENCRYPTION");
}
if (dh == null)
dh = new CDiffieHellman(256).GenerateRequest();
return encoder.GetBytes(dh.ToString());
}
public byte[] CreateClientKey(byte[] serverParam)
{
if (serverParam == null)
return null;
string response = encoder.GetString(serverParam, 0, serverParam.Length);
if (response == "NO ENCRYPTION")
{
encryption = false;
keySet = true;
key = null;
return encoder.GetBytes(response);
}
dh = new CDiffieHellman(256).GenerateResponse(response);
key = _BuildHash(dh.Key, password);
keySet = true;
encryption = true;
return encoder.GetBytes(dh.ToString());
}
public void CreateServerKey(byte[] clientResponse)
{
string response = encoder.GetString(clientResponse, 0, clientResponse.Length);
if (response == "NO ENCRYPTION")
{
keySet = true;
key = null;
return;
}
if (dh == null)
return;
dh.HandleResponse(response);
key = _BuildHash(dh.Key, password);
keySet = true;
}
public byte[] Encrypt(byte[] Data)
{
return _Encrypt(_Compress(Data));
}
public byte[] Decrypt(byte[] Data)
{
return _Decompress(_Decrypt(Data));
}
private byte[] _BuildHash(byte[] Key, string Password)
{
if (Key == null || Password == null)
return null;
byte[] hash = SHA256.ComputeHash(encoder.GetBytes(Password));
byte[] serial = new byte[Key.Length + hash.Length];
Array.Copy(Key, serial, Key.Length);
Array.Copy(hash, 0, serial, Key.Length, hash.Length);
return SHA256.ComputeHash(serial);
}
private byte[] _Encrypt(byte[] Data)
{
if (Data == null || (!keySet && encryption))
return Data;
byte[] dataLength = BitConverter.GetBytes(Data.Length);
if (!encryption)
{
int len = 4 + dataLength.Length + Data.Length;
byte[] messageLength = BitConverter.GetBytes(len);
using (var stream = new MemoryStream())
{
stream.Write(messageLength, 0, messageLength.Length);
stream.Write(dataLength, 0, dataLength.Length);
stream.Write(Data, 0, Data.Length);
return stream.ToArray();
}
}
using (Aes aes = new AesManaged())
{
aes.Key = key;
aes.GenerateIV();
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
using (var memoryStream = new MemoryStream())
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(Data, 0, Data.Length);
cryptoStream.FlushFinalBlock();
byte[] encrypted = memoryStream.ToArray();
int len = 4 + aes.IV.Length + dataLength.Length + encrypted.Length;
byte[] messageLength = BitConverter.GetBytes(len);
using (var stream = new MemoryStream())
{
stream.Write(messageLength, 0, messageLength.Length);
stream.Write(aes.IV, 0, aes.IV.Length);
stream.Write(dataLength, 0, dataLength.Length);
stream.Write(encrypted, 0, encrypted.Length);
return stream.ToArray();
}
}
}
}
private byte[] _Decrypt(byte[] Data)
{
if (Data == null || (!keySet && encryption))
return Data;
int messageLength = BitConverter.ToInt32(Data, 0);
if (messageLength > Data.Length)
return null;
int dataLength;
if (!encryption)
{
dataLength = BitConverter.ToInt32(Data, 4);
byte[] message = new byte[dataLength];
Array.Copy(Data, 8, message, 0, dataLength);
return message;
}
if (Data.Length < 25)
return null;
byte[] IV = new byte[16];
Array.Copy(Data, 4, IV, 0, 16);
dataLength = BitConverter.ToInt32(Data, 20);
using (Aes aes = new AesManaged())
{
aes.Key = key;
aes.IV = IV;
byte[] encrypted = new byte[messageLength - 24];
Array.Copy(Data, 24, encrypted, 0, encrypted.Length);
try
{
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
using (var memoryStream = new MemoryStream())
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(encrypted, 0, encrypted.Length);
cryptoStream.FlushFinalBlock();
cryptoStream.Close();
byte[] decrypted = memoryStream.ToArray();
byte[] message = new byte[dataLength];
Array.Copy(decrypted, message, dataLength);
return message;
}
}
catch
{
return null;
}
}
}
private byte[] _Compress(byte[] Data)
{
if (Data == null)
return Data;
using (var compressed = new MemoryStream())
{
using (var gz = new GZipStream(compressed, CompressionMode.Compress, true))
{
gz.Write(Data, 0, Data.Length);
}
byte[] result = null;
if (compressed.Length < Data.Length)
{
result = new byte[compressed.Length + 1];
result[0] = 1; //data stream is compressed
compressed.Position = 0;
compressed.Read(result, 1, (int)compressed.Length);
}
else
{
result = new byte[Data.Length + 1];
result[0] = 0; //data stream is not compressed
Array.Copy(Data, 0, result, 1, Data.Length);
}
return result;
}
}
private byte[] _Decompress(byte[] Data)
{
if (Data == null)
return Data;
if (Data[0] == 0) //not compressed
{
byte[] result = new byte[Data.Length - 1];
Array.Copy(Data, 1, result, 0, result.Length);
return result;
}
using (var inStream = new MemoryStream())
{
inStream.Write(Data, 1, Data.Length - 1);
inStream.Position = 0;
using (var outStream = new MemoryStream())
{
using (var gz = new GZipStream(inStream, CompressionMode.Decompress, true))
gz.CopyTo(outStream);
return outStream.ToArray();
}
}
}
}
}
+125 -125
View File
@@ -1,125 +1,125 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Timers;
namespace ClientServerLib
{
public delegate void OnServerDiscovered(string IPAddress, string Hostname);
public class CDiscover
{
public static readonly string sTimeout = "Timeout";
public static readonly string sFinished = "Finished";
private string _Keyword;
private string _BroadcastAddress;
private int _Port;
private Thread _DiscoverThread;
private bool _DiscoverRunning;
private OnServerDiscovered _OnDiscovered;
private System.Timers.Timer _BroadcastTimer;
public CDiscover(int Port, string Keyword, string BroadcastAddress = "255.255.255.255")
{
_BroadcastAddress = BroadcastAddress;
_Port = Port;
_Keyword = Keyword;
_DiscoverRunning = false;
_BroadcastTimer = new System.Timers.Timer();
_BroadcastTimer.Elapsed += new ElapsedEventHandler(OnBroadcastEvent);
_BroadcastTimer.Interval = 2500;
}
public void StartBroadcasting()
{
_BroadcastTimer.Start();
}
public void Stop()
{
_BroadcastTimer.Stop();
_DiscoverRunning = false;
}
public void Discover(OnServerDiscovered OnDiscovered, int Timeout = 5000)
{
if (_DiscoverRunning)
return;
_DiscoverRunning = true;
_DiscoverThread = new Thread(() => _Discover(Timeout));
_OnDiscovered = OnDiscovered;
_DiscoverThread.Start();
}
private void OnBroadcastEvent(object source, ElapsedEventArgs e)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
s.EnableBroadcast = true;
IPAddress broadcast = IPAddress.Parse(_BroadcastAddress);
byte[] sendbuf = Encoding.UTF8.GetBytes(_Keyword);
IPEndPoint ep = new IPEndPoint(broadcast, _Port);
s.SendTo(sendbuf, ep);
s.Close();
}
private void _Discover(int Timeout)
{
UdpClient listener = null;
Stopwatch timer = new Stopwatch();
List<string> knownServer = new List<string>();
bool foundSomething = false;
timer.Start();
while (_DiscoverRunning && timer.ElapsedMilliseconds < Timeout * 2)
{
try
{
listener = new UdpClient(_Port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _Port);
listener.Client.ReceiveTimeout = Timeout;
byte[] bytes = listener.Receive(ref groupEP);
string message = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
foundSomething = true;
if (!knownServer.Contains(groupEP.Address.ToString()))
{
knownServer.Add(groupEP.Address.ToString());
if (_OnDiscovered != null)
{
IPHostEntry e = Dns.GetHostEntry(groupEP.Address);
string hostname = e.HostName;
_OnDiscovered(groupEP.Address.ToString(), hostname);
}
}
listener.Close();
}
catch (Exception)
{
if (listener != null)
listener.Close();
}
}
_DiscoverRunning = false;
if (!foundSomething)
_OnDiscovered(sTimeout, String.Empty);
else
_OnDiscovered(sFinished, String.Empty);
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Timers;
namespace ServerLib
{
public delegate void OnServerDiscovered(string IPAddress, string Hostname);
public class CDiscover
{
public static readonly string sTimeout = "Timeout";
public static readonly string sFinished = "Finished";
private string _Keyword;
private string _BroadcastAddress;
private int _Port;
private Thread _DiscoverThread;
private bool _DiscoverRunning;
private OnServerDiscovered _OnDiscovered;
private System.Timers.Timer _BroadcastTimer;
public CDiscover(int Port, string Keyword, string BroadcastAddress = "255.255.255.255")
{
_BroadcastAddress = BroadcastAddress;
_Port = Port;
_Keyword = Keyword;
_DiscoverRunning = false;
_BroadcastTimer = new System.Timers.Timer();
_BroadcastTimer.Elapsed += new ElapsedEventHandler(OnBroadcastEvent);
_BroadcastTimer.Interval = 2500;
}
public void StartBroadcasting()
{
_BroadcastTimer.Start();
}
public void Stop()
{
_BroadcastTimer.Stop();
_DiscoverRunning = false;
}
public void Discover(OnServerDiscovered OnDiscovered, int Timeout = 5000)
{
if (_DiscoverRunning)
return;
_DiscoverRunning = true;
_DiscoverThread = new Thread(() => _Discover(Timeout));
_OnDiscovered = OnDiscovered;
_DiscoverThread.Start();
}
private void OnBroadcastEvent(object source, ElapsedEventArgs e)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
s.EnableBroadcast = true;
IPAddress broadcast = IPAddress.Parse(_BroadcastAddress);
byte[] sendbuf = Encoding.UTF8.GetBytes(_Keyword);
IPEndPoint ep = new IPEndPoint(broadcast, _Port);
s.SendTo(sendbuf, ep);
s.Close();
}
private void _Discover(int Timeout)
{
UdpClient listener = null;
Stopwatch timer = new Stopwatch();
List<string> knownServer = new List<string>();
bool foundSomething = false;
timer.Start();
while (_DiscoverRunning && timer.ElapsedMilliseconds < Timeout * 2)
{
try
{
listener = new UdpClient(_Port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _Port);
listener.Client.ReceiveTimeout = Timeout;
byte[] bytes = listener.Receive(ref groupEP);
string message = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
foundSomething = true;
if (!knownServer.Contains(groupEP.Address.ToString()))
{
knownServer.Add(groupEP.Address.ToString());
if (_OnDiscovered != null)
{
IPHostEntry e = Dns.GetHostEntry(groupEP.Address);
string hostname = e.HostName;
_OnDiscovered(groupEP.Address.ToString(), hostname);
}
}
listener.Close();
}
catch (Exception)
{
if (listener != null)
listener.Close();
}
}
_DiscoverRunning = false;
if (!foundSomething)
_OnDiscovered(sTimeout, String.Empty);
else
_OnDiscovered(sFinished, String.Empty);
}
}
}
+279 -160
View File
@@ -1,194 +1,313 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace ClientServerLib
namespace ServerLib
{
public class CServer
{
private TcpListener tcpListener;
private Thread listenThread;
private int port;
private bool encryption;
private string password;
private int bufferLength = 8192;
private bool running;
private ServiceHost _Host;
private Uri _BaseAddress;
private bool _Encrypted = false;
private HandleRequest requestCallback;
private Dictionary<int, CConnection> clients;
private Queue<int> ids;
public CServer(HandleRequest RequestCallback, int Port = 3000, string Password = null)
private static SendKeyEventDelegate _SendKeyEvent;
public static SendKeyEventDelegate SendKeyEvent
{
port = Port;
running = false;
requestCallback = RequestCallback;
encryption = Password != null;
password = Password;
internal get { return CServer._SendKeyEvent; }
set { CServer._SendKeyEvent = value; }
}
clients = new Dictionary<int, CConnection>();
ids = new Queue<int>(1000);
#region profile
for (int i = 0; i < 1000; i++)
ids.Enqueue(i);
private static GetProfileDataDelegate _GetProfileData;
public static GetProfileDataDelegate GetProfileData
{
internal get { return CServer._GetProfileData; }
set { CServer._GetProfileData = value; }
}
private static SendProfileDataDelegate _SendProfileData;
public static SendProfileDataDelegate SendProfileData
{
internal get { return CServer._SendProfileData; }
set { CServer._SendProfileData = value; }
}
private static GetProfileListDelegate _GetProfileList;
public static GetProfileListDelegate GetProfileList
{
internal get { return CServer._GetProfileList; }
set { CServer._GetProfileList = value; }
}
#endregion
#region photo
private static SendPhotoDelegate _SendPhoto;
public static SendPhotoDelegate SendPhoto
{
get { return CServer._SendPhoto; }
set { CServer._SendPhoto = value; }
}
#endregion
#region website
private static GetSiteFileDelegate _GetSiteFile;
public static GetSiteFileDelegate GetSiteFile
{
internal get { return CServer._GetSiteFile; }
set { CServer._GetSiteFile = value; }
}
private static GetDelayedImageDelegate _GetDelayedImage;
public static GetDelayedImageDelegate GetDelayedImage
{
internal get { return CServer._GetDelayedImage; }
set { CServer._GetDelayedImage = value; }
}
#endregion
#region songs
private static GetSongDelegate _GetSong;
public static GetSongDelegate GetSong
{
internal get { return CServer._GetSong; }
set { CServer._GetSong = value; }
}
private static GetAllSongsDelegate _GetAllSongs;
public static GetAllSongsDelegate GetAllSongs
{
internal get { return CServer._GetAllSongs; }
set { CServer._GetAllSongs = value; }
}
private static GetCurrentSongIdDelegate _GetCurrentSongId;
public static GetCurrentSongIdDelegate GetCurrentSongId
{
internal get { return CServer._GetCurrentSongId; }
set { CServer._GetCurrentSongId = value; }
}
#endregion
#region playlist
private static GetPlaylistsDelegate _GetPlaylists;
public static GetPlaylistsDelegate GetPlaylists
{
internal get { return _GetPlaylists; }
set { _GetPlaylists = value; }
}
private static GetPlaylistDelegate _GetPlaylist;
public static GetPlaylistDelegate GetPlaylist
{
internal get { return _GetPlaylist; }
set { _GetPlaylist = value; }
}
private static AddSongToPlaylistDelegate _AddSongToPlaylist;
public static AddSongToPlaylistDelegate AddSongToPlaylist
{
internal get { return _AddSongToPlaylist; }
set { _AddSongToPlaylist = value; }
}
private static RemoveSongFromPlaylistDelegate _RemoveSongFromPlaylist;
public static RemoveSongFromPlaylistDelegate RemoveSongFromPlaylist
{
internal get { return _RemoveSongFromPlaylist; }
set { _RemoveSongFromPlaylist = value; }
}
private static MoveSongInPlaylistDelegate _MoveSongInPlaylist;
public static MoveSongInPlaylistDelegate MoveSongInPlaylist
{
internal get { return _MoveSongInPlaylist; }
set { _MoveSongInPlaylist = value; }
}
private static PlaylistContainsSongDelegate _PlaylistContainsSong;
public static PlaylistContainsSongDelegate PlaylistContainsSong
{
internal get { return _PlaylistContainsSong; }
set { _PlaylistContainsSong = value; }
}
private static GetPlaylistSongsDelegate _GetPlaylistSongs;
public static GetPlaylistSongsDelegate GetPlaylistSongs
{
internal get { return _GetPlaylistSongs; }
set { _GetPlaylistSongs = value; }
}
private static RemovePlaylistDelegate _RemovePlaylist;
public static RemovePlaylistDelegate RemovePlaylist
{
internal get { return _RemovePlaylist; }
set { _RemovePlaylist = value; }
}
private static AddPlaylistDelegate _AddPlaylist;
public static AddPlaylistDelegate AddPlaylist
{
internal get { return _AddPlaylist; }
set { _AddPlaylist = value; }
}
#endregion
#region user management
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)
{
_Init(port, encrypted);
}
#region server control
private void _Init(int port, bool encrypted)
{
string hostname = Dns.GetHostName();
if (encrypted)
{
_BaseAddress = new Uri("https://" + hostname + ":" + port + "/");
}
else
{
_BaseAddress = new Uri("http://" + hostname + ":" + port + "/");
}
this._Encrypted = encrypted;
_Host = new WebServiceHost(typeof(CWebservice), _BaseAddress);
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, "");
}
public void Start()
{
if (!running)
try
{
running = true;
/*ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);*/
tcpListener = new TcpListener(IPAddress.Any, port);
listenThread = new Thread(new ThreadStart(ListenForClients));
listenThread.Start();
_Host.Open();
}
catch (CommunicationException e)
{
if (e is AddressAccessDeniedException || e is AddressAlreadyInUseException)
{
_RegisterUrlAndCert(_BaseAddress.Port);
try
{
_Host.Abort();
_Init(_BaseAddress.Port, _Encrypted);
_Host.Open();
}
catch (CommunicationException e2)
{
_Host.Abort();
}
}
else
{
_Host.Abort();
}
}
}
public void Stop()
{
if (running)
try
{
running = false;
tcpListener.Stop();
Thread.Sleep(100);
listenThread.Join();
lock (clients)
{
int[] cIDs = new int[clients.Count];
clients.Keys.CopyTo(cIDs, 0);
foreach (int id in cIDs)
{
clients.Remove(id);
ids.Enqueue(id);
}
}
_Host.Close();
}
catch (CommunicationException e)
{
_Host.Abort();
}
}
private void ListenForClients()
private void _RegisterUrlAndCert(int port)
{
tcpListener.Start();
TcpClient client;
#if WIN
while (running)
ProcessStartInfo info = new ProcessStartInfo
{
//wait for new client
try
{
client = tcpListener.AcceptTcpClient();
}
catch
{
client = null;
}
if (client != null)
{
int id = ids.Dequeue();
CConnection connection = new CConnection(client, id, password);
lock (clients)
{
clients.Add(id, connection);
}
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientCom));
NetworkStream clientStream = client.GetStream();
byte[] serverParams = connection.GetKeyParams();
try
{
clientStream.Write(serverParams, 0, serverParams.Length);
clientStream.Flush();
}
catch
{
client = null;
}
if (client != null)
clientThread.Start(connection);
}
}
}
private void HandleClientCom(object client)
{
CConnection connection = (CConnection)client;
TcpClient tcpClient = (TcpClient)connection.TcpClient;
NetworkStream clientStream = tcpClient.GetStream();
byte[] data = new byte[bufferLength];
int bytesRead;
while (running)
FileName = "VocaluxeServerConfig.exe",
Arguments = port.ToString() + " " + _Encrypted.ToString(),
UseShellExecute = true,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
Verb = "runas"
};
Process p = Process.Start(info);
if (p != null)
{
bytesRead = 0;
try
{
bytesRead = clientStream.Read(data, 0, bufferLength);
}
catch
{
break;
}
if (bytesRead == 0)
break;
if (!connection.KeySet)
{
byte[] clientResponse = new byte[bytesRead];
Array.Copy(data, clientResponse, bytesRead);
connection.CreateServerKey(clientResponse);
}
else
{
//receive message
int messageLength = BitConverter.ToInt32(data, 0);
while (messageLength > bytesRead)
{
if (data.Length < messageLength + bufferLength)
Array.Resize<byte>(ref data, messageLength + bufferLength);
bytesRead += clientStream.Read(data, bytesRead, bufferLength);
}
byte[] message = new byte[bytesRead];
Array.Copy(data, message, bytesRead);
byte[] decrypted = connection.Decrypt(message);
byte[] answer = HandleClientMessage(decrypted, connection);
//send message
byte[] encrypted = connection.Encrypt(answer);
try
{
clientStream.Write(encrypted, 0, encrypted.Length);
clientStream.Flush();
}
catch
{
break;
}
}
p.WaitForExit();
p.Close();
}
#else
//Required?
#endif
}
private byte[] HandleClientMessage(byte[] Message, CConnection connection)
{
return requestCallback(connection.ConnectionID, Message);
}
#endregion
}
}
@@ -0,0 +1,458 @@
using System;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.IO;
using System.ServiceModel.Channels;
namespace ServerLib
{
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 e)
{
}
return sessionKey;
}
public void SendKeyEvent(string key)
{
if (!_CheckRight(EUserRights.UseKeyboard))
{
return;
}
if (CServer.SendKeyEvent == null)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "Not found";
}
}
else
{
CServer.SendKeyEvent(key);
}
}
#region profile
public int GetOwnProfileId()
{
Guid sessionKey = _GetSession();
if (sessionKey == Guid.Empty)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.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 = System.Net.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;
}
}
if (CServer.SendProfileData == null)
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.NotFound;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "Not found";
}
return;
}
CServer.SendProfileData(profile);
}
public SProfileData GetProfile(int profileId)
{
Guid sessionKey = _GetSession();
if (_CheckRight(EUserRights.ViewOtherProfiles) || CSessionControl.GetUserIdFromSession(sessionKey) == profileId)
{
if (CServer.GetProfileData == null)
{
return new SProfileData();
}
bool isReadonly = (!CSessionControl.RequestRight(sessionKey, EUserRights.EditAllProfiles) &&
CSessionControl.GetUserIdFromSession(sessionKey) != profileId);
return CServer.GetProfileData(profileId, isReadonly);
}
else
{
return new SProfileData();
}
}
public SProfileData[] GetProfileList()
{
if (CServer.GetProfileList == null)
{
return new SProfileData[] { };
}
return CServer.GetProfileList();
}
#endregion
#region photo
public void SendPhoto(SPhotoData photo)
{
if (_CheckRight(EUserRights.UploadPhotos))
{
CServer.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 = System.Net.HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "Wrong username or password";
}
}
return sessionId;
}
public Stream Index()
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
}
return new MemoryStream(CServer.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 = CServer.GetSiteFile("js/" + filename);
if (data != null)
{
return new MemoryStream(data);
}
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.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 = CServer.GetSiteFile("css/" + filename);
if (data != null)
{
return new MemoryStream(data);
}
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.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 = CServer.GetSiteFile("css\\images\\" + filename);
if (data != null)
{
return new MemoryStream(data);
}
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.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 = CServer.GetSiteFile("img/" + filename);
if (data != null)
{
return new MemoryStream(data);
}
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.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 = CServer.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 CServer.GetDelayedImage(id);
}
public bool IsServerOnline()
{
return true;
}
#endregion
#region songs
public SSongInfo GetSong(int songId)
{
return CServer.GetSong(songId);
}
public int GetCurrentSongId()
{
return CServer.GetCurrentSongId();
}
public SSongInfo[] GetAllSongs()
{
return CServer.GetAllSongs();
}
#endregion
#region playlist
public SPlaylistInfo[] GetPlaylists()
{
return CServer.GetPlaylists();
}
public SPlaylistInfo GetPlaylist(int playlistId)
{
return CServer.GetPlaylist(playlistId);
}
public void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates)
{
if (_CheckRight(EUserRights.AddSongToPlaylist))
{
CServer.AddSongToPlaylist(songId, playlistId, allowDuplicates);
}
}
public void RemoveSongFromPlaylist(int position, int playlistId, int songId)
{
if (_CheckRight(EUserRights.RemoveSongsFromPlaylists))
{
CServer.RemoveSongFromPlaylist(position, playlistId, songId);
}
}
public void MoveSongInPlaylist(int newPosition, int playlistId, int songId)
{
if (_CheckRight(EUserRights.ReorderPlaylists))
{
CServer.MoveSongInPlaylist(newPosition, playlistId, songId);
}
}
public bool PlaylistContainsSong(int songId, int playlistId)
{
return CServer.PlaylistContainsSong(songId, playlistId);
}
public SPlaylistSongInfo[] GetPlaylistSongs(int playlistId)
{
return CServer.GetPlaylistSongs(playlistId);
}
public void RemovePlaylist(int playlistId)
{
if (_CheckRight(EUserRights.DeletePlaylists))
{
CServer.RemovePlaylist(playlistId);
}
}
public int AddPlaylist(string playlistName)
{
if (_CheckRight(EUserRights.CreatePlaylists))
{
return CServer.AddPlaylist(playlistName);
}
return -1;
}
#endregion
#region user management
public int GetUserRole(int profileId)
{
return CServer.GetUserRole(profileId);
}
public void SetUserRole(int profileId, int userRole)
{
if (_CheckRight(EUserRights.EditAllProfiles))
{
CServer.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 = System.Net.HttpStatusCode.Forbidden;
WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session";
}
return false;
}
if (!CSessionControl.RequestRight(sessionKey, requestedRight))
{
if (WebOperationContext.Current != null)
{
WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.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
}
}
@@ -0,0 +1,196 @@
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
namespace ServerLib
{
public delegate bool SendKeyEventDelegate(string key);
#region profile
public delegate SProfileData GetProfileDataDelegate(int profileId, bool isReadonly);
public delegate bool SendProfileDataDelegate(SProfileData profile);
public delegate SProfileData[] GetProfileListDelegate();
[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;
}
#endregion
#region photo
public delegate bool SendPhotoDelegate(SPhotoData photo);
[DataContract]
public struct SPhotoData
{
[DataMember]
public CBase64Image Photo;
//Add infomation about the user who took this image??
}
#endregion
#region website
public delegate byte[] GetSiteFileDelegate(string filename);
public delegate CBase64Image GetDelayedImageDelegate(string hashedFilename);
#endregion
[DataContract]
public class CBase64Image
{
[DataMember]
private string base64Data = "";
[DataMember]
private string imageId = "";
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 : "";
}
}
#region songs
public delegate SSongInfo GetSongDelegate(int songId);
public delegate SSongInfo[] GetAllSongsDelegate();
public delegate int GetCurrentSongIdDelegate();
[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; }
}
#endregion
#region playlists
public delegate SPlaylistInfo[] GetPlaylistsDelegate();
public delegate SPlaylistInfo GetPlaylistDelegate(int playlistId);
public delegate void AddSongToPlaylistDelegate(int songId, int playlistId, bool allowDuplicates);
public delegate void RemoveSongFromPlaylistDelegate(int position, int playlistId, int songId);
public delegate void MoveSongInPlaylistDelegate(int newPosition, int playlistId, int songId);
public delegate bool PlaylistContainsSongDelegate(int songId, int playlistId);
public delegate SPlaylistSongInfo[] GetPlaylistSongsDelegate(int playlistId);
public delegate void RemovePlaylistDelegate(int playlistId);
public delegate int AddPlaylistDelegate(string playlistName);
[DataContract]
public struct SPlaylistSongInfo
{
[DataMember]
public SSongInfo Song;
[DataMember]
public int PlaylistId;
[DataMember]
public int PlaylistPosition;
[DataMember]
public int GameMode;
}
[DataContract]
public struct SPlaylistInfo
{
[DataMember]
public int PlaylistId;
[DataMember]
public string PlaylistName;
[DataMember]
public int SongCount;
[DataMember]
public string LastChanged;
}
#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
}
File diff suppressed because it is too large. Load diff
@@ -1,179 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
namespace DiffieHellman
{
/// <summary>
/// Represents the Diffie-Hellman algorithm.
/// </summary>
public class CDiffieHellman : IDisposable
{
#region - Util -
static StrongNumberProvider _strongRng = new StrongNumberProvider();
#endregion
#region - Fields -
/// <summary>
/// The number of bits to generate.
/// </summary>
private int bits = 256;
/// <summary>
/// The shared prime.
/// </summary>
BigInteger prime;
/// <summary>
/// The shared base.
/// </summary>
BigInteger g;
/// <summary>
/// The private prime.
/// </summary>
BigInteger mine;
/// <summary>
/// The final key.
/// </summary>
byte[] key;
/// <summary>
/// The string representation/packet.
/// </summary>
string representation;
#endregion
#region - Properties -
/// <summary>
/// Gets the final key to use for encryption.
/// </summary>
public byte[] Key
{
get { return key; }
}
#endregion
#region - Ctor -
public CDiffieHellman()
{
}
public CDiffieHellman(int bits)
{
this.bits = bits;
}
~CDiffieHellman()
{
Dispose();
}
#endregion
#region - Implementation Methods -
#region Flow
/// <summary>
/// Generates a request packet.
/// </summary>
/// <returns></returns>
public CDiffieHellman GenerateRequest()
{
// Generate the parameters.
prime = BigInteger.GenPseudoPrime(bits, 30, _strongRng);
mine = BigInteger.GenPseudoPrime(bits, 30, _strongRng);
g = (BigInteger)5;
// Gemerate the string.
StringBuilder rep = new StringBuilder();
rep.Append(prime.ToString(36));
rep.Append("|");
rep.Append(g.ToString(36));
rep.Append("|");
// Generate the send BigInt.
using (BigInteger send = g.ModPow(mine, prime))
{
rep.Append(send.ToString(36));
}
representation = rep.ToString();
return this;
}
/// <summary>
/// Generate a response packet.
/// </summary>
/// <param name="request">The string representation of the request.</param>
/// <returns></returns>
public CDiffieHellman GenerateResponse(string request)
{
string[] parts = request.Split('|');
// Generate the would-be fields.
using (BigInteger prime = new BigInteger(parts[0], 36))
using (BigInteger g = new BigInteger(parts[1], 36))
using (BigInteger mine = BigInteger.GenPseudoPrime(bits, 30, _strongRng))
{
// Generate the key.
using (BigInteger given = new BigInteger(parts[2], 36))
using (BigInteger key = given.ModPow(mine, prime))
{
this.key = key.GetBytes();
}
// Generate the response.
using (BigInteger send = g.ModPow(mine, prime))
{
this.representation = send.ToString(36);
}
}
return this;
}
/// <summary>
/// Generates the key after a response is received.
/// </summary>
/// <param name="response">The string representation of the response.</param>
public void HandleResponse(string response)
{
// Get the response and modpow it with the stored prime.
using (BigInteger given = new BigInteger(response, 36))
using (BigInteger key = given.ModPow(mine, prime))
{
this.key = key.GetBytes();
}
Dispose();
}
#endregion
public override string ToString()
{
return representation;
}
#endregion
#region IDisposable Members
/// <summary>
/// Ends the calculation. The key will still be available.
/// </summary>
public void Dispose()
{
if (!Object.ReferenceEquals(prime, null))
prime.Dispose();
if (!Object.ReferenceEquals(mine, null))
mine.Dispose();
if (!Object.ReferenceEquals(g, null))
g.Dispose();
prime = null;
mine = null;
g = null;
representation = null;
GC.Collect();
GC.Collect();
}
#endregion
}
}
@@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
namespace DiffieHellman
{
internal class StrongNumberProvider
{
private static RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider();
public uint NextUInt32()
{
byte[] res = new byte[4];
csp.GetBytes(res);
return BitConverter.ToUInt32(res, 0);
}
public int NextInt()
{
byte[] res = new byte[4];
csp.GetBytes(res);
return BitConverter.ToInt32(res, 0);
}
public Single NextSingle()
{
float numerator = NextUInt32();
float denominator = uint.MaxValue;
return numerator / denominator;
}
}
}
@@ -0,0 +1,214 @@
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace ServerLib
{
[ServiceContract]
public interface ICWebservice
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/sendKeyEvent?key={key}")]
void SendKeyEvent(string key);
#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 = "")]
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();
#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();
#endregion
#region playlist
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getPlaylists")]
SPlaylistInfo[] GetPlaylists();
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/getPlaylist?id={playlistId}")]
SPlaylistInfo 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
}
}
@@ -8,17 +8,19 @@
<ProjectGuid>{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ClientServerLib</RootNamespace>
<RootNamespace>ServerLib</RootNamespace>
<AssemblyName>ClientServerLib</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>TRACE;DEBUG;WIN;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -33,6 +35,11 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<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.Linq" />
<Reference Include="Microsoft.CSharp" />
@@ -40,15 +47,17 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CClient.cs" />
<Compile Include="CConnection.cs" />
<Compile Include="CDiscover.cs" />
<Compile Include="CServer.cs" />
<Compile Include="DeffieHellman\BigInt.cs" />
<Compile Include="DeffieHellman\DeffieHellman.cs" />
<Compile Include="DeffieHellman\StrongNumberProvider.cs" />
<Compile Include="CWebservice.cs" />
<Compile Include="DataStructs.cs" />
<Compile Include="ICWebservice.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Structs.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,32 @@
using System;
namespace ServerLib
{
internal class CSession
{
readonly Guid _ID;
public Guid Id
{
get { return _ID; }
}
readonly int _ProfileId;
public int ProfileId
{
get { return _ProfileId; }
}
readonly EUserRoles _Roles;
internal EUserRoles Roles
{
get { return _Roles; }
}
public CSession(Guid id, int profileId, EUserRoles roles)
{
this._ID = id;
this._ProfileId = profileId;
this._Roles = roles;
}
}
}
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ServerLib
{
internal static class CSessionControl
{
private static readonly Dictionary<Guid, CSession> _ActiveSessions = new Dictionary<Guid, CSession>();
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 CServer.ValidatePassword(_GetProfileIdFormUsername(userName), password);
}
private static int _GetProfileIdFormUsername(string username)
{
return CServer.GetUserIdFromUsername(username);
}
private static EUserRoles _GetUserRoles(int profileId)
{
return (EUserRoles)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, 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;
}
}
}
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClientServerLib
{
public delegate void ResponseCallback(byte[] Response);
public delegate byte[] HandleRequest(int ConnectionID, byte[] Message);
public delegate void OnConnectionChanged(bool Connected);
public delegate void OnSend(byte[] Message);
public delegate void OnReceived(byte[] Message);
public struct SRequest
{
public byte[] Command;
public byte[] Response;
public ResponseCallback Callback;
}
}
@@ -0,0 +1,19 @@
using System;
namespace ServerLib
{
[Flags]
internal enum EUserRights
{
None = 0,
EditAllProfiles = 1,
UploadPhotos = 2,
ViewOtherProfiles = 4,
UseKeyboard = 8,
ReorderPlaylists = 16,
AddSongToPlaylist = 32,
CreatePlaylists = 64,
DeletePlaylists = 128,
RemoveSongsFromPlaylists = 256
}
}
@@ -0,0 +1,33 @@
using System.Collections.Generic;
using System.Linq;
namespace ServerLib
{
internal static class CUserRoleControl
{
private static readonly Dictionary<EUserRoles, EUserRights> _RoleRightsMapping = new Dictionary<EUserRoles, EUserRights> {
{EUserRoles.Administrator,
(EUserRights.EditAllProfiles|
EUserRights.UploadPhotos|
EUserRights.ViewOtherProfiles|
EUserRights.UseKeyboard|
EUserRights.AddSongToPlaylist|
EUserRights.ReorderPlaylists|
EUserRights.CreatePlaylists|
EUserRights.DeletePlaylists|
EUserRights.RemoveSongsFromPlaylists)},
{EUserRoles.AuthenticatedUser,
(EUserRights.UploadPhotos|
EUserRights.ViewOtherProfiles|
EUserRights.UseKeyboard)}
};
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);
}
}
}
@@ -0,0 +1,11 @@
using System;
namespace ServerLib
{
[Flags]
internal enum EUserRoles
{
AuthenticatedUser = 0,
Administrator = 1
}
}
+84
View File
@@ -0,0 +1,84 @@
using Security.Cryptography;
using Security.Cryptography.X509Certificates;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
namespace ConfigHttpApi
{
public static class ConfigHttpApi
{
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]
public static void reserveURL(string networkString)
{
HttpApi.ReserveURL(networkString, "D:(A;;GX;;;S-1-1-0)");
}
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]
public static void bindCert(string ip, int port, X509Certificate2 cert)
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(ip), port);
if (HttpApi.QuerySslCertificateInfo(endpoint) != null)
{
HttpApi.DeleteCertificateBinding(endpoint);
}
HttpApi.BindCertificate(endpoint, cert.GetCertHash(), StoreName.My, new Guid("7baf41f1-48b7-42cb-b145-f815499cb48f"));
}
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]
public static void addCertToStore(X509Certificate2 cert)
{
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
}
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]
public static X509Certificate2 getSelfSignedCert(string subjectName)
{
CngKey key = CngKey.Create(CngAlgorithm2.Rsa);
X509CertificateCreationParameters param = new X509CertificateCreationParameters(
new X500DistinguishedName("CN=Vocaluxe Server"));
param.SubjectName = new X500DistinguishedName("CN=localhost");
param.EndTime = DateTime.Today.AddYears(20);
param.SignatureAlgorithm = X509CertificateSignatureAlgorithm.RsaSha512;
OidCollection oc = new OidCollection();
oc.Add(new Oid("1.3.6.1.5.5.7.3.1"));
X509Extension eku = new X509EnhancedKeyUsageExtension(oc, true);
param.Extensions.Add(eku);
return key.CreateSelfSignedCertificate(param);
}
/*public static X509Certificate2 getCert(string subject)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
Mono.Security.Authenticode.PrivateKey key = new Mono.Security.Authenticode.PrivateKey { RSA=RSA.Create()};
Mono.Security.X509.X509CertificateBuilder x509 = new Mono.Security.X509.X509CertificateBuilder();
x509.IssuerName = "CN=Vocaluxe Server";
x509.NotAfter = DateTime.Today.AddYears(20);
x509.NotBefore = DateTime.Today.AddDays(-1);
x509.SubjectName = subject;
x509.SerialNumber = new byte[] { 1 };
x509.Version = 3;
x509.SubjectPublicKey = rsa;
ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
x509.Extensions.Add(eku);
return new X509Certificate2(x509.Sign(rsa));
}*/
}
}
+64
View File
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EC28CFA6-35A8-4971-AB07-37A54E010F69}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ConfigHttpApi</RootNamespace>
<AssemblyName>ConfigHttpApi</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="Security">
<HintPath>..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio 11.0\Libs\clrsecurity_june10\Security.dll</HintPath>
</Reference>
<Reference Include="Security.Cryptography">
<HintPath>..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio 11.0\Libs\clrsecurity_june10\Security.Cryptography.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConfigHttpApi.cs" />
<Compile Include="HttpApi.cs" />
<Compile Include="Properties\AssemblyInfo.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.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+643
View File
@@ -0,0 +1,643 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace ConfigHttpApi
{
internal static class HttpApi
{
private static readonly HTTPAPI_VERSION HttpApiVersion = new HTTPAPI_VERSION(1, 0);
#region DllImport
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpInitialize(
HTTPAPI_VERSION version,
uint flags,
IntPtr pReserved);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpSetServiceConfiguration(
IntPtr serviceIntPtr,
HTTP_SERVICE_CONFIG_ID configId,
IntPtr pConfigInformation,
int configInformationLength,
IntPtr pOverlapped);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpDeleteServiceConfiguration(
IntPtr serviceIntPtr,
HTTP_SERVICE_CONFIG_ID configId,
IntPtr pConfigInformation,
int configInformationLength,
IntPtr pOverlapped);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpTerminate(
uint Flags,
IntPtr pReserved);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpQueryServiceConfiguration(
IntPtr serviceIntPtr,
HTTP_SERVICE_CONFIG_ID configId,
IntPtr pInputConfigInfo,
int inputConfigInfoLength,
IntPtr pOutputConfigInfo,
int outputConfigInfoLength,
[Optional]
out int pReturnLength,
IntPtr pOverlapped);
enum HTTP_SERVICE_CONFIG_ID
{
HttpServiceConfigIPListenList = 0,
HttpServiceConfigSSLCertInfo,
HttpServiceConfigUrlAclInfo,
HttpServiceConfigMax
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_SSL_SET
{
public HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc;
public HTTP_SERVICE_CONFIG_SSL_PARAM ParamDesc;
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_SSL_KEY
{
public IntPtr pIpPort;
public HTTP_SERVICE_CONFIG_SSL_KEY(IntPtr pIpPort)
{
this.pIpPort = pIpPort;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct HTTP_SERVICE_CONFIG_SSL_PARAM
{
public int SslHashLength;
public IntPtr pSslHash;
public Guid AppId;
[MarshalAs(UnmanagedType.LPWStr)]
public string pSslCertStoreName;
public uint DefaultCertCheckMode;
public int DefaultRevocationFreshnessTime;
public int DefaultRevocationUrlRetrievalTimeout;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDefaultSslCtlIdentifier;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDefaultSslCtlStoreName;
public uint DefaultFlags;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct HTTPAPI_VERSION
{
public ushort HttpApiMajorVersion;
public ushort HttpApiMinorVersion;
public HTTPAPI_VERSION(ushort majorVersion, ushort minorVersion)
{
HttpApiMajorVersion = majorVersion;
HttpApiMinorVersion = minorVersion;
}
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_SSL_QUERY
{
public HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc;
public HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc;
public uint dwToken;
}
enum HTTP_SERVICE_CONFIG_QUERY_TYPE
{
HttpServiceConfigQueryExact = 0,
HttpServiceConfigQueryNext,
HttpServiceConfigQueryMax
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_URLACL_SET
{
public HTTP_SERVICE_CONFIG_URLACL_KEY KeyDesc;
public HTTP_SERVICE_CONFIG_URLACL_PARAM ParamDesc;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct HTTP_SERVICE_CONFIG_URLACL_KEY
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pUrlPrefix;
public HTTP_SERVICE_CONFIG_URLACL_KEY(string urlPrefix)
{
pUrlPrefix = urlPrefix;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct HTTP_SERVICE_CONFIG_URLACL_PARAM
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pStringSecurityDescriptor;
public HTTP_SERVICE_CONFIG_URLACL_PARAM(string securityDescriptor)
{
pStringSecurityDescriptor = securityDescriptor;
}
}
#endregion
#region Constants
public const uint HTTP_INITIALIZE_CONFIG = 0x00000002;
public const uint HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT = 0x00000002;
public const uint HTTP_SERVICE_CONFIG_SSL_FLAG_NO_RAW_FILTER = 0x00000004;
private const uint NOERROR = 0;
private const uint ERROR_INSUFFICIENT_BUFFER = 122;
private const uint ERROR_ALREADY_EXISTS = 183;
private const uint ERROR_FILE_NOT_FOUND = 2;
private const int ERROR_NO_MORE_ITEMS = 259;
#endregion
#region Public methods
public class SslCertificateInfo
{
public byte[] Hash { get; set; }
public Guid AppId { get; set; }
public string StoreName { get; set; }
public IPEndPoint IpPort { get; set; }
}
public static SslCertificateInfo QuerySslCertificateInfo(IPEndPoint ipPort)
{
SslCertificateInfo result = null;
uint retVal;
CallHttpApi(delegate
{
GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
HTTP_SERVICE_CONFIG_SSL_KEY sslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
new HTTP_SERVICE_CONFIG_SSL_QUERY
{
QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact,
KeyDesc = sslKey
};
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false);
IntPtr pOutputConfigInfo = IntPtr.Zero;
int returnLength = 0;
try
{
HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;
int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery);
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
if (retVal == ERROR_FILE_NOT_FOUND)
return;
if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122
{
pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength);
try
{
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
var outputConfigInfo =
(HTTP_SERVICE_CONFIG_SSL_SET)
Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SET));
byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength];
Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length);
Guid appId = outputConfigInfo.ParamDesc.AppId;
string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName;
result = new SslCertificateInfo { AppId = appId, Hash = hash, StoreName = storeName, IpPort = ipPort };
}
finally
{
Marshal.FreeCoTaskMem(pOutputConfigInfo);
}
}
else
{
ThrowWin32ExceptionIfError(retVal);
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
if (sockAddrHandle.IsAllocated)
sockAddrHandle.Free();
}
});
return result;
}
public static void BindCertificate(IPEndPoint ipPort, byte[] hash, StoreName storeName, Guid appId)
{
if (ipPort == null) throw new ArgumentNullException("ipPort");
if (hash == null) throw new ArgumentNullException("hash");
CallHttpApi(
delegate
{
HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET();
GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM();
GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned);
configSslParam.AppId = appId;
configSslParam.DefaultCertCheckMode = 0;
configSslParam.DefaultFlags = 0; //HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
configSslParam.DefaultRevocationFreshnessTime = 0;
configSslParam.DefaultRevocationUrlRetrievalTimeout = 0;
configSslParam.pSslCertStoreName = storeName.ToString();
configSslParam.pSslHash = handleHash.AddrOfPinnedObject();
configSslParam.SslHashLength = hash.Length;
configSslSet.ParamDesc = configSslParam;
configSslSet.KeyDesc = httpServiceConfigSslKey;
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);
try
{
uint retVal = HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
if (ERROR_ALREADY_EXISTS != retVal)
{
ThrowWin32ExceptionIfError(retVal);
}
else
{
retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
retVal = HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
if (handleHash.IsAllocated)
handleHash.Free();
if (sockAddrHandle.IsAllocated)
sockAddrHandle.Free();
}
});
}
public static void DeleteCertificateBinding(params IPEndPoint[] ipPorts)
{
if (ipPorts == null || ipPorts.Length == 0)
return;
CallHttpApi(
delegate
{
foreach (var ipPort in ipPorts)
{
HTTP_SERVICE_CONFIG_SSL_SET configSslSet =
new HTTP_SERVICE_CONFIG_SSL_SET();
GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
configSslSet.KeyDesc = httpServiceConfigSslKey;
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(
Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);
try
{
uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
if (sockAddrHandle.IsAllocated)
sockAddrHandle.Free();
}
}
});
}
public static SslCertificateInfo[] QuerySslCertificateInfo()
{
var result = new List<SslCertificateInfo>();
CallHttpApi(
delegate
{
uint token = 0;
uint retVal;
do
{
HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
new HTTP_SERVICE_CONFIG_SSL_QUERY
{
QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext,
dwToken = token,
};
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false);
IntPtr pOutputConfigInfo = IntPtr.Zero;
int returnLength = 0;
const HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;
try
{
int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery);
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
if (ERROR_NO_MORE_ITEMS == retVal)
break;
if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122
{
pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength);
try
{
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
var outputConfigInfo = (HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure(
pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SET));
byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength];
Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length);
Guid appId = outputConfigInfo.ParamDesc.AppId;
string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName;
IPEndPoint ipPort = ReadSockaddrStructure(outputConfigInfo.KeyDesc.pIpPort);
var resultItem = new SslCertificateInfo
{
AppId = appId,
Hash = hash,
StoreName = storeName,
IpPort = ipPort
};
result.Add(resultItem);
token++;
}
finally
{
Marshal.FreeCoTaskMem(pOutputConfigInfo);
}
}
else
{
ThrowWin32ExceptionIfError(retVal);
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
}
} while (NOERROR == retVal);
});
return result.ToArray();
}
public static void ReserveURL(string networkURL, string securityDescriptor)
{
if (String.IsNullOrEmpty(networkURL)) throw new ArgumentNullException("networkURL");
if (String.IsNullOrEmpty(securityDescriptor)) throw new ArgumentNullException("securityDescriptor");
CallHttpApi(
delegate
{
uint retVal = (uint)NOERROR; // NOERROR = 0
HTTP_SERVICE_CONFIG_URLACL_KEY keyDesc = new HTTP_SERVICE_CONFIG_URLACL_KEY(networkURL);
HTTP_SERVICE_CONFIG_URLACL_PARAM paramDesc = new HTTP_SERVICE_CONFIG_URLACL_PARAM(securityDescriptor);
HTTP_SERVICE_CONFIG_URLACL_SET inputConfigInfoSet = new HTTP_SERVICE_CONFIG_URLACL_SET();
inputConfigInfoSet.KeyDesc = keyDesc;
inputConfigInfoSet.ParamDesc = paramDesc;
IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_URLACL_SET)));
Marshal.StructureToPtr(inputConfigInfoSet, pInputConfigInfo, false);
try
{
retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
if ((uint)ERROR_ALREADY_EXISTS == retVal) // ERROR_ALREADY_EXISTS = 183
{
retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
if ((uint)NOERROR == retVal)
{
retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
}
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
HttpApi.HttpTerminate(HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
}
if ((uint)NOERROR != retVal)
{
ThrowWin32ExceptionIfError(retVal);
}
});
}
#endregion
private static void ThrowWin32ExceptionIfError(uint retVal)
{
if (NOERROR != retVal)
{
throw new Win32Exception(Convert.ToInt32(retVal));
}
}
private static void CallHttpApi(Action body)
{
uint retVal = HttpInitialize(HttpApiVersion, HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
try
{
body();
}
finally
{
HttpTerminate(HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
}
}
/// <summary>
/// Creates an unmanaged sockaddr structure to pass to a WinAPI function.
/// </summary>
/// <param name="ipEndPoint">IP address and port number</param>
/// <returns>a handle for the structure. Use the AddrOfPinnedObject Method to get a stable pointer to the object. </returns>
/// <remarks>When the handle goes out of scope you must explicitly release it by calling the Free method; otherwise, memory leaks may occur. </remarks>
private static GCHandle CreateSockaddrStructure(IPEndPoint ipEndPoint)
{
SocketAddress socketAddress = ipEndPoint.Serialize();
// use an array of bytes instead of the sockaddr structure
byte[] sockAddrStructureBytes = new byte[socketAddress.Size];
GCHandle sockAddrHandle = GCHandle.Alloc(sockAddrStructureBytes, GCHandleType.Pinned);
for (int i = 0; i < socketAddress.Size; ++i)
{
sockAddrStructureBytes[i] = socketAddress[i];
}
return sockAddrHandle;
}
/// <summary>
/// Reads the unmanaged sockaddr structure returned by a WinAPI function
/// </summary>
/// <param name="pSockaddrStructure">pointer to the unmanaged sockaddr structure</param>
/// <returns>IP address and port number</returns>
private static IPEndPoint ReadSockaddrStructure(IntPtr pSockaddrStructure)
{
short sAddressFamily = Marshal.ReadInt16(pSockaddrStructure);
AddressFamily addressFamily = (AddressFamily)sAddressFamily;
int sockAddrSructureSize;
IPEndPoint ipEndPointAny;
switch (addressFamily)
{
case AddressFamily.InterNetwork:
// IP v4 address
sockAddrSructureSize = 16;
ipEndPointAny = new IPEndPoint(IPAddress.Any, 0);
break;
case AddressFamily.InterNetworkV6:
// IP v6 address
sockAddrSructureSize = 28;
ipEndPointAny = new IPEndPoint(IPAddress.IPv6Any, 0);
break;
default:
throw new ArgumentOutOfRangeException("pSockaddrStructure", "Unknown address family");
}
// get bytes of the sockadrr structure
byte[] sockAddrSructureBytes = new byte[sockAddrSructureSize];
Marshal.Copy(pSockaddrStructure, sockAddrSructureBytes, 0, sockAddrSructureSize);
// create SocketAddress from bytes
var socketAddress = new SocketAddress(AddressFamily.Unspecified, sockAddrSructureSize);
for (int i = 0; i < sockAddrSructureSize; i++)
{
socketAddress[i] = sockAddrSructureBytes[i];
}
// create IPEndPoint from SocketAddress
IPEndPoint result = (IPEndPoint)ipEndPointAny.Create(socketAddress);
return result;
}
}
}
+36
View File
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("ConfigHttpApi")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ConfigHttpApi")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("89f719af-3a0d-4704-be7f-16e5b4e19c02")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- config.xml reference: https://build.phonegap.com/docs/config-xml -->
<widget xmlns = "http://www.w3.org/ns/widgets"
xmlns:gap = "http://phonegap.com/ns/1.0"
id = "net.sourceforge.vocaluxe"
version = "0.1.0">
<name>Vocaluxe</name>
<description>
Interact with Vocaluxe via your mobile device.
</description>
<author href="http://vocaluxe.sourceforge.net">
Vocaluxe Team
</author>
<!--
Enable individual API permissions here.
-->
<feature name="http://api.phonegap.com/1.0/device" />
<feature name="http://api.phonegap.com/1.0/camera" />
<feature name="http://api.phonegap.com/1.0/file" />
<!-- Customize your app and platform with the preference element. -->
<preference name="phonegap-version" value="2.9.0" />
<!-- Plugins can also be added here. -->
<gap:plugin name="com.phonegap.plugins.barcodescanner" />
<!-- Define app icon for each platform. -->
<icon src="icon.png" />
<access origin="*" />
</widget>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

+38 -13
View File
@@ -1,11 +1,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocaluxe.csproj", "{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}"
ProjectSection(ProjectDependencies) = postProject
{55F89808-4E79-4FFE-BC13-48258913F5C9} = {55F89808-4E79-4FFE-BC13-48258913F5C9}
{6F3E1874-F28A-40E9-AFBD-31934D593678} = {6F3E1874-F28A-40E9-AFBD-31934D593678}
{6F3E1874-F28A-40E9-AFBD-31934D593679} = {6F3E1874-F28A-40E9-AFBD-31934D593679}
{ED007796-367F-4142-AA55-5450C7645C2C} = {ED007796-367F-4142-AA55-5450C7645C2C}
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3} = {EC5167E4-CCFB-4CEE-987C-CF816F1062A3}
{D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC} = {D2B6DDEF-E0E1-4DDF-A73A-E6ACEF5C95EC}
{5A4053F1-5AD5-441F-B254-D97A088127B6} = {5A4053F1-5AD5-441F-B254-D97A088127B6}
EndProjectSection
@@ -20,6 +21,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartyModeChallengeMedley",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GstreamerHelper", "GstreamerHelper\GstreamerHelper.vcxproj", "{ED007796-367F-4142-AA55-5450C7645C2C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerLib", "ClientServerLib\ClientServerLib\ServerLib.csproj", "{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebserverInitalConfig", "WebserverInitalConfig\WebserverInitalConfig.csproj", "{55F89808-4E79-4FFE-BC13-48258913F5C9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
DebugLinux|x64 = DebugLinux|x64
@@ -102,10 +107,8 @@ Global
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|x64.Build.0 = DebugWin|x64
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|x86.ActiveCfg = DebugWin|x86
{5A4053F1-5AD5-441F-B254-D97A088127B6}.DebugWin|x86.Build.0 = DebugWin|x86
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x64.ActiveCfg = InstallerWin|x64
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x64.Build.0 = InstallerWin|x64
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x86.ActiveCfg = InstallerWin|x86
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x86.Build.0 = InstallerWin|x86
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x64.ActiveCfg = ReleaseWin|x64
{5A4053F1-5AD5-441F-B254-D97A088127B6}.InstallerWin|x86.ActiveCfg = ReleaseWin|x86
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|x64
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|x64.Build.0 = ReleaseLinux|x64
{5A4053F1-5AD5-441F-B254-D97A088127B6}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|x86
@@ -122,10 +125,8 @@ Global
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|x64.Build.0 = DebugWin|x64
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|x86.ActiveCfg = DebugWin|x86
{6F3E1874-F28A-40E9-AFBD-31934D593678}.DebugWin|x86.Build.0 = DebugWin|x86
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x64.ActiveCfg = InstallerWin|x64
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x64.Build.0 = InstallerWin|x64
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x86.ActiveCfg = InstallerWin|x86
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x86.Build.0 = InstallerWin|x86
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x64.ActiveCfg = ReleaseWin|x64
{6F3E1874-F28A-40E9-AFBD-31934D593678}.InstallerWin|x86.ActiveCfg = ReleaseWin|x86
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|x64.ActiveCfg = ReleaseLinux|x64
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|x64.Build.0 = ReleaseLinux|x64
{6F3E1874-F28A-40E9-AFBD-31934D593678}.ReleaseLinux|x86.ActiveCfg = ReleaseLinux|x86
@@ -140,16 +141,40 @@ Global
{ED007796-367F-4142-AA55-5450C7645C2C}.DebugWin|x64.Build.0 = DebugWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.DebugWin|x86.ActiveCfg = DebugWin|Win32
{ED007796-367F-4142-AA55-5450C7645C2C}.DebugWin|x86.Build.0 = DebugWin|Win32
{ED007796-367F-4142-AA55-5450C7645C2C}.InstallerWin|x64.ActiveCfg = InstallerWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.InstallerWin|x64.Build.0 = InstallerWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.InstallerWin|x86.ActiveCfg = InstallerWin|Win32
{ED007796-367F-4142-AA55-5450C7645C2C}.InstallerWin|x86.Build.0 = InstallerWin|Win32
{ED007796-367F-4142-AA55-5450C7645C2C}.InstallerWin|x64.ActiveCfg = ReleaseWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.InstallerWin|x86.ActiveCfg = ReleaseWin|Win32
{ED007796-367F-4142-AA55-5450C7645C2C}.ReleaseLinux|x64.ActiveCfg = ReleaseWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.ReleaseLinux|x86.ActiveCfg = ReleaseWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.ReleaseWin|x64.Build.0 = ReleaseWin|x64
{ED007796-367F-4142-AA55-5450C7645C2C}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Win32
{ED007796-367F-4142-AA55-5450C7645C2C}.ReleaseWin|x86.Build.0 = ReleaseWin|Win32
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.DebugLinux|x64.ActiveCfg = Debug|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.DebugLinux|x64.Build.0 = Debug|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.DebugLinux|x86.ActiveCfg = Debug|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.DebugWin|x64.ActiveCfg = Debug|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.DebugWin|x64.Build.0 = Debug|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.DebugWin|x86.ActiveCfg = Debug|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.InstallerWin|x64.ActiveCfg = Release|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.InstallerWin|x86.ActiveCfg = Release|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.ReleaseLinux|x64.ActiveCfg = Release|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.ReleaseLinux|x64.Build.0 = Release|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.ReleaseWin|x64.ActiveCfg = Release|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.ReleaseWin|x64.Build.0 = Release|Any CPU
{EC5167E4-CCFB-4CEE-987C-CF816F1062A3}.ReleaseWin|x86.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|x64.ActiveCfg = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugLinux|x86.ActiveCfg = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x64.ActiveCfg = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x64.Build.0 = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.DebugWin|x86.ActiveCfg = Debug|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x64.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.InstallerWin|x86.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|x64.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseLinux|x86.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x64.ActiveCfg = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x64.Build.0 = Release|Any CPU
{55F89808-4E79-4FFE-BC13-48258913F5C9}.ReleaseWin|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+4 -4
View File
@@ -124,7 +124,7 @@ namespace Vocaluxe.Base
public static EOffOn ServerActive = EOffOn.TR_CONFIG_OFF;
public static EOffOn ServerEncryption = EOffOn.TR_CONFIG_OFF;
public static int ServerPort = 3000;
public static string ServerPassword = "vocaluxe";
//public static string ServerPassword = "vocaluxe";
//Lists to save parameters and values
private static readonly List<string> _Params = new List<string>();
@@ -299,7 +299,7 @@ namespace Vocaluxe.Base
if (ServerPort < 1 || ServerPort > 65535)
ServerPort = 3000;
xmlReader.GetValue("//root/Server/ServerPassword", out ServerPassword, ServerPassword);
//xmlReader.GetValue("//root/Server/ServerPassword", out ServerPassword, ServerPassword);
#endregion Server
}
@@ -573,8 +573,8 @@ namespace Vocaluxe.Base
writer.WriteComment("Server Port (default: 3000) [1..65535]");
writer.WriteElementString("ServerPort", ServerPort.ToString());
writer.WriteComment("Server Password (default: vocaluxe)");
writer.WriteElementString("ServerPassword", ServerPassword);
//writer.WriteComment("Server Password (default: vocaluxe)");
//writer.WriteElementString("ServerPassword", ServerPassword);
writer.WriteEndElement();
#endregion Server
+14 -14
View File
@@ -1,18 +1,18 @@
#region license
// This file is part of Vocaluxe.
#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 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.
// 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/>.
// 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;
@@ -77,7 +77,7 @@ namespace Vocaluxe.Base
foreach (string file in files)
{
var playlist = new CPlaylistFile(file);
CPlaylistFile playlist = new CPlaylistFile(file, files.IndexOf(file));
_Playlists.Add(playlist);
}
}
@@ -125,7 +125,7 @@ namespace Vocaluxe.Base
public static int NewPlaylist()
{
var pl = new CPlaylistFile {PlaylistName = "New Playlist"};
CPlaylistFile pl = new CPlaylistFile { PlaylistName = "New Playlist", Id = _Playlists.Count };
_Playlists.Add(pl);
return _Playlists.Count - 1;
}
+30 -12
View File
@@ -1,18 +1,18 @@
#region license
// This file is part of Vocaluxe.
#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 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.
// 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/>.
// 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;
@@ -305,6 +305,16 @@ namespace Vocaluxe.Base
return list.ToArray();
}
public static CProfile GetProfile(int profileID)
{
if (!IsProfileIDValid(profileID))
{
return null;
}
return _Profiles[profileID];
}
public static IEnumerable<CAvatar> GetAvatars()
{
if (_Avatars.Count == 0)
@@ -480,6 +490,14 @@ namespace Vocaluxe.Base
return _Profiles[profileID].Avatar.ID;
}
public static CAvatar GetAvatar(int profileID)
{
if (!IsProfileIDValid(profileID))
return null;
return _Profiles[profileID].Avatar;
}
public static int GetProfileID(int num)
{
return _Profiles[num].ID;
+13 -12
View File
@@ -1,18 +1,18 @@
#region license
// This file is part of Vocaluxe.
#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 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.
// 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/>.
// 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;
@@ -102,6 +102,7 @@ namespace Vocaluxe.Base
#endif
Path.Combine(DataPath, FolderProfiles)
};
public static string FolderPhotos = "Photos";
public const string FolderSongs = "Songs";
public const string FolderSounds = "Sounds";
public const string FolderLanguages = "Languages";
+10 -51
View File
@@ -1,4 +1,4 @@
#region license
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
@@ -83,47 +83,6 @@ namespace Vocaluxe.Base.Server
}
#endregion Login
#region Keyboard
#endregion Keyboard
#region Profiles
public static byte[] CreateCommandSendAvatarPicture(int width, int height, byte[] data)
{
var ap = new SAvatarPicture {Height = height, Width = width, Data = new byte[data.Length]};
Array.Copy(data, ap.Data, data.Length);
return _Serialize(CommandSendAvatarPicture, ap);
}
public static bool DecodeCommandSendAvatarPicture(byte[] message, out SAvatarPicture avatarPicture)
{
return _TryDeserialize(message, out avatarPicture);
}
public static byte[] CreateCommandSendAvatarPictureJpg(byte[] avatarJpgData)
{
var ap = new SAvatarPicture {Height = 0, Width = 0, Data = new byte[avatarJpgData.Length]};
Array.Copy(avatarJpgData, ap.Data, avatarJpgData.Length);
return _Serialize(CommandSendAvatarPictureJpg, ap);
}
public static byte[] CreateCommandSendProfile(byte[] avatarJpgData, string playerName, int difficulty)
{
var ap = new SAvatarPicture {Height = 0, Width = 0, Data = new byte[avatarJpgData.Length]};
Array.Copy(avatarJpgData, ap.Data, avatarJpgData.Length);
var profile = new SProfile {Avatar = ap, PlayerName = playerName, Difficulty = difficulty};
return _Serialize(CommandSendProfile, profile);
}
public static bool DecodeCommandSendProfile(byte[] message, out SProfile profile)
{
return _TryDeserialize(message, out profile);
}
#endregion Profiles
#region Serializing
private static byte[] _Serialize<T>(T obj)
{
@@ -138,7 +97,7 @@ namespace Vocaluxe.Base.Server
stream.Write(cmd, 0, cmd.Length);
byte[] data;
string json = JsonConvert.SerializeObject(obj);
string json = JsonConvert.SerializeObject(obj);
data = _Encoder.GetBytes(json);
stream.Write(data, 0, data.Length);
return stream.ToArray();
@@ -156,16 +115,16 @@ namespace Vocaluxe.Base.Server
var data = new byte[message.Length - 4];
Array.Copy(message, 4, data, 0, data.Length);
try
{
try
{
obj = JsonConvert.DeserializeObject<T>(_Encoder.GetString(data));
return true;
}
catch
{
return false;
return true;
}
catch
{
return false;
}
}
#endregion Serializing
}
}
}
+684 -143
View File
@@ -1,49 +1,75 @@
#region license
// This file is part of Vocaluxe.
#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 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.
// 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/>.
// 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.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Linq;
using System.IO;
using System.Text;
using System.Windows.Forms;
using ClientServerLib;
using ServerLib;
using Vocaluxe.Lib.Input;
using Vocaluxe.Lib.Playlist;
using VocaluxeLib;
using VocaluxeLib.Draw;
using VocaluxeLib.Menu;
using VocaluxeLib.Profile;
using VocaluxeLib.Songs;
using System.Security.Cryptography;
namespace Vocaluxe.Base.Server
{
static class CVocaluxeServer
{
private static CServer _Server;
private static CDiscover _Discover;
private static Dictionary<int, CClientHandler> _Clients;
//private static CDiscover _Discover;
public static readonly CControllerFramework Controller = new CControllerFramework();
public static void Init()
{
_Clients = new Dictionary<int, CClientHandler>();
String pw = (CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON) ? CConfig.ServerPassword : String.Empty;
_Server = new CServer(RequestHandler, CConfig.ServerPort, pw);
_Server = new CServer(CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON);
_Discover = new CDiscover(CConfig.ServerPort, CCommands.BroadcastKeyword);
CServer.SendKeyEvent = _SendKeyEvent;
CServer.GetProfileData = _GetProfileData;
CServer.SendProfileData = _SendProfileData;
CServer.GetProfileList = _GetProfileList;
CServer.SendPhoto = _SendPhoto;
CServer.GetSiteFile = _GetSiteFile;
CServer.GetSong = _GetSong;
CServer.GetAllSongs = _GetAllSongs;
CServer.GetCurrentSongId = _GetCurrentSongId;
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;
//_Discover = new CDiscover(CConfig.ServerPort, CCommands.BroadcastKeyword);
Controller.Init();
}
@@ -52,158 +78,673 @@ namespace Vocaluxe.Base.Server
if (CConfig.ServerActive == EOffOn.TR_CONFIG_ON)
{
_Server.Start();
_Discover.StartBroadcasting();
//_Discover.StartBroadcasting();
}
}
public static void Close()
{
_Server.Stop();
_Discover.Stop();
_Clients = new Dictionary<int, CClientHandler>();
//_Discover.Stop();
}
private static byte[] RequestHandler(int connectionID, byte[] message)
private static bool _SendKeyEvent(string key)
{
byte[] answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseNOK);
if (message == null)
return answer;
if (message.Length < 4)
return answer;
bool loggedIn;
lock (_Clients)
bool result = false;
if (!string.IsNullOrEmpty(key))
{
if (!_Clients.ContainsKey(connectionID))
switch (key.ToLower())
{
var client = new CClientHandler(connectionID);
_Clients.Add(connectionID, client);
//just a small fix: There is no real login at the moment, so set it to true.
_Clients[connectionID].LoggedIn = true;
}
loggedIn = _Clients[connectionID].LoggedIn;
}
if (!loggedIn)
return CCommands.CreateCommandWithoutParams(CCommands.ResponseNOK);
int command = BitConverter.ToInt32(message, 0);
switch (command)
{
case CCommands.CommandSendKeyUp:
answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseOK);
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Up));
break;
case CCommands.CommandSendKeyDown:
answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseOK);
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Down));
break;
case CCommands.CommandSendKeyLeft:
answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseOK);
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Left));
break;
case CCommands.CommandSendKeyRight:
answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseOK);
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Right));
break;
case CCommands.CommandSendAvatarPicture:
SAvatarPicture avatarPicture;
if (CCommands.DecodeCommandSendAvatarPicture(message, out avatarPicture))
{
using (var bmp = new Bitmap(avatarPicture.Width, avatarPicture.Height))
case "up":
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Up));
result = true;
break;
case "down":
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Down));
result = true;
break;
case "left":
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Left));
result = true;
break;
case "right":
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Right));
result = true;
break;
case "escape":
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Escape));
result = true;
break;
case "return":
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Return));
result = true;
break;
case "tab":
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, Keys.Tab));
result = true;
break;
default:
foreach (char c in key.ToCharArray())
{
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(avatarPicture.Data, 0, bmpData.Scan0, avatarPicture.Data.Length);
bmp.UnlockBits(bmpData);
const string filename = "snapshot";
int i = 0;
while (File.Exists(Path.Combine(CSettings.DataPath, CSettings.FolderProfiles, filename + i + ".png")))
i++;
bmp.Save(Path.Combine(CSettings.DataPath, CSettings.FolderProfiles, filename + i + ".png"), ImageFormat.Png);
}
answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseOK);
}
break;
case CCommands.CommandSendAvatarPictureJpg:
SAvatarPicture avatarPictureJpg;
if (CCommands.DecodeCommandSendAvatarPicture(message, out avatarPictureJpg))
{
if (_AddAvatar(avatarPictureJpg.Data) != String.Empty)
answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseOK);
}
break;
case CCommands.CommandSendProfile:
SProfile profile;
if (CCommands.DecodeCommandSendProfile(message, out profile))
{
try
{
string avatarFilename = _AddAvatar(profile.Avatar.Data);
if (avatarFilename != String.Empty)
bool shift = true;
char keyChar;
if (char.ToUpper(c) != c)
{
var p = new CProfile
{
Active = EOffOn.TR_CONFIG_ON,
AvatarFileName = avatarFilename,
Difficulty = (EGameDifficulty)profile.Difficulty,
GuestProfile = EOffOn.TR_CONFIG_OFF,
PlayerName = profile.PlayerName
};
CProfiles.AddProfile(p);
answer = CCommands.CreateCommandWithoutParams(CCommands.ResponseOK);
keyChar = char.ToUpper(c);
shift = false;
}
else
{
keyChar = c;
}
if ((keyChar >= 0x30 && keyChar <= 0x39) || (keyChar >= 0x41 && keyChar <= 0x5A))
{
Keys keys = (Keys)keyChar;
if (shift)
{
keys |= Keys.Shift;
}
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, keys));
result = true;
}
}
catch (Exception) {}
}
break;
break;
}
}
return answer;
return result;
}
private static string _AddAvatar(byte[] jpgData)
#region profile
private static SProfileData _GetProfileData(int profileId, bool isReadonly)
{
CProfile profile = CProfiles.GetProfile(profileId);
if (profile == null)
{
return new SProfileData();
}
return _CreateProfileData(profile, isReadonly);
}
private static bool _SendProfileData(SProfileData profile)
{
CProfile newProfile;
CProfile existingProfile = CProfiles.GetProfile(profile.ProfileId);
if (existingProfile != null)
{
newProfile = new CProfile
{
ID = existingProfile.ID,
FileName = existingProfile.FileName,
Active = existingProfile.Active,
AvatarFileName = existingProfile.AvatarFileName,
Avatar = existingProfile.Avatar,
Difficulty = existingProfile.Difficulty,
GuestProfile = existingProfile.GuestProfile,
PlayerName = existingProfile.PlayerName
};
}
else
{
newProfile = new CProfile
{
Active = EOffOn.TR_CONFIG_ON,
GuestProfile = EOffOn.TR_CONFIG_OFF
};
}
if (profile.Avatar != null)
{
newProfile.Avatar = _AddAvatar(profile.Avatar);
}
else if (newProfile.Avatar == null || newProfile.Avatar.ID == -1)
{
newProfile.Avatar = CProfiles.GetAvatars().First();
/*CAvatar avatar = new CAvatar(-1);
avatar.LoadFromFile("Profiles\\Avatar_f.png");
CProfiles.AddAvatar(avatar);
newProfile.Avatar = avatar;*/
}
if (!string.IsNullOrEmpty(profile.PlayerName))
{
newProfile.PlayerName = profile.PlayerName;
}
else if (!string.IsNullOrEmpty(newProfile.PlayerName))
{
newProfile.PlayerName = "DummyName";
}
if (profile.Difficulty >= 0 && profile.Difficulty <= 2)
{
newProfile.Difficulty = (EGameDifficulty)profile.Difficulty;
}
if (profile.Type >= 0 && profile.Type <= 1)
{
newProfile.GuestProfile = (EOffOn)profile.Type;
}
if (!string.IsNullOrEmpty(profile.Password))
{
if (profile.Password == "***__CLEAR_PASSWORD__***")
{
newProfile.PasswordSalt = null;
newProfile.PasswordHash = null;
}
else
{
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buffer = new byte[32];
rng.GetNonZeroBytes(buffer);
byte[] salt = buffer;
byte[] hashedPassword = _Hash((new UTF8Encoding()).GetBytes(profile.Password), salt);
newProfile.PasswordSalt = salt;
newProfile.PasswordHash = hashedPassword;
}
}
if (existingProfile != null)
{
CProfiles.EditProfile(newProfile);
CProfiles.Update();
CProfiles.SaveProfiles();
}
else
{
CProfiles.AddProfile(newProfile);
}
return true;
}
private static SProfileData[] _GetProfileList()
{
List<SProfileData> result = new List<SProfileData>(CProfiles.NumProfiles);
result.AddRange(CProfiles.GetProfiles().Select(profile => _CreateProfileData(profile, true)));
return result.ToArray();
}
private static SProfileData _CreateProfileData(CProfile profile, bool isReadonly)
{
SProfileData profileData = new SProfileData
{
IsEditable = !isReadonly,
ProfileId = profile.ID,
PlayerName = profile.PlayerName,
Type = (int)profile.GuestProfile,
Difficulty = (int)profile.Difficulty
};
CAvatar avatar = profile.Avatar;
if (avatar != null)
{
if (File.Exists(avatar.FileName))
{
profileData.Avatar = new CBase64Image(_CreateDelayedImage(avatar.FileName));
}
}
return profileData;
}
private static CAvatar _AddAvatar(CBase64Image avatarData)
{
string result = String.Empty;
try
{
string filename = Path.Combine(CSettings.DataPath, CSettings.FolderProfiles, "snapshot");
int i = 0;
while (File.Exists(filename + i + ".jpg"))
i++;
filename = filename + i + ".jpg";
FileStream fs = File.Create(filename);
fs.Write(jpgData, 0, jpgData.Length);
fs.Flush();
fs.Close();
string filename = _SaveImage(avatarData, "snapshot", CSettings.FolderProfiles);
var avatar = new CAvatar(-1);
if (avatar.LoadFromFile(filename))
{
CProfiles.AddAvatar(avatar);
result = filename;
return avatar;
}
return null;
}
catch
{
return null;
}
}
#endregion
#region photo
private static List<string> photosOfThisRound = new List<string>();
private static bool _SendPhoto(SPhotoData photoData)
{
if (photoData.Photo == null)
{
return false;
}
string name = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
string filePath = _SaveImage(photoData.Photo, name, CSettings.FolderPhotos);
if (!string.IsNullOrEmpty(filePath))
{
photosOfThisRound.Add(filePath);
return true;
}
return false;
}
internal static string[] getPhotosOfThisRound()
{
var result = photosOfThisRound.ToArray();
photosOfThisRound.Clear();
return result;
}
#endregion
#region website
private static readonly Dictionary<string, string> _DelayedImagePath = new Dictionary<string, string>();
private static byte[] _GetSiteFile(string filename)
{
string path = "Website/" + filename;
path = path.Replace("..", "");
if (!File.Exists(path))
{
return null;
}
/*string content = File.ReadAllText(path);
content = content.Replace("%SERVER%", System.Net.Dns.GetHostName() + ":" + CConfig.ServerPort);
return Encoding.UTF8.GetBytes(content);*/
return File.ReadAllBytes(path);
}
private static string _CreateDelayedImage(string filename)
{
byte[] by = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(filename));
var sb = new StringBuilder();
foreach (byte b in by)
{
sb.Append(b.ToString("x2"));
}
string hashedFilename = sb.ToString();
if (!_DelayedImagePath.ContainsKey(hashedFilename))
{
_DelayedImagePath.Add(hashedFilename, filename);
}
return hashedFilename;
}
private static CBase64Image _GetDelayedImage(string hashedFilename)
{
if (!_DelayedImagePath.ContainsKey(hashedFilename))
{
throw new FileNotFoundException("Image not found");
}
string fileName = _DelayedImagePath[hashedFilename];
if (File.Exists(fileName))
{
Image image = Image.FromFile(fileName);
return new CBase64Image(image, image.RawFormat);
}
throw new FileNotFoundException("Image not found");
}
#endregion
#region songs
private static SSongInfo _GetSong(int songId)
{
CSong song = CSongs.GetSong(songId);
return _GetSongInfo(song, true);
}
private static SSongInfo[] _GetAllSongs()
{
var songs = CSongs.Songs;
return (from s in songs
select _GetSongInfo(s, false)).ToArray<SSongInfo>();
}
private static int _GetCurrentSongId()
{
CSong song = CGame.GetSong();
if (song == null)
{
return -1;
}
return song.ID;
}
private static SSongInfo _GetSongInfo(CSong song, bool includeCover)
{
SSongInfo result = new SSongInfo();
if (song != null)
{
result.Title = song.Title;
result.Artist = song.Artist;
result.Genre = song.Genres.FirstOrDefault();
result.Language = song.Languages.FirstOrDefault();
result.Year = song.Year;
result.IsDuet = song.IsDuet;
result.SongId = song.ID;
if (includeCover)
{
result.Cover = new CBase64Image(_CreateDelayedImage(song.Folder + "\\" + song.CoverFileName));
}
}
catch {}
return result;
}
#endregion
#region playlist
private static SPlaylistInfo[] _GetPlaylists()
{
return (from p in CPlaylists.Playlists
select _GetPlaylistInfo(p)).ToArray();
}
private static SPlaylistInfo _GetPlaylist(int playlistId)
{
if (CPlaylists.Playlists.Length <= playlistId || playlistId < 0)
{
throw new ArgumentException("invalid playlistId");
}
return _GetPlaylistInfo(CPlaylists.Playlists[playlistId]);
}
private static void _AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates)
{
if (CPlaylists.Playlists.Length <= playlistId || playlistId < 0)
{
throw new ArgumentException("invalid playlistId");
}
if (allowDuplicates || !_PlaylistContainsSong(songId, playlistId))
{
CPlaylists.AddPlaylistSong(playlistId, songId);
CPlaylists.SavePlaylist(playlistId);
}
else
{
throw new ArgumentException("song exists in this playlist");
}
}
private static void _RemoveSongFromPlaylist(int position, int playlistId, int songId)
{
if (CPlaylists.Playlists.Length <= playlistId || playlistId < 0)
{
throw new ArgumentException("invalid playlistId");
}
if (!_PlaylistContainsSong(songId, playlistId))
{
throw new ArgumentException("invalid songId");
}
if (position < 0 || CPlaylists.Playlists[playlistId].Songs.Count <= position
|| CPlaylists.Playlists[playlistId].Songs[position].SongID != songId)
{
throw new ArgumentException("invalid position");
}
CPlaylists.Playlists[playlistId].DeleteSong(position);
CPlaylists.SavePlaylist(playlistId);
}
private static void _MoveSongInPlaylist(int newPosition, int playlistId, int songId)
{
if (CPlaylists.Playlists.Length <= playlistId || playlistId < 0)
{
throw new ArgumentException("invalid playlistId");
}
if (!_PlaylistContainsSong(songId, playlistId))
{
throw new ArgumentException("invalid songId");
}
if (CPlaylists.Playlists[playlistId].Songs.Count < newPosition)
{
throw new ArgumentException("invalid newPosition");
}
int oldPosition = CPlaylists.Playlists[playlistId].Songs.FindIndex(s => s.SongID == songId);
CPlaylists.MovePlaylistSong(playlistId, oldPosition, newPosition);
CPlaylists.SavePlaylist(playlistId);
}
private static bool _PlaylistContainsSong(int songId, int playlistId)
{
if (CPlaylists.Playlists.Length <= playlistId || playlistId < 0)
{
throw new ArgumentException("invalid playlistId");
}
return CPlaylists.Playlists[playlistId].Songs.Any(s => s.SongID == songId);
}
private static SPlaylistSongInfo[] _GetPlaylistSongs(int playlistId)
{
if (CPlaylists.Playlists.Length <= playlistId || playlistId < 0)
{
throw new ArgumentException("invalid playlistId");
}
return _GetPlaylistSongInfos(CPlaylists.Playlists[playlistId]);
}
private static SPlaylistSongInfo _GetPlaylistSongInfo(CPlaylistSong playlistSong, int playlistId, int playlistPos)
{
SPlaylistSongInfo result = new SPlaylistSongInfo();
if (playlistSong != null)
{
result.PlaylistId = playlistId;
result.GameMode = (int)playlistSong.GameMode;
result.PlaylistPosition = playlistPos;
result.Song = _GetSongInfo(CSongs.GetSong(playlistSong.SongID), true);
}
return result;
}
private static SPlaylistSongInfo[] _GetPlaylistSongInfos(CPlaylistFile playlist)
{
SPlaylistSongInfo[] result = new SPlaylistSongInfo[playlist.Songs.Count];
for (int i = 0; i < playlist.Songs.Count; i++)
{
result[i] = _GetPlaylistSongInfo(playlist.Songs[i], playlist.Id, i);
}
return result;
}
private static SPlaylistInfo _GetPlaylistInfo(CPlaylistFile playlist)
{
return new SPlaylistInfo
{
PlaylistId = playlist.Id,
PlaylistName = playlist.PlaylistName,
SongCount = playlist.Songs.Count,
LastChanged = DateTime.Now.ToLongDateString()
};
}
private static void _RemovePlaylist(int playlistId)
{
if (CPlaylists.Playlists.Length <= playlistId || playlistId < 0)
{
throw new ArgumentException("invalid playlistId");
}
CPlaylists.DeletePlaylist(playlistId);
}
private static int _AddPlaylist(string playlistName)
{
int newPlaylistId = CPlaylists.NewPlaylist();
CPlaylists.Playlists[newPlaylistId].PlaylistName = playlistName;
CPlaylists.SavePlaylist(newPlaylistId);
return newPlaylistId;
}
#endregion
#region user management
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 (string.IsNullOrEmpty(password))
{
return true; //Allow emty passwords
}
return false;
}
byte[] salt = profile.PasswordSalt;
return _Hash((new 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
}
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;
CProfiles.EditProfile(profile);
CProfiles.Update();
CProfiles.SaveProfiles();
}
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.Any())
{
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(CBase64Image imageDate, string name, string folder)
{
Image avatarImage = imageDate.GetImage();
string extension = imageDate.GetImageType();
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
string filename = Path.Combine(folder, name);
if (File.Exists(filename + "." + extension))
{
int i = 0;
while (File.Exists(filename + "_" + i + "." + extension))
{
i++;
}
filename = filename + "_" + i + "." + extension;
}
else
{
filename = filename + "." + extension;
}
avatarImage.Save(filename);
return filename;
}
}
}
+2 -2
View File
@@ -22,7 +22,7 @@ namespace Vocaluxe.Base.Server
public byte[] Sha256;
}
public struct SAvatarPicture
public struct SPicture
{
public int Width;
public int Height;
@@ -31,7 +31,7 @@ namespace Vocaluxe.Base.Server
public struct SProfile
{
public SAvatarPicture Avatar;
public SPicture Avatar;
public string PlayerName;
public int Difficulty;
}
+16 -14
View File
@@ -1,18 +1,18 @@
#region license
// This file is part of Vocaluxe.
#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 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.
// 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/>.
// 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;
@@ -31,6 +31,7 @@ namespace Vocaluxe.Lib.Playlist
{
public string PlaylistName;
public string PlaylistFile;
public int Id = -1;
public List<CPlaylistSong> Songs = new List<CPlaylistSong>();
public CPlaylistFile()
@@ -39,8 +40,9 @@ namespace Vocaluxe.Lib.Playlist
PlaylistFile = string.Empty;
}
public CPlaylistFile(string file)
public CPlaylistFile(string file, int id)
{
Id = id;
PlaylistFile = file;
_LoadPlaylist();
}
@@ -217,7 +219,7 @@ namespace Vocaluxe.Lib.Playlist
if (destNr < 0 || destNr > Songs.Count - 1)
return;
var ps = new CPlaylistSong(songID, gm);
CPlaylistSong ps = new CPlaylistSong(songID, gm);
Songs.Insert(destNr, ps);
}
}
+126 -6
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">DebugWin</Configuration>
@@ -15,7 +15,8 @@
<IsWebBootstrapper>false</IsWebBootstrapper>
<StartupObject>Vocaluxe.CMainProgram</StartupObject>
<ApplicationIcon>Vocaluxe.ico</ApplicationIcon>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -174,10 +175,6 @@
<HintPath>..\Output\AForge.Video.DirectShow.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ClientServerLib">
<HintPath>..\ClientServerLib\ClientServerLib\bin\ClientServerLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Community.CsharpSqlite">
<HintPath>..\Output\Community.CsharpSqlite.dll</HintPath>
</Reference>
@@ -197,6 +194,7 @@
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.XML" />
</ItemGroup>
@@ -306,10 +304,122 @@
</None>
<Compile Include="Lib\Sound\PortAudio\PortAudio.cs" />
<None Include="Doc\SQLite.NET.chm" />
<Content Include="Website\locales\de.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\locales\en.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="Doc\Roadmap.txt" />
<Content Include="Vocaluxe.ico" />
<Content Include="Website\css\images\ajax-loader.gif">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>images</CustomToolNamespace>
</Content>
<Content Include="Website\css\images\alert.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\css\images\icons-18-black.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>images</CustomToolNamespace>
</Content>
<Content Include="Website\css\images\icons-18-white.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>images</CustomToolNamespace>
</Content>
<Content Include="Website\css\images\icons-36-black.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>images</CustomToolNamespace>
</Content>
<Content Include="Website\css\images\icons-36-white.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>images</CustomToolNamespace>
</Content>
<Content Include="Website\css\jquery.mobile-1.3.2.min.css">
<CustomToolNamespace>css</CustomToolNamespace>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\css\jquery.mobile.theme-1.3.2.min.css">
<CustomToolNamespace>css</CustomToolNamespace>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\css\style.css">
<CustomToolNamespace>css</CustomToolNamespace>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\addPlaylist.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\logout.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\music.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\noCover.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\playlist.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\playlists.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\spotify.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\wikipedia.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\youtube.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\img\admin.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>img</CustomToolNamespace>
</Content>
<Content Include="Website\img\keyboard.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>img</CustomToolNamespace>
</Content>
<Content Include="Website\img\photo.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>img</CustomToolNamespace>
</Content>
<Content Include="Website\img\profile.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>img</CustomToolNamespace>
</Content>
<Content Include="Website\img\profiles.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>img</CustomToolNamespace>
</Content>
<Content Include="Website\js\i18next-1.7.1.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\js\jquery-1.9.1.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CustomToolNamespace>js</CustomToolNamespace>
</Content>
<Content Include="Website\js\jquery-ui-1.10.3.custom.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\js\jquery.mobile-1.3.2.min.js">
<CustomToolNamespace>js</CustomToolNamespace>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\js\jquery.ui.touch-punch.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Website\js\main.js">
<CustomToolNamespace>js</CustomToolNamespace>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client,KB2468871">
@@ -324,12 +434,22 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ClientServerLib\ClientServerLib\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>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Website\html\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>xcopy /E /D /Y "$(ProjectDir)\Website" "$(SolutionDir)\PhoneGap"</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

+12
View File
@@ -0,0 +1,12 @@
/*! jQuery Mobile 1.3.2 | Git HEAD hash: 528cf0e <> 2013-07-19T22:17:57Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */
/*!
* jQuery Mobile 1.3.2
* Git HEAD hash: 528cf0e96940644ea644096bfeb913ed920ffaef <> Date: Fri Jul 19 2013 22:17:57 UTC
* http://jquerymobile.com
*
* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
*/.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:700;text-shadow:0 -1px 0 #000;background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111));background-image:-webkit-linear-gradient(#3c3c3c,#111);background-image:-moz-linear-gradient(#3c3c3c,#111);background-image:-ms-linear-gradient(#3c3c3c,#111);background-image:-o-linear-gradient(#3c3c3c,#111);background-image:linear-gradient(#3c3c3c,#111)}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 0 #111;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#222));background-image:-webkit-linear-gradient(#444,#222);background-image:-moz-linear-gradient(#444,#222);background-image:-ms-linear-gradient(#444,#222);background-image:-o-linear-gradient(#444,#222);background-image:linear-gradient(#444,#222)}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:700}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#2d2d2d));background-image:-webkit-linear-gradient(#444,#2d2d2d);background-image:-moz-linear-gradient(#444,#2d2d2d);background-image:-ms-linear-gradient(#444,#2d2d2d);background-image:-o-linear-gradient(#444,#2d2d2d);background-image:linear-gradient(#444,#2d2d2d)}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#555),to(#383838));background-image:-webkit-linear-gradient(#555,#383838);background-image:-moz-linear-gradient(#555,#383838);background-image:-ms-linear-gradient(#555,#383838);background-image:-o-linear-gradient(#555,#383838);background-image:linear-gradient(#555,#383838)}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#202020),to(#2c2c2c));background-image:-webkit-linear-gradient(#202020,#2c2c2c);background-image:-moz-linear-gradient(#202020,#2c2c2c);background-image:-ms-linear-gradient(#202020,#2c2c2c);background-image:-o-linear-gradient(#202020,#2c2c2c);background-image:linear-gradient(#202020,#2c2c2c)}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:700;text-shadow:0 1px 0 #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#497bae));background-image:-webkit-linear-gradient(#6facd5,#497bae);background-image:-moz-linear-gradient(#6facd5,#497bae);background-image:-ms-linear-gradient(#6facd5,#497bae);background-image:-o-linear-gradient(#6facd5,#497bae);background-image:linear-gradient(#6facd5,#497bae)}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:700}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#ccc));background-image:-webkit-linear-gradient(#ddd,#ccc);background-image:-moz-linear-gradient(#ddd,#ccc);background-image:-ms-linear-gradient(#ddd,#ccc);background-image:-o-linear-gradient(#ddd,#ccc);background-image:linear-gradient(#ddd,#ccc)}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:700}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:700;coloLine truncated
+12
View File
@@ -0,0 +1,12 @@
/*! jQuery Mobile 1.3.2 | Git HEAD hash: 528cf0e <> 2013-07-19T22:17:57Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */
/*!
* jQuery Mobile 1.3.2
* Git HEAD hash: 528cf0e96940644ea644096bfeb913ed920ffaef <> Date: Fri Jul 19 2013 22:17:57 UTC
* http://jquerymobile.com
*
* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
*/.ui-bar-a{border:1px solid #333;background:#111;color:#fff;font-weight:700;text-shadow:0 -1px 0 #000;background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111));background-image:-webkit-linear-gradient(#3c3c3c,#111);background-image:-moz-linear-gradient(#3c3c3c,#111);background-image:-ms-linear-gradient(#3c3c3c,#111);background-image:-o-linear-gradient(#3c3c3c,#111);background-image:linear-gradient(#3c3c3c,#111)}.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button{font-family:Helvetica,Arial,sans-serif}.ui-bar-a .ui-link-inherit{color:#fff}.ui-bar-a a.ui-link{color:#7cc4e7;font-weight:700}.ui-bar-a a.ui-link:visited{color:#2489ce}.ui-bar-a a.ui-link:hover{color:#2489ce}.ui-bar-a a.ui-link:active{color:#2489ce}.ui-body-a,.ui-overlay-a{border:1px solid #444;background:#222;color:#fff;text-shadow:0 1px 0 #111;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#222));background-image:-webkit-linear-gradient(#444,#222);background-image:-moz-linear-gradient(#444,#222);background-image:-ms-linear-gradient(#444,#222);background-image:-o-linear-gradient(#444,#222);background-image:linear-gradient(#444,#222)}.ui-overlay-a{background-image:none;border-width:0}.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button{font-family:Helvetica,Arial,sans-serif}.ui-body-a .ui-link-inherit{color:#fff}.ui-body-a .ui-link{color:#2489ce;font-weight:700}.ui-body-a .ui-link:visited{color:#2489ce}.ui-body-a .ui-link:hover{color:#2489ce}.ui-body-a .ui-link:active{color:#2489ce}.ui-btn-up-a{border:1px solid #111;background:#333;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#444),to(#2d2d2d));background-image:-webkit-linear-gradient(#444,#2d2d2d);background-image:-moz-linear-gradient(#444,#2d2d2d);background-image:-ms-linear-gradient(#444,#2d2d2d);background-image:-o-linear-gradient(#444,#2d2d2d);background-image:linear-gradient(#444,#2d2d2d)}.ui-btn-up-a:visited,.ui-btn-up-a a.ui-link-inherit{color:#fff}.ui-btn-hover-a{border:1px solid #000;background:#444;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#555),to(#383838));background-image:-webkit-linear-gradient(#555,#383838);background-image:-moz-linear-gradient(#555,#383838);background-image:-ms-linear-gradient(#555,#383838);background-image:-o-linear-gradient(#555,#383838);background-image:linear-gradient(#555,#383838)}.ui-btn-hover-a:visited,.ui-btn-hover-a:hover,.ui-btn-hover-a a.ui-link-inherit{color:#fff}.ui-btn-down-a{border:1px solid #000;background:#222;font-weight:700;color:#fff;text-shadow:0 1px 0 #111;background-image:-webkit-gradient(linear,left top,left bottom,from(#202020),to(#2c2c2c));background-image:-webkit-linear-gradient(#202020,#2c2c2c);background-image:-moz-linear-gradient(#202020,#2c2c2c);background-image:-ms-linear-gradient(#202020,#2c2c2c);background-image:-o-linear-gradient(#202020,#2c2c2c);background-image:linear-gradient(#202020,#2c2c2c)}.ui-btn-down-a:visited,.ui-btn-down-a:hover,.ui-btn-down-a a.ui-link-inherit{color:#fff}.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a{font-family:Helvetica,Arial,sans-serif;text-decoration:none}.ui-bar-b{border:1px solid #456f9a;background:#5e87b0;color:#fff;font-weight:700;text-shadow:0 1px 0 #3e6790;background-image:-webkit-gradient(linear,left top,left bottom,from(#6facd5),to(#497bae));background-image:-webkit-linear-gradient(#6facd5,#497bae);background-image:-moz-linear-gradient(#6facd5,#497bae);background-image:-ms-linear-gradient(#6facd5,#497bae);background-image:-o-linear-gradient(#6facd5,#497bae);background-image:linear-gradient(#6facd5,#497bae)}.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button{font-family:Helvetica,Arial,sans-serif}.ui-bar-b .ui-link-inherit{color:#fff}.ui-bar-b a.ui-link{color:#ddf0f8;font-weight:700}.ui-bar-b a.ui-link:visited{color:#ddf0f8}.ui-bar-b a.ui-link:hover{color:#ddf0f8}.ui-bar-b a.ui-link:active{color:#ddf0f8}.ui-body-b,.ui-overlay-b{border:1px solid #999;background:#f3f3f3;color:#222;text-shadow:0 1px 0 #fff;font-weight:400;background-image:-webkit-gradient(linear,left top,left bottom,from(#ddd),to(#ccc));background-image:-webkit-linear-gradient(#ddd,#ccc);background-image:-moz-linear-gradient(#ddd,#ccc);background-image:-ms-linear-gradient(#ddd,#ccc);background-image:-o-linear-gradient(#ddd,#ccc);background-image:linear-gradient(#ddd,#ccc)}.ui-overlay-b{background-image:none;border-width:0}.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button{font-family:Helvetica,Arial,sans-serif}.ui-body-b .ui-link-inherit{color:#333}.ui-body-b .ui-link{color:#2489ce;font-weight:700}.ui-body-b .ui-link:visited{color:#2489ce}.ui-body-b .ui-link:hover{color:#2489ce}.ui-body-b .ui-link:active{color:#2489ce}.ui-btn-up-b{border:1px solid #044062;background:#396b9e;font-weight:700;coloLine truncated
+91
View File
@@ -0,0 +1,91 @@
#playerAvatar {
height: 75%;
max-height: 250px;
width: auto;
}
#playerName {
text-align: center;
font-size: 20px;
font-weight: bold;
}
#displayProfileContent {
text-align: center;
}
#keyboardContent {
text-align: center;
}
.overlay {
position: relative;
height: 100%;
width: 100%;
background-color: rgba(0,0,0,0.7);
}
.ui-loader-background {
width: 100%;
height: 100%;
top: 0;
margin: 0;
background: rgba(0, 0, 0, 0.3);
display: none;
position: fixed;
z-index: 100;
}
.ui-loading .ui-loader-background {
display: block;
}
#displaySongCover {
height: 75%;
max-height: 250px;
width: auto;
}
#displaySongContent {
text-align: center;
}
#displaySongContent span {
font-size: 18px;
font-weight: bold;
}
.imageLoaderImg {
height: 100%;
width: 100%;
background: url(images/ajax-loader.gif);
background-size: 45px;
border: #000000 solid 0px;
content: '';
background-repeat: no-repeat;
background-position: center;
}
.ui-body-c, .ui-overlay-c {
background: #000000;
}
.ui-input-search {
background: #6E6E6E !important;
}
.ui-listview-filter {
background: #000000 !important;
}
.ui-custom-errorIcon {
background: url(images/alert.png) !important;
background-size: 42px 42px;
-webkit-border-radius: 0px !important;
border-radius: 0px !important;
}
.cursorStyleClickable {
cursor: pointer;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

+373
View File
@@ -0,0 +1,373 @@
<!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="phonegap.js"></script>
<script src="barcodescanner.js"></script>
<script>
if (document.location.protocol == "file:") {
if (typeof (window.deviceAndJqmLoaded) == "undefined") {
window.deviceAndJqmLoaded = $.Deferred();
}
var jqmready = $.Deferred();
var deviceready = $.Deferred();
$(document).bind("mobileinit", function () {
jqmready.resolve();
});
function deviceIsReady() {
deviceready.resolve();
}
document.addEventListener("deviceready", deviceIsReady, false);
$.when(jqmready, deviceready).then(function () {
window.deviceAndJqmLoaded.resolve();
});
}
</script>
<script src="js/jquery.mobile-1.3.2.min.js"></script>
<script src="js/jquery-ui-1.10.3.custom.min.js"></script>
<script src="js/jquery.ui.touch-punch.min.js"></script>
<script src="js/i18next-1.7.1.min.js"></script>
<script src="js/main.js"></script>
</head>
<body>
<div id="discover" data-content-theme="a" data-role="page" data-add-back-btn="false">
<div data-role="header">
<h1 data-i18n="discoverConnectHeader"></h1>
</div>
<!-- /header -->
<div id="discoverContent" data-role="content">
<label for="discoverServerAddress" class="input" data-i18n="discoverConnectServerAddress"></label>
<input type="text" id="discoverServerAddress" name="discoverServerAddress" data-mini="true">
<a data-role="button" id="discoverConnect" data-i18n="discoverConnectButton"></a>
<br />
<hr />
<br />
<a data-role="button" id="discoverReadQr" data-i18n="discoverReadQrButton"></a>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="login" data-content-theme="a" data-role="page" data-add-back-btn="false">
<div data-role="header">
<h1 data-i18n="">Login</h1>
</div>
<!-- /header -->
<div id="loginContent" data-role="content">
<label for="loginName" class="input" data-i18n="loginName"></label>
<input type="text" id="loginName" name="loginName" data-mini="true">
<label for="loginPassword" class="input" data-i18n="loginPassword"></label>
<input type="password" id="loginPassword" name="loginPassword" data-mini="true">
<br />
<a data-role="button" id="loginButton" data-i18n="loginButton"></a>
<br />
<hr />
<br />
<a data-role="button" id="registerButton" data-i18n="registerButton"></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 data-i18n="mainPageYourProfileLink"></h2>
<p data-i18n="mainPageYourProfileLinkDesc"></p>
</a>
</li>
<li>
<a id="currentSongLink" href="#" data-transition="slidefade">
<img src="img/music.png">
<h2 data-i18n="mainPageCurrentSongLink"></h2>
<p data-i18n="mainPageCurrentSongLinkDesc"></p>
</a>
</li>
<li>
<a href="#selectSong" data-transition="slidefade">
<img src="img/playlist.png">
<h2 data-i18n="mainPageSelectSong"></h2>
<p data-i18n="mainPageSelectSongDesc"></p>
</a>
</li>
<li>
<a href="#selectPlaylist" data-transition="slidefade">
<img src="img/playlists.png">
<h2 data-i18n="mainPageSelectPlaylist"></h2>
<p data-i18n="mainPageSelectPlaylistDesc"></p>
</a>
</li>
<li>
<a id="mainPageSelectProfile" href="#selectProfile" data-transition="slidefade">
<img src="img/profiles.png">
<h2 data-i18n="mainPageSelectProfile"></h2>
<p data-i18n="mainPageSelectProfileDesc"></p>
</a>
</li>
<li>
<a id="mainPageTakePhotoLink" href="#" data-transition="slidefade">
<img src="img/photo.png">
<h2 data-i18n="mainPageTakePhotoLink"></h2>
<p data-i18n="mainPageTakePhotoLinkDesc"></p>
</a>
</li>
<li>
<a id="mainPageKeyboard" href="#keyboard" data-transition="slidefade">
<img src="img/keyboard.png">
<h2 data-i18n="mainPageKeyboard"></h2>
<p data-i18n="mainPageKeyboardDesc"></p>
</a>
</li>
<li>
<a href="#selectUserAdmin" data-transition="slidefade">
<img src="img/admin.png">
<h2 data-i18n="mainPageSelectUserAdmin"></h2>
<p data-i18n="mainPageSelectUserAdminDesc"></p>
</a>
</li>
<li>
<a id="mainPageLogoutLink" href="#" data-transition="slidefade">
<img src="img/logout.png">
<h2 data-i18n="mainPageLogoutLink"></h2>
<p data-i18n="mainPageLogoutLinkDesc"></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 data-i18n="selectProfileHeader"></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 data-i18n="displayProfileHeader">Profile</h1>
</div>
<!-- /header -->
<div id="displayProfileContent" data-role="content">
<img id="playerAvatar" src="img/profile.png" alt="Avatar">
<label for="playerName" class="input" data-i18n="displayProfileName"></label>
<input type="text" id="playerName" name="playerName" data-mini="true" value="Your Name">
<label for="playerType" class="select" data-i18n="displayProfilePlayerType"></label>
<select name="playerType" id="playerType">
<option value="0" data-i18n="displayProfilePlayerTypeNormal"></option>
<option value="1" data-i18n="displayProfilePlayerTypeGuest"></option>
</select>
<label for="playerDifficulty" class="select" data-i18n="displayProfilePlayerDifficulty"></label>
<select name="playerDifficulty" id="playerDifficulty">
<option value="0" data-i18n="displayProfilePlayerDifficultyEasy"></option>
<option value="1" data-i18n="displayProfilePlayerDifficultyNormal"></option>
<option value="2" data-i18n="displayProfilePlayerDifficultyHard"></option>
</select>
<label id="playerPasswordLabel" for="playerPassword" class="input" data-i18n="displayProfilePlayerPassword"></label>
<input type="password" id="playerPassword" name="playerPassword" data-mini="true" value="**oldPassword**">
<br />
<a data-role="button" id="playerSaveButton" data-i18n="displayProfilePlayerSaveButton"></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" data-i18n="displaySongHeader"></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" data-i18n="displaySongArtist"></label>
<span id="displaySongArtist" data-mini="true">-</span>
<br />
<label for="displaySongGenre" class="input" data-i18n="displaySongGenre"></label>
<span id="displaySongGenre" data-mini="true">-</span>
<br />
<label for="displaySongYear" class="input" data-i18n="displaySongYear"></label>
<span id="displaySongYear" data-mini="true">-</span>
<br />
<label for="displaySongLanguage" class="input" data-i18n="displaySongLanguage"></label>
<span id="displaySongLanguage" data-mini="true">-</span>
<br />
<label for="displaySongIsDuet" class="input" data-i18n="displaySongIsDuet"></label>
<span id="displaySongIsDuet" data-mini="true">-</span>
<br />
<br />
<div id="displaySongLinks">
<img class="cursorStyleClickable" id="displaySongAddPlaylist" src="img/addPlaylist.png" />
<br />
<br />
<img class="cursorStyleClickable" id="displaySongLinkYoutube" src="img/youtube.png" />
<img class="cursorStyleClickable" id="displaySongLinkSpotify" src="img/spotify.png" />
<img class="cursorStyleClickable" id="displaySongLinkWikipedia" src="img/wikipedia.png" />
</div>
</div>
<!-- /content -->
<div data-role="popup" id="popupVideo" data-overlay-theme="a" data-theme="a" data-corners="false" data-tolerance="15,15">
<a href="#" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right" data-i18n="popupVideoClose"></a>
<iframe width="480" height="320" seamless></iframe>
</div>
<!-- /popup -->
</div>
<!-- /page -->
<div id="selectSong" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1 data-i18n="selectSongHeader"></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 data-i18n="keyboardHeader"></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" data-i18n="keyboardButtonUp"></a>
</div>
<div class="ui-block-c"></div>
<div class="ui-block-a">
<a data-role="button" id="keyboardButtonLeft" data-i18n="keyboardButtonLeft"></a>
</div>
<div class="ui-block-b">
</div>
<div class="ui-block-c">
<a data-role="button" id="keyboardButtonRight" data-i18n="keyboardButtonRight"></a>
</div>
<div class="ui-block-a"></div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonDown" data-i18n="keyboardButtonDown"></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" data-i18n="keyboardButtonEscape"></a>
</div>
<div class="ui-block-b">
<a data-role="button" id="keyboardButtonTab" data-i18n="keyboardButtonTab"></a>
</div>
<div class="ui-block-c">
<a data-role="button" id="keyboardButtonReturn" data-i18n="keyboardButtonReturn"></a>
</div>
</div>
<!-- <div style>
<label for="keyboardButtonKeys" data-i18n="keyboardButtonKeys"></label>
<input type="text" id="keyboardButtonKeys" data-mini="true">
</div> -->
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="selectUserAdmin" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1 data-i18n="selectUserAdminHeader"></h1>
</div>
<!-- /header -->
<div id="selectUserAdminContent" data-role="content">
<ul id="selectUserAdminList" data-role="listview"></ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="displayUserAdmin" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1 data-i18n="displayUserAdminHeader"></h1>
</div>
<!-- /header -->
<div id="displayUserAdminContent" data-role="content">
<fieldset data-role="controlgroup">
<legend></legend>
<input type="checkbox" id="roleAuthenticatedUser" checked="checked" disabled="disabled">
<label for="roleAuthenticatedUser">AuthenticatedUser</label>
<input type="checkbox" id="roleAdministrator">
<label for="roleAdministrator">Administrator</label>
</fieldset>
<a data-role="button" id="btnRoleSave" data-transition="slidefade" data-i18n="displayUserAdminContentSaveButton"></a>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="selectPlaylist" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1 data-i18n="selectPlaylistHeader"></h1>
<a id="selectPlaylistAddPlaylistButton" href="#" class="ui-btn-right" data-icon="add" data-i18n="selectPlaylistAddPlaylistButton"></a>
</div>
<!-- /header -->
<div id="selectPlaylistContent" data-role="content">
<ul data-split-theme="a" id="selectPlaylistContentList" data-role="listview" data-filter="true"></ul>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div id="displayPlaylist" data-content-theme="a" data-role="page" data-add-back-btn="true">
<div id="displayPlaylistHeader" data-role="header">
<h1 data-i18n="displayPlaylistHeader"></h1>
<a id="displayPlaylistSaveButton" class="ui-btn-right" href="#" data-icon="add" data-i18n="displayPlaylistSaveButton"></a>
</div>
<!-- /header -->
<div id="displayPlaylistContent" data-role="content">
<ol data-split-theme="a" id="displayPlaylistContentList" data-role="listview" data-filter="true"></ol>
</div>
<!-- /content -->
</div>
<!-- /page -->
<div class="ui-loader-background"></div>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
// i18next, v1.7.1
// Copyright (c)2013 Jan Mühlemann (jamuhl).
// Distributed under MIT license
// http://i18next.com
!function(){function a(a,b){if(!b||"function"==typeof b)return a;for(var c in b)a[c]=b[c];return a}function b(a,b,c){var d,e=0,f=a.length,g=void 0===f||"function"==typeof a;if(c)if(g){for(d in a)if(b.apply(a[d],c)===!1)break}else for(;f>e&&b.apply(a[e++],c)!==!1;);else if(g){for(d in a)if(b.call(a[d],d,a[d])===!1)break}else for(;f>e&&b.call(a[e],e,a[e++])!==!1;);return a}function c(a){return"string"==typeof a?a.replace(/[&<>"'\/]/g,function(a){return H[a]}):a}function d(a){var b=function(a){if(window.XMLHttpRequest)return a(null,new XMLHttpRequest);if(window.ActiveXObject)try{return a(null,new ActiveXObject("Msxml2.XMLHTTP"))}catch(b){return a(null,new ActiveXObject("Microsoft.XMLHTTP"))}return a(new Error)},c=function(a){if("string"==typeof a)return a;var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));return b.join("&")},d=function(a){a=a.replace(/\r\n/g,"\n");for(var b="",c=0;c<a.length;c++){var d=a.charCodeAt(c);128>d?b+=String.fromCharCode(d):d>127&&2048>d?(b+=String.fromCharCode(192|d>>6),b+=String.fromCharCode(128|63&d)):(b+=String.fromCharCode(224|d>>12),b+=String.fromCharCode(128|63&d>>6),b+=String.fromCharCode(128|63&d))}return b},e=function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a=d(a);var c,e,f,g,h,i,j,k="",l=0;do c=a.charCodeAt(l++),e=a.charCodeAt(l++),f=a.charCodeAt(l++),g=c>>2,h=(3&c)<<4|e>>4,i=(15&e)<<2|f>>6,j=63&f,isNaN(e)?i=j=64:isNaN(f)&&(j=64),k+=b.charAt(g)+b.charAt(h)+b.charAt(i)+b.charAt(j),c=e=f="",g=h=i=j="";while(l<a.length);return k},f=function(){for(var a=arguments[0],b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}return a},g=function(a,d,e,h){"function"==typeof e&&(h=e,e={}),e.cache=e.cache||!1,e.data=e.data||{},e.headers=e.headers||{},e.jsonp=e.jsonp||!1,e.async=void 0===e.async?!0:e.async;var i,j=f({accept:"*/*","content-type":"application/x-www-form-urlencoded;charset=UTF-8"},g.headers,e.headers);if(i="application/json"===j["content-type"]?JSON.stringify(e.data):c(e.data),"GET"===a){var k=[];if(i&&(k.push(i),i=null),e.cache||k.push("_="+(new Date).getTime()),e.jsonp&&(k.push("callback="+e.jsonp),k.push("jsonp="+e.jsonp)),k=k.join("&"),k.length>1&&(d+=d.indexOf("?")>-1?"&"+k:"?"+k),e.jsonp){var l=document.getElementsByTagName("head")[0],m=document.createElement("script");return m.type="text/javascript",m.src=d,l.appendChild(m),void 0}}b(function(b,c){if(b)return h(b);c.open(a,d,e.async);for(var f in j)j.hasOwnProperty(f)&&c.setRequestHeader(f,j[f]);c.onreadystatechange=function(){if(4===c.readyState){var a=c.responseText||"";if(!h)return;h(c.status,{text:function(){return a},json:function(){return JSON.parse(a)}})}},c.send(i)})},h={authBasic:function(a,b){g.headers.Authorization="Basic "+e(a+":"+b)},connect:function(a,b,c){return g("CONNECT",a,b,c)},del:function(a,b,c){return g("DELETE",a,b,c)},get:function(a,b,c){return g("GET",a,b,c)},head:function(a,b,c){return g("HEAD",a,b,c)},headers:function(a){g.headers=a||{}},isAllowed:function(a,b,c){this.options(a,function(a,d){c(-1!==d.text().indexOf(b))})},options:function(a,b,c){return g("OPTIONS",a,b,c)},patch:function(a,b,c){return g("PATCH",a,b,c)},post:function(a,b,c){return g("POST",a,b,c)},put:function(a,b,c){return g("PUT",a,b,c)},trace:function(a,b,c){return g("TRACE",a,b,c)}},i=a.type?a.type.toLowerCase():"get";h[i](a.url,a,function(b,c){200===b?a.success(c.json(),b,null):a.error(c.text(),b,null)})}function e(a,b){"function"==typeof a&&(b=a,a={}),a=a||{},K.extend(G,a),delete G.fixLng,"string"==typeof G.ns&&(G.ns={namespaces:[G.ns],defaultNs:G.ns}),"string"==typeof G.fallbackNS&&(G.fallbackNS=[G.fallbackNS]),G.interpolationPrefixEscaped=K.regexEscape(G.interpolationPrefix),G.interpolationSuffixEscaped=K.regexEscape(G.interpolationSuffix),G.lng||(G.lng=K.detectLanguage()),G.lng?G.useCookie&&K.cookie.create(G.cookieName,G.lng,G.cookieExpirationTime,G.cookieDomain):(G.lng=G.fallbackLng,G.useCookie&&K.cookie.remove(G.cookieName)),E=K.toLanguages(G.lng),y=E[0],K.log("currentLng set to: "+y);var c=s;a.fixLng&&(c=function(a,b){return b=b||{},b.lng=b.lng||c.lng,s(a,b)},c.lng=y),M.setCurrentLng(y),A&&G.setJqueryExt&&m();var d;if(A&&A.Deferred&&(d=A.Deferred()),!G.resStore){var e=K.toLanguages(G.lng);"string"==typeof G.preload&&(G.preload=[G.preload]);for(var f=0,g=G.preload.length;g>f;f++)for(var h=K.toLanguages(G.preload[f]),i=0,j=h.length;j>i;i++)e.indexOf(h[i])<0&&e.push(h[i]);return B.sync.load(e,G,function(a,e){C=e,F=!0,b&&b(c),d&&d.resolve(c)}),d?d.promise():void 0}return C=G.resStore,F=!0,b&&b(c),d&&d.resolve(c),d?d.promise():void 0}function f(a,b){"string"==typeof a&&(a=[a]);for(var c=0,d=a.length;d>c;c++)G.preload.indexOf(a[c])<0&&G.preload.push(a[c]);return e(b)}function g(a,b,c){"string"!=typeof b?(c=b,b=G.ns.defaultNs):G.ns.namespaces.indexOf(b)<0&&G.ns.namespaces.push(b),C[a]=C[a]||{},C[a][b]=C[a][b]||{},K.extend(C[a][b],c)}function h(a){G.ns.defaultNs=a}function i(a,b){j([a],b)}funLine truncated
+5
View File
@@ -0,0 +1,5 @@
/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
//@ sourceMappingURL=jquery.min.map
*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(Line truncated
return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+Line truncated
}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}reLine truncated
+6
View File
@@ -0,0 +1,6 @@
/*! jQuery UI - v1.10.3 - 2013-11-03
* http://jqueryui.com
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.sortable.js
* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
(function(e,t){function i(t,i){var s,n,r,o=t.nodeName.toLowerCase();return"area"===o?(s=t.parentNode,n=s.name,t.href&&n&&"map"===s.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&a(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||i:i)&&a(t)}function a(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var s=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,a){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),a&&a.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var a,s,n=e(this[0]);n.length&&n[0]!==document;){if(a=n.css("position"),("absolute"===a||"relative"===a||"fixed"===a)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++s)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,a){return!!e.data(t,a[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var a=e.attr(t,"tabindex"),s=isNaN(a);return(s||a>=0)&&i(t,!s)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,a){function s(t,i,a,s){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,a&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===a?["Left","Right"]:["Top","Bottom"],r=a.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+a]=function(i){return i===t?o["inner"+a].call(this):this.each(function(){e(this).css(r,s(this,i)+"px")})},e.fn["outer"+a]=function(t,i){return"number"!=typeof t?o["outer"+a].call(this,t):this.each(function(){e(this).css(r,s(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,a){var s,n=e.ui[t].prototype;for(s in a)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([i,a[s]])},call:function(e,t,i){var a,s=e.plugins[t];if(s&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(a=0;s.length>a;a++)e.options[s[a][0]]&&s[a][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var a=i&&"left"===i?"scrollLeft":"scrollTop",s=!1;return t[a]>0?!0:(t[a]=1,s=t[a]>0,t[a]=0,s)}})})(jQuery);(function(e,t){var i=0,s=Array.prototype.slice,a=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(n){}a(t)},e.widget=function(i,s,a){var n,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],n=u+"-"+i,a||(a=s,s=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:a.version,_proto:e.extend({},a),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(a,function(i,a){return e.isFunction(a)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,n=this._superApply;return this._suLine truncated
+9
View File
@@ -0,0 +1,9 @@
/*! jQuery Mobile 1.3.2 | Git HEAD hash: 528cf0e <> 2013-07-19T22:17:57Z | (c) 2010, 2013 jQuery Foundation, Inc. | jquery.org/license */
!function(a,b,c){"function"==typeof define&&define.amd?define(["jquery"],function(d){return c(d,a,b),d.mobile}):c(a.jQuery,a,b)}(this,document,function(a,b,c,d){!function(a){a.mobile={}}(a),function(a,b,d){var e={};a.mobile=a.extend(a.mobile,{version:"1.3.2",ns:"",subPageUrlKey:"ui-page",activePageClass:"ui-page-active",activeBtnClass:"ui-btn-active",focusClass:"ui-focus",ajaxEnabled:!0,hashListeningEnabled:!0,linkBindingEnabled:!0,defaultPageTransition:"fade",maxTransitionWidth:!1,minScrollBack:250,touchOverflowEnabled:!1,defaultDialogTransition:"pop",pageLoadErrorMessage:"Error Loading Page",pageLoadErrorMessageTheme:"e",phonegapNavigationEnabled:!1,autoInitializePage:!0,pushStateEnabled:!0,ignoreContentEnabled:!1,orientationChangeEnabled:!0,buttonMarkup:{hoverDelay:200},window:a(b),document:a(c),keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},behaviors:{},silentScroll:function(c){"number"!==a.type(c)&&(c=a.mobile.defaultHomeScroll),a.event.special.scrollstart.enabled=!1,setTimeout(function(){b.scrollTo(0,c),a.mobile.document.trigger("silentscroll",{x:0,y:c})},20),setTimeout(function(){a.event.special.scrollstart.enabled=!0},150)},nsNormalizeDict:e,nsNormalize:function(b){return b?e[b]||(e[b]=a.camelCase(a.mobile.ns+b)):void 0},getInheritedTheme:function(a,b){for(var c,d,e=a[0],f="",g=/ui-(bar|body|overlay)-([a-z])\b/;e&&(c=e.className||"",!(c&&(d=g.exec(c))&&(f=d[2])));)e=e.parentNode;return f||b||"a"},closestPageData:function(a){return a.closest(':jqmData(role="page"), :jqmData(role="dialog")').data("mobile-page")},enhanceable:function(a){return this.haveParents(a,"enhance")},hijackable:function(a){return this.haveParents(a,"ajax")},haveParents:function(b,c){if(!a.mobile.ignoreContentEnabled)return b;for(var d,e,f,g=b.length,h=a(),i=0;g>i;i++){for(e=b.eq(i),f=!1,d=b[i];d;){var j=d.getAttribute?d.getAttribute("data-"+a.mobile.ns+c):"";if("false"===j){f=!0;break}d=d.parentNode}f||(h=h.add(e))}return h},getScreenHeight:function(){return b.innerHeight||a.mobile.window.height()}},a.mobile),a.fn.jqmData=function(b,c){var e;return"undefined"!=typeof b&&(b&&(b=a.mobile.nsNormalize(b)),e=arguments.length<2||c===d?this.data(b):this.data(b,c)),e},a.jqmData=function(b,c,d){var e;return"undefined"!=typeof c&&(e=a.data(b,c?a.mobile.nsNormalize(c):c,d)),e},a.fn.jqmRemoveData=function(b){return this.removeData(a.mobile.nsNormalize(b))},a.jqmRemoveData=function(b,c){return a.removeData(b,a.mobile.nsNormalize(c))},a.fn.removeWithDependents=function(){a.removeWithDependents(this)},a.removeWithDependents=function(b){var c=a(b);(c.jqmData("dependents")||a()).remove(),c.remove()},a.fn.addDependents=function(b){a.addDependents(a(this),b)},a.addDependents=function(b,c){var d=a(b).jqmData("dependents")||a();a(b).jqmData("dependents",a.merge(d,c))},a.fn.getEncodedText=function(){return a("<div/>").text(a(this).text()).html()},a.fn.jqmEnhanceable=function(){return a.mobile.enhanceable(this)},a.fn.jqmHijackable=function(){return a.mobile.hijackable(this)};var f=a.find,g=/:jqmData\(([^)]*)\)/g;a.find=function(b,c,d,e){return b=b.replace(g,"[data-"+(a.mobile.ns||"")+"$1]"),f.call(this,b,c,d,e)},a.extend(a.find,f),a.find.matches=function(b,c){return a.find(b,null,null,c)},a.find.matchesSelector=function(b,c){return a.find(c,null,null,[b]).length>0}}(a,this),function(a,b){var c=0,d=Array.prototype.slice,e=a.cleanData;a.cleanData=function(b){for(var c,d=0;null!=(c=b[d]);d++)try{a(c).triggerHandler("remove")}catch(f){}e(b)},a.widget=function(b,c,d){var e,f,g,h,i=b.split(".")[0];b=b.split(".")[1],e=i+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][e.toLowerCase()]=function(b){return!!a.data(b,e)},a[i]=a[i]||{},f=a[i][b],g=a[i][b]=function(a,b){return this._createWidget?(arguments.length&&this._createWidget(a,b),void 0):new g(a,b)},a.extend(g,f,{version:d.version,_proto:a.extend({},d),_childConstructors:[]}),h=new c,h.options=a.widget.extend({},h.options),a.each(d,function(b,e){a.isFunction(e)&&(d[b]=function(){var a=function(){return c.prototype[b].apply(this,arguments)},d=function(a){return c.prototype[b].apply(this,a)};return function(){var b,c=this._super,f=this._superApply;return this._super=a,this._superApply=d,b=e.apply(this,arguments),this._super=c,this._superApply=f,b}}())}),g.prototype=a.widget.extend(h,{widgetEventPrefix:f?h.widgetEventPrefix:b},d,{constructor:g,namespace:i,widgetName:b,widgetFullName:e}),f?(a.each(f._childConstructors,function(b,c){var d=c.prototype;a.widget(d.namespace+"."+d.widgetName,g,c._proto)}),delete f._childConstructors):c._childConstructors.push(g),a.widget.bridge(b,g)},a.widget.extend=function(c){for(var e,f,g=d.call(arguments,1),h=0,i=g.length;i>h;h++)for(e in g[h])f=g[h][e],g[h].hasLine truncated
}if(d.which&&1!==d.which)return!1;var j,k=d.target;d.originalEvent,c.bind("vmouseup",g).bind("vclick",i),f.bind("vmousecancel",h),j=setTimeout(function(){e(b,"taphold",a.Event("taphold",{target:k}))},a.event.special.tap.tapholdThreshold)})}},a.event.special.swipe={scrollSupressionThreshold:30,durationThreshold:1e3,horizontalDistanceThreshold:30,verticalDistanceThreshold:75,start:function(b){var c=b.originalEvent.touches?b.originalEvent.touches[0]:b;return{time:(new Date).getTime(),coords:[c.pageX,c.pageY],origin:a(b.target)}},stop:function(a){var b=a.originalEvent.touches?a.originalEvent.touches[0]:a;return{time:(new Date).getTime(),coords:[b.pageX,b.pageY]}},handleSwipe:function(b,c){c.time-b.time<a.event.special.swipe.durationThreshold&&Math.abs(b.coords[0]-c.coords[0])>a.event.special.swipe.horizontalDistanceThreshold&&Math.abs(b.coords[1]-c.coords[1])<a.event.special.swipe.verticalDistanceThreshold&&b.origin.trigger("swipe").trigger(b.coords[0]>c.coords[0]?"swipeleft":"swiperight")},setup:function(){var b=this,c=a(b);c.bind(i,function(b){function e(b){g&&(f=a.event.special.swipe.stop(b),Math.abs(g.coords[0]-f.coords[0])>a.event.special.swipe.scrollSupressionThreshold&&b.preventDefault())}var f,g=a.event.special.swipe.start(b);c.bind(k,e).one(j,function(){c.unbind(k,e),g&&f&&a.event.special.swipe.handleSwipe(g,f),g=f=d})})}},a.each({scrollstop:"scrollstart",taphold:"tap",swipeleft:"swipe",swiperight:"swipe"},function(b,c){a.event.special[b]={setup:function(){a(this).bind(c,a.noop)}}})}(a,this),function(a){a.event.special.throttledresize={setup:function(){a(this).bind("resize",f)},teardown:function(){a(this).unbind("resize",f)}};var b,c,d,e=250,f=function(){c=(new Date).getTime(),d=c-g,d>=e?(g=c,a(this).trigger("throttledresize")):(b&&clearTimeout(b),b=setTimeout(f,e-d))},g=0}(a),function(a,b){function d(){var a=e();a!==f&&(f=a,i.trigger(j))}var e,f,g,h,i=a(b),j="orientationchange",k={0:!0,180:!0};if(a.support.orientation){var l=b.innerWidth||i.width(),m=b.innerHeight||i.height(),n=50;g=l>m&&l-m>n,h=k[b.orientation],(g&&h||!g&&!h)&&(k={"-90":!0,90:!0})}a.event.special.orientationchange=a.extend({},a.event.special.orientationchange,{setup:function(){return a.support.orientation&&!a.event.special.orientationchange.disabled?!1:(f=e(),i.bind("throttledresize",d),void 0)},teardown:function(){return a.support.orientation&&!a.event.special.orientationchange.disabled?!1:(i.unbind("throttledresize",d),void 0)},add:function(a){var b=a.handler;a.handler=function(a){return a.orientation=e(),b.apply(this,arguments)}}}),a.event.special.orientationchange.orientation=e=function(){var d=!0,e=c.documentElement;return d=a.support.orientation?k[b.orientation]:e&&e.clientWidth/e.clientHeight<1.1,d?"portrait":"landscape"},a.fn[j]=function(a){return a?this.bind(j,a):this.trigger(j)},a.attrFn&&(a.attrFn[j]=!0)}(a,this),function(a){a.widget("mobile.page",a.mobile.widget,{options:{theme:"c",domCache:!1,keepNativeDefault:":jqmData(role='none'), :jqmData(role='nojs')"},_create:function(){return this._trigger("beforecreate")===!1?!1:(this.element.attr("tabindex","0").addClass("ui-page ui-body-"+this.options.theme),this._on(this.element,{pagebeforehide:"removeContainerBackground",pagebeforeshow:"_handlePageBeforeShow"}),void 0)},_handlePageBeforeShow:function(){this.setContainerBackground()},removeContainerBackground:function(){a.mobile.pageContainer.removeClass("ui-overlay-"+a.mobile.getInheritedTheme(this.element.parent()))},setContainerBackground:function(b){this.options.theme&&a.mobile.pageContainer.addClass("ui-overlay-"+(b||this.options.theme))},keepNativeSelector:function(){var b=this.options,c=b.keepNative&&a.trim(b.keepNative);return c&&b.keepNative!==b.keepNativeDefault?[b.keepNative,b.keepNativeDefault].join(", "):b.keepNativeDefault}})}(a),function(a,b,c){var d=function(d){return d===c&&(d=!0),function(c,e,f,g){var h=new a.Deferred,i=e?" reverse":"",j=a.mobile.urlHistory.getActive(),k=j.lastScroll||a.mobile.defaultHomeScroll,l=a.mobile.getScreenHeight(),m=a.mobile.maxTransitionWidth!==!1&&a.mobile.window.width()>a.mobile.maxTransitionWidth,n=!a.support.cssTransitions||m||!c||"none"===c||Math.max(a.mobile.window.scrollTop(),k)>a.mobile.getMaxScrollForTransition(),o=" ui-page-pre-in",p=function(){a.mobile.pageContainer.toggleClass("ui-mobile-viewport-transitioning viewport-"+c)},q=function(){a.event.special.scrollstart.enabled=!1,b.scrollTo(0,k),setTimeout(function(){a.event.special.scrollstart.enabled=!0},150)},r=function(){g.removeClass(a.mobile.activePageClass+" out in reverse "+c).height("")},s=function(){d?g.animationComplete(t):t(),g.height(l+a.mobile.window.scrollTop()).addClass(c+" out"+i)},t=function(){g&&d&&r(),u()},u=function(){f.css("z-index",-10),f.addClass(a.mobile.activePageClass+o),a.mobile.focusPage(f),f.height(l+k),q(),f.css("z-index",""),n||f.animationComplete(v),f.removeClass(o).addClass(c+" in"+i),n&&v()},v=function(){d||g&&r(),f.removeClass("out in reverse "+c).height(""),p(),a.mobile.window.scrollTop(Line truncated
c.parent().is(":jqmData(role='collapsible-set')")&&c.siblings(".ui-collapsible").trigger("collapse")})},_init:function(){var a=this.element,b=a.children(":jqmData(role='collapsible')"),c=b.filter(":jqmData(collapsed='false')");this._refresh("true"),c.trigger("expand")},_refresh:function(b){var c=this.element.children(":jqmData(role='collapsible')");a.mobile.collapsible.prototype.enhance(c.not(".ui-collapsible")),this._addFirstLastClasses(c,this._getVisibles(c,b),b)},refresh:function(){this._refresh(!1)}},a.mobile.behaviors.addFirstLastClasses)),a.mobile.document.bind("pagecreate create",function(b){a.mobile.collapsibleset.prototype.enhanceWithin(b.target)})}(a),function(a){a.fn.fieldcontain=function(){return this.addClass("ui-field-contain ui-body ui-br").contents().filter(function(){return 3===this.nodeType&&!/\S/.test(this.nodeValue)}).remove()},a(c).bind("pagecreate create",function(b){a(":jqmData(role='fieldcontain')",b.target).jqmEnhanceable().fieldcontain()})}(a),function(a){a.fn.grid=function(b){return this.each(function(){var c,d=a(this),e=a.extend({grid:null},b),f=d.children(),g={solo:1,a:2,b:3,c:4,d:5},h=e.grid;if(!h)if(f.length<=5)for(var i in g)g[i]===f.length&&(h=i);else h="a",d.addClass("ui-grid-duo");c=g[h],d.addClass("ui-grid-"+h),f.filter(":nth-child("+c+"n+1)").addClass("ui-block-a"),c>1&&f.filter(":nth-child("+c+"n+2)").addClass("ui-block-b"),c>2&&f.filter(":nth-child("+c+"n+3)").addClass("ui-block-c"),c>3&&f.filter(":nth-child("+c+"n+4)").addClass("ui-block-d"),c>4&&f.filter(":nth-child("+c+"n+5)").addClass("ui-block-e")})}}(a),function(a,b){a.widget("mobile.navbar",a.mobile.widget,{options:{iconpos:"top",grid:null,initSelector:":jqmData(role='navbar')"},_create:function(){var d=this.element,e=d.find("a"),f=e.filter(":jqmData(icon)").length?this.options.iconpos:b;d.addClass("ui-navbar ui-mini").attr("role","navigation").find("ul").jqmEnhanceable().grid({grid:this.options.grid}),e.buttonMarkup({corners:!1,shadow:!1,inline:!0,iconpos:f}),d.delegate("a","vclick",function(b){var d=a(b.target).is("a")?a(this):a(this).parent("a");if(!d.is(".ui-disabled, .ui-btn-active")){e.removeClass(a.mobile.activeBtnClass),a(this).addClass(a.mobile.activeBtnClass);var f=a(this);a(c).one("pagehide",function(){f.removeClass(a.mobile.activeBtnClass)})}}),d.closest(".ui-page").bind("pagebeforeshow",function(){e.filter(".ui-state-persist").addClass(a.mobile.activeBtnClass)})}}),a.mobile.document.bind("pagecreate create",function(b){a.mobile.navbar.prototype.enhanceWithin(b.target)})}(a),function(a){var b={};a.widget("mobile.listview",a.mobile.widget,a.extend({options:{theme:null,countTheme:"c",headerTheme:"b",dividerTheme:"b",icon:"arrow-r",splitIcon:"arrow-r",splitTheme:"b",corners:!0,shadow:!0,inset:!1,initSelector:":jqmData(role='listview')"},_create:function(){var a=this,b="";b+=a.options.inset?" ui-listview-inset":"",a.options.inset&&(b+=a.options.corners?" ui-corner-all":"",b+=a.options.shadow?" ui-shadow":""),a.element.addClass(function(a,c){return c+" ui-listview"+b}),a.refresh(!0)},_findFirstElementByTagName:function(a,b,c,d){var e={};for(e[c]=e[d]=!0;a;){if(e[a.nodeName])return a;a=a[b]}return null},_getChildrenByTagName:function(b,c,d){var e=[],f={};for(f[c]=f[d]=!0,b=b.firstChild;b;)f[b.nodeName]&&e.push(b),b=b.nextSibling;return a(e)},_addThumbClasses:function(b){var c,d,e=b.length;for(c=0;e>c;c++)d=a(this._findFirstElementByTagName(b[c].firstChild,"nextSibling","img","IMG")),d.length&&(d.addClass("ui-li-thumb"),a(this._findFirstElementByTagName(d[0].parentNode,"parentNode","li","LI")).addClass(d.is(".ui-li-icon")?"ui-li-has-icon":"ui-li-has-thumb"))},refresh:function(b){this.parentPage=this.element.closest(".ui-page"),this._createSubPages();var d,e,f,g,h,i,j,k,l,m,n,o,p=this.options,q=this.element,r=q.jqmData("dividertheme")||p.dividerTheme,s=q.jqmData("splittheme"),t=q.jqmData("spliticon"),u=q.jqmData("icon"),v=this._getChildrenByTagName(q[0],"li","LI"),w=!!a.nodeName(q[0],"ol"),x=!a.support.cssPseudoElement,y=q.attr("start"),z={};w&&x&&q.find(".ui-li-dec").remove(),w&&(y||0===y?x?j=parseInt(y,10):(k=parseInt(y,10)-1,q.css("counter-reset","listnumbering "+k)):x&&(j=1)),p.theme||(p.theme=a.mobile.getInheritedTheme(this.element,"c"));for(var A=0,B=v.length;B>A;A++){if(d=v.eq(A),e="ui-li",b||!d.hasClass("ui-li")){f=d.jqmData("theme")||p.theme,g=this._getChildrenByTagName(d[0],"a","A");var C="list-divider"===d.jqmData("role");g.length&&!C?(n=d.jqmData("icon"),d.buttonMarkup({wrapperEls:"div",shadow:!1,corners:!1,iconpos:"right",icon:g.length>1||n===!1?!1:n||u||p.icon,theme:f}),n!==!1&&1===g.length&&d.addClass("ui-li-has-arrow"),g.first().removeClass("ui-link").addClass("ui-link-inherit"),g.length>1&&(e+=" ui-li-has-alt",h=g.last(),i=s||h.jqmData("theme")||p.splitTheme,o=h.jqmData("icon"),h.appendTo(d).attr("title",a.trim(h.getEncodedText())).addClass("ui-li-link-alt").empty().buttonMarkup({shadow:!1,corners:!1,theme:f,icon:!1,iconpos:"notext"}).find(".ui-btn-inner").append(a(c.createElement("span")).Line truncated
},_setDisabled:function(a){return this.element.attr("disabled",a),this.button.attr("aria-disabled",a),this._setOption("disabled",a)},_focusButton:function(){var a=this;setTimeout(function(){a.button.focus()},40)},_selectOptions:function(){return this.select.find("option")},_preExtension:function(){var b="";~this.element[0].className.indexOf("ui-btn-left")&&(b=" ui-btn-left"),~this.element[0].className.indexOf("ui-btn-right")&&(b=" ui-btn-right"),this.select=this.element.removeClass("ui-btn-left ui-btn-right").wrap("<div class='ui-select"+b+"'>"),this.selectID=this.select.attr("id"),this.label=a("label[for='"+this.selectID+"']").addClass("ui-select"),this.isMultiple=this.select[0].multiple,this.options.theme||(this.options.theme=a.mobile.getInheritedTheme(this.select,"c"))},_destroy:function(){var a=this.element.parents(".ui-select");a.length>0&&(a.is(".ui-btn-left, .ui-btn-right")&&this.element.addClass(a.is(".ui-btn-left")?"ui-btn-left":"ui-btn-right"),this.element.insertAfter(a),a.remove())},_create:function(){this._preExtension(),this._trigger("beforeCreate"),this.button=this._button();var c=this,d=this.options,e=d.inline||this.select.jqmData("inline"),f=d.mini||this.select.jqmData("mini"),g=d.icon?d.iconpos||this.select.jqmData("iconpos"):!1,h=(-1===this.select[0].selectedIndex?0:this.select[0].selectedIndex,this.button.insertBefore(this.select).buttonMarkup({theme:d.theme,icon:d.icon,iconpos:g,inline:e,corners:d.corners,shadow:d.shadow,iconshadow:d.iconshadow,mini:f}));this.setButtonText(),d.nativeMenu&&b.opera&&b.opera.version&&h.addClass("ui-select-nativeonly"),this.isMultiple&&(this.buttonCount=a("<span>").addClass("ui-li-count ui-btn-up-c ui-btn-corner-all").hide().appendTo(h.addClass("ui-li-has-count"))),(d.disabled||this.element.attr("disabled"))&&this.disable(),this.select.change(function(){c.refresh(),d.nativeMenu&&this.blur()}),this._handleFormReset(),this.build()},build:function(){var b=this;this.select.appendTo(b.button).bind("vmousedown",function(){b.button.addClass(a.mobile.activeBtnClass)}).bind("focus",function(){b.button.addClass(a.mobile.focusClass)}).bind("blur",function(){b.button.removeClass(a.mobile.focusClass)}).bind("focus vmouseover",function(){b.button.trigger("vmouseover")}).bind("vmousemove",function(){b.button.removeClass(a.mobile.activeBtnClass)}).bind("change blur vmouseout",function(){b.button.trigger("vmouseout").removeClass(a.mobile.activeBtnClass)}).bind("change blur",function(){b.button.removeClass("ui-btn-down-"+b.options.theme)}),b.button.bind("vmousedown",function(){b.options.preventFocusZoom&&a.mobile.zoom.disable(!0)}),b.label.bind("click focus",function(){b.options.preventFocusZoom&&a.mobile.zoom.disable(!0)}),b.select.bind("focus",function(){b.options.preventFocusZoom&&a.mobile.zoom.disable(!0)}),b.button.bind("mouseup",function(){b.options.preventFocusZoom&&setTimeout(function(){a.mobile.zoom.enable(!0)},0)}),b.select.bind("blur",function(){b.options.preventFocusZoom&&a.mobile.zoom.enable(!0)})},selected:function(){return this._selectOptions().filter(":selected")},selectedIndices:function(){var a=this;return this.selected().map(function(){return a._selectOptions().index(this)}).get()},setButtonText:function(){var b=this,d=this.selected(),e=this.placeholder,f=a(c.createElement("span"));this.button.find(".ui-btn-text").html(function(){return e=d.length?d.map(function(){return a(this).text()}).get().join(", "):b.placeholder,f.text(e).addClass(b.select.attr("class")).addClass(d.attr("class"))})},setButtonCount:function(){var a=this.selected();this.isMultiple&&this.buttonCount[a.length>1?"show":"hide"]().text(a.length)},_reset:function(){this.refresh()},refresh:function(){this.setButtonText(),this.setButtonCount()},open:a.noop,close:a.noop,disable:function(){this._setDisabled(!0),this.button.addClass("ui-disabled")},enable:function(){this._setDisabled(!1),this.button.removeClass("ui-disabled")}},a.mobile.behaviors.formReset)),a.mobile.document.bind("pagecreate create",function(b){a.mobile.selectmenu.prototype.enhanceWithin(b.target,!0)})}(a),function(a,d){function e(a,b,c,d){var e=d;return e=b>a?c+(a-b)/2:Math.min(Math.max(c,d-b/2),c+a-b)}function f(){var c=a.mobile.window;return{x:c.scrollLeft(),y:c.scrollTop(),cx:b.innerWidth||c.width(),cy:b.innerHeight||c.height()}}a.widget("mobile.popup",a.mobile.widget,{options:{theme:null,overlayTheme:null,shadow:!0,corners:!0,transition:"none",positionTo:"origin",tolerance:null,initSelector:":jqmData(role='popup')",closeLinkSelector:"a:jqmData(rel='back')",closeLinkEvents:"click.popup",navigateEvents:"navigate.popup",closeEvents:"navigate.popup pagebeforechange.popup",dismissible:!0,history:!a.mobile.browser.oldIE},_eatEventAndClose:function(a){return a.preventDefault(),a.stopImmediatePropagation(),this.options.dismissible&&this.close(),!1},_resizeScreen:function(){var a=this._ui.container.outerHeight(!0);this._ui.screen.removeAttr("style"),a>this._ui.screen.height()&&this._ui.screen.height(a)},_handleWindowKeyUp:function(bLine truncated
return c||(d=Math.round(d-a.mobile.window.height()+b.outerHeight())-60),d},_bindScrollWorkaround:function(){var b=this;this._on(a.mobile.window,{scrollstop:function(){var a=b._viewportOffset();a>2&&b._visible&&b._triggerRedraw()}})},_bindListThumbWorkaround:function(){this.element.closest(".ui-page").addClass("ui-android-2x-fixed")},_triggerRedraw:function(){var b=parseFloat(a(".ui-page-active").css("padding-bottom"));a(".ui-page-active").css("padding-bottom",b+1+"px"),setTimeout(function(){a(".ui-page-active").css("padding-bottom",b+"px")},0)},destroy:function(){this._super(),this.element.closest(".ui-page-active").removeClass("ui-android-2x-fix")}})}(a),function(a,d){a.widget("mobile.panel",a.mobile.widget,{options:{classes:{panel:"ui-panel",panelOpen:"ui-panel-open",panelClosed:"ui-panel-closed",panelFixed:"ui-panel-fixed",panelInner:"ui-panel-inner",modal:"ui-panel-dismiss",modalOpen:"ui-panel-dismiss-open",pagePanel:"ui-page-panel",pagePanelOpen:"ui-page-panel-open",contentWrap:"ui-panel-content-wrap",contentWrapOpen:"ui-panel-content-wrap-open",contentWrapClosed:"ui-panel-content-wrap-closed",contentFixedToolbar:"ui-panel-content-fixed-toolbar",contentFixedToolbarOpen:"ui-panel-content-fixed-toolbar-open",contentFixedToolbarClosed:"ui-panel-content-fixed-toolbar-closed",animate:"ui-panel-animate"},animate:!0,theme:"c",position:"left",dismissible:!0,display:"reveal",initSelector:":jqmData(role='panel')",swipeClose:!0,positionFixed:!1},_panelID:null,_closeLink:null,_page:null,_modal:null,_panelInner:null,_wrapper:null,_fixedToolbar:null,_create:function(){var b=this,c=b.element,d=c.closest(":jqmData(role='page')"),e=function(){var b=a.data(d[0],"mobilePage").options.theme,c="ui-body-"+b;return c},f=function(){var a=c.find("."+b.options.classes.panelInner);return 0===a.length&&(a=c.children().wrapAll('<div class="'+b.options.classes.panelInner+'" />').parent()),a},g=function(){var c=d.find("."+b.options.classes.contentWrap);return 0===c.length&&(c=d.children(".ui-header:not(:jqmData(position='fixed')), .ui-content:not(:jqmData(role='popup')), .ui-footer:not(:jqmData(position='fixed'))").wrapAll('<div class="'+b.options.classes.contentWrap+" "+e()+'" />').parent(),a.support.cssTransform3d&&b.options.animate&&c.addClass(b.options.classes.animate)),c},h=function(){var c=d.find("."+b.options.classes.contentFixedToolbar);return 0===c.length&&(c=d.find(".ui-header:jqmData(position='fixed'), .ui-footer:jqmData(position='fixed')").addClass(b.options.classes.contentFixedToolbar),a.support.cssTransform3d&&b.options.animate&&c.addClass(b.options.classes.animate)),c};a.extend(this,{_panelID:c.attr("id"),_closeLink:c.find(":jqmData(rel='close')"),_page:c.closest(":jqmData(role='page')"),_pageTheme:e(),_panelInner:f(),_wrapper:g(),_fixedToolbar:h()}),b._addPanelClasses(),b._wrapper.addClass(this.options.classes.contentWrapClosed),b._fixedToolbar.addClass(this.options.classes.contentFixedToolbarClosed),b._page.addClass(b.options.classes.pagePanel),a.support.cssTransform3d&&b.options.animate&&this.element.addClass(b.options.classes.animate),b._bindUpdateLayout(),b._bindCloseEvents(),b._bindLinkListeners(),b._bindPageEvents(),b.options.dismissible&&b._createModal(),b._bindSwipeEvents()},_createModal:function(){var b=this;b._modal=a("<div class='"+b.options.classes.modal+"' data-panelid='"+b._panelID+"'></div>").on("mousedown",function(){b.close()}).appendTo(this._page)},_getPosDisplayClasses:function(a){return a+"-position-"+this.options.position+" "+a+"-display-"+this.options.display},_getPanelClasses:function(){var a=this.options.classes.panel+" "+this._getPosDisplayClasses(this.options.classes.panel)+" "+this.options.classes.panelClosed;return this.options.theme&&(a+=" ui-body-"+this.options.theme),this.options.positionFixed&&(a+=" "+this.options.classes.panelFixed),a},_addPanelClasses:function(){this.element.addClass(this._getPanelClasses())},_bindCloseEvents:function(){var a=this;a._closeLink.on("click.panel",function(b){return b.preventDefault(),a.close(),!1}),a.element.on("click.panel","a:jqmData(ajax='false')",function(){a.close()})},_positionPanel:function(){var b=this,c=b._panelInner.outerHeight(),d=c>a.mobile.getScreenHeight();d||!b.options.positionFixed?(d&&(b._unfixPanel(),a.mobile.resetActivePageHeight(c)),b._scrollIntoView(c)):b._fixPanel()},_scrollIntoView:function(c){c<a(b).scrollTop()&&b.scrollTo(0,0)},_bindFixListener:function(){this._on(a(b),{throttledresize:"_positionPanel"})},_unbindFixListener:function(){this._off(a(b),"throttledresize")},_unfixPanel:function(){this.options.positionFixed&&a.support.fixedPosition&&this.element.removeClass(this.options.classes.panelFixed)},_fixPanel:function(){this.options.positionFixed&&a.support.fixedPosition&&this.element.addClass(this.options.classes.panelFixed)},_bindUpdateLayout:function(){var a=this;a.element.on("updatelayout",function(){a._open&&a._positionPanel()})},_bindLinkListeners:function(){var b=this;b._page.on("click.panel","a",function(c){if(this.hrLine truncated
/*
//@ sourceMappingURL=jquery.mobile-1.3.2.min.map
*/
+11
View File
@@ -0,0 +1,11 @@
/*
* jQuery UI Touch Punch 0.2.2
*
* Copyright 2011, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery);
File diff suppressed because it is too large. Load diff
+80
View File
@@ -0,0 +1,80 @@
{
"loginName": "Benutzer:",
"loginPassword": "Passwort:",
"loginButton": "Einloggen",
"registerButton": "Erstelle Profil",
"discoverReadQrButton": "Fotografiere QRCode",
"mainPageYourProfileLink": "Dein Profil",
"mainPageYourProfileLinkDesc": "Bearbeite dein Profil",
"mainPageCurrentSongLink": "Aktuelles Lied",
"mainPageCurrentSongLinkDesc": "Zeigt Informationen über das aktuelle Lied an",
"mainPageSelectSong": "Alle Lieder",
"mainPageSelectSongDesc": "Listet alle verfügbaren Lieder auf",
"mainPageSelectPlaylist": "Alle Playlisten",
"mainPageSelectPlaylistDesc": "Listet alle verfügbaren Playlisten auf",
"mainPageSelectProfile": "Profile",
"mainPageSelectProfileDesc": "Listet alle Profile auf",
"mainPageTakePhotoLink": "Nehme Foto auf",
"mainPageTakePhotoLinkDesc": "Nimmt ein Foto auf und zeigt es am ende der Runde an",
"mainPageKeyboard": "Tastatur",
"mainPageKeyboardDesc": "Sende Tastatureingaben",
"mainPageSelectUserAdmin": "Administration",
"mainPageSelectUserAdminDesc": "Konfiguriere die Benutzerrechte",
"mainPageLogoutLink": "Abmelden",
"mainPageLogoutLinkDesc": "Beendet diese Sitzung",
"selectProfileHeader": "Alle Profile",
"displayProfileHeader": "Profile",
"displayProfileName": "Name:",
"displayProfilePlayerType": "Player Typ:",
"displayProfilePlayerTypeNormal": "Normal",
"displayProfilePlayerTypeGuest": "Gast",
"displayProfilePlayerDifficulty": "Schwierigkeit:",
"displayProfilePlayerDifficultyEasy": "Einfach",
"displayProfilePlayerDifficultyNormal": "Normal",
"displayProfilePlayerDifficultyHard": "Schwer",
"displayProfilePlayerPassword": "Neues Passwort:",
"displayProfilePlayerSaveButton": "Speichern und hochladen",
"displaySongHeader": "Kein aktuelles Lied",
"displaySongArtist": "Künstler:",
"displaySongGenre": "Genre:",
"displaySongYear": "Jahr:",
"displaySongLanguage": "Sprache:",
"displaySongIsDuet": "Duet:",
"popupVideoClose": "Schließen",
"selectSongHeader": "Alle Lieder",
"keyboardHeader": "Tastatur",
"keyboardButtonUp": "hoch",
"keyboardButtonLeft": "links",
"keyboardButtonRight": "rechts",
"keyboardButtonDown": "runter",
"keyboardButtonEscape": "Escape",
"keyboardButtonTab": "Tab",
"keyboardButtonReturn": "Enter",
"keyboardButtonKeys": "Um andere Zeichen zu senden, hier tippen:",
"selectUserAdminHeader": "Alle Profile",
"displayUserAdminHeader": "Profile",
"displayUserAdminContentSaveButton": "Speichern",
"selectPlaylistHeader": "Wähle eine Playlist",
"displayPlaylistHeader": "Playlist",
"displayPlaylistSaveButton": "Speichern",
"selectPlaylistAddPlaylistButton": "Hinzufügen",
"Loading (external)...": "Laden (extern)...",
"Loading...": "Laden...",
"Creating...": "Erstellen...",
"Error...": "Fehler...",
"No connection": "Keine Verbindung",
"No session": "Keine Sitzung",
"Uploading photo...": "Foto hochladen...",
"Getting current song...": "Lade aktuelles Lied...",
"Login...": "Einloggen...",
"Creating profile...": "Erstelle Profil...",
"This is not a valid name.": "Dies ist kein gültiger Name.",
"Uploading profile...": "Profil hochladen...",
"songs": "Lieder",
"YourName": "DeinName",
"discoverConnectHeader": "Verbinde zum Server",
"discoverConnectServerAddress": "Serveradresse:",
"discoverConnectButton": "Verbinden",
"Checking...": "Prüfen...",
"timeout": "Zeitüberschreitung"
}
+80
View File
@@ -0,0 +1,80 @@
{
"loginName": "User:",
"loginPassword": "Password:",
"loginButton": "Login",
"registerButton": "Create Profile",
"discoverReadQrButton": "Scan QRCode",
"mainPageYourProfileLink": "Your Profile",
"mainPageYourProfileLinkDesc": "Edit your profile",
"mainPageCurrentSongLink": "Current Song",
"mainPageCurrentSongLinkDesc": "Display informations about the current song",
"mainPageSelectSong": "All songs",
"mainPageSelectSongDesc": "Lists all available songs",
"mainPageSelectPlaylist": "All playlists",
"mainPageSelectPlaylistDesc": "Lists all playlists",
"mainPageSelectProfile": "Profiles",
"mainPageSelectProfileDesc": "Shows all profiles",
"mainPageTakePhotoLink": "Take Photo",
"mainPageTakePhotoLinkDesc": "Takes a photo and displays it at the end of the current round",
"mainPageKeyboard": "Keyboard",
"mainPageKeyboardDesc": "Send keys",
"mainPageSelectUserAdmin": "Administration",
"mainPageSelectUserAdminDesc": "Configure user rights",
"mainPageLogoutLink": "Logout",
"mainPageLogoutLinkDesc": "Closes the session",
"selectProfileHeader": "All profiles",
"displayProfileHeader": "Profile",
"displayProfileName": "Name:",
"displayProfilePlayerType": "Player Type:",
"displayProfilePlayerTypeNormal": "Normal",
"displayProfilePlayerTypeGuest": "Guest",
"displayProfilePlayerDifficulty": "Difficulty:",
"displayProfilePlayerDifficultyEasy": "Easy",
"displayProfilePlayerDifficultyNormal": "Normal",
"displayProfilePlayerDifficultyHard": "Hard",
"displayProfilePlayerPassword": "New Password:",
"displayProfilePlayerSaveButton": "Save and upload",
"displaySongHeader": "No current song",
"displaySongArtist": "Artist:",
"displaySongGenre": "Genre:",
"displaySongYear": "Year:",
"displaySongLanguage": "Language:",
"displaySongIsDuet": "Duet:",
"popupVideoClose": "Close",
"selectSongHeader": "All songs",
"keyboardHeader": "Keyboard",
"keyboardButtonUp": "up",
"keyboardButtonLeft": "left",
"keyboardButtonRight": "right",
"keyboardButtonDown": "down",
"keyboardButtonEscape": "escape",
"keyboardButtonTab": "tab",
"keyboardButtonReturn": "return",
"keyboardButtonKeys": "To send other keys type here:",
"selectUserAdminHeader": "All profiles",
"displayUserAdminHeader": "Profile",
"displayUserAdminContentSaveButton": "Save",
"selectPlaylistHeader": "Select a playlist",
"displayPlaylistHeader": "Playlist",
"displayPlaylistSaveButton": "Save",
"selectPlaylistAddPlaylistButton": "Add",
"Loading (external)...": "Loading (external)...",
"Loading...": "Loading...",
"Creating...": "Creating...",
"Error...": "Error...",
"No connection": "No connection",
"No session": "No session",
"Uploading photo...": "Uploading photo...",
"Getting current song...": "Getting current song...",
"Login...": "Login...",
"Creating profile...": "Creating profile...",
"This is not a valid name.": "This is not a valid name.",
"Uploading profile...": "Uploading profile...",
"songs": "songs",
"YourName": "YourName",
"discoverConnectHeader": "Connect to server",
"discoverConnectServerAddress": "Serveraddress:",
"discoverConnectButton": "Connect",
"Checking...": "Checking...",
"timeout": "Timeout"
}
+1 -1
View File
@@ -2,5 +2,5 @@
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/></startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>
+17 -12
View File
@@ -1,18 +1,18 @@
#region license
// This file is part of Vocaluxe.
#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 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.
// 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/>.
// 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 VocaluxeLib.Draw;
@@ -48,5 +48,10 @@ namespace VocaluxeLib.Profile
{
CBase.Drawing.RemoveTexture(ref Texture);
}
public string getFileName()
{
return FileName;
}
}
}
+22 -2
View File
@@ -30,6 +30,9 @@ namespace VocaluxeLib.Profile
public string FilePath;
public string FileName;
public string AvatarFileName;
public byte[] PasswordHash;
public byte[] PasswordSalt;
public int UserRoles;
public EGameDifficulty Difficulty;
@@ -87,7 +90,15 @@ namespace VocaluxeLib.Profile
xmlReader.GetValue("//root/Info/Avatar", out AvatarFileName, String.Empty);
xmlReader.TryGetEnumValue("//root/Info/GuestProfile", ref GuestProfile);
xmlReader.TryGetEnumValue("//root/Info/Active", ref Active);
string passwordHash;
xmlReader.GetValue("//root/Info/PasswordHash", out passwordHash, "");
PasswordHash = !string.IsNullOrEmpty(passwordHash) ? Convert.FromBase64String(passwordHash) : null;
string passwordSalt;
xmlReader.GetValue("//root/Info/PasswordSalt", out passwordSalt, "");
PasswordSalt = !string.IsNullOrEmpty(passwordSalt) ? Convert.FromBase64String(passwordSalt) : null;
string userRoles;
xmlReader.GetValue("//root/Info/UserRoles", out userRoles, "0");
Int32.TryParse(userRoles, out UserRoles);
return true;
}
@@ -104,7 +115,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();
@@ -148,6 +159,15 @@ namespace VocaluxeLib.Profile
writer.WriteElementString("Avatar", Path.GetFileName(Avatar.FileName));
writer.WriteElementString("GuestProfile", Enum.GetName(typeof(EOffOn), GuestProfile));
writer.WriteElementString("Active", Enum.GetName(typeof(EOffOn), Active));
if (PasswordHash != null)
{
writer.WriteElementString("PasswordHash", Convert.ToBase64String(PasswordHash));
}
if (PasswordSalt != null)
{
writer.WriteElementString("PasswordSalt", Convert.ToBase64String(PasswordSalt));
}
writer.WriteElementString("UserRoles", UserRoles.ToString());
writer.WriteEndElement();
writer.WriteEndElement(); //end of root
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
+149
View File
@@ -0,0 +1,149 @@
using Security.Cryptography;
using Security.Cryptography.X509Certificates;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using NetFwTypeLib;
namespace WebserverInitalConfig
{
public static class ConfigHttpApi
{
public static void reserveURL(string networkString)
{
HttpApi.ReserveURL(networkString, "D:(A;;GX;;;S-1-1-0)");
}
public static void bindCert(string ip, int port, X509Certificate2 cert)
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(ip), port);
if (HttpApi.QuerySslCertificateInfo(endpoint) != null)
{
HttpApi.DeleteCertificateBinding(endpoint);
}
HttpApi.BindCertificate(endpoint, cert.GetCertHash(), StoreName.My, new Guid("{7baf41f1-48b7-42cb-b145-f815499cb48f}"));
}
public static void addCertToStore(X509Certificate2 cert)
{
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
X509Certificate2Collection oldCerts = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName,
cert.SubjectName.Name, false);
foreach (var oldCert in oldCerts)
{
store.Remove(oldCert);
}
store.Add(cert);
store.Close();
}
public static X509Certificate2 getSelfSignedCert(string subjectName)
{
var keyParam = new CngKeyCreationParameters
{
ExportPolicy = CngExportPolicies.AllowExport,
KeyCreationOptions = CngKeyCreationOptions.MachineKey | CngKeyCreationOptions.OverwriteExistingKey,
KeyUsage = CngKeyUsages.AllUsages,
Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider,
};
keyParam.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.None));
CngKey key = CngKey.Create(CngAlgorithm2.Rsa, Guid.NewGuid().ToString(), keyParam);
X509CertificateCreationParameters param = new X509CertificateCreationParameters(
new X500DistinguishedName(subjectName));
param.SubjectName = new X500DistinguishedName(subjectName);
param.EndTime = DateTime.Today.AddYears(20);
//param.SignatureAlgorithm = X509CertificateSignatureAlgorithm.RsaSha512;
OidCollection oc = new OidCollection();
oc.Add(new Oid("1.3.6.1.5.5.7.3.1"));
X509Extension eku = new X509EnhancedKeyUsageExtension(oc, true);
param.Extensions.Add(eku);
param.TakeOwnershipOfKey = true;
byte[] rawData = key.CreateSelfSignedCertificate(param).Export(X509ContentType.Pfx, "");
var cert = new X509Certificate2(rawData, "", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
cert.FriendlyName = "Vocaluxe Server Certificate";
return cert;
}
public static void addFirewallrule(string exePath, int port, bool isTCP)
{
INetFwMgr manage = (INetFwMgr)Activator.CreateInstance(
Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}")));
bool isFirewallEnabled = manage.LocalPolicy.CurrentProfile.FirewallEnabled;
if (isFirewallEnabled)
{
INetFwAuthorizedApplications applications = manage.LocalPolicy.CurrentProfile.AuthorizedApplications;
if ((from INetFwAuthorizedApplication a in applications
where a.ProcessImageFileName == exePath
select a).Count() == 0)
{
INetFwAuthorizedApplication application = (INetFwAuthorizedApplication)Activator.CreateInstance(
Type.GetTypeFromCLSID(new Guid("{EC9846B3-2762-4A6B-A214-6ACB603462D2}")));
application.Name = "Vocaluxe";
application.ProcessImageFileName = exePath;
application.Enabled = true;
applications.Add(application);
}
INetFwOpenPorts openPorts = manage.LocalPolicy.CurrentProfile.GloballyOpenPorts;
if ((from INetFwOpenPort p in openPorts
where (p.Port == port &&
(p.Protocol == (isTCP?NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP : NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP)))
select p).Count() == 0)
{
INetFwOpenPort openPort = (INetFwOpenPort)Activator.CreateInstance(
Type.GetTypeFromCLSID(new Guid("{0CA545C6-37AD-4A6C-BF92-9F7610067EF5}")));
openPort.Enabled = true;
openPort.Port = port;
openPort.Protocol = (isTCP ? NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP : NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_UDP);
openPort.Name = "Vocaluxe";
openPorts.Add(openPort);
}
}
}
/*public static X509Certificate2 getCert(string subject)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
Mono.Security.Authenticode.PrivateKey key = new Mono.Security.Authenticode.PrivateKey { RSA=RSA.Create()};
Mono.Security.X509.X509CertificateBuilder x509 = new Mono.Security.X509.X509CertificateBuilder();
x509.IssuerName = "CN=Vocaluxe Server";
x509.NotAfter = DateTime.Today.AddYears(20);
x509.NotBefore = DateTime.Today.AddDays(-1);
x509.SubjectName = subject;
x509.SerialNumber = new byte[] { 1 };
x509.Version = 3;
x509.SubjectPublicKey = rsa;
ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
x509.Extensions.Add(eku);
return new X509Certificate2(x509.Sign(rsa));
}*/
}
}
+672
View File
@@ -0,0 +1,672 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace WebserverInitalConfig
{
internal static class HttpApi
{
private static readonly HTTPAPI_VERSION HttpApiVersion = new HTTPAPI_VERSION(1, 0);
#region DllImport
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpInitialize(
HTTPAPI_VERSION version,
uint flags,
IntPtr pReserved);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpSetServiceConfiguration(
IntPtr serviceIntPtr,
HTTP_SERVICE_CONFIG_ID configId,
IntPtr pConfigInformation,
int configInformationLength,
IntPtr pOverlapped);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpDeleteServiceConfiguration(
IntPtr serviceIntPtr,
HTTP_SERVICE_CONFIG_ID configId,
IntPtr pConfigInformation,
int configInformationLength,
IntPtr pOverlapped);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpTerminate(
uint Flags,
IntPtr pReserved);
[DllImport("httpapi.dll", SetLastError = true)]
static extern uint HttpQueryServiceConfiguration(
IntPtr serviceIntPtr,
HTTP_SERVICE_CONFIG_ID configId,
IntPtr pInputConfigInfo,
int inputConfigInfoLength,
IntPtr pOutputConfigInfo,
int outputConfigInfoLength,
[Optional]
out int pReturnLength,
IntPtr pOverlapped);
enum HTTP_SERVICE_CONFIG_ID
{
HttpServiceConfigIPListenList = 0,
HttpServiceConfigSSLCertInfo,
HttpServiceConfigUrlAclInfo,
HttpServiceConfigMax
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_SSL_SET
{
public HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc;
public HTTP_SERVICE_CONFIG_SSL_PARAM ParamDesc;
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_SSL_KEY
{
public IntPtr pIpPort;
public HTTP_SERVICE_CONFIG_SSL_KEY(IntPtr pIpPort)
{
this.pIpPort = pIpPort;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct HTTP_SERVICE_CONFIG_SSL_PARAM
{
public int SslHashLength;
public IntPtr pSslHash;
public Guid AppId;
[MarshalAs(UnmanagedType.LPWStr)]
public string pSslCertStoreName;
public uint DefaultCertCheckMode;
public int DefaultRevocationFreshnessTime;
public int DefaultRevocationUrlRetrievalTimeout;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDefaultSslCtlIdentifier;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDefaultSslCtlStoreName;
public uint DefaultFlags;
}
[StructLayout(LayoutKind.Sequential, Pack = 2)]
struct HTTPAPI_VERSION
{
public ushort HttpApiMajorVersion;
public ushort HttpApiMinorVersion;
public HTTPAPI_VERSION(ushort majorVersion, ushort minorVersion)
{
HttpApiMajorVersion = majorVersion;
HttpApiMinorVersion = minorVersion;
}
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_SSL_QUERY
{
public HTTP_SERVICE_CONFIG_QUERY_TYPE QueryDesc;
public HTTP_SERVICE_CONFIG_SSL_KEY KeyDesc;
public uint dwToken;
}
enum HTTP_SERVICE_CONFIG_QUERY_TYPE
{
HttpServiceConfigQueryExact = 0,
HttpServiceConfigQueryNext,
HttpServiceConfigQueryMax
}
[StructLayout(LayoutKind.Sequential)]
struct HTTP_SERVICE_CONFIG_URLACL_SET
{
public HTTP_SERVICE_CONFIG_URLACL_KEY KeyDesc;
public HTTP_SERVICE_CONFIG_URLACL_PARAM ParamDesc;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct HTTP_SERVICE_CONFIG_URLACL_KEY
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pUrlPrefix;
public HTTP_SERVICE_CONFIG_URLACL_KEY(string urlPrefix)
{
pUrlPrefix = urlPrefix;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct HTTP_SERVICE_CONFIG_URLACL_PARAM
{
[MarshalAs(UnmanagedType.LPWStr)]
public string pStringSecurityDescriptor;
public HTTP_SERVICE_CONFIG_URLACL_PARAM(string securityDescriptor)
{
pStringSecurityDescriptor = securityDescriptor;
}
}
#endregion
#region Constants
public const uint HTTP_INITIALIZE_CONFIG = 0x00000002;
public const uint HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT = 0x00000002;
public const uint HTTP_SERVICE_CONFIG_SSL_FLAG_NO_RAW_FILTER = 0x00000004;
private const uint NOERROR = 0;
private const uint ERROR_INSUFFICIENT_BUFFER = 122;
private const uint ERROR_ALREADY_EXISTS = 183;
private const uint ERROR_FILE_NOT_FOUND = 2;
private const int ERROR_NO_MORE_ITEMS = 259;
#endregion
#region Public methods
public class SslCertificateInfo
{
public byte[] Hash { get; set; }
public Guid AppId { get; set; }
public string StoreName { get; set; }
public IPEndPoint IpPort { get; set; }
}
public static SslCertificateInfo QuerySslCertificateInfo(IPEndPoint ipPort)
{
SslCertificateInfo result = null;
uint retVal;
CallHttpApi(delegate
{
GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
HTTP_SERVICE_CONFIG_SSL_KEY sslKey = new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
new HTTP_SERVICE_CONFIG_SSL_QUERY
{
QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryExact,
KeyDesc = sslKey
};
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false);
IntPtr pOutputConfigInfo = IntPtr.Zero;
int returnLength = 0;
try
{
HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;
int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery);
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
if (retVal == ERROR_FILE_NOT_FOUND)
return;
if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122
{
pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength);
try
{
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
var outputConfigInfo =
(HTTP_SERVICE_CONFIG_SSL_SET)
Marshal.PtrToStructure(pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SET));
byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength];
Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length);
Guid appId = outputConfigInfo.ParamDesc.AppId;
string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName;
result = new SslCertificateInfo { AppId = appId, Hash = hash, StoreName = storeName, IpPort = ipPort };
}
finally
{
Marshal.FreeCoTaskMem(pOutputConfigInfo);
}
}
else
{
ThrowWin32ExceptionIfError(retVal);
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
if (sockAddrHandle.IsAllocated)
sockAddrHandle.Free();
}
});
return result;
}
public static void BindCertificate(IPEndPoint ipPort, byte[] hash, StoreName storeName, Guid appId)
{
if (ipPort == null) throw new ArgumentNullException("ipPort");
if (hash == null) throw new ArgumentNullException("hash");
CallHttpApi(
delegate
{
HTTP_SERVICE_CONFIG_SSL_SET configSslSet = new HTTP_SERVICE_CONFIG_SSL_SET();
GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
HTTP_SERVICE_CONFIG_SSL_PARAM configSslParam = new HTTP_SERVICE_CONFIG_SSL_PARAM();
GCHandle handleHash = GCHandle.Alloc(hash, GCHandleType.Pinned);
configSslParam.AppId = appId;
configSslParam.DefaultCertCheckMode = 0;
configSslParam.DefaultFlags = 0; //HTTP_SERVICE_CONFIG_SSL_FLAG_NEGOTIATE_CLIENT_CERT;
configSslParam.DefaultRevocationFreshnessTime = 0;
configSslParam.DefaultRevocationUrlRetrievalTimeout = 0;
configSslParam.pSslCertStoreName = storeName.ToString();
configSslParam.pSslHash = handleHash.AddrOfPinnedObject();
configSslParam.SslHashLength = hash.Length;
configSslSet.ParamDesc = configSslParam;
configSslSet.KeyDesc = httpServiceConfigSslKey;
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);
try
{
uint retVal = HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
if (ERROR_ALREADY_EXISTS != retVal)
{
ThrowWin32ExceptionIfError(retVal);
}
else
{
retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
retVal = HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
if (handleHash.IsAllocated)
handleHash.Free();
if (sockAddrHandle.IsAllocated)
sockAddrHandle.Free();
}
});
}
public static void DeleteCertificateBinding(params IPEndPoint[] ipPorts)
{
if (ipPorts == null || ipPorts.Length == 0)
return;
CallHttpApi(
delegate
{
foreach (var ipPort in ipPorts)
{
HTTP_SERVICE_CONFIG_SSL_SET configSslSet =
new HTTP_SERVICE_CONFIG_SSL_SET();
GCHandle sockAddrHandle = CreateSockaddrStructure(ipPort);
IntPtr pIpPort = sockAddrHandle.AddrOfPinnedObject();
HTTP_SERVICE_CONFIG_SSL_KEY httpServiceConfigSslKey =
new HTTP_SERVICE_CONFIG_SSL_KEY(pIpPort);
configSslSet.KeyDesc = httpServiceConfigSslKey;
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(
Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_SET)));
Marshal.StructureToPtr(configSslSet, pInputConfigInfo, false);
try
{
uint retVal = HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo,
pInputConfigInfo,
Marshal.SizeOf(configSslSet),
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
if (sockAddrHandle.IsAllocated)
sockAddrHandle.Free();
}
}
});
}
public static SslCertificateInfo[] QuerySslCertificateInfo()
{
var result = new List<SslCertificateInfo>();
CallHttpApi(
delegate
{
uint token = 0;
uint retVal;
do
{
HTTP_SERVICE_CONFIG_SSL_QUERY inputConfigInfoQuery =
new HTTP_SERVICE_CONFIG_SSL_QUERY
{
QueryDesc = HTTP_SERVICE_CONFIG_QUERY_TYPE.HttpServiceConfigQueryNext,
dwToken = token,
};
IntPtr pInputConfigInfo =
Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_SSL_QUERY)));
Marshal.StructureToPtr(inputConfigInfoQuery, pInputConfigInfo, false);
IntPtr pOutputConfigInfo = IntPtr.Zero;
int returnLength = 0;
const HTTP_SERVICE_CONFIG_ID queryType = HTTP_SERVICE_CONFIG_ID.HttpServiceConfigSSLCertInfo;
try
{
int inputConfigInfoSize = Marshal.SizeOf(inputConfigInfoQuery);
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
if (ERROR_NO_MORE_ITEMS == retVal)
break;
if (ERROR_INSUFFICIENT_BUFFER == retVal) // ERROR_INSUFFICIENT_BUFFER = 122
{
pOutputConfigInfo = Marshal.AllocCoTaskMem(returnLength);
try
{
retVal = HttpQueryServiceConfiguration(IntPtr.Zero,
queryType,
pInputConfigInfo,
inputConfigInfoSize,
pOutputConfigInfo,
returnLength,
out returnLength,
IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
var outputConfigInfo = (HTTP_SERVICE_CONFIG_SSL_SET)Marshal.PtrToStructure(
pOutputConfigInfo, typeof(HTTP_SERVICE_CONFIG_SSL_SET));
byte[] hash = new byte[outputConfigInfo.ParamDesc.SslHashLength];
Marshal.Copy(outputConfigInfo.ParamDesc.pSslHash, hash, 0, hash.Length);
Guid appId = outputConfigInfo.ParamDesc.AppId;
string storeName = outputConfigInfo.ParamDesc.pSslCertStoreName;
IPEndPoint ipPort = ReadSockaddrStructure(outputConfigInfo.KeyDesc.pIpPort);
var resultItem = new SslCertificateInfo
{
AppId = appId,
Hash = hash,
StoreName = storeName,
IpPort = ipPort
};
result.Add(resultItem);
token++;
}
finally
{
Marshal.FreeCoTaskMem(pOutputConfigInfo);
}
}
else
{
ThrowWin32ExceptionIfError(retVal);
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
}
} while (NOERROR == retVal);
});
return result.ToArray();
}
public static void ReserveURL(string networkURL, string securityDescriptor)
{
if (String.IsNullOrEmpty(networkURL)) throw new ArgumentNullException("networkURL");
if (String.IsNullOrEmpty(securityDescriptor)) throw new ArgumentNullException("securityDescriptor");
CallHttpApi(
delegate
{
uint retVal = (uint)NOERROR; // NOERROR = 0
HTTP_SERVICE_CONFIG_URLACL_KEY keyDesc = new HTTP_SERVICE_CONFIG_URLACL_KEY(networkURL);
HTTP_SERVICE_CONFIG_URLACL_PARAM paramDesc = new HTTP_SERVICE_CONFIG_URLACL_PARAM(securityDescriptor);
HTTP_SERVICE_CONFIG_URLACL_SET inputConfigInfoSet = new HTTP_SERVICE_CONFIG_URLACL_SET();
inputConfigInfoSet.KeyDesc = keyDesc;
inputConfigInfoSet.ParamDesc = paramDesc;
IntPtr pInputConfigInfo = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_URLACL_SET)));
Marshal.StructureToPtr(inputConfigInfoSet, pInputConfigInfo, false);
try
{
retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
if ((uint)ERROR_ALREADY_EXISTS == retVal) // ERROR_ALREADY_EXISTS = 183
{
retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
if ((uint)NOERROR == retVal)
{
retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
}
else if ((uint)ERROR_FILE_NOT_FOUND == retVal) // ERROR_FILE_NOT_FOUND = 2
{
string networkURLOld = networkURL.Contains("https") ? networkURL.Replace("https", "http") :
networkURL.Replace("http", "https");
HTTP_SERVICE_CONFIG_URLACL_KEY keyDescOld = new HTTP_SERVICE_CONFIG_URLACL_KEY(networkURLOld);
HTTP_SERVICE_CONFIG_URLACL_PARAM paramDescOld = new HTTP_SERVICE_CONFIG_URLACL_PARAM(securityDescriptor);
HTTP_SERVICE_CONFIG_URLACL_SET inputConfigInfoSetOld = new HTTP_SERVICE_CONFIG_URLACL_SET();
inputConfigInfoSetOld.KeyDesc = keyDescOld;
inputConfigInfoSetOld.ParamDesc = paramDescOld;
IntPtr pInputConfigInfoOld = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(HTTP_SERVICE_CONFIG_URLACL_SET)));
Marshal.StructureToPtr(inputConfigInfoSetOld, pInputConfigInfoOld, false);
retVal = HttpApi.HttpDeleteServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfoOld,
Marshal.SizeOf(inputConfigInfoSetOld),
IntPtr.Zero);
if ((uint)NOERROR == retVal)
{
retVal = HttpApi.HttpSetServiceConfiguration(IntPtr.Zero,
HTTP_SERVICE_CONFIG_ID.HttpServiceConfigUrlAclInfo,
pInputConfigInfo,
Marshal.SizeOf(inputConfigInfoSet),
IntPtr.Zero);
}
}
}
}
finally
{
Marshal.FreeCoTaskMem(pInputConfigInfo);
HttpApi.HttpTerminate(HttpApi.HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
}
if ((uint)NOERROR != retVal)
{
ThrowWin32ExceptionIfError(retVal);
}
});
}
#endregion
private static void ThrowWin32ExceptionIfError(uint retVal)
{
if (NOERROR != retVal)
{
throw new Win32Exception(Convert.ToInt32(retVal));
}
}
private static void CallHttpApi(Action body)
{
uint retVal = HttpInitialize(HttpApiVersion, HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
ThrowWin32ExceptionIfError(retVal);
try
{
body();
}
finally
{
HttpTerminate(HTTP_INITIALIZE_CONFIG, IntPtr.Zero);
}
}
/// <summary>
/// Creates an unmanaged sockaddr structure to pass to a WinAPI function.
/// </summary>
/// <param name="ipEndPoint">IP address and port number</param>
/// <returns>a handle for the structure. Use the AddrOfPinnedObject Method to get a stable pointer to the object. </returns>
/// <remarks>When the handle goes out of scope you must explicitly release it by calling the Free method; otherwise, memory leaks may occur. </remarks>
private static GCHandle CreateSockaddrStructure(IPEndPoint ipEndPoint)
{
SocketAddress socketAddress = ipEndPoint.Serialize();
// use an array of bytes instead of the sockaddr structure
byte[] sockAddrStructureBytes = new byte[socketAddress.Size];
GCHandle sockAddrHandle = GCHandle.Alloc(sockAddrStructureBytes, GCHandleType.Pinned);
for (int i = 0; i < socketAddress.Size; ++i)
{
sockAddrStructureBytes[i] = socketAddress[i];
}
return sockAddrHandle;
}
/// <summary>
/// Reads the unmanaged sockaddr structure returned by a WinAPI function
/// </summary>
/// <param name="pSockaddrStructure">pointer to the unmanaged sockaddr structure</param>
/// <returns>IP address and port number</returns>
private static IPEndPoint ReadSockaddrStructure(IntPtr pSockaddrStructure)
{
short sAddressFamily = Marshal.ReadInt16(pSockaddrStructure);
AddressFamily addressFamily = (AddressFamily)sAddressFamily;
int sockAddrSructureSize;
IPEndPoint ipEndPointAny;
switch (addressFamily)
{
case AddressFamily.InterNetwork:
// IP v4 address
sockAddrSructureSize = 16;
ipEndPointAny = new IPEndPoint(IPAddress.Any, 0);
break;
case AddressFamily.InterNetworkV6:
// IP v6 address
sockAddrSructureSize = 28;
ipEndPointAny = new IPEndPoint(IPAddress.IPv6Any, 0);
break;
default:
throw new ArgumentOutOfRangeException("pSockaddrStructure", "Unknown address family");
}
// get bytes of the sockadrr structure
byte[] sockAddrSructureBytes = new byte[sockAddrSructureSize];
Marshal.Copy(pSockaddrStructure, sockAddrSructureBytes, 0, sockAddrSructureSize);
// create SocketAddress from bytes
var socketAddress = new SocketAddress(AddressFamily.Unspecified, sockAddrSructureSize);
for (int i = 0; i < sockAddrSructureSize; i++)
{
socketAddress[i] = sockAddrSructureBytes[i];
}
// create IPEndPoint from SocketAddress
IPEndPoint result = (IPEndPoint)ipEndPointAny.Create(socketAddress);
return result;
}
}
}
+40
View File
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace WebserverInitalConfig
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: WebserverInitalConfig port isHttps");
}
ConfigHttpApi.addFirewallrule(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Vocaluxe.exe"), Int32.Parse(args[0]), true);
if (args[1].ToLower() == "true")
{
string hostname = Dns.GetHostName();
var cert = ConfigHttpApi.getSelfSignedCert("CN=" + hostname + " C=DE O=Vocaluxe OU=Vocaluxe Server");
ConfigHttpApi.addCertToStore(cert);
ConfigHttpApi.bindCert("0.0.0.0", Int32.Parse(args[0]), cert);
ConfigHttpApi.reserveURL("https://+:" + args[0] + "/");
}
else
{
ConfigHttpApi.reserveURL("http://+:" + args[0] + "/");
}
}
}
}
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("Vocaluxe Server Config")]
[assembly: AssemblyDescription("Configures your computer to run the Vocaluxe Server")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Vocaluxe")]
[assembly: AssemblyProduct("Vocaluxe Server Config")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("b2df9255-3927-4125-ab3c-23c35794b04d")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{55F89808-4E79-4FFE-BC13-48258913F5C9}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WebserverInitalConfig</RootNamespace>
<AssemblyName>VocaluxeServerConfig</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Output\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Vocaluxe.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Interop.NetFwTypeLib, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>..\Output\Interop.NetFwTypeLib.dll</HintPath>
</Reference>
<Reference Include="Security, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Output\Security.dll</HintPath>
</Reference>
<Reference Include="Security.Cryptography, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Output\Security.Cryptography.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ConfigHttpApi.cs" />
<Compile Include="HttpApi.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="app.manifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="Vocaluxe.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC-Manifestoptionen
Wenn Sie die Zugangsebene für das Windows-Benutzerkonto ändern möchten, ersetzen Sie den
requestedExecutionLevel-Knoten durch eines der folgenden Elemente.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Durch Angeben des requestedExecutionLevel-Knotens wird die Datei- und Registrierungsvirtualisierung deaktiviert.
Wenn Sie Datei- und Registrierungsvirtualisierung für Abwärts-
kompatibilität verwenden möchten, löschen Sie den requestedExecutionLevel-Knoten.
-->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Eine Liste aller Windows-Versionen, mit denen die Anwendung kompatibel ist.
Windows wählt automatisch die am stärksten kompatible Umgebung aus.-->
<!-- Wenn die Anwendung mit Windows Vista kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>-->
<!-- Wenn die Anwendung mit Windows 7 kompatibel ist, heben Sie die Kommentierung des folgenden supportedOS-Knotens auf.-->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
<!-- Wenn die Anwendung mit Windows 8 kompatibel ist, heben Sie die Auskommentierung des folgenden supportedOS-Knotens auf-->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>-->
</application>
</compatibility>
<!-- Designs für allgemeine Windows-Steuerelemente und -Dialogfelder (Windows XP und höher) aktivieren -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->
</asmv1:assembly>