/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase SetDynamicsHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(BulkDynamicsRequest)) { return(OperationFailed("wrong type of request object")); } BulkDynamicsRequest request = (BulkDynamicsRequest)irequest; foreach (ObjectDynamicsData ddata in request.Updates) { SceneObjectGroup sog = m_scene.GetSceneObjectGroup(ddata.ObjectID); if (sog == null) { m_log.WarnFormat("[ObjectHandlers] missing requested object; {0}", ddata.ObjectID.ToString()); continue; } sog.RootPart.Velocity = ddata.Velocity; sog.RootPart.Acceleration = ddata.Acceleration; sog.UpdateGroupRotationPR(ddata.Position, ddata.Rotation); } return(new ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase SetRotationHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(SetPartRotationRequest)) { return(OperationFailed("wrong type of request object")); } SetPartRotationRequest request = (SetPartRotationRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } SceneObjectPart sop = request.LinkNum == 0 ? sog.RootPart : sog.GetLinkNumPart(request.LinkNum); if (sop == null) { return(OperationFailed("no such part")); } sop.RotationOffset = request.Rotation; sog.ScheduleGroupForTerseUpdate(); return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase GetObjectPartsHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(GetObjectPartsRequest)) { return(OperationFailed("wrong type of request object")); } GetObjectPartsRequest request = (GetObjectPartsRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } GetObjectPartsResponse response = new GetObjectPartsResponse(); foreach (SceneObjectPart part in sog.Parts) { PartInformation info = new PartInformation(); info.LinkNum = part.LinkNum; info.Name = part.Name; info.Description = part.Description; info.OffsetPosition = part.OffsetPosition; info.OffsetRotation = part.RotationOffset; info.Type = part.GetPrimType(); response.Parts.Add(info); } return(response); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase SetColorHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(SetPartColorRequest)) { return(OperationFailed("wrong type of request object")); } SetPartColorRequest request = (SetPartColorRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } SceneObjectPart sop = request.LinkNum == 0 ? sog.RootPart : sog.GetLinkNumPart(request.LinkNum); if (sop == null) { return(OperationFailed("no such part")); } sop.SetFaceColorAlpha(SceneObjectPart.ALL_SIDES, request.Color, request.Alpha); sog.ScheduleGroupForFullUpdate(); // Full or terse? Don't seem to be sent with terse return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase MessageObjectHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(MessageObjectRequest)) { return(OperationFailed("wrong type")); } MessageObjectRequest request = (MessageObjectRequest)irequest; IScriptModule m_scriptModule = m_scene.RequestModuleInterface <IScriptModule>(); if (m_scriptModule == null) { return(OperationFailed("unable to locate appropriate handler")); } SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } object[] args = new object[] { request._UserAccount.PrincipalID.ToString(), request.Message }; m_scriptModule.PostObjectEvent(sog.RootPart.UUID, "dataserver", args); return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase GetObjectInventoryHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(GetObjectInventoryRequest)) { return(OperationFailed("wrong type")); } GetObjectInventoryRequest request = (GetObjectInventoryRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } GetObjectInventoryResponse response = new GetObjectInventoryResponse(); lock (sog.RootPart.TaskInventory) { foreach (KeyValuePair <UUID, TaskInventoryItem> inv in sog.RootPart.TaskInventory) { ObjectInventoryInformation item = new ObjectInventoryInformation(inv.Value); response.Inventory.Add(item); } } return(response); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase CreateObjectHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(CreateObjectRequest)) { return(OperationFailed("wrong type of request object")); } CreateObjectRequest request = (CreateObjectRequest)irequest; if (request.AssetID == UUID.Zero) { return(OperationFailed("missing asset id")); } SceneObjectGroup sog = null; try { m_log.DebugFormat("[ObjectHandlers] create object \"{0}\" from asset {1}", request.Name, request.AssetID); sog = GetRezReadySceneObject(request.AssetID, request.Name, request.Description, request._UserAccount.PrincipalID, UUID.Zero); if (sog == null) { return(OperationFailed("unable to create object from asset")); } if (request.ObjectID != UUID.Zero) { sog.UUID = request.ObjectID; } if (!String.IsNullOrEmpty(request.StartParameter)) { if (m_jsonstore != null) { // really should register an event handler on the scene to destroy this // store when we are done UUID storeID = sog.UUID; m_jsonstore.CreateStore(request.StartParameter, ref storeID); } } if (!m_scene.AddNewSceneObject(sog, false, request.Position, request.Rotation, request.Velocity)) { return(OperationFailed("failed to add the object to the scene")); } sog.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); sog.ScheduleGroupForFullUpdate(); } catch (Exception e) { m_log.WarnFormat("[ObjectHandlers] exception thrown in CreateObjectHandler; {0}", e.ToString()); return(OperationFailed(e.Message)); } return(new CreateObjectResponse(sog.UUID)); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase UnregisterUpdatedCallbackHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(UnregisterUpdatedCallbackRequest)) { return(OperationFailed("wrong type")); } UnregisterUpdatedCallbackRequest request = (UnregisterUpdatedCallbackRequest)irequest; StringBuilder warnings = new StringBuilder(); foreach (UUID oid in request.ObjectIDs) { // Find the EventCallback structure List <EventCallback> cb = null; lock (m_objectRegistry) { List <EventCallback> cblist = null; if (!m_objectRegistry.TryGetValue(oid, out cblist)) { warnings.AppendFormat("no handler for requested object {0}; ", oid); continue; } cb = cblist.FindAll(delegate(EventCallback test) { return(test.RequestID == request.RequestID && test.EventType == EventType.Position); }); if (cb == null || (cb != null && cb.Count == 0)) { return(OperationFailed(String.Format("invalid request id {0}", request.RequestID))); } foreach (EventCallback e in cb) { cblist.Remove(e); } } lock (m_endpointRegistry) { List <EventCallback> cblist = null; if (m_endpointRegistry.TryGetValue(cb[0].EndPointID, out cblist)) { foreach (EventCallback e in cb) { cblist.Remove(e); } if (cblist.Count == 0) { EndPoint ep = m_dispatcher.LookupEndPoint(cb[0].EndPointID); ep.RemoveCloseHandler(this.EndPointCloseHandler); m_endpointRegistry.Remove(cb[0].EndPointID); } } } m_log.DebugFormat("[EventHandlers] unregistered touch callback for {0}", oid); } return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, warnings.ToString())); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase RegisterTouchCallbackHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(RegisterTouchCallbackRequest)) { return(OperationFailed("wrong type")); } RegisterTouchCallbackRequest request = (RegisterTouchCallbackRequest)irequest; // Get the object and register a handler for it SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed(String.Format("no such object; {0}", request.ObjectID))); } if (sog.UUID != request.ObjectID) { return(OperationFailed("touch callback must be registered for root prim")); } UUID requestID = UUID.Random(); sog.RootPart.SetScriptEvents(requestID, (int)scriptEvents.touch); // Create the event callback structure EventCallback cb = new EventCallback(request.ObjectID, request.EndPointID, requestID); // Add it to the object registry for handling the touch events lock (m_objectRegistry) { if (!m_objectRegistry.ContainsKey(request.ObjectID)) { m_objectRegistry.Add(request.ObjectID, new List <EventCallback>()); } m_objectRegistry[request.ObjectID].Add(cb); } // Add it to the endpoint registry for handling changes in the endpoint state lock (m_endpointRegistry) { if (!m_endpointRegistry.ContainsKey(request.EndPointID)) { m_endpointRegistry.Add(request.EndPointID, new List <EventCallback>()); // Only need to register the handler for the first request for this endpoint EndPoint ep = m_dispatcher.LookupEndPoint(request.EndPointID); ep.AddCloseHandler(this.EndPointCloseHandler); } m_endpointRegistry[request.EndPointID].Add(cb); } m_log.DebugFormat("[EventHandlers] registered touch callback for {0}", request.ObjectID); return(new RegisterTouchCallbackResponse(requestID)); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase DeleteAllObjectsHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(DeleteAllObjectsRequest)) { return(OperationFailed("wrong type of request object")); } DeleteAllObjectsRequest request = (DeleteAllObjectsRequest)irequest; m_scene.DeleteAllSceneObjects(); return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase GetObjectRotationHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(GetObjectRotationRequest)) { return(OperationFailed("wrong type")); } GetObjectRotationRequest request = (GetObjectRotationRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } return(new ObjectRotationResponse(request.ObjectID, sog.GroupRotation)); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase GetSunParametersHandler(Dispatcher.Messages.RequestBase request) { if (request.GetType() != typeof(GetSunParametersRequest)) { return(OperationFailed("wrong type")); } GetSunParametersRequest req = (GetSunParametersRequest)request; SunParametersResponse res = new SunParametersResponse(); res.YearLength = m_SunModule.GetSunParameter("year_length"); res.DayLength = m_SunModule.GetSunParameter("day_length"); res.HorizonShift = m_SunModule.GetSunParameter("day_night_offset"); res.DayTimeSunHourScale = m_SunModule.GetSunParameter("day_time_sun_hour_scale"); res.CurrentTime = m_SunModule.GetSunParameter("current_time"); return(res); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase SetObjectPositionHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(SetObjectPositionRequest)) { return(OperationFailed("wrong type")); } SetObjectPositionRequest request = (SetObjectPositionRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } sog.UpdateGroupPosition(request.Position); return(new ObjectPositionResponse(request.ObjectID, sog.AbsolutePosition)); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase DeleteObjectHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(DeleteObjectRequest)) { return(OperationFailed("wrong type of request object")); } DeleteObjectRequest request = (DeleteObjectRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed("no such object")); } m_scene.DeleteSceneObject(sog, false, true); return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase FindObjectsHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(FindObjectsRequest)) { return(OperationFailed("wrong type of request object")); } FindObjectsRequest request = (FindObjectsRequest)irequest; // Set up the bounding box such that min.X <= max.X, min.Y <= max.Y, min.Z <= max.Z Vector3 min = new Vector3(0.0f, 0.0f, 0.0f); Vector3 max = new Vector3(Constants.RegionSize, Constants.RegionSize, float.MaxValue); min.X = Math.Min(request.CoordinateA.X, request.CoordinateB.X); min.Y = Math.Min(request.CoordinateA.Y, request.CoordinateB.Y); min.Z = Math.Min(request.CoordinateA.Z, request.CoordinateB.Z); max.X = Math.Max(request.CoordinateA.X, request.CoordinateB.X); max.Y = Math.Max(request.CoordinateA.Y, request.CoordinateB.Y); max.Z = Math.Max(request.CoordinateA.Z, request.CoordinateB.Z); // Set up the pattern Regex pattern = null; if (!String.IsNullOrEmpty(request.Pattern)) { pattern = new Regex(request.Pattern); } Predicate <SceneObjectGroup> pred = sog => SearchPredicate(sog, min, max, pattern, request.OwnerID); List <SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups().FindAll(pred); FindObjectsResponse resp = new FindObjectsResponse(); foreach (SceneObjectGroup sog in sceneObjects) { resp.Objects.Add(sog.UUID); } return(resp); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase ChatHandler(Dispatcher.Messages.RequestBase request) { if (request.GetType() != typeof(ChatRequest)) { return(OperationFailed("wrong type")); } ChatRequest req = (ChatRequest)request; OSChatMessage msg = new OSChatMessage(); msg.Scene = m_scene; msg.Type = ChatTypeEnum.Say; msg.Sender = null; msg.From = req._UserAccount.Name; msg.Message = req.Message; msg.Position = req.Position; msg.Channel = req.Channel; m_scene.EventManager.TriggerOnChatBroadcast(new Object(), msg); return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase DeleteBulkObjectsHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(DeleteBulkObjectsRequest)) { return(OperationFailed("wrong type of request object")); } DeleteBulkObjectsRequest request = (DeleteBulkObjectsRequest)irequest; StringBuilder warnings = new StringBuilder(); foreach (UUID id in request.ObjectIDs) { SceneObjectGroup sog = m_scene.GetSceneObjectGroup(id); if (sog == null) { warnings.AppendFormat("no such object {0}; ", id); continue; } m_scene.DeleteSceneObject(sog, false, true); } return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, warnings.ToString())); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- protected ResponseBase RenewEndPointRequestHandler(RequestBase irequest) { if (irequest.GetType() != typeof(RenewEndPointRequest)) return OperationFailed("wrong type of request object"); RenewEndPointRequest request = (RenewEndPointRequest)irequest; EndPoint ep = m_dispatcher.LookupEndPoint(request.EndPointID); if (ep == null) return OperationFailed(String.Format("Unknown endpoint identifier; {0}",request.EndPointID)); ep.LastRenewTime = Util.EnvironmentTickCount(); ep.LifeSpan = Math.Max(request.LifeSpan,m_dispatcher.MaxInterPingTime); return new CreateEndPointResponse(request.EndPointID,ep.LifeSpan); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase SetTerrainHeightHandler(RequestBase irequest) { if (irequest.GetType() != typeof(SetTerrainHeightRequest)) return OperationFailed("wrong type"); SetTerrainHeightRequest request = (SetTerrainHeightRequest)irequest; m_scene.Heightmap[request.X,request.Y] = request.Height; return new TerrainHeightResponse(request.X, request.Y, m_scene.Heightmap[request.X, request.Y]); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- protected ResponseBase CreateEndPointRequestHandler(RequestBase irequest) { if (irequest.GetType() != typeof(CreateEndPointRequest)) return OperationFailed("wrong type of request object"); CreateEndPointRequest request = (CreateEndPointRequest)irequest; if (String.IsNullOrEmpty(request.CallbackHost)) return OperationFailed("Missing required parameter, CallbackHost"); // As a security measure, only accept callbacks to the host where the // callback creation request originated. This prevents someone from using // the dispatcher for generating random spam to hosts IPAddress addr; try { addr = (IPAddress)IPAddress.Parse(request.CallbackHost); } catch (Exception e) { return OperationFailed(String.Format("Failed to parse endpoint address, {0}", request.CallbackHost)); } if (addr.Equals(request._SourceAddress)) return OperationFailed(String.Format("Endpoint address must match request address, {0}",request.CallbackHost)); UUID id = UUID.Random(); EndPoint ep = new EndPoint(id,addr,request.CallbackPort); ep.LastRenewTime = Util.EnvironmentTickCount(); ep.LifeSpan = Math.Max(request.LifeSpan,m_dispatcher.MaxInterPingTime); m_dispatcher.RegisterEndPoint(id,ep); return new CreateEndPointResponse(id,ep.LifeSpan); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase CreateBulkObjectsHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(CreateBulkObjectsRequest)) { return(OperationFailed("wrong type of request object")); } StringBuilder warnings = new StringBuilder(); CreateBulkObjectsRequest request = (CreateBulkObjectsRequest)irequest; foreach (ObjectSpecification obj in request.Objects) { ObjectDynamicsData odata = obj.ObjectData; if (odata == null) { warnings.AppendFormat("missing object specification for asset {0}; ", obj.AssetID); continue; } if (obj.AssetID == UUID.Zero) { warnings.AppendFormat("missing asset for object {0}; ", odata.ObjectID); continue; } SceneObjectGroup sog = null; try { m_log.DebugFormat("[ObjectHandlers] create object \"{0}\" from asset {1}", obj.Name, obj.AssetID); sog = GetRezReadySceneObject(obj.AssetID, obj.Name, obj.Description, request._UserAccount.PrincipalID, UUID.Zero); if (sog == null) { warnings.AppendFormat("unable to create object from asset {0}; ", obj.AssetID); continue; } if (odata.ObjectID != UUID.Zero) { sog.UUID = odata.ObjectID; } if (!String.IsNullOrEmpty(obj.StartParameter)) { if (m_jsonstore != null) { // really should register an event handler on the scene to destroy this // store when we are done UUID storeID = sog.UUID; m_jsonstore.CreateStore(obj.StartParameter, ref storeID); } } if (!m_scene.AddNewSceneObject(sog, false, odata.Position, odata.Rotation, odata.Velocity)) { warnings.AppendFormat("failed to add the object {0} to the scene; ", odata.ObjectID); continue; } sog.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); sog.ScheduleGroupForFullUpdate(); } catch (Exception e) { m_log.WarnFormat("[ObjectHandlers] exception thrown in CreateObjectsHandler; {0}", e.ToString()); return(OperationFailed(e.Message)); } } return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, warnings.ToString())); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public bool AuthorizeRequest(RequestBase irequest, out String message) { message = String.Empty; if (! m_useAuthentication) return true; UserAccount acct; HashSet<String> dlist; String scene; if (m_capCache.GetCapability(irequest._Capability, out acct, out dlist, out scene)) { if (irequest._Domain == m_dispatcher.Domain || dlist.Contains(irequest._Domain) || dlist.Contains(MasterDomain)) { if (irequest._Scene == scene) { irequest._UserAccount = acct; return true; } else { message = "capability does not authorize access to scene"; } } else { message = "capability does not authorize access to message domain"; } } else { message = "no such capability"; } return false; }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- protected ResponseBase CreateCapabilityRequestHandler(RequestBase irequest) { if (irequest.GetType() != typeof(CreateCapabilityRequest)) return OperationFailed("wrong type"); CreateCapabilityRequest request = (CreateCapabilityRequest)irequest; // Get a handle to the scene for the request to be used later Scene scene; // if no scene is specified, then we'll just use a random one // in theory no scene needs to be set unless the services in each one are different if (String.IsNullOrEmpty(request._Scene)) scene = m_sceneList[0]; else if (! m_sceneCache.TryGetValue(request._Scene, out scene)) return OperationFailed("no scene specified"); // Grab the account information and cache it for later use UserAccount account = null; if (request.UserID != UUID.Zero) account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID,request.UserID); else if (! String.IsNullOrEmpty(request.FirstName) && ! String.IsNullOrEmpty(request.LastName)) account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID,request.FirstName,request.LastName); else if (! String.IsNullOrEmpty(request.EmailAddress)) account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID,request.EmailAddress); if (account == null) return OperationFailed(String.Format("failed to locate account for user {0}",request.UserID.ToString())); // Authenticate the user with the hashed passwd from the request if (scene.AuthenticationService.Authenticate(account.PrincipalID,request.HashedPasswd,0) == String.Empty) return OperationFailed(String.Format("failed to authenticate user {0}", account.PrincipalID.ToString())); if (! AuthorizeCapability(scene, account)) return OperationFailed(String.Format("user {0} is not authorized to access this interface", account.PrincipalID.ToString())); // OK... we have validated all the requirements for access to the dispatcher messages // so its now time to build & save the capability HashSet<String> dlist = new HashSet<String>(request.DomainList); // Clamp the lifespan for externally requested capabilities, region modules can register // caps with longer or infinite lifespans if (request.LifeSpan <= 0) return OperationFailed(String.Format("lifespan must be greater than 0 {0}",request.LifeSpan)); int span = Math.Min(request.LifeSpan,m_maxLifeSpan); // add it to the authentication cache UUID capability = UUID.Random(); m_capCache.AddCapability(capability,account,dlist,scene.Name,span); return new CapabilityResponse(capability,span); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- protected ResponseBase DestroyCapabilityRequestHandler(RequestBase irequest) { if (irequest.GetType() != typeof(DestroyCapabilityRequest)) return OperationFailed("wrong type"); DestroyCapabilityRequest request = (DestroyCapabilityRequest)irequest; // update the capability cache if (! m_capCache.RemoveCapability(request._Capability)) return OperationFailed(String.Format("unable to remove the capability")); return new ResponseBase(ResponseCode.Success,""); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- public Dispatcher.Messages.ResponseBase UnregisterTouchCallbackHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(UnregisterTouchCallbackRequest)) { return(OperationFailed("wrong type")); } UnregisterTouchCallbackRequest request = (UnregisterTouchCallbackRequest)irequest; // Find the EventCallback structure EventCallback cb = null; lock (m_objectRegistry) { List <EventCallback> cblist = null; if (!m_objectRegistry.TryGetValue(request.ObjectID, out cblist)) { return(OperationFailed(String.Format("no handler for requested object; {0}", request.ObjectID))); } cb = cblist.Find(delegate(EventCallback test) { return(test.RequestID == request.RequestID); }); if (cb == null) { return(OperationFailed(String.Format("invalid request id; {0}", request.RequestID))); } cblist.Remove(cb); if (cblist.Count == 0) { m_objectRegistry.Remove(request.ObjectID); } } lock (m_endpointRegistry) { List <EventCallback> cblist = null; if (m_endpointRegistry.TryGetValue(cb.EndPointID, out cblist)) { cblist.Remove(cb); if (cblist.Count == 0) { EndPoint ep = m_dispatcher.LookupEndPoint(cb.EndPointID); ep.RemoveCloseHandler(this.EndPointCloseHandler); m_endpointRegistry.Remove(cb.EndPointID); } } } // Remove the touch event callback from the SOG SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) { return(OperationFailed(String.Format("no such object; {0}", request.ObjectID))); } sog.RootPart.RemoveScriptEvents(cb.RequestID); m_log.DebugFormat("[EventHandlers] unregistered touch callback for {0}", request.ObjectID); return(new Dispatcher.Messages.ResponseBase(ResponseCode.Success, "")); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- private ResponseBase InvokeHandler(RequestBase req) { OperationHandler handler; // check to see if this is a pre-authenticate request and handle it there, all of these // operations must be synchronous if (m_PreHandlerRegistry.TryGetValue(req.GetType().FullName, out handler)) return handler(req); // Check to see if we have a valid capability and expand it String message; if (! m_authorizer.AuthorizeRequest(req, out message)) return OperationFailed(String.Format("Unauthorized invocation; {0}", message)); // Find the regular handler if (! FindHandler(req,out handler)) return OperationFailed(String.Format("Unknown message type; {0}",req.GetType().FullName)); if (req._AsyncRequest) { // Util.FireAndForget( delegate { handler(req); } ); EnqueueRequest(req); return new ResponseBase(ResponseCode.Queued,""); } ResponseBase resp = handler(req); RecordCompletedOperation(req); return resp; }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- protected ResponseBase CreateEndPointRequestHandler(RequestBase irequest) { if (irequest.GetType() != typeof(CreateEndPointRequest)) return OperationFailed("wrong type of request object"); CreateEndPointRequest request = (CreateEndPointRequest)irequest; UUID id = UUID.Random(); EndPoint ep = new EndPoint(id,request.CallbackHost,request.CallbackPort); ep.LastRenewTime = Util.EnvironmentTickCount(); ep.LifeSpan = Math.Max(request.LifeSpan,m_dispatcher.MaxInterPingTime); m_dispatcher.RegisterEndPoint(id,ep); return new CreateEndPointResponse(id,ep.LifeSpan); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- protected ResponseBase RenewCapabilityRequestHandler(RequestBase irequest) { if (irequest.GetType() != typeof(RenewCapabilityRequest)) return OperationFailed("wrong type"); RenewCapabilityRequest request = (RenewCapabilityRequest)irequest; // Clamp the lifespan for externally requested capabilities, region modules can register // caps with longer or infinite lifespans if (request.LifeSpan <= 0) return OperationFailed(String.Format("lifespan must be greater than 0 {0}",request.LifeSpan)); int span = Math.Min(request.LifeSpan,m_maxLifeSpan); // update the capability cache if (! m_capCache.UpdateCapability(request._Capability,span)) return OperationFailed(String.Format("unable to update the capability")); return new CapabilityResponse(request._Capability,span); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase GetDependentAssetsHandler(RequestBase irequest) { if (irequest.GetType() != typeof(GetDependentAssetsRequest)) return OperationFailed("wrong type"); GetDependentAssetsRequest request = (GetDependentAssetsRequest)irequest; AssetBase asset = m_cache.Get(request.AssetID.ToString()); if (asset == null) return OperationFailed("no such asset"); UuidGatherer gatherer = new UuidGatherer(m_scene.AssetService); gatherer.AddForInspection(request.AssetID); gatherer.GatherAll(); Dictionary<UUID,sbyte> assetids = (Dictionary<UUID,sbyte>)gatherer.GatheredUuids; List<UUID> assets = new List<UUID>(assetids.Keys); return new GetDependentAssetsResponse(assets); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase SetAvatarAppearanceHandler(RequestBase irequest) { if (irequest.GetType() != typeof(SetAvatarAppearanceRequest)) return OperationFailed("wrong type"); SetAvatarAppearanceRequest request = (SetAvatarAppearanceRequest)irequest; // Get the scenepresence for the avatar we are going to update UUID id = request.AvatarID == UUID.Zero ? request._UserAccount.PrincipalID : request.AvatarID; ScenePresence sp = m_scene.GetScenePresence(id); if (sp == null || sp.IsChildAgent) return OperationFailed(String.Format("cannot find user {0}",request._UserAccount.PrincipalID)); // Clean out the current outfit folder, this is to keep v3 viewers from // reloading the old appearance CleanCurrentOutfitFolder(sp); // Delete existing npc attachments m_scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); // ---------- Update the appearance and save it ---------- int serial = sp.Appearance.Serial; OSDMap osd = (OSDMap)OSDParser.DeserializeJson(request.SerializedAppearance); sp.Appearance = new AvatarAppearance(osd); sp.Appearance.Serial = serial + 1; m_scene.AvatarService.SetAppearance(sp.UUID,sp.Appearance); m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); // ---------- Send out the new appearance to everyone ---------- // Rez needed attachments m_scene.AttachmentsModule.RezAttachments(sp); // this didn't work, still looking for a way to get the viewer to change its appearance //sp.ControllingClient.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); // this didn't work either, //AddWearablesToCurrentOutfitFolder(sp); sp.SendAvatarDataToAllClients(); sp.SendAppearanceToAllOtherClients(); sp.SendAppearanceToClient(sp); // the viewers seem to ignore this packet when it describes their own avatar return new ResponseBase(ResponseCode.Success,""); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- protected ResponseBase CloseEndPointRequestHandler(RequestBase irequest) { if (irequest.GetType() != typeof(CloseEndPointRequest)) return OperationFailed("wrong type of request object"); CloseEndPointRequest request = (CloseEndPointRequest)irequest; EndPoint ep = m_dispatcher.LookupEndPoint(request.EndPointID); if (ep == null) return OperationFailed(String.Format("Unknown endpoint identifier; {0}",request.EndPointID)); try { ep.TriggerCloseHandlers(); m_dispatcher.UnregisterEndPoint(ep.EndPointID); } catch (Exception e) { m_log.WarnFormat("[EndPointHandlers] close event failed; {0}",e.Message); } return new ResponseBase(ResponseCode.Success,""); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- /// public Dispatcher.Messages.ResponseBase RegisterUpdatedCallbackHandler(Dispatcher.Messages.RequestBase irequest) { if (irequest.GetType() != typeof(RegisterUpdatedCallbackRequest)) { return(OperationFailed("wrong type")); } RegisterUpdatedCallbackRequest request = (RegisterUpdatedCallbackRequest)irequest; StringBuilder warnings = new StringBuilder(); UUID requestID = UUID.Random(); foreach (UUID oid in request.ObjectIDs) { // Get the object and register a handler for it SceneObjectGroup sog = m_scene.GetSceneObjectGroup(oid); if (sog == null) { warnings.AppendFormat("no such object {0}; ", oid); continue; } if (sog.UUID != oid) { warnings.AppendFormat("updated callback must be registered for root prim; "); continue; } // Create the event callback structure EventCallback cb = new EventCallback(oid, request.EndPointID, requestID, EventType.Position); // Add it to the object registry for handling events lock (m_objectRegistry) { if (!m_objectRegistry.ContainsKey(oid)) { m_objectRegistry.Add(oid, new List <EventCallback>()); } m_objectRegistry[oid].Add(cb); } // Add it to the endpoint registry for handling changes in the endpoint state lock (m_endpointRegistry) { if (!m_endpointRegistry.ContainsKey(request.EndPointID)) { m_endpointRegistry.Add(request.EndPointID, new List <EventCallback>()); // Only need to register the handler for the first request for this endpoint EndPoint ep = m_dispatcher.LookupEndPoint(request.EndPointID); ep.AddCloseHandler(this.EndPointCloseHandler); } m_endpointRegistry[request.EndPointID].Add(cb); } m_LastPositions[oid] = sog.RootPart.GroupPosition; m_log.DebugFormat("[EventHandlers] registered updated callback for {0}", oid); } return(new RegisterUpdatedCallbackResponse(requestID, warnings.ToString())); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- /// TODO: should probably move this to the object messages domain, it is the /// only message that requires access to the scene public ResponseBase GetAssetFromObjectHandler(RequestBase irequest) { if (irequest.GetType() != typeof(GetAssetFromObjectRequest)) return OperationFailed("wrong type"); GetAssetFromObjectRequest request = (GetAssetFromObjectRequest)irequest; SceneObjectGroup sog = m_scene.GetSceneObjectGroup(request.ObjectID); if (sog == null) return OperationFailed("no such object"); string itemXml; itemXml = SceneObjectSerializer.ToOriginalXmlFormat(sog,false); AssetBase asset = new AssetBase(); asset.FullID = UUID.Random(); asset.Data = Utils.StringToBytes(itemXml); asset.Name = sog.GetPartName(sog.RootPart.LocalId); asset.Description = sog.GetPartDescription(sog.RootPart.LocalId); asset.Type = (sbyte)AssetType.Object; asset.CreatorID = sog.OwnerID.ToString(); asset.Local = true; asset.Temporary = false; m_cache.Cache(asset); return new GetAssetResponse(asset); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase GetAvatarAppearanceHandler(RequestBase irequest) { if (irequest.GetType() != typeof(GetAvatarAppearanceRequest)) return OperationFailed("wrong type"); GetAvatarAppearanceRequest request = (GetAvatarAppearanceRequest)irequest; UUID id = request.AvatarID == UUID.Zero ? request._UserAccount.PrincipalID : request.AvatarID; ScenePresence sp = m_scene.GetScenePresence(id); if (sp == null || sp.IsChildAgent) return OperationFailed(String.Format("cannot find user {0}",request._UserAccount.PrincipalID)); OSDMap osd = sp.Appearance.Pack(); String appearance = OSDParser.SerializeJsonString(osd); return new AvatarAppearanceResponse(appearance); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase AddAssetHandler(RequestBase irequest) { if (m_cache == null) return OperationFailed("No asset cache"); if (irequest.GetType() != typeof(AddAssetRequest)) return OperationFailed("wrong type"); AddAssetRequest request = (AddAssetRequest)irequest; UUID id = request.Asset.AssetID; if ((id == UUID.Zero) || (m_cache.Get(id.ToString()) == null)) { if (id == UUID.Zero) id = UUID.Random(); AssetBase asset = (AssetBase)request; asset.Local = true; asset.Temporary = false; m_cache.Cache(asset); } return new AddAssetResponse(id); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- private void EnqueueRequest(RequestBase req) { lock (m_requestQueue) { // put the request in the queue m_requestQueue.Enqueue(req); // if there are already enough threads operating here, // then there is nothing else to do if (m_requestThreads >= m_maxRequestThreads) return; // Guess there is work for a new thread m_requestThreads++; } Util.FireAndForget(delegate { ProcessRequestQueue(); }); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase GetAssetHandler(RequestBase irequest) { if (m_cache == null) return OperationFailed("No asset cache"); if (irequest.GetType() != typeof(GetAssetRequest)) return OperationFailed("wrong type"); GetAssetRequest request = (GetAssetRequest)irequest; AssetBase asset = m_scene.AssetService.Get(request.AssetID.ToString()); // AssetBase asset = m_cache.Get(request.AssetID.ToString()); if (asset == null) return OperationFailed("no such asset"); return new GetAssetResponse(asset); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- private bool FindHandler(RequestBase req, out OperationHandler handler) { handler = null; string opkey = req._Domain + m_separator + req.GetType().FullName; // First look for a scene-specific handler if (! String.IsNullOrEmpty(req._Scene)) { if (m_HandlerRegistry.TryGetValue(req._Scene + m_separator + opkey, out handler)) return true; } // Look for a scene-independent handler if (m_HandlerRegistry.TryGetValue(opkey, out handler)) return true; return false; }
/// ----------------------------------------------------------------- /// <summary> /// </summary> // ----------------------------------------------------------------- public ResponseBase TestAssetHandler(RequestBase irequest) { if (m_cache == null) return OperationFailed("No asset cache"); if (irequest.GetType() != typeof(TestAssetRequest)) return OperationFailed("wrong type"); TestAssetRequest request = (TestAssetRequest)irequest; AssetBase asset = m_cache.Get(request.AssetID.ToString()); return new TestAssetResponse(asset != null ? true : false); }
/// ----------------------------------------------------------------- /// <summary> /// </summary> /// ----------------------------------------------------------------- private void RecordCompletedOperation(RequestBase req) { lock (m_dispatcherStats) { String tname = req.GetType().Name; DispatcherStat stat = null; if (! m_dispatcherStats.TryGetValue(tname, out stat)) { stat = new DispatcherStat(); m_dispatcherStats[tname] = stat; } UInt64 tdiff = (UInt64)Util.EnvironmentTickCountSubtract(req.RequestEntryTime); stat.TotalTime += tdiff; stat.TotalRequests++; } }