diff --git a/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs b/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs index a2453db1b8..0f6b4c7dfd 100644 --- a/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs +++ b/OpenSim/Region/Communications/Hypergrid/HGGridServicesStandalone.cs @@ -461,6 +461,16 @@ namespace OpenSim.Region.Communications.Hypergrid regInfo = RequestNeighbourInfo(regionHandle); if (regInfo != null) { + try + { + regionHandle = Convert.ToUInt64(regInfo.regionSecret); + } + catch (Exception) + { + m_log.Warn("[HGrid]: Invalid hyperlink region."); + return false; + } + //don't want to be creating a new link to the remote instance every time like we are here bool retValue = false; @@ -472,6 +482,7 @@ namespace OpenSim.Region.Communications.Hypergrid if (remObject != null) { + m_log.Debug("[HGrid]: Inform region of prim crossing: " + regInfo.RemotingAddress + ":" + regInfo.RemotingPort); retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.Guid, objData, XMLMethod); } else @@ -810,6 +821,7 @@ namespace OpenSim.Region.Communications.Hypergrid /// public bool IncomingPrim(ulong regionHandle, UUID primID, string objData, int XMLMethod) { + m_log.Debug("[HGrid]: Incoming Prim"); m_localBackend.TriggerExpectPrim(regionHandle, primID, objData, XMLMethod); return true; diff --git a/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs b/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs index cb60d3f0f9..33ccbf4d39 100644 --- a/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs +++ b/OpenSim/Region/Environment/Modules/Communications/Local/LocalInterregionComms.cs @@ -116,6 +116,10 @@ namespace OpenSim.Region.Environment.Modules.Communications.Local #region IInterregionComms + /** + * Agent-related communications + */ + public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit) { foreach (Scene s in m_sceneList) @@ -204,6 +208,37 @@ namespace OpenSim.Region.Environment.Modules.Communications.Local return false; } + /** + * Object-related communications + */ + + public bool SendCreateObject(ulong regionHandle, ISceneObject sog) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); + return s.IncomingCreateObject(sog); + } + } + return false; + } + #endregion /* IInterregionComms */ + + #region Misc + + public UUID GetRegionID(ulong regionhandle) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionhandle) + return s.RegionInfo.RegionID; + } + // ? weird. should not happen + return m_sceneList[0].RegionInfo.RegionID; + } + #endregion } } diff --git a/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs b/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs index cfcd618161..95b95eed28 100644 --- a/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs +++ b/OpenSim/Region/Environment/Modules/Communications/REST/RESTInterregionComms.cs @@ -123,12 +123,17 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST protected virtual void AddHTTPHandlers() { m_aScene.CommsManager.HttpServer.AddHTTPHandler("/agent/", AgentHandler); + m_aScene.CommsManager.HttpServer.AddHTTPHandler("/object/", ObjectHandler); } #endregion /* IRegionModule */ #region IInterregionComms + /** + * Agent-related communications + */ + public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit) { // Try local first @@ -209,7 +214,32 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST //else // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); return false; - } + } + + /** + * Object-related communications + */ + + public bool SendCreateObject(ulong regionHandle, ISceneObject sog) + { + // Try local first + ISceneObject sogClone = sog.CloneForNewScene(); + if (m_localBackend.SendCreateObject(regionHandle, sogClone)) + { + //m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded"); + return true; + } + + // else do the remote thing + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + return DoCreateObjectCall(regInfo, sog); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + return false; + } #endregion /* IInterregionComms */ @@ -454,10 +484,95 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST return true; } + protected bool DoCreateObjectCall(RegionInfo region, ISceneObject sog) + { + ulong regionHandle = GetRegionHandle(region.RegionHandle); + string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/object/" + sog.UUID + "/" + regionHandle.ToString() + "/"; + //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri); + + WebRequest ObjectCreateRequest = WebRequest.Create(uri); + ObjectCreateRequest.Method = "POST"; + ObjectCreateRequest.ContentType = "text/xml"; + ObjectCreateRequest.Timeout = 10000; + + OSDMap args = new OSDMap(2); + args["sog"] = OSD.FromString(sog.ToXmlString2()); + args["extra"] = OSD.FromString(sog.ExtraToXmlString()); + if (m_aScene.m_allowScriptCrossings) + { + string state = sog.GetStateSnapshot(); + if (state.Length > 0) + args["state"] = OSD.FromString(state); + } + + string strBuffer = ""; + byte[] buffer = new byte[1]; + try + { + strBuffer = OSDParser.SerializeJsonString(args); + System.Text.UTF8Encoding str = new System.Text.UTF8Encoding(); + buffer = str.GetBytes(strBuffer); + + } + catch (Exception e) + { + m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message); + // ignore. buffer will be empty, caller should check. + } + + Stream os = null; + try + { // send the Post + ObjectCreateRequest.ContentLength = buffer.Length; //Count bytes to send + os = ObjectCreateRequest.GetRequestStream(); + os.Write(buffer, 0, strBuffer.Length); //Send it + os.Close(); + m_log.InfoFormat("[REST COMMS]: Posted ChildAgentUpdate request to remote sim {0}", uri); + } + //catch (WebException ex) + catch + { + // m_log.InfoFormat("[REST COMMS]: Bad send on CreateObject {0}", ex.Message); + + return false; + } + + // Let's wait for the response + //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall"); + + try + { + WebResponse webResponse = ObjectCreateRequest.GetResponse(); + if (webResponse == null) + { + m_log.Info("[REST COMMS]: Null reply on DoCreateObjectCall post"); + } + + StreamReader sr = new StreamReader(webResponse.GetResponseStream()); + //reply = sr.ReadToEnd().Trim(); + sr.ReadToEnd().Trim(); + sr.Close(); + //m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", reply); + + } + catch (WebException ex) + { + m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateObjectCall {0}", ex.Message); + // ignore, really + } + + return true; + + } + #endregion /* Do Work */ #region Incoming calls from remote instances + /** + * Agent-related incoming calls + */ + public Hashtable AgentHandler(Hashtable request) { //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); @@ -487,17 +602,17 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST string method = (string)request["http-method"]; if (method.Equals("PUT")) { - DoPut(request, responsedata); + DoAgentPut(request, responsedata); return responsedata; } else if (method.Equals("POST")) { - DoPost(request, responsedata, agentID); + DoAgentPost(request, responsedata, agentID); return responsedata; } else if (method.Equals("DELETE")) { - DoDelete(request, responsedata, agentID, action, regionHandle); + DoAgentDelete(request, responsedata, agentID, action, regionHandle); return responsedata; } @@ -534,12 +649,12 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST } catch (Exception ex) { - m_log.InfoFormat("[REST COMMS]: exception on parse of ChildAgentUpdate message {0}", ex.Message); + m_log.InfoFormat("[REST COMMS]: exception on parse of REST message {0}", ex.Message); return null; } } - protected virtual void DoPost(Hashtable request, Hashtable responsedata, UUID id) + protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) { OSDMap args = GetOSDMap(request); if (args == null) @@ -573,7 +688,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST responsedata["str_response_string"] = result.ToString(); } - protected virtual void DoPut(Hashtable request, Hashtable responsedata) + protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata) { OSDMap args = GetOSDMap(request); if (args == null) @@ -639,7 +754,7 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST responsedata["str_response_string"] = result.ToString(); } - protected virtual void DoDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) + protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) { //Console.WriteLine(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle); @@ -651,7 +766,118 @@ namespace OpenSim.Region.Environment.Modules.Communications.REST responsedata["int_response_code"] = 200; responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); } - + + /** + * Object-related incoming calls + */ + + public Hashtable ObjectHandler(Hashtable request) + { + //m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called"); + + //Console.WriteLine("---------------------------"); + //Console.WriteLine(" >> uri=" + request["uri"]); + //Console.WriteLine(" >> content-type=" + request["content-type"]); + //Console.WriteLine(" >> http-method=" + request["http-method"]); + //Console.WriteLine("---------------------------\n"); + + Hashtable responsedata = new Hashtable(); + responsedata["content_type"] = "text/html"; + + UUID objectID; + string action; + ulong regionHandle; + if (!GetParams((string)request["uri"], out objectID, out regionHandle, out action)) + { + m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + // Next, let's parse the verb + string method = (string)request["http-method"]; + if (method.Equals("POST")) + { + DoObjectPost(request, responsedata, regionHandle); + return responsedata; + } + //else if (method.Equals("PUT")) + //{ + // DoObjectPut(request, responsedata, agentID); + // return responsedata; + //} + //else if (method.Equals("DELETE")) + //{ + // DoObjectDelete(request, responsedata, agentID, action, regionHandle); + // return responsedata; + //} + else + { + m_log.InfoFormat("[REST COMMS]: method {0} not supported in object message", method); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + } + + protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle) + { + OSDMap args = GetOSDMap(request); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + string sogXmlStr = "", extraStr = "", stateXmlStr = ""; + if (args["sog"] != null) + sogXmlStr = args["sog"].AsString(); + if (args["extra"] != null) + extraStr = args["extra"].AsString(); + + UUID regionID = m_localBackend.GetRegionID(regionhandle); + SceneObjectGroup sog = null; + try + { + sog = new SceneObjectGroup(sogXmlStr); + sog.ExtraFromXmlString(extraStr); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message); + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + if ((args["state"] != null) && m_aScene.m_allowScriptCrossings) + { + stateXmlStr = args["state"].AsString(); + if (stateXmlStr != "") + { + try + { + sog.SetState(stateXmlStr, regionID); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message); + + } + } + } + // This is the meaning of POST object + bool result = m_localBackend.SendCreateObject(regionhandle, sog); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + #endregion #region Misc diff --git a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs index 783b3f94fd..bfa17fc3e0 100644 --- a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs @@ -70,6 +70,9 @@ namespace OpenSim.Region.Framework.Interfaces /// /// bool SendCloseAgent(ulong regionHandle, UUID id); + + bool SendCreateObject(ulong regionHandle, ISceneObject sog); + } // This may not be needed, but having it here for now. diff --git a/OpenSim/Region/Framework/Interfaces/ISceneObject.cs b/OpenSim/Region/Framework/Interfaces/ISceneObject.cs new file mode 100644 index 0000000000..79a43d6075 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/ISceneObject.cs @@ -0,0 +1,16 @@ +using System; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface ISceneObject + { + UUID UUID { get; } + ISceneObject CloneForNewScene(); + string ToXmlString2(); + string ExtraToXmlString(); + void ExtraFromXmlString(string xmlstr); + string GetStateSnapshot(); + void SetState(string xmlstr, UUID regionID); + } +} diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2fae8ac2f7..b10acc7039 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2011,22 +2011,27 @@ namespace OpenSim.Region.Framework.Scenes /// public bool CrossPrimGroupIntoNewRegion(ulong newRegionHandle, SceneObjectGroup grp, bool silent) { + //Console.WriteLine(" >>> CrossPrimGroupIntoNewRegion <<<"); + bool successYN = false; grp.RootPart.UpdateFlag = 0; - int primcrossingXMLmethod = 0; + //int primcrossingXMLmethod = 0; if (newRegionHandle != 0) { - string objectState = grp.GetStateSnapshot(); + //string objectState = grp.GetStateSnapshot(); - successYN - = m_sceneGridService.PrimCrossToNeighboringRegion( - newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod); - if (successYN && (objectState != "") && m_allowScriptCrossings) - { - successYN = m_sceneGridService.PrimCrossToNeighboringRegion( - newRegionHandle, grp.UUID, objectState, 100); - } + //successYN + // = m_sceneGridService.PrimCrossToNeighboringRegion( + // newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod); + //if (successYN && (objectState != "") && m_allowScriptCrossings) + //{ + // successYN = m_sceneGridService.PrimCrossToNeighboringRegion( + // newRegionHandle, grp.UUID, objectState, 100); + //} + + // And the new channel... + successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp); if (successYN) { @@ -2065,6 +2070,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Handle a scene object that is crossing into this region from another. + /// NOTE: Unused as of 2009-02-09. Soon to be deleted. /// /// /// @@ -2079,98 +2085,13 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("[INTERREGION]: A new prim {0} arrived from a neighbor", primID); SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData); - // If the user is banned, we won't let any of their objects - // enter. Period. - // - if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) - { - m_log.Info("[INTERREGION]: Denied prim crossing for "+ - "banned avatar"); + return AddSceneObject(primID, sceneObject); - return false; - } - - // Force allocation of new LocalId - // - foreach (SceneObjectPart p in sceneObject.Children.Values) - p.LocalId = 0; - - if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) - { - if (sceneObject.RootPart.Shape.State != 0) - { - // Fix up attachment Parent Local ID - // - ScenePresence sp = GetScenePresence(sceneObject.OwnerID); - - uint parentLocalID = 0; - if (sp != null) - parentLocalID = sp.LocalId; - - sceneObject.RootPart.IsAttachment = true; - sceneObject.RootPart.SetParentLocalId(parentLocalID); - - AddRestoredSceneObject(sceneObject, false, false); - - // Handle attachment special case - // - SceneObjectPart RootPrim = GetSceneObjectPart(primID); - - if (RootPrim != null) - { - SceneObjectGroup grp = RootPrim.ParentGroup; - - RootPrim.SetParentLocalId(parentLocalID); - - if (grp != null) - { - m_log.DebugFormat("[ATTACHMENT]: Received "+ - "attachment {0}, inworld asset id {1}", - grp.RootPart.LastOwnerID.ToString(), - grp.UUID.ToString()); - - if (sp != null) - { - grp.SetFromAssetID(grp.RootPart.LastOwnerID); - m_log.DebugFormat("[ATTACHMENT]: Attach "+ - "to avatar {0}", - sp.UUID.ToString()); - AttachObject(sp.ControllingClient, - grp.LocalId, (uint)0, - grp.GroupRotation, - grp.AbsolutePosition, false); - grp.SendGroupFullUpdate(); - } - else - { - RootPrim.RemFlag(PrimFlags.TemporaryOnRez); - RootPrim.AddFlag(PrimFlags.TemporaryOnRez); - } - } - } - } - else - { - AddRestoredSceneObject(sceneObject, true, false); - - if (!Permissions.CanObjectEntry(sceneObject.UUID, - true, sceneObject.AbsolutePosition)) - { - // Deny non attachments based on parcel settings - // - m_log.Info("[INTERREGION]: Denied prim crossing "+ - "because of parcel settings"); - - DeleteSceneObject(sceneObject, false); - - return false; - } - } - } } else if ((XMLMethod == 100) && m_allowScriptCrossings) { m_log.Warn("[INTERREGION]: Prim state data arrived from a neighbor"); + XmlDocument doc = new XmlDocument(); doc.LoadXml(objXMLData); @@ -2244,6 +2165,123 @@ namespace OpenSim.Region.Framework.Scenes return true; } + public bool IncomingCreateObject(ISceneObject sog) + { + //Console.WriteLine(" >>> IncomingCreateObject <<<"); + SceneObjectGroup newObject; + try + { + newObject = (SceneObjectGroup)sog; + } + catch (Exception e) + { + m_log.WarnFormat("[SCENE]: Problem casting object: {0}", e.Message); + return false; + } + + if (!AddSceneObject(newObject.UUID, newObject)) + { + m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName); + return false; + } + newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1); + return true; + } + + public bool AddSceneObject(UUID primID, SceneObjectGroup sceneObject) + { + // If the user is banned, we won't let any of their objects + // enter. Period. + // + if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID)) + { + m_log.Info("[INTERREGION]: Denied prim crossing for " + + "banned avatar"); + + return false; + } + + // Force allocation of new LocalId + // + foreach (SceneObjectPart p in sceneObject.Children.Values) + p.LocalId = 0; + + if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) + { + if (sceneObject.RootPart.Shape.State != 0) + { + // Fix up attachment Parent Local ID + // + ScenePresence sp = GetScenePresence(sceneObject.OwnerID); + + uint parentLocalID = 0; + if (sp != null) + parentLocalID = sp.LocalId; + + sceneObject.RootPart.IsAttachment = true; + sceneObject.RootPart.SetParentLocalId(parentLocalID); + + AddRestoredSceneObject(sceneObject, false, false); + + // Handle attachment special case + // + SceneObjectPart RootPrim = GetSceneObjectPart(primID); + //SceneObjectPart RootPrim = sceneObject.RootPart; + + if (RootPrim != null) + { + SceneObjectGroup grp = RootPrim.ParentGroup; + + RootPrim.SetParentLocalId(parentLocalID); + + if (grp != null) + { + m_log.DebugFormat("[ATTACHMENT]: Received " + + "attachment {0}, inworld asset id {1}", + //grp.RootPart.LastOwnerID.ToString(), + grp.GetFromAssetID(), + grp.UUID.ToString()); + + if (sp != null) + { + //grp.SetFromAssetID(grp.RootPart.LastOwnerID); + m_log.DebugFormat("[ATTACHMENT]: Attach " + + "to avatar {0}", + sp.UUID.ToString()); + AttachObject(sp.ControllingClient, + grp.LocalId, (uint)0, + grp.GroupRotation, + grp.AbsolutePosition, false); + grp.SendGroupFullUpdate(); + } + else + { + RootPrim.RemFlag(PrimFlags.TemporaryOnRez); + RootPrim.AddFlag(PrimFlags.TemporaryOnRez); + } + } + } + } + else + { + AddRestoredSceneObject(sceneObject, true, false); + + if (!Permissions.CanObjectEntry(sceneObject.UUID, + true, sceneObject.AbsolutePosition)) + { + // Deny non attachments based on parcel settings + // + m_log.Info("[INTERREGION]: Denied prim crossing " + + "because of parcel settings"); + + DeleteSceneObject(sceneObject, false); + + return false; + } + } + } + return true; + } #endregion #region Add/Remove Avatar Methods diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 2877dcd134..2edfca8a5e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -590,6 +590,7 @@ namespace OpenSim.Region.Framework.Scenes // Saves and gets assetID UUID itemId; + if (group.GetFromAssetID() == UUID.Zero) { m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 5fa6609208..c3485aba18 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -309,6 +309,8 @@ namespace OpenSim.Region.Framework.Scenes public string GetStateSnapshot() { + Console.WriteLine(" >>> GetStateSnapshot <<<"); + List assemblies = new List(); Dictionary states = new Dictionary(); @@ -358,9 +360,16 @@ namespace OpenSim.Region.Framework.Scenes Byte[] data = new Byte[fi.Length]; - FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read); - fs.Read(data, 0, data.Length); - fs.Close(); + try + { + FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read); + fs.Read(data, 0, data.Length); + fs.Close(); + } + catch (Exception e) + { + m_log.DebugFormat("[SOG]: Unable to open script assembly {0}, reason: {1}", assembly, e.Message); + } XmlElement assemblyData = xmldoc.CreateElement("", "Assembly", ""); XmlAttribute assemblyName = xmldoc.CreateAttribute("", "Filename", ""); @@ -397,5 +406,73 @@ namespace OpenSim.Region.Framework.Scenes return xmldoc.InnerXml; } + + public void SetState(string objXMLData, UUID RegionID) + { + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(objXMLData); + + XmlNodeList rootL = doc.GetElementsByTagName("ScriptData"); + if (rootL.Count == 1) + { + XmlNode rootNode = rootL[0]; + if (rootNode != null) + { + XmlNodeList partL = rootNode.ChildNodes; + + foreach (XmlNode part in partL) + { + XmlNodeList nodeL = part.ChildNodes; + + switch (part.Name) + { + case "Assemblies": + foreach (XmlNode asm in nodeL) + { + string fn = asm.Attributes.GetNamedItem("Filename").Value; + + Byte[] filedata = Convert.FromBase64String(asm.InnerText); + string path = Path.Combine("ScriptEngines", RegionID.ToString()); + path = Path.Combine(path, fn); + + if (!File.Exists(path)) + { + FileStream fs = File.Create(path); + fs.Write(filedata, 0, filedata.Length); + fs.Close(); + } + } + break; + case "ScriptStates": + foreach (XmlNode st in nodeL) + { + string id = st.Attributes.GetNamedItem("UUID").Value; + UUID uuid = new UUID(id); + XmlNode state = st.ChildNodes[0]; + + XmlDocument sdoc = new XmlDocument(); + XmlNode sxmlnode = sdoc.CreateNode( + XmlNodeType.XmlDeclaration, + "", ""); + sdoc.AppendChild(sxmlnode); + + XmlNode newnode = sdoc.ImportNode(state, true); + sdoc.AppendChild(newnode); + + string spath = Path.Combine("ScriptEngines", RegionID.ToString()); + spath = Path.Combine(spath, uuid.ToString()); + FileStream sfs = File.Create(spath + ".state"); + System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + Byte[] buf = enc.GetBytes(sdoc.InnerXml); + sfs.Write(buf, 0, buf.Length); + sfs.Close(); + } + break; + } + } + } + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index d3b96261e7..e732b42e54 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Threading; using System.Xml; using System.Xml.Serialization; using OpenMetaverse; @@ -84,7 +85,7 @@ namespace OpenSim.Region.Framework.Scenes /// A scene object group is conceptually an object in the scene. The object is constituted of SceneObjectParts /// (often known as prims), one of which is considered the root part. /// - public partial class SceneObjectGroup : EntityBase + public partial class SceneObjectGroup : EntityBase, ISceneObject { // private PrimCountTaintedDelegate handlerPrimCountTainted = null; @@ -3030,5 +3031,31 @@ namespace OpenSim.Region.Framework.Scenes part.SetAttachmentPoint(point); } } + + #region ISceneObject + + public virtual ISceneObject CloneForNewScene() + { + SceneObjectGroup sog = Copy(this.OwnerID, this.GroupID, false); + return sog; + } + + public virtual string ExtraToXmlString() + { + return "" + GetFromAssetID().ToString() + ""; + } + + public virtual void ExtraFromXmlString(string xmlstr) + { + string id = xmlstr.Substring(xmlstr.IndexOf("")); + id = xmlstr.Replace("", ""); + id = id.Replace("", ""); + + UUID uuid = UUID.Zero; + UUID.TryParse(id, out uuid); + + SetFromAssetID(uuid); + } + #endregion } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e9f93a6533..0ed35afe68 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3036,7 +3036,7 @@ namespace OpenSim.Region.Framework.Scenes gobj.RootPart.SetParentLocalId(0); gobj.RootPart.IsAttachment = false; gobj.AbsolutePosition = gobj.RootPart.AttachedPos; - gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); + //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); m_log.DebugFormat("[ATTACHMENT]: Sending attachment {0} to region {1}", gobj.UUID, regionHandle); m_scene.CrossPrimGroupIntoNewRegion(regionHandle, gobj, silent); }