Implemented a per player comunicationsystem for the app.

This commit is contained in:
lukeIam committed 2014-03-01 15:43:02 +01:00
1 parent 35cdd55c49
commit 3144ea24b9
12 files changed
+455 -44

No files matched your search

+3 -1
View File
@@ -1,4 +1,5 @@
using System;
using ServerLib.PlayerComunication;
using System;
using System.Diagnostics;
using System.Net;
using System.ServiceModel;
@@ -73,6 +74,7 @@ namespace ServerLib
public CServer(int port, bool encrypted)
{
_Init(port, encrypted);
CPlayerCommunication.Init();
}
public string GetBaseAddress()
+28 -8
View File
@@ -1,9 +1,10 @@
using System;
using ServerLib.PlayerComunication;
using System;
using System.IO;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.IO;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
namespace ServerLib
{
@@ -82,8 +83,8 @@ namespace ServerLib
if (profile.ProfileId != -1) //-1 is the id for a new profile
{
if (CSessionControl.GetUserIdFromSession(sessionKey) != profile.ProfileId
&& !(_CheckRight(EUserRights.EditAllProfiles) ))
if (CSessionControl.GetUserIdFromSession(sessionKey) != profile.ProfileId
&& !(_CheckRight(EUserRights.EditAllProfiles)))
{
return;
}
@@ -303,7 +304,7 @@ namespace ServerLib
{
return true;
}
#endregion
#region songs
@@ -403,7 +404,7 @@ namespace ServerLib
CServer.SetUserRole(profileId, userRole);
}
}
public bool HasUserRight(int right)
{
return _CheckRightWithNoErrorMessage((EUserRights)right);
@@ -452,7 +453,26 @@ namespace ServerLib
return true;
}
public SPlayerComunicationFrame[] PlayerComunication(SPlayerComunicationFrame[] recivedData)
{
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 null;
}
int userId = CSessionControl.GetUserIdFromSession(sessionKey);
CPlayerCommunication.AddMessagesFromPlayer(recivedData, userId);
return CPlayerCommunication.GetAllMessagesForPlayer(userId);
}
#endregion
}
}
+27 -13
View File
@@ -1,9 +1,10 @@
using System;
using ServerLib.PlayerComunication.DataTypes;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Text.RegularExpressions;
namespace ServerLib
@@ -108,8 +109,8 @@ namespace ServerLib
public delegate SSongInfo[] GetAllSongsDelegate();
public delegate int GetCurrentSongIdDelegate();
[DataContract]
public struct SSongInfo
{
@@ -155,26 +156,26 @@ namespace ServerLib
[DataContract]
public struct SPlaylistSongInfo
{
[DataMember]
[DataMember]
public SSongInfo Song;
[DataMember]
public int PlaylistId;
[DataMember]
[DataMember]
public int PlaylistPosition;
[DataMember]
public int GameMode;
}
[DataContract]
public struct SPlaylistInfo
{
[DataMember]
[DataMember]
public int PlaylistId;
[DataMember]
[DataMember]
public string PlaylistName;
[DataMember]
[DataMember]
public int SongCount;
[DataMember]
[DataMember]
public string LastChanged;
}
@@ -192,5 +193,18 @@ namespace ServerLib
public delegate int GetUserIdFromUsernameDelegate(string username);
[DataContract]
public struct SPlayerComunicationFrame
{
[DataMember]
public int ProfileId;
[DataMember]
public DateTime ValidTill;
[DataMember]
public EPlayerComunicationType Type;
[DataMember]
public String Data;
}
#endregion
}
@@ -209,6 +209,13 @@ namespace ServerLib
UriTemplate = "/hasUserRight?right={right}")]
bool HasUserRight(int right);
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "/playerComunication")]
SPlayerComunicationFrame[] PlayerComunication(SPlayerComunicationFrame[] recivedData);
#endregion
}
}
@@ -0,0 +1,209 @@
using ServerLib.PlayerComunication.DataTypes;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Threading;
using System.Web.Script.Serialization;
namespace ServerLib.PlayerComunication
{
public static class CPlayerCommunication
{
public delegate void IncommingMessageDelegate(CPlayerComunicationData data);
private static readonly Dictionary<int, List<SPlayerComunicationFrame>> _OutgoingMessagesPerUser
= new Dictionary<int, List<SPlayerComunicationFrame>>();
private static readonly Queue<SPlayerComunicationFrame> _IncommingMessages = new Queue<SPlayerComunicationFrame>();
private static readonly Dictionary<EPlayerComunicationType, List<IncommingMessageDelegate>> _IncommingMessageHandler
= new Dictionary<EPlayerComunicationType, List<IncommingMessageDelegate>>();
private static readonly Dictionary<EPlayerComunicationType, List<int>> _Subscriptions
= new Dictionary<EPlayerComunicationType, List<int>>();
private static readonly Dictionary<EPlayerComunicationType, Type> _TypeMapping
= new Dictionary<EPlayerComunicationType, Type>();
internal static void Init()
{
SetDataType(EPlayerComunicationType.RegisterSubscription, typeof(CPlayerComunicationDataSubscription));
AddIncommingHandler(EPlayerComunicationType.RegisterSubscription,
data => _AddSubscription(((CPlayerComunicationDataSubscription)data).Type,
((CPlayerComunicationDataSubscription)data).PlayerId));
SetDataType(EPlayerComunicationType.UnregisterSubscription, typeof(CPlayerComunicationDataSubscription));
AddIncommingHandler(EPlayerComunicationType.UnregisterSubscription,
data => _RemoveSubscription(((CPlayerComunicationDataSubscription)data).Type,
((CPlayerComunicationDataSubscription)data).PlayerId));
}
public static void AddNewPlayerMessage(int targetPlayerId,
EPlayerComunicationType type, ISerializable data,
DateTime validTill)
{
if (!_OutgoingMessagesPerUser.ContainsKey(targetPlayerId))
{
_OutgoingMessagesPerUser.Add(targetPlayerId, new List<SPlayerComunicationFrame>(2));
}
_OutgoingMessagesPerUser[targetPlayerId].Add(new SPlayerComunicationFrame
{
ProfileId = targetPlayerId,
Type = type,
Data = _SerializeHelper(data),
ValidTill = validTill
});
}
public static void AddNewPlayerMessage(int tagertPlayerId,
EPlayerComunicationType type, ISerializable data)
{
AddNewPlayerMessage(tagertPlayerId, type, data, DateTime.Now.AddMinutes(1));
}
public static void AddNewPlayerMessage(EPlayerComunicationType type, ISerializable data,
DateTime validTill)
{
if (_Subscriptions.ContainsKey(type))
{
foreach (int subscribedPlayers in _Subscriptions[type])
{
AddNewPlayerMessage(subscribedPlayers, type, data, validTill);
}
}
}
public static void AddNewPlayerMessage(EPlayerComunicationType type, ISerializable data)
{
AddNewPlayerMessage(type, data, DateTime.Now.AddMinutes(1));
}
internal static SPlayerComunicationFrame[] GetAllMessagesForPlayer(int playerId)
{
SPlayerComunicationFrame[] messages = null;
if (_OutgoingMessagesPerUser.ContainsKey(playerId))
{
messages = _OutgoingMessagesPerUser[playerId].ToArray();
_OutgoingMessagesPerUser[playerId].Clear();
}
return new SPlayerComunicationFrame[]{
new SPlayerComunicationFrame()
{
ProfileId = 0,
Type = EPlayerComunicationType.RegisterSubscription,
ValidTill = DateTime.Now.AddMinutes(1),
Data = _SerializeHelper(new CPlayerComunicationDataString(){Data = "Test"})
}
};
//return messages;
}
public static void RemoveAllMessages(int playerId, EPlayerComunicationType type)
{
if (_OutgoingMessagesPerUser.ContainsKey(playerId))
{
_OutgoingMessagesPerUser[playerId].RemoveAll(m => m.Type == type);
}
}
internal static void AddMessagesFromPlayer(IEnumerable<SPlayerComunicationFrame> messages, int playerId)
{
if (messages == null || playerId < 0)
{
return;
}
foreach (SPlayerComunicationFrame message in messages)
{
SPlayerComunicationFrame data = message;
data.ProfileId = playerId;
_IncommingMessages.Enqueue(data);
}
if (_IncommingMessages.Count > 0)
{
ThreadPool.QueueUserWorkItem(_ProcessIncommingQueue);
}
}
private static void _ProcessIncommingQueue(object dummy)
{
lock (_IncommingMessages)
{
foreach (SPlayerComunicationFrame message in _IncommingMessages)
{
if (_IncommingMessageHandler.ContainsKey(message.Type))
{
List<IncommingMessageDelegate> handlers = _IncommingMessageHandler[message.Type];
var deserializedData = _DeserializeHelper(message.Data, message.Type);
foreach (IncommingMessageDelegate handler in handlers)
{
handler(deserializedData);
}
}
}
}
}
public static void SetDataType(EPlayerComunicationType type, Type dataType)
{
if (_TypeMapping.ContainsKey(type))
{
_TypeMapping.Add(type, dataType);
}
else
{
_TypeMapping[type] = dataType;
}
}
public static void AddIncommingHandler(EPlayerComunicationType type, IncommingMessageDelegate handler)
{
if (!_IncommingMessageHandler.ContainsKey(type))
{
_IncommingMessageHandler.Add(type, new List<IncommingMessageDelegate>(2));
}
_IncommingMessageHandler[type].Add(handler);
}
private static void _AddSubscription(EPlayerComunicationType type, int playerId)
{
if (!_Subscriptions.ContainsKey(type))
{
_Subscriptions.Add(type, new List<int>(2));
}
if (!_Subscriptions[type].Contains(playerId))
{
_Subscriptions[type].Add(playerId);
}
}
private static void _RemoveSubscription(EPlayerComunicationType type, int playerId)
{
if (_Subscriptions.ContainsKey(type) && _Subscriptions[type].Contains(playerId))
{
_Subscriptions[type].Remove(playerId);
}
}
private static CPlayerComunicationData _DeserializeHelper(String data, EPlayerComunicationType type)
{
if (_TypeMapping.ContainsKey(type))
{
return (CPlayerComunicationData)(new JavaScriptSerializer()).Deserialize(data, _TypeMapping[type]);
}
else
{
return new CPlayerComunicationDataString { Data = data };
}
}
private static string _SerializeHelper(Object data)
{
return (new JavaScriptSerializer()).Serialize(data);
}
}
}
@@ -0,0 +1,10 @@
using System;
namespace ServerLib.PlayerComunication.DataTypes
{
[Serializable]
public abstract class CPlayerComunicationData
{
}
}
@@ -0,0 +1,13 @@
using System;
using System.Runtime.Serialization;
namespace ServerLib.PlayerComunication.DataTypes
{
[Serializable]
public class CPlayerComunicationDataString : CPlayerComunicationData
{
[DataMember]
public string Data { get; set; }
}
}
@@ -0,0 +1,15 @@
using System;
using System.Runtime.Serialization;
namespace ServerLib.PlayerComunication.DataTypes
{
[Serializable]
public class CPlayerComunicationDataSubscription : CPlayerComunicationData
{
[DataMember]
public EPlayerComunicationType Type { get; set; }
[DataMember]
public int PlayerId { get; set; }
}
}
@@ -0,0 +1,12 @@
using System;
namespace ServerLib.PlayerComunication.DataTypes
{
[Serializable]
public enum EPlayerComunicationType
{
RegisterSubscription,
UnregisterSubscription
}
}
@@ -58,6 +58,7 @@
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceModel.Web" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Services" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
@@ -67,9 +68,14 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CDiscover.cs" />
<Compile Include="PlayerComunication\DataTypes\CPlayerComunicationData.cs" />
<Compile Include="PlayerComunication\DataTypes\CPlayerComunicationDataString.cs" />
<Compile Include="CServer.cs" />
<Compile Include="PlayerComunication\CUserCommunication.cs" />
<Compile Include="CWebservice.cs" />
<Compile Include="DataStructs.cs" />
<Compile Include="PlayerComunication\DataTypes\CPlayerComunicationDataSubscription.cs" />
<Compile Include="PlayerComunication\DataTypes\EPlayerComunicationType.cs" />
<Compile Include="ICWebservice.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Session.cs" />