Merged with Kitty's Script engine code.
parent
1c93854b47
commit
f5d25981ac
|
@ -1564,5 +1564,12 @@ VALUES
|
|||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region REGION SYNC
|
||||
public List<SceneObjectGroup> LoadObjectsInGivenSpace(UUID regionID, float lowerX, float lowerY, float upperX, float upperY)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
}
|
||||
|
|
|
@ -523,6 +523,148 @@ namespace OpenSim.Data.MySQL
|
|||
return new List<SceneObjectGroup>(objects.Values);
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
public List<SceneObjectGroup> LoadObjectsInGivenSpace(UUID regionID, float lowerX, float lowerY, float upperX, float upperY)
|
||||
{
|
||||
const int ROWS_PER_QUERY = 5000;
|
||||
|
||||
Dictionary<UUID, SceneObjectPart> prims = new Dictionary<UUID, SceneObjectPart>(ROWS_PER_QUERY);
|
||||
Dictionary<UUID, SceneObjectGroup> objects = new Dictionary<UUID, SceneObjectGroup>();
|
||||
int count = 0;
|
||||
|
||||
#region Prim Loading
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
//cmd.CommandText =
|
||||
// "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID";
|
||||
cmd.CommandText = "SELECT * FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID " +
|
||||
"and GroupPositionX>=?lowerX " +
|
||||
"and GroupPositionX<=?upperX and GroupPositionY>=?lowerY and GroupPositionY<=?upperY ";
|
||||
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("lowerX", lowerX);
|
||||
cmd.Parameters.AddWithValue("lowerY", lowerY);
|
||||
cmd.Parameters.AddWithValue("upperX", upperX);
|
||||
cmd.Parameters.AddWithValue("upperY", upperY);
|
||||
|
||||
using (IDataReader reader = ExecuteReader(cmd))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
SceneObjectPart prim = BuildPrim(reader);
|
||||
if (reader["Shape"] is DBNull)
|
||||
prim.Shape = PrimitiveBaseShape.Default;
|
||||
else
|
||||
prim.Shape = BuildShape(reader);
|
||||
|
||||
UUID parentID = DBGuid.FromDB(reader["SceneGroupID"].ToString());
|
||||
if (parentID != prim.UUID)
|
||||
prim.ParentUUID = parentID;
|
||||
|
||||
prims[prim.UUID] = prim;
|
||||
|
||||
++count;
|
||||
if (count % ROWS_PER_QUERY == 0)
|
||||
m_log.Debug("[REGION DB]: Loaded " + count + " prims...");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Prim Loading
|
||||
|
||||
#region SceneObjectGroup Creation
|
||||
|
||||
// Create all of the SOGs from the root prims first
|
||||
foreach (SceneObjectPart prim in prims.Values)
|
||||
{
|
||||
if (prim.ParentUUID == UUID.Zero)
|
||||
objects[prim.UUID] = new SceneObjectGroup(prim);
|
||||
}
|
||||
|
||||
// Add all of the children objects to the SOGs
|
||||
foreach (SceneObjectPart prim in prims.Values)
|
||||
{
|
||||
SceneObjectGroup sog;
|
||||
if (prim.UUID != prim.ParentUUID)
|
||||
{
|
||||
if (objects.TryGetValue(prim.ParentUUID, out sog))
|
||||
{
|
||||
int originalLinkNum = prim.LinkNum;
|
||||
|
||||
sog.AddPart(prim);
|
||||
|
||||
// SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum.
|
||||
// We override that here
|
||||
if (originalLinkNum != 0)
|
||||
prim.LinkNum = originalLinkNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[REGION DB]: Database contains an orphan child prim {0} {1} in region {2} pointing to missing parent {3}. This prim will not be loaded.",
|
||||
prim.Name, prim.UUID, regionID, prim.ParentUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion SceneObjectGroup Creation
|
||||
|
||||
m_log.DebugFormat("[REGION DB]: Loaded {0} objects using {1} prims", objects.Count, prims.Count);
|
||||
|
||||
#region Prim Inventory Loading
|
||||
|
||||
// Instead of attempting to LoadItems on every prim,
|
||||
// most of which probably have no items... get a
|
||||
// list from DB of all prims which have items and
|
||||
// LoadItems only on those
|
||||
List<SceneObjectPart> primsWithInventory = new List<SceneObjectPart>();
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand itemCmd = dbcon.CreateCommand())
|
||||
{
|
||||
itemCmd.CommandText = "SELECT DISTINCT primID FROM primitems";
|
||||
using (IDataReader itemReader = ExecuteReader(itemCmd))
|
||||
{
|
||||
while (itemReader.Read())
|
||||
{
|
||||
if (!(itemReader["primID"] is DBNull))
|
||||
{
|
||||
UUID primID = DBGuid.FromDB(itemReader["primID"].ToString());
|
||||
if (prims.ContainsKey(primID))
|
||||
primsWithInventory.Add(prims[primID]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SceneObjectPart prim in primsWithInventory)
|
||||
{
|
||||
LoadItems(prim);
|
||||
}
|
||||
|
||||
#endregion Prim Inventory Loading
|
||||
|
||||
m_log.DebugFormat("[REGION DB]: Loaded inventory from {0} objects", primsWithInventory.Count);
|
||||
|
||||
return new List<SceneObjectGroup>(objects.Values);
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Load in a prim's persisted inventory.
|
||||
/// </summary>
|
||||
|
|
|
@ -108,5 +108,12 @@ namespace OpenSim.Data.Null
|
|||
public void Shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
public List<SceneObjectGroup> LoadObjectsInGivenSpace(UUID regionID, float lowerX, float lowerY, float upperX, float upperY)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2332,5 +2332,11 @@ namespace OpenSim.Data.SQLite
|
|||
}
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
public List<SceneObjectGroup> LoadObjectsInGivenSpace(UUID regionID, float lowerX, float lowerY, float upperX, float upperY)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2260,5 +2260,11 @@ namespace OpenSim.Data.SQLiteLegacy
|
|||
}
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
public List<SceneObjectGroup> LoadObjectsInGivenSpace(UUID regionID, float lowerX, float lowerY, float upperX, float upperY)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
}
|
||||
|
|
|
@ -359,8 +359,59 @@ namespace OpenSim
|
|||
"kill uuid <UUID>",
|
||||
"Kill an object by UUID", KillUUID);
|
||||
|
||||
//REGION SYNC
|
||||
//Add one more command handler for "sync start", to pass simulator-wise information to one valide Scene.
|
||||
//A trick to enable Script Engine to run scripts in several adjacent regions (all objects and their scripts
|
||||
//exisited in the valid region, but all regions have their Scene data structure up and hold the RegionInfo.
|
||||
//More details, see ScriptEngineToSceneConnector.cs.
|
||||
m_console.Commands.AddCommand("region", false, "sync start",
|
||||
"sync start",
|
||||
"start synchronization with the authoratative Scene", SyncStart);
|
||||
//End REGION SYNC
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
protected void SyncStart(string module, string[] cmdparams)
|
||||
{
|
||||
m_log.Debug("OpenSim: receives sync start command, do something");
|
||||
|
||||
//string validLocalScene = m_config.
|
||||
IConfig regionSyncConfig = m_config.Source.Configs["RegionSyncModule"];
|
||||
|
||||
if (regionSyncConfig == null || regionSyncConfig.GetString("Enabled", "").ToLower() != "true")
|
||||
{
|
||||
m_log.Warn("[OpenSim] Not in sync mode. Ignore cmmand.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionSyncConfig.GetString("Mode", "").ToLower() == "server")
|
||||
{
|
||||
m_log.Warn("[OpenSim] In server mode. Should not initiate sync start. Ignore command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (regionSyncConfig.GetString("Mode", "").ToLower() == "script_engine")
|
||||
{
|
||||
//if this is a remote script engine, proceed with following actions
|
||||
string validSceneName = regionSyncConfig.GetString("ValidScriptEngineScene", "");
|
||||
|
||||
if (!validSceneName.Equals(""))
|
||||
{
|
||||
Scene validScene;
|
||||
m_sceneManager.TryGetScene(validSceneName, out validScene);
|
||||
|
||||
List<Scene> localScenes = m_sceneManager.Scenes;
|
||||
//First, let the valid scene's SEToSceneConnector be aware of all local scenes.
|
||||
//The SEToSceneConnector will also pass a reference to all other scenes, so that they can
|
||||
//call the appropriate IsBorderCrossing().
|
||||
validScene.EventManager.TriggerPopulateLocalSceneList(localScenes); //TO BE FINISHED
|
||||
//validScene.EventManager.TriggerPopulateLocalSceneList(localScenes, cmdparams);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
|
||||
|
||||
public override void ShutdownSpecific()
|
||||
{
|
||||
if (m_shutdownCommandsFile != String.Empty)
|
||||
|
|
|
@ -71,6 +71,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
private string m_regionName;
|
||||
|
||||
private System.Timers.Timer m_statsTimer = new System.Timers.Timer(30000);
|
||||
|
||||
//KittyL: added to identify different actors
|
||||
private ActorType m_actorType = ActorType.ClientManager;
|
||||
|
||||
// The queue of incoming messages which need handling
|
||||
//private Queue<string> m_inQ = new Queue<string>();
|
||||
#endregion
|
||||
|
||||
// Constructor
|
||||
|
@ -704,6 +710,9 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
private void DoInitialSync()
|
||||
{
|
||||
m_scene.DeleteAllSceneObjects();
|
||||
//KittyL: added to distinguish different actors
|
||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.ActorType, m_actorType.ToString()));
|
||||
|
||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.RegionName, m_scene.RegionInfo.RegionName));
|
||||
m_log.WarnFormat("Sending region name: \"{0}\"", m_scene.RegionInfo.RegionName);
|
||||
Send(new RegionSyncMessage(RegionSyncMessage.MsgType.GetTerrain));
|
||||
|
|
|
@ -5,18 +5,39 @@ using log4net;
|
|||
|
||||
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||
{
|
||||
#region ActorType Enum
|
||||
public enum ActorType
|
||||
{
|
||||
Null,
|
||||
ClientManager,
|
||||
ScriptEngine
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ActorStatus Enum
|
||||
public enum ActorStatus
|
||||
{
|
||||
Null,
|
||||
Idle,
|
||||
Sync
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// A message for synchonization message between scenes
|
||||
/// </summary>
|
||||
public class RegionSyncMessage
|
||||
{
|
||||
//KittyL: added to help identify different actors
|
||||
|
||||
|
||||
#region MsgType Enum
|
||||
public enum MsgType
|
||||
{
|
||||
Null,
|
||||
//ConnectSyncClient,
|
||||
//DisconnectSyncClient,
|
||||
// CM -> SIM
|
||||
// CM -> SIM(Scene)
|
||||
ActorConnect,
|
||||
AgentAdd,
|
||||
AgentUpdate,
|
||||
|
@ -45,7 +66,38 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
EchoRequest,
|
||||
EchoResponse,
|
||||
RegionName,
|
||||
RegionStatus
|
||||
RegionStatus,
|
||||
//Added by KittyL
|
||||
// Actor -> Scene
|
||||
ActorType, //to register the type (e.g. Client Manager or Script Engine) with Scene when sync channel is initialized
|
||||
SetObjectProperty,
|
||||
ActorStop,
|
||||
ResetScene,
|
||||
OnRezScript,
|
||||
OnScriptReset,
|
||||
OnUpdateScript,
|
||||
QuarkSubscription,
|
||||
// Scene -> Script Engine
|
||||
NewObjectWithScript,
|
||||
SceneLocation,
|
||||
//For load balancing purpose (among script engines)
|
||||
//Temorarily put here, for easier first round of implemention.
|
||||
//Script engine --> Scene
|
||||
ActorStatus, //if the actor is busying syncing with a Scene, or is just idle. Status: {sync, idle}
|
||||
LoadBalanceRequest,
|
||||
LoadMigrationListenerInitiated,
|
||||
//Scene --> Script engine
|
||||
LoadMigrationNotice,
|
||||
LoadBalanceResponse,
|
||||
LoadBalanceRejection,
|
||||
//Overloaded script engine overloaded -> idle script engine
|
||||
//MigratingQuarks,
|
||||
MigrationSpace,
|
||||
ScriptStateSyncStart,
|
||||
ScriptStateSyncPerObject,
|
||||
ScriptStateSyncEnd,
|
||||
//Idle script engine overloaded -> overloaded script engine
|
||||
ScriptStateSyncRequest,
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ using OpenSim.Region.Framework.Scenes;
|
|||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
||||
{
|
||||
|
@ -192,5 +193,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
{
|
||||
m_ClientBalancer.BalanceLoad();
|
||||
}
|
||||
//KittyL:
|
||||
public void BroadcastToCM(RegionSyncMessage.MsgType msgType, SceneObjectGroup sog)
|
||||
{
|
||||
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
|
||||
|
||||
//m_log.Debug("SOG " + sog.UUID);
|
||||
|
||||
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml);
|
||||
Broadcast(rsm);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,21 +47,72 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
{
|
||||
public class RegionSyncServerModule : IRegionModule, IRegionSyncServerModule, ICommandableModule
|
||||
{
|
||||
private static int DefaultPort = 13000;
|
||||
|
||||
#region IRegionModule Members
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// If no syncConfig, do not start up server mode
|
||||
IConfig syncConfig = config.Configs["RegionSyncModule"];
|
||||
if (syncConfig == null || syncConfig.GetString("Mode", "server").ToLower() != "server")
|
||||
if (syncConfig == null)
|
||||
{
|
||||
scene.RegionSyncEnabled = false;
|
||||
m_active = false;
|
||||
m_log.Warn("[REGION SYNC SERVER MODULE] Not in server mode. Shutting down.");
|
||||
m_log.Warn("[REGION SYNC SERVER MODULE] No RegionSyncModule config section found. Shutting down.");
|
||||
return;
|
||||
}
|
||||
m_serveraddr = syncConfig.GetString("ServerIPAddress", "127.0.0.1");
|
||||
m_serverport = syncConfig.GetInt("ServerPort", 13000);
|
||||
|
||||
// If syncConfig does not indicate "enabled", do not start up server mode
|
||||
bool enabled = syncConfig.GetBoolean("Enabled", true);
|
||||
if(!enabled)
|
||||
{
|
||||
scene.RegionSyncEnabled = false;
|
||||
m_active = false;
|
||||
m_log.Warn("[REGION SYNC SERVER MODULE] RegionSyncModule is not enabled. Shutting down.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If syncConfig does not indicate "server", do not start up server mode
|
||||
string mode = syncConfig.GetString("Mode", "server").ToLower();
|
||||
if(mode != "server")
|
||||
{
|
||||
scene.RegionSyncEnabled = false;
|
||||
m_active = false;
|
||||
m_log.WarnFormat("[REGION SYNC SERVER MODULE] RegionSyncModule is in {0} mode. Shutting down.", mode);
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable region sync in server mode on the scene and module
|
||||
scene.RegionSyncEnabled = true;
|
||||
scene.RegionSyncMode = mode;
|
||||
m_active = true;
|
||||
|
||||
// Init the sync statistics log file
|
||||
string syncstats = "syncstats" + "_" + scene.RegionInfo.RegionName + ".txt";
|
||||
m_statsWriter = File.AppendText(syncstats);
|
||||
|
||||
//Get sync server info for Client Manager actors
|
||||
string serverAddr = scene.RegionInfo.RegionName + "_ServerIPAddress";
|
||||
m_serveraddr = syncConfig.GetString(serverAddr, "127.0.0.1");
|
||||
string serverPort = scene.RegionInfo.RegionName + "_ServerPort";
|
||||
m_serverport = syncConfig.GetInt(serverPort, DefaultPort);
|
||||
// Client manager load balancing
|
||||
m_maxClientsPerManager = syncConfig.GetInt("MaxClientsPerManager", 100);
|
||||
DefaultPort++;
|
||||
|
||||
//Get sync server info for Script Engine actors
|
||||
string seServerAddr = scene.RegionInfo.RegionName + "_SceneToSESyncServerIP";
|
||||
m_seSyncServeraddr = syncConfig.GetString(seServerAddr, "127.0.0.1");
|
||||
string seServerPort = scene.RegionInfo.RegionName + "_SceneToSESyncServerPort";
|
||||
m_seSyncServerport = syncConfig.GetInt(seServerPort, DefaultPort);
|
||||
DefaultPort++;
|
||||
|
||||
//Get quark information
|
||||
QuarkInfo.SizeX = syncConfig.GetInt("QuarkSizeX", (int)Constants.RegionSize);
|
||||
QuarkInfo.SizeY = syncConfig.GetInt("QuarkSizeY", (int)Constants.RegionSize);
|
||||
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<IRegionSyncServerModule>(this);
|
||||
|
||||
|
@ -90,6 +141,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
m_scene.SceneGraph.OnObjectDuplicate += new ObjectDuplicateDelegate(SceneGraph_OnObjectDuplicate);
|
||||
//m_scene.SceneGraph.OnObjectRemove += new ObjectDeleteDelegate(SceneGraph_OnObjectRemove);
|
||||
//m_scene.StatsReporter.OnSendStatsResult += new SimStatsReporter.SendStatResult(StatsReporter_OnSendStatsResult);
|
||||
m_scene.EventManager.OnOarFileLoaded += new EventManager.OarFileLoaded(EventManager_OnOarFileLoaded);
|
||||
|
||||
m_log.Warn("[REGION SYNC SERVER MODULE] Starting RegionSyncServer");
|
||||
// Start the server and listen for RegionSyncClients
|
||||
|
@ -97,17 +149,18 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
m_server.Start();
|
||||
m_statsTimer.Elapsed += new System.Timers.ElapsedEventHandler(StatsTimerElapsed);
|
||||
m_statsTimer.Start();
|
||||
|
||||
m_log.Warn("[REGION SYNC SERVER MODULE] Starting SceneToScriptEngineSyncServer");
|
||||
//Start the sync server for script engines
|
||||
m_sceneToSESyncServer = new SceneToScriptEngineSyncServer(m_scene, m_seSyncServeraddr, m_seSyncServerport);
|
||||
m_sceneToSESyncServer.Start();
|
||||
//m_log.Warn("[REGION SYNC SERVER MODULE] Post-Initialised");
|
||||
}
|
||||
|
||||
private void StatsTimerElapsed(object source, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
if (Synced)
|
||||
{
|
||||
TextWriter tw = File.AppendText("syncstats.txt");
|
||||
m_server.ReportStats(tw);
|
||||
tw.Close();
|
||||
}
|
||||
m_server.ReportStats(m_statsWriter);
|
||||
}
|
||||
|
||||
void IRegionModule.Close()
|
||||
|
@ -124,6 +177,15 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
|
||||
//KittyL added
|
||||
//Later, should make quarkIDs the argument to the function call
|
||||
//public void SendResetScene()
|
||||
//{
|
||||
// m_server.Broadcast(new RegionSyncMessage(RegionSyncMessage.MsgType.ResetScene, "reset"));
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICommandableModule Members
|
||||
|
@ -142,6 +204,8 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
private Dictionary<UUID, ScenePresence> m_presenceUpdates = new Dictionary<UUID, ScenePresence>();
|
||||
|
||||
private System.Timers.Timer m_statsTimer = new System.Timers.Timer(1000);
|
||||
//private TextWriter m_statsWriter = File.AppendText("syncstats.txt");
|
||||
private TextWriter m_statsWriter;
|
||||
|
||||
public void QueuePartForUpdate(SceneObjectPart part)
|
||||
{
|
||||
|
@ -198,8 +262,19 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
{
|
||||
if (!sog.IsDeleted)
|
||||
{
|
||||
/*
|
||||
string sogxml = SceneObjectSerializer.ToXml2Format(sog);
|
||||
|
||||
m_log.Debug("[REGION SYNC SERVER MODULE]: to update object " + sog.UUID + ", localID: "+sog.LocalId
|
||||
+ ", with color " + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.A
|
||||
+ "," + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.B + "," + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.G
|
||||
+ "," + sog.RootPart.Shape.Textures.DefaultTexture.RGBA.R);
|
||||
|
||||
m_server.Broadcast(new RegionSyncMessage(RegionSyncMessage.MsgType.UpdatedObject, sogxml));
|
||||
* */
|
||||
//KittyL: modified to broadcast to different types of actors
|
||||
m_server.BroadcastToCM(RegionSyncMessage.MsgType.UpdatedObject, sog);
|
||||
m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.UpdatedObject, sog);
|
||||
}
|
||||
}
|
||||
foreach (ScenePresence presence in presenceUpdates)
|
||||
|
@ -211,11 +286,11 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
OSDMap data = new OSDMap(7);
|
||||
data["id"] = OSD.FromUUID(presence.UUID);
|
||||
// Do not include offset for appearance height. That will be handled by RegionSyncClient before sending to viewers
|
||||
if (presence.AbsolutePosition.IsFinite())
|
||||
if(presence.AbsolutePosition.IsFinite())
|
||||
data["pos"] = OSD.FromVector3(presence.AbsolutePosition);
|
||||
else
|
||||
data["pos"] = OSD.FromVector3(Vector3.Zero);
|
||||
if (presence.Velocity.IsFinite())
|
||||
if(presence.Velocity.IsFinite())
|
||||
data["vel"] = OSD.FromVector3(presence.Velocity);
|
||||
else
|
||||
data["vel"] = OSD.FromVector3(Vector3.Zero);
|
||||
|
@ -225,6 +300,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
data["anim"] = OSD.FromString(presence.Animator.CurrentMovementAnimation);
|
||||
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.UpdatedAvatar, OSDParser.SerializeJsonString(data));
|
||||
m_server.EnqueuePresenceUpdate(presence.UUID, rsm.ToBytes());
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -268,15 +344,35 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
m_appearanceTimers[agentID] = appearanceSetter;
|
||||
}
|
||||
|
||||
public void DeleteObject(ulong regionHandle, uint localID)
|
||||
public void DeleteObject(ulong regionHandle, uint localID, SceneObjectPart part)
|
||||
{
|
||||
if (!Active || !Synced)
|
||||
return;
|
||||
|
||||
//First, tell client managers to remove the SceneObjectPart
|
||||
OSDMap data = new OSDMap(2);
|
||||
data["regionHandle"] = OSD.FromULong(regionHandle);
|
||||
data["localID"] = OSD.FromUInteger(localID);
|
||||
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
|
||||
//m_server.BroadcastToCM(rsm);
|
||||
m_server.Broadcast(rsm);
|
||||
|
||||
//KittyL: Second, tell script engine to remove the object, identified by UUID
|
||||
//UUID objID = m_scene.GetSceneObjectPart(localID).ParentGroup.UUID;
|
||||
//SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
|
||||
if (part != null)
|
||||
{
|
||||
data = new OSDMap(1);
|
||||
|
||||
data["UUID"] = OSD.FromUUID(part.UUID);
|
||||
rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
|
||||
|
||||
//when an object is deleted, this function (DeleteObject) could be triggered more than once. So we check
|
||||
//if the object part is already removed is the scene (part==null)
|
||||
m_log.Debug("Inform script engine about the deleted object");
|
||||
m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool Active
|
||||
|
@ -284,17 +380,26 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
get { return m_active; }
|
||||
}
|
||||
|
||||
// Check if the sync server module is connected to any clients
|
||||
// Check if the sync server module is connected to any clients (KittyL: edited for testing if connected to any actors)
|
||||
public bool Synced
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_server == null || !m_server.Synced)
|
||||
//if((m_server == null || !m_server.Synced) && (m_sceneToSESyncServer==null || !m_sceneToSESyncServer.Synced))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void SendLoadWorldMap(ITerrainChannel heightMap)
|
||||
{
|
||||
RegionSyncMessage msg = new RegionSyncMessage(RegionSyncMessage.MsgType.Terrain, m_scene.Heightmap.SaveToXmlString());
|
||||
m_server.Broadcast(msg);
|
||||
//KittyL: added for SE
|
||||
m_sceneToSESyncServer.SendToAllConnectedSE(msg);
|
||||
}
|
||||
|
||||
#region cruft
|
||||
#if false
|
||||
|
||||
|
@ -350,6 +455,16 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
private ILog m_log;
|
||||
//private int m_moveCounter = 0;
|
||||
private RegionSyncServer m_server = null;
|
||||
|
||||
//Sync-server for script engines
|
||||
private string m_seSyncServeraddr;
|
||||
private int m_seSyncServerport;
|
||||
private SceneToScriptEngineSyncServer m_sceneToSESyncServer = null;
|
||||
|
||||
//quark related information
|
||||
//private int QuarkInfo.SizeX;
|
||||
//private int QuarkInfo.SizeY;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
@ -357,11 +472,27 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
{
|
||||
if (!Synced)
|
||||
return;
|
||||
|
||||
// m_log.Debug("[RegionSyncServerModule]: SceneGraph_OnObjectCreate() called");
|
||||
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
/*
|
||||
string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)entity);
|
||||
|
||||
SceneObjectGroup sog = (SceneObjectGroup)entity;
|
||||
m_log.Debug("SOG " + sog.UUID);
|
||||
|
||||
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml);
|
||||
m_server.Broadcast(rsm);
|
||||
//KittyL: edited to support both Client Manager and Script Engine actors
|
||||
//m_server.Broadcast(rsm);
|
||||
m_server.BroadcastToCM(rsm);
|
||||
* */
|
||||
SceneObjectGroup sog = (SceneObjectGroup)entity;
|
||||
m_server.BroadcastToCM(RegionSyncMessage.MsgType.NewObject, sog);
|
||||
|
||||
m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.NewObject, sog);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -375,9 +506,13 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
return;
|
||||
if (original is SceneObjectGroup && copy is SceneObjectGroup)
|
||||
{
|
||||
string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)copy);
|
||||
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml);
|
||||
m_server.Broadcast(rsm);
|
||||
|
||||
//string sogxml = SceneObjectSerializer.ToXml2Format((SceneObjectGroup)copy);
|
||||
//RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.NewObject, sogxml);
|
||||
//m_server.Broadcast(rsm);
|
||||
SceneObjectGroup sog = (SceneObjectGroup)copy;
|
||||
m_server.BroadcastToCM(RegionSyncMessage.MsgType.NewObject, sog);
|
||||
m_sceneToSESyncServer.SendToSE(RegionSyncMessage.MsgType.NewObject, sog);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -394,6 +529,20 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
// No reason to send the entire object, just send the UUID to be deleted
|
||||
RegionSyncMessage rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemovedObject, entity.UUID.ToString());
|
||||
m_server.Broadcast(rsm);
|
||||
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(entity.UUID);
|
||||
if (part != null)
|
||||
{
|
||||
OSDMap data = new OSDMap(1);
|
||||
|
||||
data["UUID"] = OSD.FromUUID(part.UUID);
|
||||
rsm = new RegionSyncMessage(RegionSyncMessage.MsgType.RemovedObject, OSDParser.SerializeJsonString(data));
|
||||
|
||||
//when an object is deleted, this function (DeleteObject) could be triggered more than once. So we check
|
||||
//if the object part is already removed is the scene (part==null)
|
||||
m_log.Debug("Inform script engine about the deleted object");
|
||||
m_sceneToSESyncServer.SendToSE(rsm, part.ParentGroup);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -532,6 +681,12 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
m_server.Broadcast(new RegionSyncMessage(RegionSyncMessage.MsgType.RemovedAvatar, OSDParser.SerializeJsonString(data)));
|
||||
}
|
||||
|
||||
private void EventManager_OnOarFileLoaded(Guid requestID, string errorMsg)
|
||||
{
|
||||
//we ignore the requestID and the errorMsg
|
||||
SendLoadWorldMap(m_scene.Heightmap);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Console Command Interface
|
||||
|
@ -609,6 +764,7 @@ namespace OpenSim.Region.CoreModules.RegionSync.RegionSyncModule
|
|||
m_log.DebugFormat("[REGION SYNC SERVER MODULE] LocalChat({0},{1})", msg, channel);
|
||||
m_scene.EventManager.TriggerOnChatBroadcast(this, osm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
|||
{
|
||||
if (s.RegionInfo.RegionHandle == destination.RegionHandle)
|
||||
{
|
||||
m_log.WarnFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName);
|
||||
m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName);
|
||||
return s.NewUserConnection(aCircuit, teleportFlags, out reason);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,10 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
ArrayList GetScriptErrors(UUID itemID);
|
||||
void ResumeScripts();
|
||||
|
||||
#region REGION SYNC
|
||||
void SuspendScripts();
|
||||
#endregion REGION SYNC
|
||||
|
||||
/// <summary>
|
||||
/// Stop all the scripts in this entity.
|
||||
/// </summary>
|
||||
|
|
|
@ -107,5 +107,9 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
void StoreRegionWindlightSettings(RegionLightShareData wl);
|
||||
|
||||
void Shutdown();
|
||||
|
||||
#region REGION SYNC
|
||||
List<SceneObjectGroup> LoadObjectsInGivenSpace(UUID regionID, float lowerX, float lowerY, float upperX, float upperY);
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,8 +41,13 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
void QueuePartForUpdate(SceneObjectPart part);
|
||||
void QueuePresenceForTerseUpdate(ScenePresence presence);
|
||||
void SendUpdates();
|
||||
void DeleteObject(ulong regionHandle, uint localID);
|
||||
//void DeleteObject(ulong regionHandle, uint localID);
|
||||
void DeleteObject(ulong regionHandle, uint localID, SceneObjectPart part);
|
||||
void SendAppearance(UUID agentID, byte[] vp, Primitive.TextureEntry te);
|
||||
|
||||
//KittyL: added to support remote script engine actor
|
||||
//void SendRezScript(SceneObjectGroup sog);
|
||||
//void SendResetScene();
|
||||
void SendLoadWorldMap(ITerrainChannel heightMap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -335,6 +335,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public delegate void RegionUp(GridRegion region);
|
||||
public event RegionUp OnRegionUp;
|
||||
|
||||
|
||||
public class MoneyTransferArgs : EventArgs
|
||||
{
|
||||
public UUID sender;
|
||||
|
@ -2013,5 +2014,86 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//REGION SYNC
|
||||
#region REGION SYNC RELATED EVENTS
|
||||
|
||||
//OnScriptEngineSyncStop: triggered when user types "sync stop" on the script engine's console
|
||||
public delegate void ScriptEngineSyncStop();
|
||||
public event ScriptEngineSyncStop OnScriptEngineSyncStop;
|
||||
public void TriggerScriptEngineSyncStop()
|
||||
{
|
||||
ScriptEngineSyncStop handlerScriptEngineSyncStop = OnScriptEngineSyncStop;
|
||||
if (handlerScriptEngineSyncStop != null)
|
||||
{
|
||||
foreach (ScriptEngineSyncStop d in handlerScriptEngineSyncStop.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
d();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[EVENT MANAGER]: Delegate for TriggerScriptEngineSyncStop failed - continuing. {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//OnUpdateTaskInventoryScriptAsset: triggered after Scene receives client's upload of updated script and stores it as asset
|
||||
public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID);
|
||||
public event UpdateScript OnUpdateScript;
|
||||
public void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
|
||||
{
|
||||
UpdateScript handlerUpdateScript = OnUpdateScript;
|
||||
if (handlerUpdateScript != null)
|
||||
{
|
||||
foreach (UpdateScript d in handlerUpdateScript.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
d(clientId, itemId, primId, isScriptRunning, newAssetID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[EVENT MANAGER]: Delegate for TriggerUpdateScript failed - continuing. {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//OnPopulateLocalSceneList: Triggered by OpenSim to the valid local scene, should only happen in script engine
|
||||
public delegate void PopulateLocalSceneList(List<Scene> localScenes);
|
||||
public event PopulateLocalSceneList OnPopulateLocalSceneList;
|
||||
public void TriggerPopulateLocalSceneList(List<Scene> localScenes)
|
||||
//public delegate void PopulateLocalSceneList(List<Scene> localScenes, string[] cmdparams);
|
||||
//public event PopulateLocalSceneList OnPopulateLocalSceneList;
|
||||
//public void TriggerPopulateLocalSceneList(List<Scene> localScenes, string[] cmdparams)
|
||||
{
|
||||
PopulateLocalSceneList handlerPopulateLocalSceneList = OnPopulateLocalSceneList;
|
||||
if (handlerPopulateLocalSceneList != null)
|
||||
{
|
||||
foreach (PopulateLocalSceneList d in handlerPopulateLocalSceneList.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
d(localScenes);
|
||||
//d(localScenes, cmdparams);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[EVENT MANAGER]: Delegate for TriggerPopulateLocalSceneList failed - continuing. {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,6 +149,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return UUID.Zero;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//REGION SYNC
|
||||
//Scene does permission checking, asset creation and storing, then informs Script Engine to
|
||||
//update the script.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// <summary>
|
||||
/// Capability originating call to update the asset of a script in a prim's (task's) inventory
|
||||
/// </summary>
|
||||
|
@ -195,9 +200,13 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId);
|
||||
AssetService.Store(asset);
|
||||
|
||||
if (isScriptRunning)
|
||||
//REGION SYNC: if RegionSyncEnabled, move script related operations to be after update inventory item
|
||||
if (!RegionSyncEnabled)
|
||||
{
|
||||
part.Inventory.RemoveScriptInstance(item.ItemID, false);
|
||||
if (isScriptRunning)
|
||||
{
|
||||
part.Inventory.RemoveScriptInstance(item.ItemID, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Update item with new asset
|
||||
|
@ -207,23 +216,89 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
part.GetProperties(remoteClient);
|
||||
|
||||
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
|
||||
////REGION SYNC
|
||||
if (!RegionSyncEnabled)
|
||||
{
|
||||
//Original OpenSim code below
|
||||
|
||||
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
|
||||
ArrayList errors = new ArrayList();
|
||||
|
||||
if (isScriptRunning)
|
||||
{
|
||||
// Needs to determine which engine was running it and use that
|
||||
//
|
||||
part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0);
|
||||
errors = part.Inventory.GetScriptErrors(item.ItemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("Script saved", false);
|
||||
}
|
||||
part.ParentGroup.ResumeScripts();
|
||||
return errors;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Distributed Scene Graph is in place, trigger event OnUpdateScript to
|
||||
//let SceneToSEConnector to contact remote script engine for script update
|
||||
m_log.Debug("Scene.Inventory: to call EventManager.TriggerUpdateTaskInventoryScriptAsset, agentID: " + remoteClient.AgentId);
|
||||
EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID);
|
||||
|
||||
//For now, we simple tell client that script saved while waiting for remote script engine to re-rez the script.
|
||||
//Later will change the BaseHttpServer's code to return error list to client.
|
||||
remoteClient.SendAgentAlertMessage("Script saved", false);
|
||||
ArrayList errors = new ArrayList();
|
||||
return errors;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//REGION SYNC
|
||||
//Scene does permission checking, asset creation and storing, then informs Script Engine to
|
||||
//update the script.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//Only should be called when this is the cached Scene of script engine (e.g. from ScriptEngineToSceneConnector)
|
||||
public ArrayList OnUpdateScript(UUID avatarID, UUID itemID, UUID primID, bool isScriptRunning, UUID newAssetID)
|
||||
{
|
||||
ArrayList errors = new ArrayList();
|
||||
//This function is supposed to be executed only on a remote script engine, not an authorative Scene
|
||||
if (!IsSyncedScriptEngine())
|
||||
{
|
||||
m_log.Warn("This is not the script engine. Should not have received OnUpdateScript event.");
|
||||
return errors;
|
||||
}
|
||||
SceneObjectPart part = GetSceneObjectPart(primID);
|
||||
SceneObjectGroup group = part.ParentGroup;
|
||||
if (isScriptRunning)
|
||||
{
|
||||
m_log.Debug("To RemoveScriptInstance");
|
||||
part.Inventory.RemoveScriptInstance(itemID, false);
|
||||
}
|
||||
|
||||
// Retrieve item
|
||||
TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemID);
|
||||
|
||||
// Update item with new asset
|
||||
item.AssetID = newAssetID;
|
||||
group.UpdateInventoryItem(item);
|
||||
m_log.Debug("UpdateInventoryItem on object "+group.UUID);
|
||||
|
||||
if (isScriptRunning)
|
||||
{
|
||||
// Needs to determine which engine was running it and use that
|
||||
//
|
||||
part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0);
|
||||
errors = part.Inventory.GetScriptErrors(item.ItemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("Script saved", false);
|
||||
m_log.Debug("To CreateScriptInstance");
|
||||
part.Inventory.CreateScriptInstance(itemID, 0, false, DefaultScriptEngine, 0);
|
||||
errors = part.Inventory.GetScriptErrors(itemID);
|
||||
}
|
||||
|
||||
part.ParentGroup.ResumeScripts();
|
||||
|
||||
return errors;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// <see>CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])</see>
|
||||
|
@ -235,6 +310,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (TryGetScenePresence(avatarId, out avatar))
|
||||
{
|
||||
//REGION SYNC LOG
|
||||
m_log.Debug("Scene.Inventory: Avatar " + avatarId + ", triggers UpdateTaskInventoryScriptAsset");
|
||||
return CapsUpdateTaskInventoryScriptAsset(
|
||||
avatar.ControllingClient, itemId, primId, isScriptRunning, data);
|
||||
}
|
||||
|
|
|
@ -322,6 +322,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
protected IDialogModule m_dialogModule;
|
||||
protected IEntityTransferModule m_teleportModule;
|
||||
|
||||
#region REGION SYNC
|
||||
protected IRegionSyncServerModule m_regionSyncServerModule;
|
||||
protected IRegionSyncClientModule m_regionSyncClientModule;
|
||||
|
||||
|
@ -344,11 +345,152 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return (m_regionSyncClientModule != null && m_regionSyncClientModule.Active && m_regionSyncClientModule.Synced);
|
||||
}
|
||||
|
||||
//Return true if the sync server thread is active (Mode == server) and has some actors connected
|
||||
public bool IsSyncedServer()
|
||||
{
|
||||
return (m_regionSyncServerModule != null && m_regionSyncServerModule.Active && m_regionSyncServerModule.Synced);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//KittyL: below variables and functions added to support additional actors, e.g. script engine
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//Return true if the sync server thread is active (Mode == server)
|
||||
public bool IsAuthoritativeScene()
|
||||
{
|
||||
//if this is the authoratative scene, then m_regionSyncServerModule.Active == true (mode=server)
|
||||
return (m_regionSyncServerModule != null && m_regionSyncServerModule.Active);
|
||||
}
|
||||
|
||||
private bool m_regionSyncEnabled = false;
|
||||
public bool RegionSyncEnabled
|
||||
{
|
||||
get { return m_regionSyncEnabled; }
|
||||
set { m_regionSyncEnabled = value; }
|
||||
}
|
||||
|
||||
private string m_regionSyncMode = "";
|
||||
public string RegionSyncMode
|
||||
{
|
||||
get { return m_regionSyncMode; }
|
||||
set { m_regionSyncMode = value; }
|
||||
}
|
||||
|
||||
|
||||
protected IScriptEngineToSceneConnectorModule m_scriptEngineToSceneConnectorModule;
|
||||
|
||||
|
||||
public IScriptEngineToSceneConnectorModule ScriptEngineToSceneConnectorModule
|
||||
{
|
||||
get { return m_scriptEngineToSceneConnectorModule; }
|
||||
set { m_scriptEngineToSceneConnectorModule = value; }
|
||||
}
|
||||
|
||||
public bool IsSyncedScriptEngine()
|
||||
{
|
||||
return (m_scriptEngineToSceneConnectorModule != null && m_scriptEngineToSceneConnectorModule.Active && m_scriptEngineToSceneConnectorModule.Synced);
|
||||
}
|
||||
|
||||
public bool ToScheduleFullUpdate()
|
||||
{
|
||||
//Only Scene (SyncServer) or Client Manager (SyncClient) will schedule update to send to its client. Script Engine will not (its update should be sent to Scene).
|
||||
return (IsSyncedClient() || IsSyncedServer() || (IsSyncedScriptEngine() && m_scriptEngineToSceneConnectorModule.DebugWithViewer));
|
||||
}
|
||||
|
||||
|
||||
public bool ToRezScriptByRemoteScriptEngine()
|
||||
{
|
||||
//Only Auth. Scene should trigger scritp rez by remote script engine.
|
||||
return IsSyncedServer();
|
||||
}
|
||||
|
||||
|
||||
//This function should only be called by an actor who's local Scene is just a cache of the authorative Scene.
|
||||
//If the object already exists, use the new copy to replace it.
|
||||
//Return true if added, false if just updated
|
||||
public bool AddOrUpdateObjectInLocalScene(SceneObjectGroup sog, bool debugWithViewer)
|
||||
{
|
||||
return m_sceneGraph.AddOrUpdateObjectInScene(sog, debugWithViewer);
|
||||
|
||||
}
|
||||
|
||||
//public delegate bool TestBorderCrossingOutsideScenes(Scene currentScene, Vector3 pos);
|
||||
public delegate bool TestBorderCrossingOutsideScenes(uint locX, uint locY, Vector3 pos);
|
||||
private TestBorderCrossingOutsideScenes m_isOutsideScenesFunc = null;
|
||||
public TestBorderCrossingOutsideScenes IsOutsideScenes
|
||||
{
|
||||
get { return m_isOutsideScenesFunc; }
|
||||
set { m_isOutsideScenesFunc = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the given position goes outside of the current scene (if not a script engine executing this function),
|
||||
/// or outside of all scenes hosted by the script engine. Parameters curLocX, curLocY, and offset uniquely identify
|
||||
/// the position in the entire space.
|
||||
/// </summary>
|
||||
/// <param name="curLocX">the X coordinate of the scene's left-bottom corner</param>
|
||||
/// <param name="curLocY">the Y coordinate of the scene's left-bottom corner</param>
|
||||
/// <param name="offset">the offset position to the scene's left-bottom corner</param>
|
||||
/// <returns></returns>
|
||||
public bool IsBorderCrossing(uint curLocX, uint curLocY, Vector3 offset)
|
||||
{
|
||||
Vector3 val = offset;
|
||||
if (!RegionSyncEnabled || !(RegionSyncMode == "script_engine"))
|
||||
{
|
||||
//if we are not running Region Sync code, or if we are but this OpenSim instance is not the script engine, then
|
||||
//proceed as original code
|
||||
bool crossing = TestBorderCross(val - Vector3.UnitX, Cardinals.E) || TestBorderCross(val + Vector3.UnitX, Cardinals.W)
|
||||
|| TestBorderCross(val - Vector3.UnitY, Cardinals.N) || TestBorderCross(val + Vector3.UnitY, Cardinals.S);
|
||||
return crossing;
|
||||
}
|
||||
else
|
||||
{
|
||||
//this is script engine
|
||||
if (m_isOutsideScenesFunc == null)
|
||||
{
|
||||
m_log.Warn("Scene " + RegionInfo.RegionName + ": Function IsOutsideScenes not hooked up yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_isOutsideScenesFunc(curLocX, curLocY, val);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadPrimsFromStorageInGivenSpace(string regionName, float minX, float minY, float maxX, float maxY)
|
||||
{
|
||||
m_log.Info("[SCENE]: Loading objects from datastore");
|
||||
|
||||
GridRegion regionInfo = GridService.GetRegionByName(UUID.Zero, regionName);
|
||||
//TODO: need to load objects from the specified space
|
||||
List<SceneObjectGroup> PrimsFromDB = m_storageManager.DataStore.LoadObjectsInGivenSpace(regionInfo.RegionID, minX, minY, maxX, maxY);
|
||||
|
||||
m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count + " objects from the datastore");
|
||||
|
||||
foreach (SceneObjectGroup group in PrimsFromDB)
|
||||
{
|
||||
if (group.RootPart == null)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE] Found a SceneObjectGroup with m_rootPart == null and {0} children",
|
||||
group.Children == null ? 0 : group.Children.Count);
|
||||
}
|
||||
|
||||
AddRestoredSceneObject(group, true, true);
|
||||
SceneObjectPart rootPart = group.GetChildPart(group.UUID);
|
||||
rootPart.ObjectFlags &= ~(uint)PrimFlags.Scripted;
|
||||
rootPart.TrimPermissions();
|
||||
group.CheckSculptAndLoad();
|
||||
//rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
|
||||
}
|
||||
m_log.Info("[SCENE]: Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
|
||||
}
|
||||
|
||||
//public void ToInformActorsLoadOar()
|
||||
//{
|
||||
// m_regionSyncServerModule.SendResetScene();
|
||||
// }
|
||||
|
||||
#endregion
|
||||
|
||||
protected ICapabilitiesModule m_capsModule;
|
||||
public ICapabilitiesModule CapsModule
|
||||
{
|
||||
|
@ -1293,8 +1435,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_dialogModule = RequestModuleInterface<IDialogModule>();
|
||||
m_capsModule = RequestModuleInterface<ICapabilitiesModule>();
|
||||
m_teleportModule = RequestModuleInterface<IEntityTransferModule>();
|
||||
|
||||
//REGION SYNC
|
||||
RegionSyncServerModule = RequestModuleInterface<IRegionSyncServerModule>();
|
||||
RegionSyncClientModule = RequestModuleInterface<IRegionSyncClientModule>();
|
||||
ScriptEngineToSceneConnectorModule = RequestModuleInterface<IScriptEngineToSceneConnectorModule>();
|
||||
|
||||
// Shoving this in here for now, because we have the needed
|
||||
// interfaces at this point
|
||||
|
@ -1900,6 +2045,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
m_log.Warn("[TERRAIN]: Scene.cs: LoadWorldMap() - Failed with exception " + e.ToString());
|
||||
}
|
||||
|
||||
//REGION SYNC
|
||||
//Inform actors of the new terrain
|
||||
if (IsSyncedServer())
|
||||
RegionSyncServerModule.SendLoadWorldMap(Heightmap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -3510,7 +3660,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
// REGION SYNC
|
||||
if( IsSyncedServer() )
|
||||
RegionSyncServerModule.DeleteObject(m_regionHandle, localID);
|
||||
RegionSyncServerModule.DeleteObject(m_regionHandle, localID, part);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -352,14 +352,24 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
sceneObject.AttachToScene(m_parentScene);
|
||||
|
||||
//KittyL: edited to support script engine actor
|
||||
//if (sendClientUpdates)
|
||||
// sceneObject.ScheduleGroupForFullUpdate();
|
||||
if (sendClientUpdates)
|
||||
{
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
|
||||
Entities.Add(sceneObject);
|
||||
m_numPrim += sceneObject.Children.Count;
|
||||
|
||||
if (attachToBackup)
|
||||
//KittyL: edited to support script engine actor
|
||||
//if (attachToBackup)
|
||||
// sceneObject.AttachToBackup();
|
||||
if (attachToBackup && m_parentScene.IsAuthoritativeScene())
|
||||
{
|
||||
sceneObject.AttachToBackup();
|
||||
}
|
||||
|
||||
if (OnObjectCreate != null)
|
||||
OnObjectCreate(sceneObject);
|
||||
|
@ -607,7 +617,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap);
|
||||
List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray);
|
||||
|
||||
|
||||
// Remove the presence reference from the dictionary
|
||||
if (newmap.ContainsKey(agentID))
|
||||
{
|
||||
|
@ -1828,6 +1838,62 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
#endregion
|
||||
|
||||
|
||||
#region REGION SYNC
|
||||
|
||||
protected internal bool IsObjectInScene(SceneObjectGroup sog)
|
||||
{
|
||||
if (Entities.ContainsKey(sog.UUID))
|
||||
return true;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Return false if the entity with the UUID is not a SceneObjectGroup,
|
||||
//otherwise, return true.
|
||||
protected internal bool AddOrUpdateObjectInScene(SceneObjectGroup updatedSog, bool debugWithViewer)
|
||||
{
|
||||
UUID sogID = updatedSog.UUID;
|
||||
|
||||
if (Entities.ContainsKey(sogID))
|
||||
{
|
||||
//update the object
|
||||
EntityBase entity = Entities[sogID];
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
SceneObjectGroup oldSog = (SceneObjectGroup)entity;
|
||||
oldSog.UpdateObjectProperties(updatedSog);
|
||||
|
||||
if (debugWithViewer)
|
||||
{
|
||||
//if we need to debug the script engine with a viewer attaching to it,
|
||||
//we need to schedule updates to be sent to the viewer
|
||||
oldSog.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("Entity with " + sogID + " is not of type SceneObjectGroup");
|
||||
//return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Add a new object
|
||||
//For now, we set sendClientUpdates to true, for debugging purpose -- so that we could log a viewer in to
|
||||
//see if scripts are running properly
|
||||
//Since this is a Script Engine's local Scene cache, do not backup to DB
|
||||
AddSceneObject(updatedSog, false, debugWithViewer);
|
||||
//AddSceneObject(updatedSog, false, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,5 +429,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
part.Inventory.ResumeScripts();
|
||||
}
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
public void SuspendScripts()
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
part.Inventory.SuspendScripts();
|
||||
}
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,12 +292,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
Vector3 val = value;
|
||||
|
||||
if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
|
||||
|| m_scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || m_scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
|
||||
&& !IsAttachmentCheckFull())
|
||||
//REGION SYNC touched
|
||||
|
||||
//if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
|
||||
// || m_scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || m_scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
|
||||
// && !IsAttachmentCheckFull())
|
||||
if (m_scene.IsBorderCrossing(LocX, LocY, val) && !IsAttachmentCheckFull())
|
||||
{
|
||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
||||
}
|
||||
//end REGION SYNC touched
|
||||
if (RootPart.GetStatusSandbox())
|
||||
{
|
||||
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
|
||||
|
@ -1289,7 +1293,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// REGION SYNC
|
||||
if (Scene.IsSyncedServer())
|
||||
{
|
||||
Scene.RegionSyncServerModule.DeleteObject(part.RegionHandle, part.LocalId);
|
||||
Scene.RegionSyncServerModule.DeleteObject(part.RegionHandle, part.LocalId, part);
|
||||
//return;
|
||||
}
|
||||
Scene.ForEachScenePresence(delegate(ScenePresence avatar)
|
||||
|
@ -3615,5 +3619,69 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region REGION SYNC
|
||||
|
||||
//the LocX and LocY of the authoritative scene that this object is located
|
||||
|
||||
private uint m_locX;
|
||||
private uint m_locY;
|
||||
public uint LocX
|
||||
{
|
||||
get { return m_locX; }
|
||||
set { m_locX = value; }
|
||||
}
|
||||
public uint LocY
|
||||
{
|
||||
get { return m_locY; }
|
||||
set { m_locY = value; }
|
||||
}
|
||||
|
||||
|
||||
//update the existing copy of the object with updated properties in 'updatedSog'
|
||||
//TODO: handle updates on script content seperately (e.g. user edited the script and saved it).
|
||||
public void UpdateObjectProperties(SceneObjectGroup updatedSog)
|
||||
{
|
||||
if (!this.GroupID.Equals(updatedSog.GroupID))
|
||||
return;
|
||||
|
||||
//So far this function is written with Script Engine updating local Scene cache in mind.
|
||||
|
||||
//We do not want to simply call SceneObjectGroup.Copy here to clone the object.
|
||||
//We need to preserve the references to the prims (SceneObjectParts) inside the group,
|
||||
//since their scripts are referencing back to the prims, and we have to update those
|
||||
//references if we call SceneObjectGroup.Copy(), which creates new SceneObjectPart for all
|
||||
//non root parts. (So is SceneObjectGroup.CopyPart().)
|
||||
//Plus, we do not need to trigger client updating, since Script engine does not have client connections.
|
||||
Dictionary<UUID, SceneObjectPart> updatedParts = new Dictionary<UUID, SceneObjectPart>();
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, SceneObjectPart> pair in updatedSog.Children){
|
||||
UUID partUUID = pair.Key;
|
||||
SceneObjectPart updatedPart = pair.Value;
|
||||
if(m_parts.ContainsKey(partUUID)){
|
||||
//update the existing part
|
||||
SceneObjectPart oldPart = m_parts[partUUID];
|
||||
oldPart.UpdateObjectPartProperties(updatedPart);
|
||||
updatedParts.Add(partUUID, updatedPart);
|
||||
}else{
|
||||
//a new part
|
||||
m_parts.Add(partUUID,updatedPart);
|
||||
}
|
||||
}
|
||||
|
||||
//delete the parts that are no longer in the object-group
|
||||
foreach(KeyValuePair<UUID, SceneObjectPart> pair in m_parts){
|
||||
if(!updatedParts.ContainsKey(pair.Key)){
|
||||
m_parts.Remove(pair.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//update the authoritative scene that this object is located, which is identified by (LocX, LocY)
|
||||
this.m_locX = updatedSog.LocX;
|
||||
this.m_locY = updatedSog.LocY;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4734,5 +4734,60 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Color color = Color;
|
||||
return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
|
||||
public void UpdateObjectPartProperties(SceneObjectPart updatedPart)
|
||||
{
|
||||
//So far this function is written with Script Engine updating local Scene cache in mind.
|
||||
//
|
||||
//Assumptions:
|
||||
//(1) prim's UUID and LocalID won't change.
|
||||
//(2) CreaterIF, OwnerID, GroupID, won't change
|
||||
//For now, we only update a small set of properties, which is a subset of the serialized object data.
|
||||
//We simply assume other properties won't change. (Just a temporary work-around.)
|
||||
//Properties that will be updated:
|
||||
//GroupPosition, OffsetPosition,RotationOffset, Velocity, AngularVelocity, Acceleration,
|
||||
//<Color /> <LinkNum>0</LinkNum> , Scale
|
||||
//
|
||||
//And we do not update Physics properties.
|
||||
|
||||
//The above assumptions and limited updating actions can be easily fixed once Scene supports
|
||||
//[property name, property value] type of detailed updates.
|
||||
|
||||
//Need to be able to update TaskInventory, so that new scripts will be added
|
||||
|
||||
if (updatedPart == null)
|
||||
return;
|
||||
|
||||
this.GroupPosition = updatedPart.GroupPosition;
|
||||
this.OffsetPosition = updatedPart.OffsetPosition;
|
||||
this.RotationOffset = updatedPart.RotationOffset;
|
||||
this.AngularVelocity = updatedPart.AngularVelocity;
|
||||
this.Acceleration = updatedPart.Acceleration;
|
||||
this.Color = updatedPart.Color;
|
||||
this.LinkNum = updatedPart.LinkNum;
|
||||
this.Velocity = updatedPart.Velocity;
|
||||
this.Scale = updatedPart.Scale;
|
||||
this.SitAnimation = updatedPart.SitAnimation;
|
||||
this.SitName = updatedPart.SitName;
|
||||
this.SitTargetAvatar = updatedPart.SitTargetAvatar;
|
||||
this.SitTargetOrientation = updatedPart.SitTargetOrientation;
|
||||
this.SitTargetOrientationLL = updatedPart.SitTargetOrientationLL;
|
||||
this.SitTargetPosition = updatedPart.SitTargetPosition;
|
||||
this.SitTargetPositionLL = updatedPart.SitTargetPositionLL;
|
||||
|
||||
this.ObjectFlags = updatedPart.ObjectFlags;
|
||||
|
||||
this.m_inventory.Items = (TaskInventoryDictionary)updatedPart.m_inventory.Items.Clone();
|
||||
|
||||
//update shape information, for now, only update fileds in Shape whose set functions are defined in PrimitiveBaseShape
|
||||
this.Shape = updatedPart.Shape.Copy();
|
||||
this.Shape.TextureEntry = updatedPart.Shape.TextureEntry;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1061,5 +1061,34 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
public void SuspendScripts()
|
||||
{
|
||||
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
|
||||
if (engines == null)
|
||||
return;
|
||||
|
||||
lock (m_items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_items.Values)
|
||||
{
|
||||
if (item.InvType == (int)InventoryType.LSL)
|
||||
{
|
||||
foreach (IScriptModule engine in engines)
|
||||
{
|
||||
if (engine != null)
|
||||
{
|
||||
if (item.OwnerChanged)
|
||||
engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
|
||||
item.OwnerChanged = false;
|
||||
engine.SuspendScript(item.ItemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
}
|
||||
|
|
|
@ -768,7 +768,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public void RegisterToEvents()
|
||||
{
|
||||
// REGION SYNC
|
||||
if (!m_scene.IsSyncedServer())// || m_scene.RegionSyncEnabled == false)
|
||||
if (m_scene.IsSyncedServer() || m_scene.RegionSyncEnabled == false)
|
||||
{
|
||||
// These client messages will not be handled by client managers but instead
|
||||
// they are caught by the RegionSyncClient module and passed up to the auth sim
|
||||
|
|
|
@ -278,6 +278,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
|||
//int time = System.Environment.TickCount;
|
||||
|
||||
writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
|
||||
|
||||
//REGION SYNG
|
||||
//Need to add LocX,LocY of the Scene that the object is located in.
|
||||
//writer.WriteStartElement(String.Empty, "LocX", String.Empty);
|
||||
//end of REGION SYGN
|
||||
|
||||
sceneObject.RootPart.ToXml(writer);
|
||||
writer.WriteStartElement(String.Empty, "OtherParts", String.Empty);
|
||||
|
||||
|
|
|
@ -120,6 +120,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
public List<SceneObjectGroup> LoadObjectsInGivenSpace(UUID regionID, float lowerX, float lowerY, float upperX, float upperY)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endregion REGION SYNC
|
||||
}
|
||||
|
||||
public FakeStorageManager() : base(new FakeRegionDataStore())
|
||||
|
|
|
@ -352,6 +352,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
}
|
||||
}
|
||||
|
||||
#region LSL Util functions
|
||||
|
||||
// convert a LSL_Rotation to a Quaternion
|
||||
protected Quaternion Rot2Quaternion(LSL_Rotation r)
|
||||
{
|
||||
|
@ -757,6 +759,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return rotBetween;
|
||||
}
|
||||
|
||||
#endregion //of LSL Util functions
|
||||
|
||||
public void llWhisper(int channelID, string text)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
@ -1154,6 +1158,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return wind;
|
||||
}
|
||||
|
||||
#region REGION SYNC
|
||||
|
||||
//REGION SYNC TOUCHED -- set via sync'ing with remote Scene
|
||||
public void llSetStatus(int status, int value)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
@ -1329,6 +1336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
SetScale(m_host, scale);
|
||||
}
|
||||
|
||||
//REGION SYNC TOUCHED -- set via sync'ing with remote Scene
|
||||
protected void SetScale(SceneObjectPart part, LSL_Vector scale)
|
||||
{
|
||||
// TODO: this needs to trigger a persistance save as well
|
||||
|
@ -1358,12 +1366,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
if (scale.z > World.m_maxNonphys)
|
||||
scale.z = World.m_maxNonphys;
|
||||
|
||||
Vector3 tmp = part.Scale;
|
||||
tmp.X = (float)scale.x;
|
||||
tmp.Y = (float)scale.y;
|
||||
tmp.Z = (float)scale.z;
|
||||
part.Scale = tmp;
|
||||
part.SendFullUpdateToAllClients();
|
||||
if (World.ScriptEngineToSceneConnectorModule==null)
|
||||
{
|
||||
//If Script engine is local to Scene (REGION SYNC mode=server, and XEngine enabled=true, and no remote Script Engine connected)
|
||||
Vector3 tmp = part.Scale;
|
||||
tmp.X = (float)scale.x;
|
||||
tmp.Y = (float)scale.y;
|
||||
tmp.Z = (float)scale.z;
|
||||
part.Scale = tmp;
|
||||
part.SendFullUpdateToAllClients();
|
||||
}
|
||||
else
|
||||
{
|
||||
//set via sync'ing with remote Scene
|
||||
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(part.ParentGroup.LocX, part.ParentGroup.LocY, part.UUID, "scale", scale);
|
||||
}
|
||||
}
|
||||
|
||||
public LSL_Vector llGetScale()
|
||||
|
@ -1381,14 +1398,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return;
|
||||
}
|
||||
|
||||
//REGION SYNC TOUCHED -- set via sync'ing with remote Scene
|
||||
public void llSetColor(LSL_Vector color, int face)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if (face == ScriptBaseClass.ALL_SIDES)
|
||||
face = SceneObjectPart.ALL_SIDES;
|
||||
|
||||
m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
|
||||
|
||||
if (World.ScriptEngineToSceneConnectorModule == null)
|
||||
{
|
||||
m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
|
||||
}
|
||||
else
|
||||
{
|
||||
object[] valParams = new object[2];
|
||||
//valParams[0] = (object)color.x;
|
||||
//valParams[1] = (object)color.y;
|
||||
//valParams[2] = (object)color.z;
|
||||
Vector3 vcolor = new Vector3((float)color.x, (float)color.y, (float)color.z);
|
||||
valParams[0] = (object)vcolor;
|
||||
valParams[1] = (object)face;
|
||||
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "color", (object)valParams);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTexGen(SceneObjectPart part, int face,int style)
|
||||
|
@ -1897,12 +1929,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
}
|
||||
}
|
||||
|
||||
//REGION SYNC TOUCHED -- set via sync'ing with remote Scene -- SetPos is modified.
|
||||
public void llSetPos(LSL_Vector pos)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
SetPos(m_host, pos);
|
||||
|
||||
|
||||
ScriptSleep(200);
|
||||
}
|
||||
|
||||
|
@ -1916,6 +1949,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return end;
|
||||
}
|
||||
|
||||
//REGION SYNC TOUCHED -- set via sync'ing with remote Scene
|
||||
protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
|
||||
{
|
||||
// Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
|
||||
|
@ -1930,16 +1964,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
targetPos.z = ground;
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
|
||||
parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
|
||||
//KittyL: edited below
|
||||
if ((World.ScriptEngineToSceneConnectorModule == null))
|
||||
{
|
||||
parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
|
||||
}
|
||||
else
|
||||
{
|
||||
object[] valParams = new object[1];
|
||||
Vector3 pos = new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z);
|
||||
valParams[0] = (Vector3)pos;
|
||||
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (llVecDist(new LSL_Vector(0,0,0), targetPos) <= 10.0f)
|
||||
{
|
||||
part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
parent.HasGroupChanged = true;
|
||||
parent.ScheduleGroupForTerseUpdate();
|
||||
//KittyL: edited below
|
||||
if ((World.ScriptEngineToSceneConnectorModule == null))
|
||||
{
|
||||
part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
parent.HasGroupChanged = true;
|
||||
parent.ScheduleGroupForTerseUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
object[] valParams = new object[3];
|
||||
valParams[0] = (object)targetPos.x;
|
||||
valParams[1] = (object)targetPos.y;
|
||||
valParams[2] = (object)targetPos.z;
|
||||
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "pos", (object)valParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2692,6 +2749,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
ScriptSleep(100);
|
||||
}
|
||||
|
||||
//REGION SYNC TOUCHED -- set via sync'ing with remote Scene
|
||||
public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
@ -2703,35 +2761,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
if (dist > m_ScriptDistanceFactor * 10.0f)
|
||||
return;
|
||||
|
||||
TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
|
||||
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
|
||||
if (World.ScriptEngineToSceneConnectorModule == null)
|
||||
{
|
||||
if (inv.Value.Name == inventory)
|
||||
//if Scene co-locates with Script Engine
|
||||
|
||||
TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
|
||||
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
|
||||
{
|
||||
// make sure we're an object.
|
||||
if (inv.Value.InvType != (int)InventoryType.Object)
|
||||
if (inv.Value.Name == inventory)
|
||||
{
|
||||
llSay(0, "Unable to create requested object. Object is missing from database.");
|
||||
return;
|
||||
}
|
||||
// make sure we're an object.
|
||||
if (inv.Value.InvType != (int)InventoryType.Object)
|
||||
{
|
||||
llSay(0, "Unable to create requested object. Object is missing from database.");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
|
||||
Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
|
||||
Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
|
||||
Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
|
||||
|
||||
// need the magnitude later
|
||||
float velmag = (float)Util.GetMagnitude(llvel);
|
||||
// need the magnitude later
|
||||
float velmag = (float)Util.GetMagnitude(llvel);
|
||||
|
||||
SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
|
||||
SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
|
||||
|
||||
// If either of these are null, then there was an unknown error.
|
||||
if (new_group == null)
|
||||
continue;
|
||||
if (new_group.RootPart == null)
|
||||
continue;
|
||||
// If either of these are null, then there was an unknown error.
|
||||
if (new_group == null)
|
||||
continue;
|
||||
if (new_group.RootPart == null)
|
||||
continue;
|
||||
|
||||
// objects rezzed with this method are die_at_edge by default.
|
||||
new_group.RootPart.SetDieAtEdge(true);
|
||||
// objects rezzed with this method are die_at_edge by default.
|
||||
new_group.RootPart.SetDieAtEdge(true);
|
||||
|
||||
new_group.ResumeScripts();
|
||||
|
||||
|
@ -2739,23 +2801,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
"object_rez", new Object[] {
|
||||
new LSL_String(
|
||||
new_group.RootPart.UUID.ToString()) },
|
||||
new DetectParams[0]));
|
||||
new DetectParams[0]));
|
||||
|
||||
float groupmass = new_group.GetMass();
|
||||
float groupmass = new_group.GetMass();
|
||||
|
||||
if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero)
|
||||
{
|
||||
//Recoil.
|
||||
llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
|
||||
if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero)
|
||||
{
|
||||
//Recoil.
|
||||
llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
|
||||
}
|
||||
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
|
||||
ScriptSleep((int)((groupmass * velmag) / 10));
|
||||
ScriptSleep(100);
|
||||
return;
|
||||
}
|
||||
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
|
||||
ScriptSleep((int)((groupmass * velmag) / 10));
|
||||
ScriptSleep(100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
llSay(0, "Could not find object " + inventory);
|
||||
llSay(0, "Could not find object " + inventory);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Scene does not co-locate with Script Engine
|
||||
Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
|
||||
Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
|
||||
Quaternion llrot = Rot2Quaternion(rot);
|
||||
object[] valParams = new object[5];
|
||||
valParams[0] = (object)inventory;
|
||||
valParams[1] = (object)llpos;
|
||||
valParams[2] = (object)llpos;
|
||||
valParams[3] = (object)llrot;
|
||||
valParams[4] = (object)param;
|
||||
//we borrow the implementation SendSetPrimProperties to send the message to Scene
|
||||
World.ScriptEngineToSceneConnectorModule.SendSetPrimProperties(m_host.ParentGroup.LocX, m_host.ParentGroup.LocY, m_host.UUID, "object_rez", (object)valParams);
|
||||
|
||||
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
|
||||
//ScriptSleep((int)((groupmass * velmag) / 10));
|
||||
ScriptSleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
|
||||
|
@ -6542,6 +6624,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return Util.SHA1Hash(src).ToLower();
|
||||
}
|
||||
|
||||
#endregion REGION SYNC
|
||||
|
||||
protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
|
||||
{
|
||||
ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
|
||||
|
|
|
@ -322,6 +322,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
m_Scene.EventManager.OnGetScriptRunning += OnGetScriptRunning;
|
||||
m_Scene.EventManager.OnShutdown += OnShutdown;
|
||||
|
||||
//REGION SYNC events
|
||||
m_Scene.EventManager.OnScriptEngineSyncStop += OnScriptEngineSyncStop;
|
||||
//end REGION SYNC
|
||||
|
||||
if (m_SleepTime > 0)
|
||||
{
|
||||
m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoMaintenance),
|
||||
|
@ -1601,5 +1605,57 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
|
||||
instance.Resume();
|
||||
}
|
||||
|
||||
#region REGION SYNC functions
|
||||
|
||||
//eventually triggered when user typed "sync stop" at the script engine's console
|
||||
public void OnScriptEngineSyncStop()
|
||||
{
|
||||
//DoBackup();
|
||||
|
||||
//save the script states, stop script instances, and clear records
|
||||
//similar to RemoveRegion(), except that still keep the engine in
|
||||
//m_scriptEngines.
|
||||
lock (m_Scripts)
|
||||
{
|
||||
foreach (IScriptInstance instance in m_Scripts.Values)
|
||||
{
|
||||
// Force a final state save
|
||||
//
|
||||
if (m_Assemblies.ContainsKey(instance.AssetID))
|
||||
{
|
||||
string assembly = m_Assemblies[instance.AssetID];
|
||||
instance.SaveState(assembly);
|
||||
}
|
||||
|
||||
// Clear the event queue and abort the instance thread
|
||||
//
|
||||
instance.ClearQueue();
|
||||
instance.Stop(0);
|
||||
|
||||
// Release events, timer, etc
|
||||
//
|
||||
instance.DestroyScriptInstance();
|
||||
|
||||
// Unload scripts and app domains
|
||||
// Must be done explicitly because they have infinite
|
||||
// lifetime
|
||||
//
|
||||
m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
|
||||
if (m_DomainScripts[instance.AppDomain].Count == 0)
|
||||
{
|
||||
m_DomainScripts.Remove(instance.AppDomain);
|
||||
UnloadAppDomain(instance.AppDomain);
|
||||
}
|
||||
}
|
||||
m_Scripts.Clear();
|
||||
m_PrimObjects.Clear();
|
||||
m_Assemblies.Clear();
|
||||
m_DomainScripts.Clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue