public void TestCrossOnSameSimulatorPrimLimitsOkay() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); int sceneObjectIdTail = 0x2; EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); LandManagementModule lmmA = new LandManagementModule(); LandManagementModule lmmB = new LandManagementModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig permissionsConfig = config.AddConfig("Permissions"); permissionsConfig.Set("permissionmodules", "PrimLimitsModule"); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules( sceneA, config, etmA, lmmA, new PrimLimitsModule(), new PrimCountModule()); SceneHelpers.SetupSceneModules( sceneB, config, etmB, lmmB, new PrimLimitsModule(), new PrimCountModule()); // We must set up the parcel for this to work. Normally this is taken care of by OpenSimulator startup // code which is not yet easily invoked by tests. lmmA.EventManagerOnNoLandDataFromStorage(); lmmB.EventManagerOnNoLandDataFromStorage(); AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); TestClient tc = new TestClient(acd, sceneA); List <TestClient> destinationTestClients = new List <TestClient>(); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence sp1SceneA = SceneHelpers.AddScenePresence(sceneA, tc, acd); SceneObjectGroup so1 = SceneHelpers.AddSceneObject(sceneA, 1, userId, "", sceneObjectIdTail); UUID so1Id = so1.UUID; so1.AbsolutePosition = new Vector3(128, 10, 20); // Cross with a negative value. We must make this call rather than setting AbsolutePosition directly // because only this will execute permission checks in the source region. sceneA.SceneGraph.UpdatePrimGroupPosition(so1.LocalId, new Vector3(128, -10, 20), sp1SceneA.ControllingClient); // crossing is async Thread.Sleep(500); Assert.IsNull(sceneA.GetSceneObjectGroup(so1Id)); Assert.NotNull(sceneB.GetSceneObjectGroup(so1Id)); }
// I'm commenting this test because it does not represent // crossings. The Thread.Sleep's in here are not meaningful mocks, // and they sometimes fail in panda. // We need to talk in order to develop a test // that really tests region crossings. There are 3 async components, // but things are synchronous among them. So there should be // 3 threads in here. //[Test] public void T021_TestCrossToNewRegion() { TestHelper.InMethod(); scene.RegisterRegionWithGrid(); scene2.RegisterRegionWithGrid(); // Adding child agent to region 1001 string reason; scene2.NewUserConnection(acd1, 0, out reason); scene2.AddNewClient(testclient); ScenePresence presence = scene.GetScenePresence(agent1); presence.MakeRootAgent(new Vector3(0, unchecked (Constants.RegionSize - 1), 0), true); ScenePresence presence2 = scene2.GetScenePresence(agent1); // Adding neighbour region caps info to presence2 string cap = presence.ControllingClient.RequestClientInfo().CapsPath; presence2.AddNeighbourRegion(region1, cap); Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); // Cross to x+1 presence.AbsolutePosition = new Vector3(Constants.RegionSize + 1, 3, 100); presence.Update(); EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset, "Crossing"); // Mimicking communication between client and server, by waiting OK from client // sent by TestClient.CrossRegion call. Originally, this is network comm. if (!wh.WaitOne(5000, false)) { presence.Update(); if (!wh.WaitOne(8000, false)) { throw new ArgumentException("1 - Timeout waiting for signal/variable."); } } // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which // would normally be fired after receiving the reply packet from comm. done on the last line. testclient.CompleteMovement(); // Crossings are asynchronous int timer = 10; // Make sure cross hasn't already finished if (!presence.IsInTransit && !presence.IsChildAgent) { // If not and not in transit yet, give it some more time Thread.Sleep(5000); } // Enough time, should at least be in transit by now. while (presence.IsInTransit && timer > 0) { Thread.Sleep(1000); timer -= 1; } Assert.That(timer, Is.GreaterThan(0), "Timed out waiting to cross 2->1."); Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); // Cross Back presence2.AbsolutePosition = new Vector3(-10, 3, 100); presence2.Update(); if (!wh.WaitOne(5000, false)) { presence2.Update(); if (!wh.WaitOne(8000, false)) { throw new ArgumentException("2 - Timeout waiting for signal/variable."); } } testclient.CompleteMovement(); if (!presence2.IsInTransit && !presence2.IsChildAgent) { // If not and not in transit yet, give it some more time Thread.Sleep(5000); } // Enough time, should at least be in transit by now. while (presence2.IsInTransit && timer > 0) { Thread.Sleep(1000); timer -= 1; } Assert.That(timer, Is.GreaterThan(0), "Timed out waiting to cross 1->2."); Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); }
private List <SensedEntity> doObjectSensor(SenseRepeatClass ts) { List <EntityBase> Entities; List <SensedEntity> sensedEntities = new List <SensedEntity>(); // If this is an object sense by key try to get it directly // rather than getting a list to scan through if (ts.keyID != UUID.Zero) { EntityBase e = null; m_CmdManager.m_ScriptEngine.World.Entities.TryGetValue(ts.keyID, out e); if (e == null) { return(sensedEntities); } Entities = new List <EntityBase>(); Entities.Add(e); } else { Entities = m_CmdManager.m_ScriptEngine.World.GetEntities(); } SceneObjectPart SensePoint = ts.host; Vector3 fromRegionPos = SensePoint.AbsolutePosition; // pre define some things to avoid repeated definitions in the loop body Vector3 toRegionPos; double dis; int objtype; SceneObjectPart part; float dx; float dy; float dz; Quaternion q = SensePoint.RotationOffset; if (SensePoint.ParentGroup.RootPart.IsAttachment) { // In attachments, the sensor cone always orients with the // avatar rotation. This may include a nonzero elevation if // in mouselook. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); q = avatar.Rotation; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); Vector3 ZeroVector = new Vector3(0, 0, 0); bool nameSearch = (ts.name != null && ts.name != ""); foreach (EntityBase ent in Entities) { bool keep = true; if (nameSearch && ent.Name != ts.name) // Wrong name and it is a named search { continue; } if (ent.IsDeleted) // taken so long to do this it has gone from the scene { continue; } if (!(ent is SceneObjectGroup)) // dont bother if it is a pesky avatar { continue; } toRegionPos = ent.AbsolutePosition; // Calculation is in line for speed dx = toRegionPos.X - fromRegionPos.X; dy = toRegionPos.Y - fromRegionPos.Y; dz = toRegionPos.Z - fromRegionPos.Z; // Weed out those that will not fit in a cube the size of the range // no point calculating if they are within a sphere the size of the range // if they arent even in the cube if (Math.Abs(dx) > ts.range || Math.Abs(dy) > ts.range || Math.Abs(dz) > ts.range) { dis = ts.range + 1.0; } else { dis = Math.Sqrt(dx * dx + dy * dy + dz * dz); } if (keep && dis <= ts.range && ts.host.UUID != ent.UUID) { // In Range and not the object containing the script, is it the right Type ? objtype = 0; part = ((SceneObjectGroup)ent).RootPart; if (part.AttachmentPoint != 0) // Attached so ignore { continue; } if (part.Inventory.ContainsScripts()) { objtype |= ACTIVE | SCRIPTED; // Scripted and active. It COULD have one hidden ... } else { if (ent.Velocity.Equals(ZeroVector)) { objtype |= PASSIVE; // Passive non-moving } else { objtype |= ACTIVE; // moving so active } } // If any of the objects attributes match any in the requested scan type if (((ts.type & objtype) != 0)) { // Right type too, what about the other params , key and name ? if (ts.arc < Math.PI) { // not omni-directional. Can you see it ? // vec forward_dir = llRot2Fwd(llGetRot()) // vec obj_dir = toRegionPos-fromRegionPos // dot=dot(forward_dir,obj_dir) // mag_fwd = mag(forward_dir) // mag_obj = mag(obj_dir) // ang = acos(dot /(mag_fwd*mag_obj)) double ang_obj = 0; try { Vector3 diff = toRegionPos - fromRegionPos; LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); double mag_obj = LSL_Types.Vector3.Mag(obj_dir); ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); } catch { } if (ang_obj > ts.arc) { keep = false; } } if (keep == true) { // add distance for sorting purposes later sensedEntities.Add(new SensedEntity(dis, ent.UUID)); } } } } return(sensedEntities); }
private void SendScriptErrorMessage(Exception e, ScriptEventCode ev) { StringBuilder msg = new StringBuilder(); bool toowner = false; msg.Append("YEngine: "); if (e.Message != null) { string text = e.Message; if (text.StartsWith("(OWNER)")) { text = text.Substring(7); toowner = true; } msg.Append(text); } msg.Append(" (script: "); msg.Append(m_Item.Name); msg.Append(" event: "); msg.Append(ev.ToString()); msg.Append(" primID: "); msg.Append(m_Part.UUID.ToString()); msg.Append(" at: <"); Vector3 pos = m_Part.AbsolutePosition; msg.Append((int)Math.Floor(pos.X)); msg.Append(','); msg.Append((int)Math.Floor(pos.Y)); msg.Append(','); msg.Append((int)Math.Floor(pos.Z)); msg.Append(">) Script must be Reset to re-enable.\n"); string msgst = msg.ToString(); if (msgst.Length > 1000) { msgst = msgst.Substring(0, 1000); } if (toowner) { ScenePresence sp = m_Engine.World.GetScenePresence(m_Part.OwnerID); if (sp != null && !sp.IsNPC) { m_Engine.World.SimChatToAgent(m_Part.OwnerID, Utils.StringToBytes(msgst), 0x7FFFFFFF, m_Part.AbsolutePosition, m_Part.Name, m_Part.UUID, false); } } else { m_Engine.World.SimChat(Utils.StringToBytes(msgst), ChatTypeEnum.DebugChannel, 0x7FFFFFFF, m_Part.AbsolutePosition, m_Part.Name, m_Part.UUID, false); } m_log.Debug(string.Format( "[SCRIPT ERROR]: {0} (at event {1}, part {2} {3} at {4} in {5}", (e.Message == null)? "" : e.Message, ev.ToString(), m_Part.Name, m_Part.UUID, m_Part.AbsolutePosition, m_Part.ParentGroup.Scene.Name)); m_SleepUntil = DateTime.MaxValue; }
// This handler detects chat events int he virtual world. public void OnSimChat(Object sender, OSChatMessage msg) { // early return if this comes from the IRC forwarder if (cs.irc.Equals(sender)) { return; } // early return if nothing to forward if (msg.Message.Length == 0) { return; } // check for commands coming from avatars or in-world // object (if commands are enabled) if (cs.CommandsEnabled && msg.Channel == cs.CommandChannel) { m_log.DebugFormat("[IRC-Region {0}] command on channel {1}: {2}", Region, msg.Channel, msg.Message); string[] messages = msg.Message.Split(' '); string command = messages[0].ToLower(); try { switch (command) { // These commands potentially require a change in the // underlying ChannelState. case "server": cs.Close(this); cs = cs.UpdateServer(this, messages[1]); cs.Open(this); break; case "port": cs.Close(this); cs = cs.UpdatePort(this, messages[1]); cs.Open(this); break; case "channel": cs.Close(this); cs = cs.UpdateChannel(this, messages[1]); cs.Open(this); break; case "nick": cs.Close(this); cs = cs.UpdateNickname(this, messages[1]); cs.Open(this); break; // These may also (but are less likely) to require a // change in ChannelState. case "client-reporting": cs = cs.UpdateClientReporting(this, messages[1]); break; case "in-channel": cs = cs.UpdateRelayIn(this, messages[1]); break; case "out-channel": cs = cs.UpdateRelayOut(this, messages[1]); break; // These are all taken to be temporary changes in state // so the underlying connector remains intact. But note // that with regions sharing a connector, there could // be interference. case "close": enabled = false; cs.Close(this); break; case "connect": enabled = true; cs.Open(this); break; case "reconnect": enabled = true; cs.Close(this); cs.Open(this); break; // This one is harmless as far as we can judge from here. // If it is not, then the complaints will eventually make // that evident. default: m_log.DebugFormat("[IRC-Region {0}] Forwarding unrecognized command to IRC : {1}", Region, msg.Message); cs.irc.Send(msg.Message); break; } } catch (Exception ex) { m_log.WarnFormat("[IRC-Region {0}] error processing in-world command channel input: {1}", Region, ex.Message); m_log.Debug(ex); } return; } // The command channel remains enabled, even if we have otherwise disabled the IRC // interface. if (!enabled) { return; } // drop messages unless they are on a valid in-world // channel as configured in the ChannelState if (!cs.ValidInWorldChannels.Contains(msg.Channel)) { m_log.DebugFormat("[IRC-Region {0}] dropping message {1} on channel {2}", Region, msg, msg.Channel); return; } ScenePresence avatar = null; string fromName = msg.From; if (msg.Sender != null) { avatar = scene.GetScenePresence(msg.Sender.AgentId); if (avatar != null) { fromName = avatar.Name; } } if (!cs.irc.Connected) { m_log.WarnFormat("[IRC-Region {0}] IRCConnector not connected: dropping message from {1}", Region, fromName); return; } m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL)) { string txt = msg.Message; if (txt.StartsWith("/me ")) { txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4)); } cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt); return; } if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword && msg.Channel == cs.RelayChannelOut) { Match m = cs.AccessPasswordRegex.Match(msg.Message); if (null != m) { m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), m.Groups["message"].ToString()); cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(), scene.RegionInfo.RegionName, m.Groups["message"].ToString()); } } }
/// <summary> /// Does the actual movement of the bot /// </summary> /// <param name="pos"></param> protected void walkTo(ScenePresence presence, Vector3 pos) { Vector3 bot_forward = new Vector3(2, 0, 0); Vector3 bot_toward = Vector3.Zero; Vector3 dif = pos - presence.AbsolutePosition; bool isJumping = (Math.Abs(dif.X) < 2 && Math.Abs(dif.Y) < 2 && Math.Abs(dif.Z) > 1.5f) || _amountOfTimesLeftToJump > 0; if (dif != Vector3.Zero) { try { bot_toward = Util.GetNormalizedVector(dif); Quaternion rot_result = llRotBetween(bot_forward, bot_toward); m_bodyDirection = rot_result; } catch (ArgumentException) { } } //if the bot is being forced to turn around 180 degrees, it won't be able to and it will get stuck // and eventually teleport (mantis 2898). This detects when the vector is too close to zero and // needs to have help being turned around so that it can then go in the correct direction if (m_bodyDirection.ApproxEquals(new Quaternion(), 0.01f)) { //Turn to the right until we move far enough away from zero that we will turn around on our own bot_toward = new Vector3(0, 1, 0); Quaternion rot_result = llRotBetween(bot_forward, bot_toward); m_bodyDirection = rot_result; } if (isJumping) { //Add UP_POS as well (meaning that we need to be able to move freely up as well as along the ground) m_movementFlag = (uint)(AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); presence.ShouldJump = true; if (_amountOfTimesLeftToJump == 0) { _amountOfTimesLeftToJump = 10;//Because we need the bot to apply force over multiple frames (just like agents do) } _amountOfTimesLeftToJump--; //Make sure that we aren't jumping too far (apply a constant to make sure of this) const double JUMP_CONST = 0.3; bot_toward = Util.GetNormalizedVector(dif); if (Math.Abs(bot_toward.X) < JUMP_CONST) { bot_toward.X = (float)JUMP_CONST * (bot_toward.X < 0 ? -1 : 1); } if (Math.Abs(bot_toward.Y) < JUMP_CONST) { bot_toward.Y = (float)JUMP_CONST * (bot_toward.Y < 0 ? -1 : 1); } if (presence.PhysicsActor.IsColliding)//After they leave the ground, don't use as much force so we don't send the bot flying into the air { bot_forward = new Vector3(4, 0, 4); } else { bot_forward = new Vector3(2, 0, 2); } Quaternion rot_result = llRotBetween(bot_forward, bot_toward); m_bodyDirection = rot_result; } else { m_movementFlag = (uint)(AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); } if (presence.AllowMovement) { OnBotAgentUpdate(presence, bot_toward, m_movementFlag, m_bodyDirection); } else { OnBotAgentUpdate(presence, Vector3.Zero, (uint)AgentManager.ControlFlags.AGENT_CONTROL_STOP, Quaternion.Identity); } if (!isJumping) { m_movementFlag = (uint)AgentManager.ControlFlags.NONE; } }
public void OnBotAgentUpdate(ScenePresence presence, Vector3 toward, uint controlFlag, Quaternion bodyRotation) { OnBotAgentUpdate(presence, toward, controlFlag, bodyRotation, true); }
private void RegisterNewPresence(ScenePresence presence) { presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings; }
private void GetExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID) { int parcelid = -1; if (httpRequest.Query.Count > 0) { if (httpRequest.Query.ContainsKey("parcelid")) { Int32.TryParse((string)httpRequest.Query["parcelid"], out parcelid); } } ViewerEnvironment VEnv = null; ScenePresence sp = m_scene.GetScenePresence(agentID); if (sp != null && sp.Environment != null) { if (parcelid == -1) { VEnv = sp.Environment; } else { OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcelid); httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def); httpResponse.StatusCode = (int)HttpStatusCode.OK; return; } } else if (parcelid == -1) { VEnv = GetRegionEnvironment(); } else { if (m_scene.RegionInfo.EstateSettings.AllowEnvironmentOverride) { ILandObject land = m_scene.LandChannel.GetLandObject(parcelid); if (land != null && land.LandData != null && land.LandData.Environment != null) { VEnv = land.LandData.Environment; } } if (VEnv == null) { OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcelid); httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def); httpResponse.StatusCode = (int)HttpStatusCode.OK; return; } } OSDMap map = new OSDMap(); OSDMap cenv = (OSDMap)VEnv.ToOSD(); cenv["parcel_id"] = parcelid; cenv["region_id"] = regionID; map["environment"] = cenv; map["parcel_id"] = parcelid; map["success"] = true; string env = OSDParser.SerializeLLSDXmlString(map); if (String.IsNullOrEmpty(env)) { StringBuilder sb = LLSDxmlEncode.Start(); LLSDxmlEncode.AddArray(sb); LLSDxmlEncode.AddMap(sb); LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb); LLSDxmlEncode.AddElem("regionID", regionID, sb); LLSDxmlEncode.AddEndMap(sb); LLSDxmlEncode.AddEndArray(sb); env = LLSDxmlEncode.End(sb); } httpResponse.RawBuffer = Util.UTF8NBGetbytes(env); httpResponse.StatusCode = (int)HttpStatusCode.OK; }
protected void OnInstantMessage(IClientAPI client, GridInstantMessage im) { m_log.InfoFormat("[WATER WARS]: GameManagerTopLevelInteraction.OnInstantMessage received"); if (im.dialog == (byte)InstantMessageDialog.InventoryAccepted && client.AgentId == m_playerId) { m_log.InfoFormat("[WATER WARS]: Now we get to do something cool! IMSessionId [{0}]", im.imSessionID); UUID itemId = new UUID(im.imSessionID); Scene scene = client.Scene as Scene; // This really need to be a 'has inventory item' method in Scene.Inventory.cs InventoryItemBase item = new InventoryItemBase(itemId, m_playerId); item = scene.InventoryService.GetItem(item); if (item == null) { m_log.Error("[WATER WARS]: Failed to find item " + itemId); return; } else if (item.Name != HUD_ITEM_NAME) { m_log.InfoFormat( "[WATER WARS]: Ignoring hud item {0} since it's not a {1}", item.Name, HUD_ITEM_NAME); return; } uint attachmentPoint = (uint)AttachmentPoint.HUDTop; ScenePresence sp = scene.GetScenePresence(client.AgentId); List <SceneObjectGroup> existingAttachments = sp.GetAttachments(attachmentPoint); if (existingAttachments.Count == 0) { IAttachmentsModule module = client.Scene.RequestModuleInterface <IAttachmentsModule>(); SceneObjectGroup sog = (SceneObjectGroup)module.RezSingleAttachmentFromInventory( sp, new UUID(im.imSessionID), (uint)AttachmentPoint.HUDTop); // A tempoary messy solution to an occasional race where the attached hud sometimes ends up positioned // on the avatar itself and does not show up as attached within inventory. Thread.Sleep(1000); Vector3 newPos = new Vector3(0, 0, -0.1f); m_log.InfoFormat("[WATER WARS]: Resetting HUD position to {0}", newPos); module.UpdateAttachmentPosition(sog, newPos); /* * sog.UpdateGroupPosition(newPos); * sog.HasGroupChanged = true; * sog.ScheduleGroupForTerseUpdate(); */ } else { m_log.InfoFormat( "[WATER WARS]: Not attaching given hud for {0} since something is already attached at {1}", client.Name, attachmentPoint); } client.OnInstantMessage -= OnInstantMessage; } }
private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { int maxCacheitemsLoop = cacheItems.Length; if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES) { maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); } m_BakedTextureModule = m_scene.RequestModuleInterface <IBakedTextureModule>(); if (cacheItems.Length > 0) { m_log.Debug("[Cacheitems]: " + cacheItems.Length); for (int iter = 0; iter < maxCacheitemsLoop; iter++) { m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + cacheItems[iter].TextureID); } ScenePresence p = null; if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) { WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; if (existingitems == null) { if (m_BakedTextureModule != null) { WearableCacheItem[] savedcache = null; try { if (p.Appearance.WearableCacheItemsDirty) { savedcache = m_BakedTextureModule.Get(p.UUID); p.Appearance.WearableCacheItems = savedcache; p.Appearance.WearableCacheItemsDirty = false; } } /* * The following Catch types DO NOT WORK with m_BakedTextureModule.Get * it jumps to the General Packet Exception Handler if you don't catch Exception! * * catch (System.Net.Sockets.SocketException) * { * cacheItems = null; * } * catch (WebException) * { * cacheItems = null; * } * catch (InvalidOperationException) * { * cacheItems = null; * } */ catch (Exception) { // The service logs a sufficient error message. } if (savedcache != null) { existingitems = savedcache; } } } // Existing items null means it's a fully new appearance if (existingitems == null) { for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; if (face == null) { textureEntry.CreateFace(cacheItems[i].TextureIndex); textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; continue; } cacheItems[i].TextureID = face.TextureID; if (m_scene.AssetService != null) { cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); } } else { m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } } } else { // for each uploaded baked texture for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) { Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; if (face == null) { textureEntry.CreateFace(cacheItems[i].TextureIndex); textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; continue; } cacheItems[i].TextureID = face.TextureID; } else { m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } } for (int i = 0; i < maxCacheitemsLoop; i++) { if (cacheItems[i].TextureAsset == null) { cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); } } } p.Appearance.WearableCacheItems = cacheItems; if (m_BakedTextureModule != null) { m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); p.Appearance.WearableCacheItemsDirty = true; } } } }
/// <summary> /// Try to get a scene presence from the scene /// </summary> /// <param name="agentID"></param> /// <param name="scenePresence">null if there is no scene presence with the given agent id</param> /// <returns>true if there was a scene presence with the given id, false otherwise.</returns> public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence);
internal ScenePresenceStateMachine(ScenePresence sp) { m_sp = sp; m_state = ScenePresenceState.Running; }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { // m_log.DebugFormat( // "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}", // (InstantMessageDialog)im.dialog, client.Name, // im.fromAgentID, im.fromAgentName, im.toAgentID); Scene scene = FindClientScene(client.AgentId); if (scene == null) // Something seriously wrong here. { return; } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { //m_log.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0])); if (im.binaryBucket.Length < 17) // Invalid { return; } UUID receipientID = new UUID(im.toAgentID); ScenePresence user = scene.GetScenePresence(receipientID); UUID copyID; // First byte is the asset type AssetType assetType = (AssetType)im.binaryBucket[0]; if (AssetType.Folder == assetType) { UUID folderID = new UUID(im.binaryBucket, 1); m_log.DebugFormat( "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory", folderID, new UUID(im.toAgentID)); InventoryFolderBase folderCopy = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); if (folderCopy == null) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } // The outgoing binary bucket should contain only the byte which signals an asset folder is // being copied and the following bytes for the copied folder's UUID copyID = folderCopy.ID; byte[] copyIDBytes = copyID.GetBytes(); im.binaryBucket = new byte[1 + copyIDBytes.Length]; im.binaryBucket[0] = (byte)AssetType.Folder; Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(folderCopy); } // HACK!! // Insert the ID of the copied folder into the IM so that we know which item to move to trash if it // is rejected. // XXX: This is probably a misuse of the session ID slot. im.imSessionID = copyID.Guid; } else { // First byte of the array is probably the item type // Next 16 bytes are the UUID UUID itemID = new UUID(im.binaryBucket, 1); m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} " + "into agent {1}'s inventory", itemID, new UUID(im.toAgentID)); InventoryItemBase itemCopy = scene.GiveInventoryItem( new UUID(im.toAgentID), client.AgentId, itemID); if (itemCopy == null) { client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); return; } copyID = itemCopy.ID; Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(itemCopy); } // HACK!! // Insert the ID of the copied item into the IM so that we know which item to move to trash if it // is rejected. // XXX: This is probably a misuse of the session ID slot. im.imSessionID = copyID.Guid; } // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. // if (user != null) { user.ControllingClient.SendInstantMessage(im); return; } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { if (!success) { client.SendAlertMessage("User not online. Inventory has been saved"); } }); } } } else if (im.dialog == (byte)InstantMessageDialog.InventoryAccepted) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011 // and is apparently supposed to fix bulk inventory updates after accepting items. But // instead it appears to cause two copies of an accepted folder for the receiving user in // at least some cases. Folder/item update is already done when the offer is made (see code above) // // Send BulkUpdateInventory // IInventoryService invService = scene.InventoryService; // UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip // // InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId); // folder = invService.GetFolder(folder); // // ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID)); // // // If the user has left the scene by the time the message comes back then we can't send // // them the update. // if (fromUser != null) // fromUser.ControllingClient.SendBulkUpdateInventory(folder); }); } } } // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~<name> // to the requested folder, which in this case is #RLV. However, it is the viewer that appears to be // response from renaming the #RLV/~example folder to ~example. For some reason this is not yet // happening, possibly because we are not sending the correct inventory update messages with the correct // transaction IDs else if (im.dialog == (byte)InstantMessageDialog.TaskInventoryAccepted) { UUID destinationFolderID = UUID.Zero; if (im.binaryBucket != null && im.binaryBucket.Length >= 16) { destinationFolderID = new UUID(im.binaryBucket, 0); } if (destinationFolderID != UUID.Zero) { InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); if (destinationFolder == null) { m_log.WarnFormat( "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", client.Name, scene.Name, destinationFolderID); return; } IInventoryService invService = scene.InventoryService; UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; UUID?previousParentFolderID = null; if (item != null) // It's an item { previousParentFolderID = item.Folder; item.Folder = destinationFolderID; invService.DeleteItems(item.Owner, new List <UUID>() { item.ID }); scene.AddInventoryItem(client, item); } else { folder = new InventoryFolderBase(inventoryID, client.AgentId); folder = invService.GetFolder(folder); if (folder != null) // It's a folder { previousParentFolderID = folder.ParentID; folder.ParentID = destinationFolderID; invService.MoveFolder(folder); } } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). if (previousParentFolderID != null) { InventoryFolderBase previousParentFolder = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); previousParentFolder = invService.GetFolder(previousParentFolder); scene.SendInventoryUpdate(client, previousParentFolder, true, true); scene.SendInventoryUpdate(client, destinationFolder, true, true); } } } else if ( im.dialog == (byte)InstantMessageDialog.InventoryDeclined || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) { // Here, the recipient is local and we can assume that the // inventory is loaded. Courtesy of the above bulk update, // It will have been pushed to the client, too // IInventoryService invService = scene.InventoryService; InventoryFolderBase trashFolder = invService.GetFolderForType(client.AgentId, AssetType.TrashFolder); UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; UUID?previousParentFolderID = null; if (item != null && trashFolder != null) { previousParentFolderID = item.Folder; item.Folder = trashFolder.ID; // Diva comment: can't we just update this item??? List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); invService.DeleteItems(item.Owner, uuids); scene.AddInventoryItem(client, item); } else { folder = new InventoryFolderBase(inventoryID, client.AgentId); folder = invService.GetFolder(folder); if (folder != null & trashFolder != null) { previousParentFolderID = folder.ParentID; folder.ParentID = trashFolder.ID; invService.MoveFolder(folder); } } if ((null == item && null == folder) | null == trashFolder) { string reason = String.Empty; if (trashFolder == null) { reason += " Trash folder not found."; } if (item == null) { reason += " Item not found."; } if (folder == null) { reason += " Folder not found."; } client.SendAgentAlertMessage("Unable to delete " + "received inventory" + reason, false); } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). else if (previousParentFolderID != null) { InventoryFolderBase previousParentFolder = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); previousParentFolder = invService.GetFolder(previousParentFolder); scene.SendInventoryUpdate(client, previousParentFolder, true, true); scene.SendInventoryUpdate(client, trashFolder, true, true); } if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); } } } } }
public override bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence) { throw new NotImplementedException(); }
private void SetExtEnvironmentSettings(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID agentID, Caps caps) { bool success = false; string message = "Could not process request"; int parcel = -1; int track = -1; StringBuilder sb = LLSDxmlEncode.Start(); ScenePresence sp = m_scene.GetScenePresence(agentID); if (sp == null || sp.IsChildAgent || sp.IsNPC) { message = "Could not locate your avatar"; goto Error; } if (httpRequest.Query.Count > 0) { if (httpRequest.Query.ContainsKey("parcelid")) { if (!Int32.TryParse((string)httpRequest.Query["parcelid"], out parcel)) { message = "Failed to decode request"; goto Error; } } if (httpRequest.Query.ContainsKey("trackno")) { if (!Int32.TryParse((string)httpRequest.Query["trackno"], out track)) { message = "Failed to decode request"; goto Error; } } if (track != -1) { message = "Environment Track not supported"; goto Error; } } ViewerEnvironment VEnv = m_scene.RegionEnvironment; ILandObject lchannel; if (parcel == -1) { if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false)) { message = "Insufficient estate permissions, settings has not been saved."; goto Error; } VEnv = m_scene.RegionEnvironment; lchannel = null; } else { lchannel = m_landChannel.GetLandObject(parcel); if (lchannel == null || lchannel.LandData == null) { message = "Could not locate requested parcel"; goto Error; } if (!m_scene.Permissions.CanEditParcelProperties(agentID, lchannel, GroupPowers.AllowEnvironment, true)) // wrong { message = "No permission to change parcel environment"; goto Error; } VEnv = lchannel.LandData.Environment; } try { OSD req = OSDParser.Deserialize(httpRequest.InputStream); if (req is OSDMap) { OSDMap map = req as OSDMap; if (map.TryGetValue("environment", out OSD env)) { if (VEnv == null) { // need a proper clone VEnv = m_DefaultEnv.Clone(); } OSDMap evmap = env as OSDMap; if (evmap.TryGetValue("day_asset", out OSD tmp) && !evmap.ContainsKey("day_cycle")) { string id = tmp.AsString(); AssetBase asset = m_assetService.Get(id); if (asset == null || asset.Data == null || asset.Data.Length == 0) { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; return; } try { OSD oenv = OSDParser.Deserialize(asset.Data); evmap.TryGetValue("day_name", out tmp); if (tmp is OSDString) { VEnv.FromAssetOSD(tmp.AsString(), oenv); } else { VEnv.FromAssetOSD(null, oenv); } } catch { httpResponse.StatusCode = (int)HttpStatusCode.NotFound; return; } } else { VEnv.FromOSD(env); } if (lchannel == null) { StoreOnRegion(VEnv); m_log.InfoFormat("[{0}]: ExtEnvironment region {1} settings from agentID {2} saved", Name, caps.RegionName, agentID); } else { lchannel.StoreEnvironment(VEnv); m_log.InfoFormat("[{0}]: ExtEnvironment parcel {1} of region {2} settings from agentID {3} saved", Name, parcel, caps.RegionName, agentID); } WindlightRefresh(0, lchannel == null); success = true; } } else if (req is OSDArray) { VEnv = new ViewerEnvironment(); VEnv.FromWLOSD(req); StoreOnRegion(VEnv); success = true; WindlightRefresh(0); m_log.InfoFormat("[{0}]: ExtEnvironment region {1} settings from agentID {2} saved", Name, caps.RegionName, agentID); LLSDxmlEncode.AddMap(sb); LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb); LLSDxmlEncode.AddElem("regionID", regionID, sb); LLSDxmlEncode.AddElem("success", success, sb); LLSDxmlEncode.AddEndMap(sb); httpResponse.RawBuffer = Util.UTF8NBGetbytes(LLSDxmlEncode.End(sb)); httpResponse.StatusCode = (int)HttpStatusCode.OK; return; } } catch (Exception e) { m_log.ErrorFormat("[{0}]: ExtEnvironment settings not saved for region {1}, Exception: {2} - {3}", Name, caps.RegionName, e.Message, e.StackTrace); success = false; message = String.Format("ExtEnvironment Set for region {0} has failed, settings not saved.", caps.RegionName); } Error: string response; LLSDxmlEncode.AddMap(sb); LLSDxmlEncode.AddElem("success", success, sb); if (!success) { LLSDxmlEncode.AddElem("message", message, sb); } LLSDxmlEncode.AddEndMap(sb); response = LLSDxmlEncode.End(sb); httpResponse.RawBuffer = Util.UTF8NBGetbytes(response); httpResponse.StatusCode = (int)HttpStatusCode.OK; }
public void Populate(Scene scene) { SceneObjectPart part = scene.GetSceneObjectPart(Key); if (part == null) // Avatar, maybe? { ScenePresence presence = scene.GetScenePresence(Key); if (presence == null) { return; } Name = presence.Firstname + " " + presence.Lastname; Owner = Key; Position = new LSL_Types.Vector3( presence.AbsolutePosition.X, presence.AbsolutePosition.Y, presence.AbsolutePosition.Z); Rotation = new LSL_Types.Quaternion( presence.Rotation.X, presence.Rotation.Y, presence.Rotation.Z, presence.Rotation.W); Velocity = new LSL_Types.Vector3( presence.Velocity.X, presence.Velocity.Y, presence.Velocity.Z); Type = 0x01; // Avatar if (presence.Velocity != Vector3.Zero) { Type |= 0x02; // Active } Group = presence.ControllingClient.ActiveGroupId; return; } part = part.ParentGroup.RootPart; // We detect objects only LinkNum = 0; // Not relevant Group = part.GroupID; Name = part.Name; Owner = part.OwnerID; if (part.Velocity == Vector3.Zero) { Type = 0x04; // Passive } else { Type = 0x02; // Passive } foreach (SceneObjectPart p in part.ParentGroup.Children.Values) { if (p.Inventory.ContainsScripts()) { Type |= 0x08; // Scripted break; } } Position = new LSL_Types.Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); Quaternion wr = part.ParentGroup.GroupRotation; Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); Velocity = new LSL_Types.Vector3(part.Velocity.X, part.Velocity.Y, part.Velocity.Z); }
private void SetEnvironmentSettings(IOSHttpRequest request, IOSHttpResponse response, UUID agentID) { // m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}", // Name, agentID, caps.RegionName); bool success = false; string fail_reason = ""; if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false)) { fail_reason = "Insufficient estate permissions, settings has not been saved."; goto Error; } ScenePresence sp = m_scene.GetScenePresence(agentID); if (sp == null || sp.IsChildAgent || sp.IsNPC) { response.StatusCode = (int)HttpStatusCode.NotFound; return; } if (sp.Environment != null) { fail_reason = "The environment you see is a forced one. Disable if on control object or tp out and back to region"; goto Error; } ILandObject land = m_scene.LandChannel.GetLandObject(sp.AbsolutePosition.X, sp.AbsolutePosition.Y); if (land != null && land.LandData != null && land.LandData.Environment != null) { fail_reason = "The parcel where you are has own environment set. You need a updated viewer to change environment"; goto Error; } try { ViewerEnvironment VEnv = new ViewerEnvironment(); OSD env = OSDParser.Deserialize(request.InputStream); VEnv.FromWLOSD(env); StoreOnRegion(VEnv); WindlightRefresh(0); m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}", Name, agentID, m_scene.Name); success = true; } catch (Exception e) { m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}", Name, m_scene.Name, e.Message, e.StackTrace); success = false; fail_reason = String.Format("Environment Set for region {0} has failed, settings not saved.", m_scene.Name); } Error: StringBuilder sb = LLSDxmlEncode.Start(); LLSDxmlEncode.AddMap(sb); LLSDxmlEncode.AddElem("messageID", UUID.Zero, sb); LLSDxmlEncode.AddElem("regionID", regionID, sb); LLSDxmlEncode.AddElem("success", success, sb); if (!success) { LLSDxmlEncode.AddElem("fail_reason", fail_reason, sb); } LLSDxmlEncode.AddEndMap(sb); response.RawBuffer = Util.UTF8NBGetbytes(LLSDxmlEncode.End(sb)); response.StatusCode = (int)HttpStatusCode.OK; }
/// <summary> /// Does the actual movement of the bot /// </summary> /// <param name="pos"></param> protected void flyTo(ScenePresence presence, Vector3 pos) { Vector3 bot_forward = new Vector3(1, 0, 0), bot_toward = Vector3.Zero; if (pos - presence.AbsolutePosition != Vector3.Zero) { try { bot_toward = Util.GetNormalizedVector(pos - presence.AbsolutePosition); Quaternion rot_result = llRotBetween(bot_forward, bot_toward); m_bodyDirection = rot_result; } catch (ArgumentException) { } } //if the bot is being forced to turn around 180 degrees, it won't be able to and it will get stuck // and eventually teleport (mantis 2898). This detects when the vector is too close to zero and // needs to have help being turned around so that it can then go in the correct direction if (m_bodyDirection.ApproxEquals(new Quaternion(), 0.01f)) { //Turn to the right until we move far enough away from zero that we will turn around on our own bot_toward = new Vector3(0, 1, 0); Quaternion rot_result = llRotBetween(bot_forward, bot_toward); m_bodyDirection = rot_result; } m_movementFlag = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; Vector3 diffPos = pos - presence.AbsolutePosition; if (Math.Abs(diffPos.X) > 1.5 || Math.Abs(diffPos.Y) > 1.5) { m_movementFlag |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; } if (presence.AbsolutePosition.Z < pos.Z - 1) { m_movementFlag |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; } else if (presence.AbsolutePosition.Z > pos.Z + 1) { m_movementFlag |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG; } if (bot_forward.X > 0) { m_movementFlag |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; m_movementFlag |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS; } if (bot_forward.X < 0) { m_movementFlag |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; m_movementFlag |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG; } if (presence.AllowMovement) { OnBotAgentUpdate(presence, bot_toward, m_movementFlag, m_bodyDirection); } m_movementFlag = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; }
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 = part.AbsolutePosition; cAgent.SatOnPrim = part.UUID; cAgent.SatOnPrimOffset = part.SitTargetPosition; } else { cAgent.Position = pos; } if (sceneObjectGroup != null) { cAgent.SatOnGroup = sceneObjectGroup.UUID; } 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); }
public void TestAcceptGivenItem() { // TestHelpers.EnableLogging(); UUID initialSessionId = TestHelpers.ParseTail(0x10); UUID itemId = TestHelpers.ParseTail(0x100); UUID assetId = TestHelpers.ParseTail(0x200); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); TestClient giverClient = (TestClient)giverSp.ControllingClient; ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); TestClient receiverClient = (TestClient)receiverSp.ControllingClient; // Create the object to test give InventoryItemBase originalItem = UserInventoryHelpers.CreateInventoryItem( m_scene, "givenObj", itemId, assetId, giverSp.UUID, InventoryType.Object); byte[] giveImBinaryBucket = new byte[17]; byte[] itemIdBytes = itemId.GetBytes(); Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); GridInstantMessage giveIm = new GridInstantMessage( m_scene, giverSp.UUID, giverSp.Name, receiverSp.UUID, (byte)InstantMessageDialog.InventoryOffered, false, "inventory offered msg", initialSessionId, false, Vector3.Zero, giveImBinaryBucket, true); giverClient.HandleImprovedInstantMessage(giveIm); // These details might not all be correct. GridInstantMessage acceptIm = new GridInstantMessage( m_scene, receiverSp.UUID, receiverSp.Name, giverSp.UUID, (byte)InstantMessageDialog.InventoryAccepted, false, "inventory accepted msg", initialSessionId, false, Vector3.Zero, null, true); receiverClient.HandleImprovedInstantMessage(acceptIm); // Test for item remaining in the giver's inventory (here we assume a copy item) // TODO: Test no-copy items. InventoryItemBase originalItemAfterGive = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); Assert.That(originalItemAfterGive, Is.Not.Null); Assert.That(originalItemAfterGive.ID, Is.EqualTo(originalItem.ID)); // Test for item successfully making it into the receiver's inventory InventoryItemBase receivedItem = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, receiverSp.UUID, "Objects/givenObj"); Assert.That(receivedItem, Is.Not.Null); Assert.That(receivedItem.ID, Is.Not.EqualTo(originalItem.ID)); // Test that on a delete, item still exists and is accessible for the giver. m_scene.InventoryService.DeleteItems(receiverSp.UUID, new List <UUID>() { receivedItem.ID }); InventoryItemBase originalItemAfterDelete = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); Assert.That(originalItemAfterDelete, Is.Not.Null); // TODO: Test scenario where giver deletes their item first. }
internal void UpdateThrottle(int pimagethrottle, ScenePresence p) { m_throttler.UpdateThrottle(pimagethrottle, p); }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { m_log.InfoFormat( "[INVENTORY TRANSFER]: {0} IM type received from {1}", (InstantMessageDialog)im.dialog, client.Name); Scene scene = FindClientScene(client.AgentId); if (scene == null) // Something seriously wrong here. { return; } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { //m_log.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0])); if (im.binaryBucket.Length < 17) // Invalid { return; } UUID receipientID = new UUID(im.toAgentID); ScenePresence user = scene.GetScenePresence(receipientID); UUID copyID; // First byte is the asset type AssetType assetType = (AssetType)im.binaryBucket[0]; if (AssetType.Folder == assetType) { UUID folderID = new UUID(im.binaryBucket, 1); m_log.DebugFormat("[INVENTORY TRANSFER]: Inserting original folder {0} " + "into agent {1}'s inventory", folderID, new UUID(im.toAgentID)); InventoryFolderBase folderCopy = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); if (folderCopy == null) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } // The outgoing binary bucket should contain only the byte which signals an asset folder is // being copied and the following bytes for the copied folder's UUID copyID = folderCopy.ID; byte[] copyIDBytes = copyID.GetBytes(); im.binaryBucket = new byte[1 + copyIDBytes.Length]; im.binaryBucket[0] = (byte)AssetType.Folder; Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(folderCopy); } // HACK!! im.imSessionID = folderID.Guid; } else { // First byte of the array is probably the item type // Next 16 bytes are the UUID UUID itemID = new UUID(im.binaryBucket, 1); m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} " + "into agent {1}'s inventory", itemID, new UUID(im.toAgentID)); InventoryItemBase itemCopy = scene.GiveInventoryItem( new UUID(im.toAgentID), client.AgentId, itemID); if (itemCopy == null) { client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); return; } copyID = itemCopy.ID; Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(itemCopy); } // HACK!! im.imSessionID = itemID.Guid; } // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. // if (user != null) { user.ControllingClient.SendInstantMessage(im); return; } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { if (!success) { client.SendAlertMessage("User not online. Inventory has been saved"); } }); } } } else if (im.dialog == (byte)InstantMessageDialog.InventoryAccepted) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); } } } else if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) { // Here, the recipient is local and we can assume that the // inventory is loaded. Courtesy of the above bulk update, // It will have been pushed to the client, too // IInventoryService invService = scene.InventoryService; InventoryFolderBase trashFolder = invService.GetFolderForType(client.AgentId, AssetType.TrashFolder); UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; if (item != null && trashFolder != null) { item.Folder = trashFolder.ID; // Diva comment: can't we just update this item??? List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); invService.DeleteItems(item.Owner, uuids); scene.AddInventoryItem(client, item); } else { folder = new InventoryFolderBase(inventoryID, client.AgentId); folder = invService.GetFolder(folder); if (folder != null & trashFolder != null) { folder.ParentID = trashFolder.ID; invService.MoveFolder(folder); } } if ((null == item && null == folder) | null == trashFolder) { string reason = String.Empty; if (trashFolder == null) { reason += " Trash folder not found."; } if (item == null) { reason += " Item not found."; } if (folder == null) { reason += " Folder not found."; } client.SendAgentAlertMessage("Unable to delete " + "received inventory" + reason, false); } ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); } } } }
private void AlterThrottle(int setting, ScenePresence p) { p.ControllingClient.SetAgentThrottleSilent((int)Throttle, setting); }
public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource) { if (script.StartsWith("//MRM:")) { return; } List <IScriptModule> engines = new List <IScriptModule>( myScriptEngine.World.RequestModuleInterfaces <IScriptModule>()); List <string> names = new List <string>(); foreach (IScriptModule m in engines) { names.Add(m.ScriptEngineName); } int lineEnd = script.IndexOf('\n'); if (lineEnd > 1) { string firstline = script.Substring(0, lineEnd).Trim(); int colon = firstline.IndexOf(':'); if (firstline.Length > 2 && firstline.Substring(0, 2) == "//" && colon != -1) { string engineName = firstline.Substring(2, colon - 2); if (names.Contains(engineName)) { engine = engineName; script = "//" + script.Substring(script.IndexOf(':') + 1); } else { if (engine == myScriptEngine.ScriptEngineName) { SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart( localID); TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); ScenePresence presence = myScriptEngine.World.GetScenePresence( item.OwnerID); if (presence != null) { presence.ControllingClient.SendAgentAlertMessage( "Selected engine unavailable. " + "Running script on " + myScriptEngine.ScriptEngineName, false); } } } } } if (engine != myScriptEngine.ScriptEngineName) { return; } m_log.Debug("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + script.Length); myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script, startParam, postOnRez); }
internal void UpdateThrottle(int pimagethrottle, ScenePresence p) { // Client set throttle ! CapSetThrottle = 2 * pimagethrottle; ProcessTime(); }
private void OnMakeRootAgent(ScenePresence sp) { AgentRegionLoginLog(sp); }
private void GetNextDestination() { //Fire the move event CheckInformationBeforeMove(); ScenePresence botPresence = m_controller.Scene.GetScenePresence(m_controller.Bot.AgentID); var physActor = botPresence.PhysicsActor; if (m_controller == null || physActor == null) { return; } if (m_paused) { StopMoving(botPresence, LastFlying, false); return; } Vector3 pos; TravelMode state; bool teleport; bool changingNodes; float closeToPoint = physActor.Flying ? 1.5f : 1.0f; TimeSpan diffFromLastFrame = (DateTime.Now - m_timeOfLastStep); if (m_nodeGraph.GetNextPosition(botPresence, closeToPoint, diffFromLastFrame, m_baseDescription.TimeBeforeTeleportToNextPositionOccurs, out pos, out state, out teleport, out changingNodes)) { if (changingNodes) { _amountOfTimesLeftToJump = 0; } m_hasFiredFinishedMovingEvent = false; if (teleport) { //We're forced to teleport to the next location Teleport(botPresence, pos); m_nodeGraph.CurrentPos++; changingNodes = true; //Trigger the update to tell the user that the move failed TriggerFailedToMoveToNextNode(botPresence, m_nodeGraph.CurrentPos == 0 ? m_nodeGraph.NumberOfNodes : m_nodeGraph.CurrentPos); } else { switch (state) { case TravelMode.Fly: FlyTo(botPresence, pos); break; case TravelMode.Run: botPresence.SetAlwaysRun = true; WalkTo(botPresence, pos); break; case TravelMode.Walk: botPresence.SetAlwaysRun = false; WalkTo(botPresence, pos); break; case TravelMode.Teleport: //We have to do this here as if there is a wait before the teleport, we won't get the wait event fired if (changingNodes) { TriggerChangingNodes(botPresence, m_nodeGraph.CurrentPos == 0 ? m_nodeGraph.NumberOfNodes : m_nodeGraph.CurrentPos); } Teleport(botPresence, pos); m_nodeGraph.CurrentPos++; changingNodes = true; break; case TravelMode.Wait: StopMoving(botPresence, LastFlying, false); break; } } //Tell the user that we've switched nodes if (changingNodes) { TriggerChangingNodes(botPresence, m_nodeGraph.CurrentPos == 0 ? m_nodeGraph.NumberOfNodes : m_nodeGraph.CurrentPos); } } else { StopMoving(botPresence, LastFlying, true); if (!m_hasFiredFinishedMovingEvent) { m_hasFiredFinishedMovingEvent = true; TriggerFinishedMovement(botPresence); } } }
public void TestCrossOnSameSimulatorWithSittingAvatar() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); int sceneObjectIdTail = 0x2; Vector3 so1StartPos = new Vector3(128, 10, 20); EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); // In order to run a single threaded regression test we do not want the entity transfer module waiting // for a callback from the destination scene before removing its avatar data. entityTransferConfig.Set("wait_for_callback", false); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); SceneObjectGroup so1 = SceneHelpers.AddSceneObject(sceneA, 1, userId, "", sceneObjectIdTail); UUID so1Id = so1.UUID; so1.AbsolutePosition = so1StartPos; AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); TestClient tc = new TestClient(acd, sceneA); List <TestClient> destinationTestClients = new List <TestClient>(); EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence sp1SceneA = SceneHelpers.AddScenePresence(sceneA, tc, acd); sp1SceneA.AbsolutePosition = so1StartPos; sp1SceneA.HandleAgentRequestSit(sp1SceneA.ControllingClient, sp1SceneA.UUID, so1.UUID, Vector3.Zero); sceneA.Update(4); sceneB.Update(4); // Cross sceneA.SceneGraph.UpdatePrimGroupPosition( so1.LocalId, new Vector3(so1StartPos.X, so1StartPos.Y - 20, so1StartPos.Z), sp1SceneA.ControllingClient); // crossing is async sceneA.Update(4); sceneB.Update(4); Thread.Sleep(500); SceneObjectGroup so1PostCross; ScenePresence sp1SceneAPostCross = sceneA.GetScenePresence(userId); Assert.IsTrue(sp1SceneAPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly false"); ScenePresence sp1SceneBPostCross = sceneB.GetScenePresence(userId); TestClient sceneBTc = ((TestClient)sp1SceneBPostCross.ControllingClient); sceneBTc.CompleteMovement(); sceneA.Update(4); sceneB.Update(4); Assert.IsFalse(sp1SceneBPostCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true"); Assert.IsTrue(sp1SceneBPostCross.IsSatOnObject); Assert.IsNull(sceneA.GetSceneObjectGroup(so1Id), "uck"); so1PostCross = sceneB.GetSceneObjectGroup(so1Id); Assert.NotNull(so1PostCross); Assert.AreEqual(1, so1PostCross.GetSittingAvatarsCount()); Vector3 so1PostCrossPos = so1PostCross.AbsolutePosition; // Console.WriteLine("CRISSCROSS"); // Recross sceneB.SceneGraph.UpdatePrimGroupPosition( so1PostCross.LocalId, new Vector3(so1PostCrossPos.X, so1PostCrossPos.Y + 20, so1PostCrossPos.Z), sp1SceneBPostCross.ControllingClient); sceneA.Update(4); sceneB.Update(4); // crossing is async Thread.Sleep(500); { ScenePresence sp1SceneBPostReCross = sceneB.GetScenePresence(userId); Assert.IsTrue(sp1SceneBPostReCross.IsChildAgent, "sp1SceneBPostReCross.IsChildAgent unexpectedly false"); ScenePresence sp1SceneAPostReCross = sceneA.GetScenePresence(userId); TestClient sceneATc = ((TestClient)sp1SceneAPostReCross.ControllingClient); sceneATc.CompleteMovement(); Assert.IsFalse(sp1SceneAPostReCross.IsChildAgent, "sp1SceneAPostCross.IsChildAgent unexpectedly true"); Assert.IsTrue(sp1SceneAPostReCross.IsSatOnObject); Assert.IsNull(sceneB.GetSceneObjectGroup(so1Id), "uck2"); SceneObjectGroup so1PostReCross = sceneA.GetSceneObjectGroup(so1Id); Assert.NotNull(so1PostReCross); Assert.AreEqual(1, so1PostReCross.GetSittingAvatarsCount()); } }
public void Teleport(ScenePresence botPresence, Vector3 pos) { botPresence.StandUp(false, true); botPresence.Teleport(pos); }
/// <summary> /// Try to teleport an agent to a new region. /// </summary> /// <param name="remoteClient"></param> /// <param name="RegionHandle"></param> /// <param name="position"></param> /// <param name="lookAt"></param> /// <param name="flags"></param> public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) return; bool destRegionUp = true; IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); // Reset animations; the viewer does that in teleports. avatar.ResetAnimations(); if (regionHandle == m_regionInfo.RegionHandle) { // Teleport within the same region if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, avatar.Name, avatar.UUID, emergencyPos); position = emergencyPos; } // TODO: Get proper AVG Height float localAVHeight = 1.56f; float posZLimit = (float)avatar.Scene.Heightmap[(int)position.X, (int)position.Y]; float newPosZ = posZLimit + localAVHeight; if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) { position.Z = newPosZ; } // Only send this if the event queue is null if (eq == null) avatar.ControllingClient.SendTeleportLocationStart(); avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); avatar.Teleport(position); } else { RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); if (reg != null) { uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); /// /// Hypergrid mod start /// /// bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle); bool isHomeUser = true; ulong realHandle = regionHandle; CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID); if (uinfo != null) { isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile); realHandle = m_hg.FindRegionHandle(regionHandle); m_log.Debug("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString()); } /// /// Hypergrid mod stop /// /// if (eq == null) avatar.ControllingClient.SendTeleportLocationStart(); // Let's do DNS resolution only once in this process, please! // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = reg.ExternalEndPoint; if (endPoint.Address == null) { // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. destRegionUp = false; } if (destRegionUp) { // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (avatar.ParentID != (uint)0) avatar.StandUp(); if (!avatar.ValidateAttachments()) { avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); return; } // the avatar.Close below will clear the child region list. We need this below for (possibly) // closing the child agents, so save it here (we need a copy as it is Clear()-ed). //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport // failure at this point (unlike a border crossing failure). So perhaps this can never fail // once we reach here... //avatar.Scene.RemoveCapsHandler(avatar.UUID); string capsPath = String.Empty; AgentCircuitData agentCircuit = avatar.ControllingClient.RequestClientInfo(); agentCircuit.BaseFolder = UUID.Zero; agentCircuit.InventoryFolder = UUID.Zero; agentCircuit.startpos = position; agentCircuit.child = true; if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) { // brand new agent, let's create a new caps seed agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); } string reason = String.Empty; //if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agentCircuit)) if (!m_interregionCommsOut.SendCreateChildAgent(reg.RegionHandle, agentCircuit, out reason)) { avatar.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", reason)); return; } // Let's close some agents if (isHyperLink) // close them all except this one { List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles); regions.Remove(avatar.Scene.RegionInfo.RegionHandle); SendCloseChildAgentConnections(avatar.UUID, regions); } else // close just a few avatar.CloseChildAgents(newRegionX, newRegionY); if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) { capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); if (eq != null) { #region IP Translation for NAT IClientIPEndpoint ipepClient; if (avatar.ClientView.TryGet(out ipepClient)) { endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); } #endregion eq.EnableSimulator(realHandle, endPoint, avatar.UUID); // ES makes the client send a UseCircuitCode message to the destination, // which triggers a bunch of things there. // So let's wait Thread.Sleep(2000); eq.EstablishAgentCommunication(avatar.UUID, endPoint, capsPath); } else { avatar.ControllingClient.InformClientOfNeighbour(realHandle, endPoint); // TODO: make Event Queue disablable! } } else { // child agent already there agentCircuit.CapsPath = avatar.Scene.CapsModule.GetChildSeed(avatar.UUID, reg.RegionHandle); capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + agentCircuit.CapsPath + "0000/"; } //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, // position, false); //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, // position, false)) //{ // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); // // We should close that agent we just created over at destination... // List<ulong> lst = new List<ulong>(); // lst.Add(realHandle); // SendCloseChildAgentAsync(avatar.UUID, lst); // return; //} SetInTransit(avatar.UUID); // Let's send a full update of the agent. This is a synchronous call. AgentData agent = new AgentData(); avatar.CopyTo(agent); agent.Position = position; agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort + "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/"; m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); m_log.DebugFormat( "[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID); /// /// Hypergrid mod: realHandle instead of reg.RegionHandle /// /// if (eq != null) { eq.TeleportFinishEvent(realHandle, 13, endPoint, 4, teleportFlags, capsPath, avatar.UUID); } else { avatar.ControllingClient.SendRegionTeleport(realHandle, 13, endPoint, 4, teleportFlags, capsPath); } /// /// Hypergrid mod stop /// // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // that the client contacted the destination before we send the attachments and close things here. if (!WaitForCallback(avatar.UUID)) { // Client never contacted destination. Let's restore everything back avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination."); ResetFromTransit(avatar.UUID); // Yikes! We should just have a ref to scene here. avatar.Scene.InformClientOfNeighbours(avatar); // Finally, kill the agent we just created at the destination. m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID); return; } // Can't go back from here if (KiPrimitive != null) { KiPrimitive(avatar.LocalId); } avatar.MakeChildAgent(); // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone /// /// Hypergrid mod: extra check for isHyperLink /// if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) { Thread.Sleep(5000); avatar.Close(); CloseConnection(avatar.UUID); } // if (teleport success) // seems to be always success here // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it if (avatar.Scene.NeedSceneCacheClear(avatar.UUID) || isHyperLink) { m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); m_log.DebugFormat( "[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); } } else { avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); } } else { // TP to a place that doesn't exist (anymore) // Inform the viewer about that avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); // and set the map-tile to '(Offline)' uint regX, regY; Utils.LongToUInts(regionHandle, out regX, out regY); MapBlockData block = new MapBlockData(); block.X = (ushort)(regX / Constants.RegionSize); block.Y = (ushort)(regY / Constants.RegionSize); block.Access = 254; // == not there List<MapBlockData> blocks = new List<MapBlockData>(); blocks.Add(block); avatar.ControllingClient.SendMapBlock(blocks, 0); } } }
public void UpdateMovementAnimations(bool p) { ScenePresence presence = m_controller.Scene.GetScenePresence(m_controller.Bot.AgentID); presence.UpdateMovementAnimations(); }
public void Init() { m_scene = new SceneHelpers().SetupScene(); m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); }
public ScenePresenceAnimator(ScenePresence sp) { m_scenePresence = sp; CurrentMovementAnimation = "CROUCH"; }