private string DoAgent2Put(Stream request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { if (!Util.CheckHttpAuthorization(_gridSendKey, httpRequest.Headers)) { m_log.WarnFormat("[REST COMMS]: /agent2/ communication from untrusted peer {0}", httpRequest.RemoteIPEndPoint.Address.ToString()); httpResponse.StatusCode = 401; return("Untrusted"); } UUID agentId; ulong regionHandle; string action; //unused if (!GetParams(path, out agentId, out regionHandle, out action)) { m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", path); httpResponse.StatusCode = 400; return("Invalid Parameters"); } ulong createdOn = Util.GetLongTickCount(); AgentPutMessage message = ProtoBuf.Serializer.Deserialize <AgentPutMessage>(request); if (message == null) { httpResponse.StatusCode = 400; return("Invalid Request"); } //CAU2 is the meaning of PUT var agentData = message.ToAgentData(); agentData.AgentDataCreatedOn = createdOn; //used to calculate interpolation values ChildAgentUpdate2Response status = m_localBackend.SendChildAgentUpdate2(m_localBackend.GetRegion(regionHandle), agentData); bool result = (status == ChildAgentUpdate2Response.Ok); switch (status) { case ChildAgentUpdate2Response.Ok: httpResponse.StatusCode = 200; break; case ChildAgentUpdate2Response.AccessDenied: httpResponse.StatusCode = 403; break; default: httpResponse.StatusCode = 500; break; } return(result.ToString()); }
public override async Task StateEntry() { await _avatar.TriggerOnTransitStageChanged(TransitStage.SendEstablishChildPresence, _avatar.RideOnPrims); SimpleRegionInfo destination = _avatar.TransitArgs.DestinationRegion; //do we have a presence on the destination? if (!_avatar.ScenePresence.RemotePresences.HasPresenceOnRegion(destination.RegionHandle)) { //no, we need to establish a new presence Tuple <EstablishPresenceResult, string> result = await _avatar.ScenePresence.RemotePresences.EstablishPresenceOnRegionLocked(destination, false, true); if (result.Item1 != EstablishPresenceResult.Success) { //something broke _avatar.ScenePresence.ControllingClient.SendAlertMessage( "Unable to complete transfer to new region: " + result.Item2); throw new SendAvatarException( String.Format("Could not establish presence on remote region: {0}", result.Item2)); } RollbackActions.Push(() => { _avatar.ScenePresence.RemotePresences.DropRemotePresenceLocked(destination, true).Wait(); }); } AvatarRemotePresence remotePresence = null; _avatar.ScenePresence.RemotePresences.TryGetRemotePresenceLocked(destination.RegionHandle, (AvatarRemotePresence pres) => { remotePresence = pres; } ); if (remotePresence == null) { //something is horked throw new SendAvatarException( String.Format("Presence could not be established on new region for {0}", _avatar.ScenePresence.Name)); } //we have a presence now, we can send the child agent update await _avatar.TriggerOnTransitStageChanged(TransitStage.SendAvatarHandoff, _avatar.RideOnPrims); //the ChildAgentUpdate below will always stop attachment scripts to transmit their state //if anything from this point on fails, we need to start the scripts running again RollbackActions.Push(() => { List <SceneObjectGroup> attachments = _avatar.ScenePresence.GetAttachments(); foreach (var att in attachments) { att.EndTransit(false); } } ); // Invoke the agent2 entry point ChildAgentUpdate2Response rc = this.SendChildAgentUpdate2(); switch (rc) { case ChildAgentUpdate2Response.Ok: break; // continue normally case ChildAgentUpdate2Response.AccessDenied: throw new SendAvatarException( String.Format("Region entry denied for {0}", _avatar.ScenePresence.Name)); case ChildAgentUpdate2Response.MethodNotAvailalble: throw new SendAvatarException( String.Format("Region change not available for {0}", _avatar.ScenePresence.Name)); case ChildAgentUpdate2Response.Error: default: throw new SendAvatarException( String.Format("Region change failed for {0}", _avatar.ScenePresence.Name)); } //this avatar is now considered a child agent _avatar.ScenePresence.MakeChildAgent(_avatar.TransitArgs.DestinationRegion.RegionHandle); //if there is a failure, we will need to restore the user as a root agent Vector3 restorePos = _avatar.ScenePresence.AbsolutePosition; Util.ForceValidRegionXY(ref restorePos); RollbackActions.Push(() => { _avatar.ScenePresence.MakeRootAgent(restorePos); }); //the user is ready to be transfered IEventQueue eq = _avatar.ScenePresence.Scene.RequestModuleInterface <IEventQueue>(); bool eventWasQueued = false; switch (_avatar.TransitArgs.Type) { case TransitType.OutboundCrossing: eventWasQueued = eq.CrossRegion(_avatar.TransitArgs.DestinationRegion.RegionHandle, _avatar.TransitArgs.LocationInDestination, _avatar.ScenePresence.Velocity, _avatar.TransitArgs.DestinationRegion.ExternalEndPoint, remotePresence.PresenceInfo.FullCapsSeedURL, _avatar.ScenePresence.UUID, _avatar.ScenePresence.ControllingClient.SessionId); break; case TransitType.OutboundTeleport: eventWasQueued = eq.TeleportFinishEvent(_avatar.TransitArgs.DestinationRegion.RegionHandle, 13, _avatar.TransitArgs.DestinationRegion.ExternalEndPoint, 4, (uint)_avatar.TransitArgs.TeleportFlags, remotePresence.PresenceInfo.FullCapsSeedURL, _avatar.ScenePresence.UUID); break; default: throw new SendAvatarException(String.Format("Invalid transit type {0} for sending avatar {1}", _avatar.TransitArgs.Type)); } if (!eventWasQueued) { throw new SendAvatarException(String.Format("Unable to enqueue transfer event for {0}", _avatar.ScenePresence.Name)); } //wait for confirmation of avatar on the other side await _avatar.WaitForRelease(); //matching endtransit for all attachments List <SceneObjectGroup> sentAttachments = _avatar.ScenePresence.GetAttachments(); foreach (var att in sentAttachments) { att.EndTransit(true); } _avatar.ScenePresence.AttachmentsCrossedToNewRegion(); //unsit the SP if appropriate if (_avatar.TransitArgs.RideOnPart != null) { _avatar.TransitArgs.RideOnPart.RemoveSeatedAvatar(_avatar.ScenePresence, false); } //this avatar is history. _avatar.ScenePresence.Reset(_avatar.TransitArgs.DestinationRegion); _avatar.ScenePresence.Scene.EventManager.TriggerAvatarLeavingRegion(_avatar.ScenePresence, _avatar.TransitArgs.DestinationRegion); }
private ChildAgentUpdate2Response SendChildAgentUpdate2() { ScenePresence agent = _avatar.ScenePresence; SceneObjectGroup sceneObjectGroup = _avatar.TransitArgs.RideOnGroup; SceneObjectPart part = _avatar.TransitArgs.RideOnPart; ulong newRegionHandle = _avatar.TransitArgs.DestinationRegion.RegionHandle; SimpleRegionInfo neighbourRegion = _avatar.TransitArgs.DestinationRegion; Vector3 pos = _avatar.TransitArgs.LocationInDestination; AgentLocomotionFlags locomotionFlags = 0; if (_avatar.TransitArgs.Type == TransitType.OutboundCrossing) { locomotionFlags = AgentLocomotionFlags.Crossing; } else if (_avatar.TransitArgs.Type == TransitType.OutboundTeleport) { locomotionFlags = AgentLocomotionFlags.Teleport; } AgentData cAgent = new AgentData(); agent.CopyToForRootAgent(cAgent); if (part == null) { cAgent.Position = pos; } cAgent.LocomotionState = 1; cAgent.LocomotionFlags = locomotionFlags; List <SceneObjectGroup> attachments = agent.CollectAttachmentsForCrossing(); //try the new comms first var engine = ProviderRegistry.Instance.Get <ISerializationEngine>(); if (engine == null) { _log.ErrorFormat("[SCENE COMM]: Cannot send child agent update to {0}, Serialization engine is missing!", neighbourRegion.RegionHandle); return(ChildAgentUpdate2Response.Error); } List <byte[]> serializedAttachments = new List <byte[]>(); foreach (var att in attachments) { //mark the SOG in-transit. this along with the serialization below sends a disable to the script engine, but they are not cumulative att.StartTransit(); //we are stopping the scripts as part of the serialization process here //this means that later on, should the remote creation call fail, we need to re-enable them //reenabling is done via EndTransit with success==false byte[] sogBytes = engine.SceneObjectSerializer.SerializeGroupToBytes(att, SerializationFlags.FromCrossing | SerializationFlags.StopScripts | SerializationFlags.SerializeScriptBytecode); serializedAttachments.Add(sogBytes); } cAgent.SerializedAttachments = serializedAttachments; var scene = agent.Scene; cAgent.CallbackURI = scene.RegionInfo.InsecurePublicHTTPServerURI + "/agent/" + agent.UUID.ToString() + "/" + agent.Scene.RegionInfo.RegionHandle.ToString() + "/release/"; ChildAgentUpdate2Response resp = scene.InterregionComms.SendChildAgentUpdate2(neighbourRegion, cAgent); if (resp == ChildAgentUpdate2Response.Error) { _log.ErrorFormat("[SCENE COMM]: Error sending child agent update to {0}", neighbourRegion.RegionHandle); } else if (resp == ChildAgentUpdate2Response.MethodNotAvailalble) { _log.ErrorFormat("[SCENE COMM]: Error sending child agent update to {0}, ChildAgentUpdate2 not available. Falling back to old method", neighbourRegion.RegionHandle); } return(resp); }