public DataService(IModelSerializer serializer, FSO.Content.Content content) { this.Serializer = serializer; this.DataDefinition = content.DataDefinition; //Build Struct => Field[] maps for quicker serialization foreach (var derived in DataDefinition.DerivedStructs) { var type = MaskedStructUtils.FromID(derived.ID); List <StructField> fields = new List <StructField>(); var parent = DataDefinition.Structs.First(x => x.ID == derived.Parent); foreach (var field in parent.Fields) { var mask = derived.FieldMasks.FirstOrDefault(x => x.ID == field.ID); if (mask == null) { continue; } /* * var action = DerivedStructFieldMaskType.KEEP; * if (mask != null){ * action = mask.Type; * } * if (action == DerivedStructFieldMaskType.REMOVE){ * //These seems wrong, ServerMyAvatar and MyAvatar both exclude bookmarks by this logic * //continue; * } */ fields.Add(field); } MaskedStructToActualFields.Add(type, fields.ToArray()); } foreach (var _struct in DataDefinition.Structs) { StructToActualFields.Add(_struct.ID, _struct.Fields.ToArray()); } var assembly = Assembly.GetAssembly(typeof(DataService)); foreach (Type type in assembly.GetTypes()) { System.Attribute[] attributes = System.Attribute.GetCustomAttributes(type); foreach (Attribute attribute in attributes) { if (attribute is DataServiceModel) { var _struct = DataDefinition.GetStruct(type.Name); if (_struct != null) { ModelTypeById.Add(_struct.ID, type); ModelIdByType.Add(type, _struct.ID); } } } } }
public void AddProvider(IDataServiceProvider provider) { provider.Init(); var type = provider.GetValueType(); var structDef = DataDefinition.Structs.First(x => x.Name == type.Name); ProviderByTypeId.Add(structDef.ID, provider); ProviderByType.Add(type, provider); var derived = DataDefinition.DerivedStructs.Where(x => x.Parent == structDef.ID); foreach (var item in derived) { ProviderByDerivedStruct.Add(MaskedStructUtils.FromID(item.ID), provider); } }
/// <summary> /// The user is asking for some in RAM data /// </summary> /// <param name="session"></param> /// <param name="packet"></param> public async void Handle(IVoltronSession session, DataServiceWrapperPDU packet) { try //data service throws exceptions (SecurityException, etc) when invalid requests are made. These should not crash the server... { if (packet.Body is cTSONetMessageStandard) { var msg = (cTSONetMessageStandard)packet.Body; if (msg.ComplexParameter is cTSOTopicUpdateMessage) { var update = msg.ComplexParameter as cTSOTopicUpdateMessage; DataService.ApplyUpdate(update, session); return; } var type = MaskedStructUtils.FromID(packet.RequestTypeID); if (!msg.Parameter.HasValue) { return; } //Lookup the entity, then process the request and send the response var task = DataService.Get(type, msg.Parameter.Value); if (task != null) { var entity = await task; var serialized = DataService.SerializeUpdate(type, entity, msg.Parameter.Value); for (int i = 0; i < serialized.Count; i++) { object serial = serialized[i]; session.Write(new DataServiceWrapperPDU() { SendingAvatarID = packet.SendingAvatarID, RequestTypeID = packet.RequestTypeID, Body = serial }); } } } else if (packet.Body is cTSOTopicUpdateMessage) { //Client wants to update a value in the data service var update = packet.Body as cTSOTopicUpdateMessage; DataService.ApplyUpdate(update, session); List <uint> resultDotPath = new List <uint>(); foreach (var item in update.DotPath) { var ires = item; if (ires == 0x1095C1E1) { ires = 0x7EA285CD; //rewrite: filter id -> returns -> result list } resultDotPath.Add(ires); if (ires == packet.RequestTypeID) { break; } } var result = await DataService.SerializePath(resultDotPath.ToArray()); if (result != null) { session.Write(new DataServiceWrapperPDU() { SendingAvatarID = packet.SendingAvatarID, RequestTypeID = packet.RequestTypeID, Body = result }); } /*var task = DataService.Get(update.DotPath[0], update.DotPath[1]); * if(task != null) * { * var entity = await task; * * var serialized = DataService.SerializeUpdate(type, entity, msg.Parameter.Value); * }*/ /**/ } } catch (Exception e) { //SerializePath throws generic exceptions. //plus we don't want weird special cases crashing the whole server. LOG.Error(e, "Voltron DataService request failed: from avatar " + session.AvatarId + ", \n" + e.ToString()); } }
/// <summary> /// The user is asking for some in RAM data /// </summary> /// <param name="session"></param> /// <param name="packet"></param> public async void Handle(IVoltronSession session, DataServiceWrapperPDU packet) { try //data service throws exceptions (SecurityException, etc) when invalid requests are made. These should not crash the server... { if (packet.Body is cTSONetMessageStandard) { var msg = (cTSONetMessageStandard)packet.Body; if (msg.ComplexParameter is cTSOTopicUpdateMessage) { var update = msg.ComplexParameter as cTSOTopicUpdateMessage; DataService.ApplyUpdate(update, session); return; } var type = MaskedStructUtils.FromID(packet.RequestTypeID); if (!msg.Parameter.HasValue) { return; } //if (type == MaskedStruct.MapView_NearZoom_Lot_Thumbnail || type == MaskedStruct.Thumbnail_Lot || type == MaskedStruct.MapView_NearZoom_Lot) { } if (type != MaskedStruct.MyAvatar && type != MaskedStruct.SimPage_Main && type != MaskedStruct.MapView_RollOverInfo_Lot_Price && type != MaskedStruct.MapView_RollOverInfo_Lot && type != MaskedStruct.Unknown && type != MaskedStruct.SimPage_DescriptionPanel && type != MaskedStruct.PropertyPage_LotInfo && type != MaskedStruct.Messaging_Message_Avatar && type != MaskedStruct.Messaging_Icon_Avatar && type != MaskedStruct.MapView_NearZoom_Lot_Thumbnail && type != MaskedStruct.Thumbnail_Lot && type != MaskedStruct.CurrentCity && type != MaskedStruct.MapView_NearZoom_Lot && type != MaskedStruct.Thumbnail_Avatar && type != MaskedStruct.SimPage_MyLot && type != MaskedStruct.SimPage_JobsPanel && type != MaskedStruct.FriendshipWeb_Avatar && type != MaskedStruct.SimPage_SkillsPanel && type != MaskedStruct.AdmitInfo_Lot) { //Currently broken for some reason return; } //Lookup the entity, then process the request and send the response var task = DataService.Get(type, msg.Parameter.Value); if (task != null) { var entity = await task; var serialized = DataService.SerializeUpdate(type, entity, msg.Parameter.Value); for (int i = 0; i < serialized.Count; i++) { object serial = serialized[i]; session.Write(new DataServiceWrapperPDU() { SendingAvatarID = packet.SendingAvatarID, RequestTypeID = packet.RequestTypeID, Body = serial }); } } } else if (packet.Body is cTSOTopicUpdateMessage) { //Client wants to update a value in the data service var update = packet.Body as cTSOTopicUpdateMessage; DataService.ApplyUpdate(update, session); List <uint> resultDotPath = new List <uint>(); foreach (var item in update.DotPath) { var ires = item; if (ires == 0x1095C1E1) { ires = 0x7EA285CD; //rewrite: filter id -> returns -> result list } resultDotPath.Add(ires); if (ires == packet.RequestTypeID) { break; } } var result = await DataService.SerializePath(resultDotPath.ToArray()); if (result != null) { session.Write(new DataServiceWrapperPDU() { SendingAvatarID = packet.SendingAvatarID, RequestTypeID = packet.RequestTypeID, Body = result }); } /*var task = DataService.Get(update.DotPath[0], update.DotPath[1]); * if(task != null) * { * var entity = await task; * * var serialized = DataService.SerializeUpdate(type, entity, msg.Parameter.Value); * }*/ /**/ } } catch (Exception e) { //SerializePath throws generic exceptions. //plus we don't want weird special cases crashing the whole server. LOG.Error(e, "Voltron DataService request failed!"); } }