mirror of
https://github.com/opensim/opensim.git
synced 2026-08-05 08:55:56 +08:00
Merge branch 'master-core' into mantis5110
This commit is contained in:
@@ -41,19 +41,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
/// </summary>
|
||||
public class AgentAssetTransactions
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// Fields
|
||||
private bool m_dumpAssetsToFile;
|
||||
public AssetTransactionModule Manager;
|
||||
private Scene m_Scene;
|
||||
public UUID UserID;
|
||||
public Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
|
||||
public Dictionary<UUID, AssetXferUploader> XferUploaders =
|
||||
new Dictionary<UUID, AssetXferUploader>();
|
||||
|
||||
// Methods
|
||||
public AgentAssetTransactions(UUID agentID, AssetTransactionModule manager, bool dumpAssetsToFile)
|
||||
public AgentAssetTransactions(UUID agentID, Scene scene,
|
||||
bool dumpAssetsToFile)
|
||||
{
|
||||
m_Scene = scene;
|
||||
UserID = agentID;
|
||||
Manager = manager;
|
||||
m_dumpAssetsToFile = dumpAssetsToFile;
|
||||
}
|
||||
|
||||
@@ -61,7 +64,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
{
|
||||
if (!XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile);
|
||||
AssetXferUploader uploader = new AssetXferUploader(m_Scene,
|
||||
m_dumpAssetsToFile);
|
||||
|
||||
lock (XferUploaders)
|
||||
{
|
||||
@@ -88,22 +92,25 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
|
||||
uint callbackID, string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
public void RequestCreateInventoryItem(IClientAPI remoteClient,
|
||||
UUID transactionID, UUID folderID, uint callbackID,
|
||||
string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
{
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID,
|
||||
callbackID, description, name, invType, type,
|
||||
wearableType, nextOwnerMask);
|
||||
XferUploaders[transactionID].RequestCreateInventoryItem(
|
||||
remoteClient, transactionID, folderID,
|
||||
callbackID, description, name, invType, type,
|
||||
wearableType, nextOwnerMask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed.
|
||||
/// Get an uploaded asset. If the data is successfully retrieved,
|
||||
/// the transaction will be removed.
|
||||
/// </summary>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <returns>The asset if the upload has completed, null if it has not.</returns>
|
||||
@@ -125,105 +132,56 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
return null;
|
||||
}
|
||||
|
||||
//private void CreateItemFromUpload(AssetBase asset, IClientAPI ourClient, UUID inventoryFolderID, uint nextPerms, uint wearableType)
|
||||
//{
|
||||
// Manager.MyScene.CommsManager.AssetCache.AddAsset(asset);
|
||||
// CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
|
||||
// ourClient.AgentId);
|
||||
|
||||
// if (userInfo != null)
|
||||
// {
|
||||
// InventoryItemBase item = new InventoryItemBase();
|
||||
// item.Owner = ourClient.AgentId;
|
||||
// item.Creator = ourClient.AgentId;
|
||||
// item.ID = UUID.Random();
|
||||
// item.AssetID = asset.FullID;
|
||||
// item.Description = asset.Description;
|
||||
// item.Name = asset.Name;
|
||||
// item.AssetType = asset.Type;
|
||||
// item.InvType = asset.Type;
|
||||
// item.Folder = inventoryFolderID;
|
||||
// item.BasePermissions = 0x7fffffff;
|
||||
// item.CurrentPermissions = 0x7fffffff;
|
||||
// item.EveryOnePermissions = 0;
|
||||
// item.NextPermissions = nextPerms;
|
||||
// item.Flags = wearableType;
|
||||
// item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
|
||||
// userInfo.AddItem(item);
|
||||
// ourClient.SendInventoryItemCreateUpdate(item);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_log.ErrorFormat(
|
||||
// "[ASSET TRANSACTIONS]: Could not find user {0} for inventory item creation",
|
||||
// ourClient.AgentId);
|
||||
// }
|
||||
//}
|
||||
|
||||
public void RequestUpdateTaskInventoryItem(
|
||||
IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
|
||||
public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
|
||||
SceneObjectPart part, UUID transactionID,
|
||||
TaskInventoryItem item)
|
||||
{
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
AssetBase asset = XferUploaders[transactionID].GetAssetData();
|
||||
AssetBase asset = GetTransactionAsset(transactionID);
|
||||
|
||||
// Only legacy viewers use this, and they prefer CAPS, which
|
||||
// we have, so this really never runs.
|
||||
// Allow it, but only for "safe" types.
|
||||
if ((InventoryType)item.InvType != InventoryType.Notecard &&
|
||||
(InventoryType)item.InvType != InventoryType.LSL)
|
||||
return;
|
||||
|
||||
if (asset != null)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ASSET TRANSACTIONS]: Updating task item {0} in {1} with asset in transaction {2}",
|
||||
item.Name, part.Name, transactionID);
|
||||
|
||||
asset.FullID = UUID.Random();
|
||||
asset.Name = item.Name;
|
||||
asset.Description = item.Description;
|
||||
asset.Type = (sbyte)item.Type;
|
||||
item.AssetID = asset.FullID;
|
||||
|
||||
Manager.MyScene.AssetService.Store(asset);
|
||||
m_Scene.AssetService.Store(asset);
|
||||
|
||||
if (part.Inventory.UpdateInventoryItem(item))
|
||||
{
|
||||
if ((InventoryType)item.InvType == InventoryType.Notecard)
|
||||
remoteClient.SendAgentAlertMessage("Notecard saved", false);
|
||||
else if ((InventoryType)item.InvType == InventoryType.LSL)
|
||||
remoteClient.SendAgentAlertMessage("Script saved", false);
|
||||
else
|
||||
remoteClient.SendAgentAlertMessage("Item saved", false);
|
||||
|
||||
part.GetProperties(remoteClient);
|
||||
}
|
||||
part.Inventory.UpdateInventoryItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID,
|
||||
InventoryItemBase item)
|
||||
public void RequestUpdateInventoryItem(IClientAPI remoteClient,
|
||||
UUID transactionID, InventoryItemBase item)
|
||||
{
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
if (XferUploaders.ContainsKey(transactionID))
|
||||
{
|
||||
UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId);
|
||||
AssetBase asset = GetTransactionAsset(transactionID);
|
||||
|
||||
AssetBase asset = Manager.MyScene.AssetService.Get(assetID.ToString());
|
||||
|
||||
if (asset == null)
|
||||
if (asset != null)
|
||||
{
|
||||
asset = GetTransactionAsset(transactionID);
|
||||
}
|
||||
|
||||
if (asset != null && asset.FullID == assetID)
|
||||
{
|
||||
// Assets never get updated, new ones get created
|
||||
asset.FullID = UUID.Random();
|
||||
asset.Name = item.Name;
|
||||
asset.Description = item.Description;
|
||||
asset.Type = (sbyte)item.AssetType;
|
||||
item.AssetID = asset.FullID;
|
||||
|
||||
Manager.MyScene.AssetService.Store(asset);
|
||||
}
|
||||
m_Scene.AssetService.Store(asset);
|
||||
|
||||
IInventoryService invService = Manager.MyScene.InventoryService;
|
||||
invService.UpdateItem(item);
|
||||
IInventoryService invService = m_Scene.InventoryService;
|
||||
invService.UpdateItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,22 +34,19 @@ using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using Mono.Addins;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
{
|
||||
public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AssetTransactionModule")]
|
||||
public class AssetTransactionModule : INonSharedRegionModule,
|
||||
IAgentAssetTransactions
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private readonly Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
|
||||
protected Scene m_Scene;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private Scene m_scene = null;
|
||||
|
||||
[Obsolete]
|
||||
public Scene MyScene
|
||||
{
|
||||
get{ return m_scene;}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Each agent has its own singleton collection of transactions
|
||||
@@ -57,33 +54,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
private Dictionary<UUID, AgentAssetTransactions> AgentTransactions =
|
||||
new Dictionary<UUID, AgentAssetTransactions>();
|
||||
|
||||
|
||||
public AssetTransactionModule()
|
||||
{
|
||||
//m_log.Debug("creating AgentAssetTransactionModule");
|
||||
}
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||
{
|
||||
// m_log.Debug("initialising AgentAssetTransactionModule");
|
||||
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
|
||||
scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
|
||||
|
||||
scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
// EVIL HACK!
|
||||
// This needs killing!
|
||||
//
|
||||
if (m_scene == null)
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
m_Scene = scene;
|
||||
scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
|
||||
scene.EventManager.OnNewClient += NewClient;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -96,9 +84,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
get { return "AgentTransactionModule"; }
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return true; }
|
||||
get { return typeof(IAgentAssetTransactions); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -111,8 +99,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
|
||||
#region AgentAssetTransactions
|
||||
/// <summary>
|
||||
/// Get the collection of asset transactions for the given user. If one does not already exist, it
|
||||
/// is created.
|
||||
/// Get the collection of asset transactions for the given user.
|
||||
/// If one does not already exist, it is created.
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <returns></returns>
|
||||
@@ -122,7 +110,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
{
|
||||
if (!AgentTransactions.ContainsKey(userID))
|
||||
{
|
||||
AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile);
|
||||
AgentAssetTransactions transactions =
|
||||
new AgentAssetTransactions(userID, m_Scene,
|
||||
m_dumpAssetsToFile);
|
||||
|
||||
AgentTransactions.Add(userID, transactions);
|
||||
}
|
||||
|
||||
@@ -131,8 +122,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the given agent asset transactions. This should be called when a client is departing
|
||||
/// from a scene (and hence won't be making any more transactions here).
|
||||
/// Remove the given agent asset transactions. This should be called
|
||||
/// when a client is departing from a scene (and hence won't be making
|
||||
/// any more transactions here).
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
public void RemoveAgentAssetTransactions(UUID userID)
|
||||
@@ -146,10 +138,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an inventory item from data that has been received through a transaction.
|
||||
///
|
||||
/// This is called when new clothing or body parts are created. It may also be called in other
|
||||
/// situations.
|
||||
/// Create an inventory item from data that has been received through
|
||||
/// a transaction.
|
||||
/// This is called when new clothing or body parts are created.
|
||||
/// It may also be called in other situations.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
@@ -161,61 +153,72 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
/// <param name="type"></param>
|
||||
/// <param name="wearableType"></param>
|
||||
/// <param name="nextOwnerMask"></param>
|
||||
public void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID,
|
||||
uint callbackID, string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
public void HandleItemCreationFromTransaction(IClientAPI remoteClient,
|
||||
UUID transactionID, UUID folderID, uint callbackID,
|
||||
string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
|
||||
// m_log.DebugFormat(
|
||||
// "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
|
||||
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
AgentAssetTransactions transactions =
|
||||
GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.RequestCreateInventoryItem(
|
||||
remoteClient, transactionID, folderID, callbackID, description,
|
||||
name, invType, type, wearableType, nextOwnerMask);
|
||||
transactions.RequestCreateInventoryItem(remoteClient, transactionID,
|
||||
folderID, callbackID, description, name, invType, type,
|
||||
wearableType, nextOwnerMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update an inventory item with data that has been received through a transaction.
|
||||
/// Update an inventory item with data that has been received through a
|
||||
/// transaction.
|
||||
///
|
||||
/// This is called when clothing or body parts are updated (for instance, with new textures or
|
||||
/// colours). It may also be called in other situations.
|
||||
/// This is called when clothing or body parts are updated (for
|
||||
/// instance, with new textures or colours). It may also be called in
|
||||
/// other situations.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="item"></param>
|
||||
public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID,
|
||||
InventoryItemBase item)
|
||||
public void HandleItemUpdateFromTransaction(IClientAPI remoteClient,
|
||||
UUID transactionID, InventoryItemBase item)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
|
||||
// item.Name);
|
||||
// m_log.DebugFormat(
|
||||
// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
|
||||
// item.Name);
|
||||
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
AgentAssetTransactions transactions =
|
||||
GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
|
||||
transactions.RequestUpdateInventoryItem(remoteClient,
|
||||
transactionID, item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update a task inventory item with data that has been received through a transaction.
|
||||
/// Update a task inventory item with data that has been received
|
||||
/// through a transaction.
|
||||
///
|
||||
/// This is currently called when, for instance, a notecard in a prim is saved. The data is sent
|
||||
/// up through a single AssetUploadRequest. A subsequent UpdateTaskInventory then references the transaction
|
||||
/// This is currently called when, for instance, a notecard in a prim
|
||||
/// is saved. The data is sent up through a single AssetUploadRequest.
|
||||
/// A subsequent UpdateTaskInventory then references the transaction
|
||||
/// and comes through this method.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="item"></param>
|
||||
public void HandleTaskItemUpdateFromTransaction(
|
||||
IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
|
||||
public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient,
|
||||
SceneObjectPart part, UUID transactionID,
|
||||
TaskInventoryItem item)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
|
||||
// item.Name);
|
||||
// m_log.DebugFormat(
|
||||
// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
|
||||
// item.Name);
|
||||
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
AgentAssetTransactions transactions =
|
||||
GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.RequestUpdateTaskInventoryItem(remoteClient, part, transactionID, item);
|
||||
transactions.RequestUpdateTaskInventoryItem(remoteClient, part,
|
||||
transactionID, item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -227,8 +230,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param></param>
|
||||
/// <param name="tempFile"></param>
|
||||
public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type,
|
||||
byte[] data, bool storeLocal, bool tempFile)
|
||||
public void HandleUDPUploadRequest(IClientAPI remoteClient,
|
||||
UUID assetID, UUID transaction, sbyte type, byte[] data,
|
||||
bool storeLocal, bool tempFile)
|
||||
{
|
||||
// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile);
|
||||
|
||||
@@ -251,27 +255,33 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
}
|
||||
}
|
||||
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
AgentAssetTransactions transactions =
|
||||
GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
AssetXferUploader uploader =
|
||||
transactions.RequestXferUploader(transaction);
|
||||
|
||||
AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
|
||||
if (uploader != null)
|
||||
{
|
||||
uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
|
||||
uploader.Initialise(remoteClient, assetID, transaction, type,
|
||||
data, storeLocal, tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle asset transfer data packets received in response to the asset upload request in
|
||||
/// HandleUDPUploadRequest()
|
||||
/// Handle asset transfer data packets received in response to the
|
||||
/// asset upload request in HandleUDPUploadRequest()
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="xferID"></param>
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
|
||||
public void HandleXfer(IClientAPI remoteClient, ulong xferID,
|
||||
uint packetID, byte[] data)
|
||||
{
|
||||
//m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!");
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
AgentAssetTransactions transactions =
|
||||
GetUserTransactions(remoteClient.AgentId);
|
||||
|
||||
transactions.HandleXfer(xferID, packetID, data);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
@@ -50,17 +50,17 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
private bool m_finished = false;
|
||||
private string m_name = String.Empty;
|
||||
private bool m_storeLocal;
|
||||
private AgentAssetTransactions m_userTransactions;
|
||||
private uint nextPerm = 0;
|
||||
private IClientAPI ourClient;
|
||||
private UUID TransactionID = UUID.Zero;
|
||||
private sbyte type = 0;
|
||||
private byte wearableType = 0;
|
||||
public ulong XferID;
|
||||
private Scene m_Scene;
|
||||
|
||||
public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile)
|
||||
public AssetXferUploader(Scene scene, bool dumpAssetToFile)
|
||||
{
|
||||
m_userTransactions = transactions;
|
||||
m_Scene = scene;
|
||||
m_dumpAssetToFile = dumpAssetToFile;
|
||||
}
|
||||
|
||||
@@ -108,11 +108,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
/// <param name="packetID"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns>True if the transfer is complete, false otherwise</returns>
|
||||
public bool Initialise(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data,
|
||||
bool storeLocal, bool tempFile)
|
||||
public bool Initialise(IClientAPI remoteClient, UUID assetID,
|
||||
UUID transaction, sbyte type, byte[] data, bool storeLocal,
|
||||
bool tempFile)
|
||||
{
|
||||
ourClient = remoteClient;
|
||||
m_asset = new AssetBase(assetID, "blank", type, remoteClient.AgentId.ToString());
|
||||
m_asset = new AssetBase(assetID, "blank", type,
|
||||
remoteClient.AgentId.ToString());
|
||||
m_asset.Data = data;
|
||||
m_asset.Description = "empty";
|
||||
m_asset.Local = storeLocal;
|
||||
@@ -137,12 +139,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
protected void RequestStartXfer()
|
||||
{
|
||||
XferID = Util.GetNextXferID();
|
||||
ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]);
|
||||
ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID,
|
||||
0, new byte[0]);
|
||||
}
|
||||
|
||||
protected void SendCompleteMessage()
|
||||
{
|
||||
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
|
||||
ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
|
||||
m_asset.FullID);
|
||||
|
||||
m_finished = true;
|
||||
if (m_createItem)
|
||||
@@ -151,18 +155,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
}
|
||||
else if (m_storeLocal)
|
||||
{
|
||||
m_userTransactions.Manager.MyScene.AssetService.Store(m_asset);
|
||||
m_Scene.AssetService.Store(m_asset);
|
||||
}
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", m_asset.FullID, TransactionID);
|
||||
"[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}",
|
||||
m_asset.FullID, TransactionID);
|
||||
|
||||
if (m_dumpAssetToFile)
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
string filename =
|
||||
String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day,
|
||||
now.Hour, now.Minute, now.Second, m_asset.Name, m_asset.Type);
|
||||
String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
|
||||
now.Year, now.Month, now.Day, now.Hour, now.Minute,
|
||||
now.Second, m_asset.Name, m_asset.Type);
|
||||
SaveAssetToFile(filename, m_asset.Data);
|
||||
}
|
||||
}
|
||||
@@ -181,9 +187,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
|
||||
uint callbackID, string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
public void RequestCreateInventoryItem(IClientAPI remoteClient,
|
||||
UUID transactionID, UUID folderID, uint callbackID,
|
||||
string description, string name, sbyte invType,
|
||||
sbyte type, byte wearableType, uint nextOwnerMask)
|
||||
{
|
||||
if (TransactionID == transactionID)
|
||||
{
|
||||
@@ -212,7 +219,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
|
||||
private void DoCreateItem(uint callbackID)
|
||||
{
|
||||
m_userTransactions.Manager.MyScene.AssetService.Store(m_asset);
|
||||
m_Scene.AssetService.Store(m_asset);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.Owner = ourClient.AgentId;
|
||||
@@ -232,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
item.Flags = (uint) wearableType;
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
|
||||
if (m_userTransactions.Manager.MyScene.AddInventoryItem(item))
|
||||
if (m_Scene.AddInventoryItem(item))
|
||||
ourClient.SendInventoryItemCreateUpdate(item, callbackID);
|
||||
else
|
||||
ourClient.SendAlertMessage("Unable to create inventory item");
|
||||
|
||||
@@ -115,7 +115,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Check for the existence of the baked texture assets. Request a rebake
|
||||
/// unless checkonly is true.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="checkonly"></param>
|
||||
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||
{
|
||||
return ValidateBakedTextureCache(client, true);
|
||||
}
|
||||
|
||||
private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
@@ -131,15 +142,33 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
|
||||
if (face == null || face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||
|
||||
// if there is no texture entry, skip it
|
||||
if (face == null)
|
||||
continue;
|
||||
|
||||
// if the texture is one of the "defaults" then skip it
|
||||
// this should probably be more intelligent (skirt texture doesnt matter
|
||||
// if the avatar isnt wearing a skirt) but if any of the main baked
|
||||
// textures is default then the rest should be as well
|
||||
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||
continue;
|
||||
|
||||
defonly = false; // found a non-default texture reference
|
||||
|
||||
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
|
||||
return false;
|
||||
{
|
||||
// the asset didn't exist if we are only checking, then we found a bad
|
||||
// one and we're done otherwise, ask for a rebake
|
||||
if (checkonly) return false;
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY] missing baked texture {0}, request rebake",face.TextureID);
|
||||
client.SendRebakeAvatarTextures(face.TextureID);
|
||||
}
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY]: complete texture check for {0}",client.AgentId);
|
||||
|
||||
// If we only found default textures, then the appearance is not cached
|
||||
return (defonly ? false : true);
|
||||
}
|
||||
@@ -158,61 +187,43 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
return;
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Start SetAppearance for {0}",client.AgentId);
|
||||
m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}",client.AgentId);
|
||||
|
||||
// TODO: This is probably not necessary any longer, just assume the
|
||||
// textureEntry set implies that the appearance transaction is complete
|
||||
bool changed = false;
|
||||
|
||||
// Process the texture entry transactionally, this doesn't guarantee that Appearance is
|
||||
// going to be handled correctly but it does serialize the updates to the appearance
|
||||
lock (m_setAppearanceLock)
|
||||
{
|
||||
if (textureEntry != null)
|
||||
{
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry);
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Prepare to check textures for {0}",client.AgentId);
|
||||
|
||||
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||
{
|
||||
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
|
||||
if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||
Util.FireAndForget(delegate(object o) {
|
||||
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
|
||||
client.SendRebakeAvatarTextures(face.TextureID);
|
||||
});
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId);
|
||||
}
|
||||
|
||||
// Process the visual params, this may change height as well
|
||||
if (visualParams != null)
|
||||
{
|
||||
if (sp.Appearance.SetVisualParams(visualParams))
|
||||
{
|
||||
changed = true;
|
||||
if (sp.Appearance.AvatarHeight > 0)
|
||||
sp.SetHeight(sp.Appearance.AvatarHeight);
|
||||
}
|
||||
changed = sp.Appearance.SetVisualParams(visualParams);
|
||||
if (sp.Appearance.AvatarHeight > 0)
|
||||
sp.SetHeight(sp.Appearance.AvatarHeight);
|
||||
}
|
||||
|
||||
// Send the appearance back to the avatar, not clear that this is needed
|
||||
sp.ControllingClient.SendAvatarDataImmediate(sp);
|
||||
// AvatarAppearance avp = sp.Appearance;
|
||||
// sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes());
|
||||
// Process the baked texture array
|
||||
if (textureEntry != null)
|
||||
{
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY]: received texture update for {0}",client.AgentId);
|
||||
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); });
|
||||
|
||||
// This appears to be set only in the final stage of the appearance
|
||||
// update transaction. In theory, we should be able to do an immediate
|
||||
// appearance send and save here.
|
||||
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
QueueAppearanceSend(client.AgentId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// If something changed in the appearance then queue an appearance save
|
||||
if (changed)
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
|
||||
// And always queue up an appearance update to send out
|
||||
QueueAppearanceSend(client.AgentId);
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
|
||||
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -235,6 +246,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
#region UpdateAppearanceTimer
|
||||
|
||||
/// <summary>
|
||||
/// Queue up a request to send appearance, makes it possible to
|
||||
/// accumulate changes without sending out each one separately.
|
||||
/// </summary>
|
||||
public void QueueAppearanceSend(UUID agentid)
|
||||
{
|
||||
// m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
|
||||
@@ -274,21 +289,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
// sp.ControllingClient.SendAvatarDataImmediate(sp);
|
||||
|
||||
// Send the appearance back to the avatar
|
||||
// AvatarAppearance avp = sp.Appearance;
|
||||
// sp.ControllingClient.SendAppearance(avp.Owner, avp.VisualParams, avp.Texture.GetBytes());
|
||||
|
||||
/*
|
||||
// this needs to be fixed, the flag should be on scene presence not the region module
|
||||
// Start the animations if necessary
|
||||
if (!m_startAnimationSet)
|
||||
{
|
||||
sp.Animator.UpdateMovementAnimations();
|
||||
m_startAnimationSet = true;
|
||||
}
|
||||
*/
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
}
|
||||
|
||||
private void HandleAppearanceSave(UUID agentid)
|
||||
@@ -374,8 +377,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
|
||||
|
||||
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
|
||||
// we need to clean out the existing textures
|
||||
sp.Appearance.ResetAppearance();
|
||||
|
||||
// operate on a copy of the appearance so we don't have to lock anything
|
||||
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
|
||||
|
||||
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
||||
{
|
||||
if (wear.Type < AvatarWearable.MAX_WEARABLES)
|
||||
@@ -388,9 +395,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
SetAppearanceAssets(sp.UUID, ref avatAppearance);
|
||||
|
||||
// could get fancier with the locks here, but in the spirit of "last write wins"
|
||||
// this should work correctly
|
||||
// this should work correctly, also, we don't need to send the appearance here
|
||||
// since the "iswearing" will trigger a new set of visual param and baked texture changes
|
||||
// when those complete, the new appearance will be sent
|
||||
sp.Appearance = avatAppearance;
|
||||
m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance);
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
}
|
||||
|
||||
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
|
||||
|
||||
@@ -37,12 +37,11 @@ using System.Xml.Linq;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Communications.Osp;
|
||||
using OpenSim.Framework.Serialization;
|
||||
using OpenSim.Framework.Serialization.External;
|
||||
using OpenSim.Region.CoreModules.World.Archiver;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
@@ -398,20 +397,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
// Don't use the item ID that's in the file
|
||||
item.ID = UUID.Random();
|
||||
|
||||
UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService);
|
||||
if (UUID.Zero != ospResolvedId)
|
||||
UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService);
|
||||
if (UUID.Zero != ospResolvedId) // The user exists in this grid
|
||||
{
|
||||
item.CreatorIdAsUuid = ospResolvedId;
|
||||
|
||||
// XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the
|
||||
// database). Instead, replace with the UUID that we found.
|
||||
item.CreatorId = ospResolvedId.ToString();
|
||||
|
||||
item.CreatorData = string.Empty;
|
||||
}
|
||||
else
|
||||
else if (item.CreatorData == null || item.CreatorData == String.Empty)
|
||||
{
|
||||
item.CreatorIdAsUuid = m_userInfo.PrincipalID;
|
||||
}
|
||||
|
||||
|
||||
item.Owner = m_userInfo.PrincipalID;
|
||||
|
||||
// Reset folder ID to the one in which we want to load it
|
||||
|
||||
@@ -36,8 +36,6 @@ using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Serialization;
|
||||
using OpenSim.Framework.Serialization.External;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Communications.Osp;
|
||||
using OpenSim.Region.CoreModules.World.Archiver;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
@@ -139,20 +137,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
|
||||
}
|
||||
|
||||
protected void SaveInvItem(InventoryItemBase inventoryItem, string path)
|
||||
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||
{
|
||||
string filename = path + CreateArchiveItemName(inventoryItem);
|
||||
|
||||
// Record the creator of this item for user record purposes (which might go away soon)
|
||||
m_userUuids[inventoryItem.CreatorIdAsUuid] = 1;
|
||||
|
||||
InventoryItemBase saveItem = (InventoryItemBase)inventoryItem.Clone();
|
||||
saveItem.CreatorId = OspResolver.MakeOspa(saveItem.CreatorIdAsUuid, m_scene.UserAccountService);
|
||||
|
||||
string serialization = UserInventoryItemSerializer.Serialize(saveItem);
|
||||
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
|
||||
m_archiveWriter.WriteFile(filename, serialization);
|
||||
|
||||
m_assetGatherer.GatherAssetUuids(saveItem.AssetID, (AssetType)saveItem.AssetType, m_assetUuids);
|
||||
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -161,7 +156,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// <param name="inventoryFolder">The inventory folder to save</param>
|
||||
/// <param name="path">The path to which the folder should be saved</param>
|
||||
/// <param name="saveThisFolderItself">If true, save this folder itself. If false, only saves contents</param>
|
||||
protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself)
|
||||
protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||
{
|
||||
if (saveThisFolderItself)
|
||||
{
|
||||
@@ -176,19 +171,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
foreach (InventoryFolderBase childFolder in contents.Folders)
|
||||
{
|
||||
SaveInvFolder(childFolder, path, true);
|
||||
SaveInvFolder(childFolder, path, true, options, userAccountService);
|
||||
}
|
||||
|
||||
foreach (InventoryItemBase item in contents.Items)
|
||||
{
|
||||
SaveInvItem(item, path);
|
||||
SaveInvItem(item, path, options, userAccountService);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute the inventory write request
|
||||
/// </summary>
|
||||
public void Execute()
|
||||
public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -266,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath);
|
||||
|
||||
//recurse through all dirs getting dirs and files
|
||||
SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly);
|
||||
SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService);
|
||||
}
|
||||
else if (inventoryItem != null)
|
||||
{
|
||||
@@ -274,14 +269,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
"[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
|
||||
inventoryItem.Name, inventoryItem.ID, m_invPath);
|
||||
|
||||
SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH);
|
||||
SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService);
|
||||
}
|
||||
|
||||
// Don't put all this profile information into the archive right now.
|
||||
//SaveUsers();
|
||||
|
||||
new AssetsRequest(
|
||||
new AssetsArchiver(m_archiveWriter), m_assetUuids, m_scene.AssetService, ReceivedAllAssets).Execute();
|
||||
new AssetsArchiver(m_archiveWriter),
|
||||
m_assetUuids, m_scene.AssetService,
|
||||
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
|
||||
options, ReceivedAllAssets).Execute();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -75,6 +75,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
||||
private Scene m_aScene;
|
||||
|
||||
private IUserAccountService m_UserAccountService;
|
||||
protected IUserAccountService UserAccountService
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_UserAccountService == null)
|
||||
// What a strange thing to do...
|
||||
foreach (Scene s in m_scenes.Values)
|
||||
{
|
||||
m_UserAccountService = s.RequestModuleInterface<IUserAccountService>();
|
||||
break;
|
||||
}
|
||||
|
||||
return m_UserAccountService;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public InventoryArchiverModule() {}
|
||||
|
||||
public InventoryArchiverModule(bool disablePresenceChecks)
|
||||
@@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
scene.AddCommand(
|
||||
this, "save iar",
|
||||
"save iar <first> <last> <inventory path> <password> [<IAR path>]",
|
||||
"save iar <first> <last> <inventory path> <password> [--p|-profile=<url>] [<IAR path>]",
|
||||
"Save user inventory archive (IAR).",
|
||||
"<first> is the user's first name." + Environment.NewLine
|
||||
+ "<last> is the user's last name." + Environment.NewLine
|
||||
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
|
||||
+ "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||
+ "<IAR path> is the filesystem path at which to save the IAR."
|
||||
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
|
||||
HandleSaveInvConsoleCommand);
|
||||
@@ -157,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
try
|
||||
{
|
||||
new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute();
|
||||
new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(options, UserAccountService);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
@@ -197,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
try
|
||||
{
|
||||
new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute();
|
||||
new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(options, UserAccountService);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
@@ -235,14 +254,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
if (m_scenes.Count > 0)
|
||||
{
|
||||
UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
|
||||
|
||||
|
||||
if (userInfo != null)
|
||||
{
|
||||
if (CheckPresence(userInfo.PrincipalID))
|
||||
{
|
||||
|
||||
InventoryArchiveReadRequest request;
|
||||
bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge);
|
||||
@@ -256,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
UpdateClientWithLoadedNodes(userInfo, request.Execute());
|
||||
|
||||
return true;
|
||||
@@ -268,6 +288,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_log.ErrorFormat("[INVENTORY ARCHIVER]: User {0} {1} not found",
|
||||
firstName, lastName);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -368,10 +391,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
|
||||
{
|
||||
Guid id = Guid.NewGuid();
|
||||
|
||||
|
||||
Dictionary<string, object> options = new Dictionary<string, object>();
|
||||
|
||||
OptionSet ops = new OptionSet();
|
||||
//ops.Add("v|version=", delegate(string v) { options["version"] = v; });
|
||||
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
||||
|
||||
List<string> mainParams = ops.Parse(cmdparams);
|
||||
|
||||
try
|
||||
{
|
||||
if (cmdparams.Length < 6)
|
||||
if (mainParams.Count < 6)
|
||||
{
|
||||
m_log.Error(
|
||||
"[INVENTORY ARCHIVER]: usage is save iar <first name> <last name> <inventory path> <user password> [<save file path>]");
|
||||
@@ -379,18 +410,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
|
||||
|
||||
string firstName = cmdparams[2];
|
||||
string lastName = cmdparams[3];
|
||||
string invPath = cmdparams[4];
|
||||
string pass = cmdparams[5];
|
||||
string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME);
|
||||
if (options.ContainsKey("profile"))
|
||||
m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -profile option if you want to produce a compatible IAR");
|
||||
|
||||
string firstName = mainParams[2];
|
||||
string lastName = mainParams[3];
|
||||
string invPath = mainParams[4];
|
||||
string pass = mainParams[5];
|
||||
string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME);
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
|
||||
savePath, invPath, firstName, lastName);
|
||||
|
||||
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary<string, object>());
|
||||
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
|
||||
}
|
||||
catch (InventoryArchiverException e)
|
||||
{
|
||||
@@ -518,5 +551,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ using OpenSim.Framework;
|
||||
using OpenSim.Framework.Serialization;
|
||||
using OpenSim.Framework.Serialization.External;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Communications.Osp;
|
||||
using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
|
||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
@@ -96,14 +95,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
item1.Name = m_item1Name;
|
||||
item1.AssetID = UUID.Random();
|
||||
item1.GroupID = UUID.Random();
|
||||
item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName);
|
||||
//item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName);
|
||||
//item1.CreatorId = userUuid.ToString();
|
||||
//item1.CreatorId = "00000000-0000-0000-0000-000000000444";
|
||||
item1.CreatorId = m_ua2.PrincipalID.ToString();
|
||||
item1.Owner = UUID.Zero;
|
||||
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene("Inventory");
|
||||
UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
|
||||
|
||||
string item1FileName
|
||||
= string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
|
||||
tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
|
||||
tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string, object>(), scene.UserAccountService));
|
||||
tar.Close();
|
||||
m_iarStream = new MemoryStream(archiveWriteStream.ToArray());
|
||||
}
|
||||
@@ -386,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
Scene scene = SceneSetupHelpers.SetupScene("inventory");
|
||||
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
|
||||
UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood");
|
||||
UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire");
|
||||
|
||||
@@ -551,7 +553,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
string item1FileName
|
||||
= string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName);
|
||||
tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1));
|
||||
tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary<string,object>(), null));
|
||||
tar.Close();
|
||||
|
||||
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
|
||||
|
||||
@@ -876,8 +876,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
|
||||
agent.MakeChildAgent();
|
||||
|
||||
// now we have a child agent in this region. Request all interesting data about other (root) agents
|
||||
agent.SendInitialFullUpdateToAllClients();
|
||||
agent.SendOtherAgentsAvatarDataToMe();
|
||||
agent.SendOtherAgentsAppearanceToMe();
|
||||
|
||||
CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
|
||||
|
||||
|
||||
@@ -27,8 +27,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
@@ -52,14 +55,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>();
|
||||
|
||||
private Scene m_scene;
|
||||
private string m_ProfileServerURI;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public HGAssetMapper(Scene scene)
|
||||
public HGAssetMapper(Scene scene, string profileURL)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_ProfileServerURI = profileURL;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -95,16 +100,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
try
|
||||
{
|
||||
asset1.ID = url + "/" + asset.ID;
|
||||
// UUID temp = UUID.Zero;
|
||||
// TODO: if the creator is local, stick this grid's URL in front
|
||||
//if (UUID.TryParse(asset.Metadata.CreatorID, out temp))
|
||||
// asset1.Metadata.CreatorID = ??? + "/" + asset.Metadata.CreatorID;
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_log.Warn("[HG ASSET MAPPER]: Oops.");
|
||||
}
|
||||
|
||||
AdjustIdentifiers(asset1.Metadata);
|
||||
if (asset1.Metadata.Type == (sbyte)AssetType.Object)
|
||||
asset1.Data = AdjustIdentifiers(asset.Data);
|
||||
else
|
||||
asset1.Data = asset.Data;
|
||||
|
||||
m_scene.AssetService.Store(asset1);
|
||||
m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url);
|
||||
}
|
||||
@@ -118,7 +125,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
private void Copy(AssetBase from, AssetBase to)
|
||||
{
|
||||
to.Data = from.Data;
|
||||
//to.Data = from.Data; // don't copy this, it's copied elsewhere
|
||||
to.Description = from.Description;
|
||||
to.FullID = from.FullID;
|
||||
to.ID = from.ID;
|
||||
@@ -129,6 +136,70 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
}
|
||||
|
||||
private void AdjustIdentifiers(AssetMetadata meta)
|
||||
{
|
||||
if (meta.CreatorID != null && meta.CreatorID != string.Empty)
|
||||
{
|
||||
UUID uuid = UUID.Zero;
|
||||
UUID.TryParse(meta.CreatorID, out uuid);
|
||||
UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
|
||||
if (creator != null)
|
||||
meta.CreatorID = m_ProfileServerURI + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName;
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] AdjustIdentifiers(byte[] data)
|
||||
{
|
||||
string xml = Utils.BytesToString(data);
|
||||
return Utils.StringToBytes(RewriteSOP(xml));
|
||||
}
|
||||
|
||||
protected string RewriteSOP(string xml)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.LoadXml(xml);
|
||||
XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart");
|
||||
|
||||
foreach (XmlNode sop in sops)
|
||||
{
|
||||
UserAccount creator = null;
|
||||
bool hasCreatorData = false;
|
||||
XmlNodeList nodes = sop.ChildNodes;
|
||||
foreach (XmlNode node in nodes)
|
||||
{
|
||||
if (node.Name == "CreatorID")
|
||||
{
|
||||
UUID uuid = UUID.Zero;
|
||||
UUID.TryParse(node.InnerText, out uuid);
|
||||
creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
|
||||
}
|
||||
if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
|
||||
hasCreatorData = true;
|
||||
|
||||
//if (node.Name == "OwnerID")
|
||||
//{
|
||||
// UserAccount owner = GetUser(node.InnerText);
|
||||
// if (owner != null)
|
||||
// node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName;
|
||||
//}
|
||||
}
|
||||
|
||||
if (!hasCreatorData && creator != null)
|
||||
{
|
||||
XmlElement creatorData = doc.CreateElement("CreatorData");
|
||||
creatorData.InnerText = m_ProfileServerURI + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName;
|
||||
sop.AppendChild(creatorData);
|
||||
}
|
||||
}
|
||||
|
||||
using (StringWriter wr = new StringWriter())
|
||||
{
|
||||
doc.Save(wr);
|
||||
return wr.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: unused
|
||||
// private void Dump(Dictionary<UUID, bool> lst)
|
||||
// {
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
get { return m_assMapper; }
|
||||
}
|
||||
|
||||
private string m_ProfileServerURI;
|
||||
|
||||
// private bool m_Initialized = false;
|
||||
|
||||
#region INonSharedRegionModule
|
||||
@@ -73,6 +75,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
{
|
||||
m_Enabled = true;
|
||||
m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name);
|
||||
|
||||
IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
|
||||
if (thisModuleConfig != null)
|
||||
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
|
||||
else
|
||||
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
return;
|
||||
|
||||
base.AddRegion(scene);
|
||||
m_assMapper = new HGAssetMapper(scene);
|
||||
m_assMapper = new HGAssetMapper(scene, m_ProfileServerURI);
|
||||
scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
|
||||
|
||||
}
|
||||
@@ -97,7 +105,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
string userAssetServer = string.Empty;
|
||||
if (IsForeignUser(avatarID, out userAssetServer))
|
||||
{
|
||||
m_assMapper.Post(assetID, avatarID, userAssetServer);
|
||||
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
protected bool m_Enabled = false;
|
||||
protected Scene m_Scene;
|
||||
protected IUserManagement m_UserManagement;
|
||||
protected IUserManagement UserManagementModule
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_UserManagement == null)
|
||||
m_UserManagement = m_Scene.RequestModuleInterface<IUserManagement>();
|
||||
return m_UserManagement;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region INonSharedRegionModule
|
||||
|
||||
@@ -542,6 +553,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
SceneObjectGroup group
|
||||
= SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData);
|
||||
|
||||
Util.FireAndForget(delegate { AddUserData(group); });
|
||||
|
||||
group.RootPart.FromFolderID = item.Folder;
|
||||
|
||||
// If it's rezzed in world, select it. Much easier to
|
||||
@@ -699,6 +712,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void AddUserData(SceneObjectGroup sog)
|
||||
{
|
||||
UserManagementModule.AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData);
|
||||
foreach (SceneObjectPart sop in sog.Parts)
|
||||
UserManagementModule.AddUser(sop.CreatorID, sop.CreatorData);
|
||||
}
|
||||
|
||||
public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
|
||||
{
|
||||
}
|
||||
@@ -779,9 +799,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID)
|
||||
{
|
||||
IInventoryService invService = m_Scene.RequestModuleInterface<IInventoryService>();
|
||||
InventoryItemBase assetRequestItem = new InventoryItemBase(itemID, agentID);
|
||||
assetRequestItem = invService.GetItem(assetRequestItem);
|
||||
return assetRequestItem;
|
||||
InventoryItemBase item = new InventoryItemBase(itemID, agentID);
|
||||
item = invService.GetItem(item);
|
||||
|
||||
if (item.CreatorData != null && item.CreatorData != string.Empty)
|
||||
UserManagementModule.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -275,6 +275,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
|
||||
}
|
||||
|
||||
public void AddUser(UUID uuid, string first, string last, string profileURL)
|
||||
{
|
||||
AddUser(uuid, profileURL + ";" + first + " " + last);
|
||||
}
|
||||
|
||||
//public void AddUser(UUID uuid, string userData)
|
||||
//{
|
||||
// if (m_UserCache.ContainsKey(uuid))
|
||||
|
||||
@@ -91,9 +91,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset
|
||||
{
|
||||
m_Registered = true;
|
||||
|
||||
m_log.Info("[RegionAssetService]: Starting...");
|
||||
m_log.Info("[HGAssetService]: Starting...");
|
||||
|
||||
Object[] args = new Object[] { m_Config, MainServer.Instance, string.Empty };
|
||||
|
||||
Object[] args = new Object[] { m_Config, MainServer.Instance, "HGAssetService" };
|
||||
|
||||
ServerUtils.LoadPlugin<IServiceConnector>("OpenSim.Server.Handlers.dll:AssetServiceConnector", args);
|
||||
}
|
||||
|
||||
@@ -190,7 +190,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
|
||||
new AssetsRequest(
|
||||
new AssetsArchiver(archiveWriter), assetUuids,
|
||||
m_scene.AssetService, awre.ReceivedAllAssets).Execute();
|
||||
m_scene.AssetService, m_scene.UserAccountService,
|
||||
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -238,10 +239,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
|
||||
if (majorVersion == 1)
|
||||
{
|
||||
m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
|
||||
}
|
||||
//if (majorVersion == 1)
|
||||
//{
|
||||
// m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
|
||||
//}
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
XmlTextWriter xtw = new XmlTextWriter(sw);
|
||||
|
||||
@@ -34,6 +34,7 @@ using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Serialization;
|
||||
using OpenSim.Framework.Serialization.External;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
@@ -100,17 +101,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
/// Asset service used to request the assets
|
||||
/// </value>
|
||||
protected IAssetService m_assetService;
|
||||
protected IUserAccountService m_userAccountService;
|
||||
protected UUID m_scopeID; // the grid ID
|
||||
|
||||
protected AssetsArchiver m_assetsArchiver;
|
||||
|
||||
protected Dictionary<string, object> m_options;
|
||||
|
||||
protected internal AssetsRequest(
|
||||
AssetsArchiver assetsArchiver, IDictionary<UUID, AssetType> uuids,
|
||||
IAssetService assetService, AssetsRequestCallback assetsRequestCallback)
|
||||
IAssetService assetService, IUserAccountService userService,
|
||||
UUID scope, Dictionary<string, object> options,
|
||||
AssetsRequestCallback assetsRequestCallback)
|
||||
{
|
||||
m_assetsArchiver = assetsArchiver;
|
||||
m_uuids = uuids;
|
||||
m_assetsRequestCallback = assetsRequestCallback;
|
||||
m_assetService = assetService;
|
||||
m_userAccountService = userService;
|
||||
m_scopeID = scope;
|
||||
m_options = options;
|
||||
m_repliesRequired = uuids.Count;
|
||||
|
||||
m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
|
||||
@@ -241,7 +251,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
{
|
||||
// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id);
|
||||
m_foundAssetUuids.Add(asset.FullID);
|
||||
m_assetsArchiver.WriteAsset(asset);
|
||||
|
||||
m_assetsArchiver.WriteAsset(PostProcess(asset));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -288,5 +299,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
"[ARCHIVER]: Terminating archive creation since asset requster callback failed with {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected AssetBase PostProcess(AssetBase asset)
|
||||
{
|
||||
if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("profile"))
|
||||
{
|
||||
//m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID);
|
||||
string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), m_options["profile"].ToString(), m_userAccountService, m_scopeID);
|
||||
asset.Data = Utils.StringToBytes(xml);
|
||||
}
|
||||
return asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
|
||||
private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds)
|
||||
{
|
||||
m_scene.Restart(timeInSeconds);
|
||||
IRestartModule restartModule = m_scene.RequestModuleInterface<IRestartModule>();
|
||||
if (restartModule != null)
|
||||
{
|
||||
List<int> times = new List<int>();
|
||||
while (timeInSeconds > 0)
|
||||
{
|
||||
times.Add(timeInSeconds);
|
||||
if (timeInSeconds > 300)
|
||||
timeInSeconds -= 120;
|
||||
else if (timeInSeconds > 30)
|
||||
timeInSeconds -= 30;
|
||||
else
|
||||
timeInSeconds -= 15;
|
||||
}
|
||||
|
||||
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleChangeEstateCovenantRequest(IClientAPI remoteClient, UUID estateCovenantID)
|
||||
|
||||
263
OpenSim/Region/CoreModules/World/Region/RestartModule.cs
Normal file
263
OpenSim/Region/CoreModules/World/Region/RestartModule.cs
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Timers;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using Timer=System.Timers.Timer;
|
||||
using Mono.Addins;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.World.Region
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")]
|
||||
public class RestartModule : INonSharedRegionModule, IRestartModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected Scene m_Scene;
|
||||
protected Timer m_CountdownTimer = null;
|
||||
protected DateTime m_RestartBegin;
|
||||
protected List<int> m_Alerts;
|
||||
protected string m_Message;
|
||||
protected UUID m_Initiator;
|
||||
protected bool m_Notice = false;
|
||||
protected IDialogModule m_DialogModule = null;
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
m_Scene = scene;
|
||||
scene.RegisterModuleInterface<IRestartModule>(this);
|
||||
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||
false, "region restart bluebox",
|
||||
"region restart bluebox <message> <time> ...",
|
||||
"Restart the region", HandleRegionRestart);
|
||||
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||
false, "region restart notice",
|
||||
"region restart notice <message> <time> ...",
|
||||
"Restart the region", HandleRegionRestart);
|
||||
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||
false, "region restart abort",
|
||||
"region restart abort [<message>]",
|
||||
"Restart the region", HandleRegionRestart);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
m_DialogModule = m_Scene.RequestModuleInterface<IDialogModule>();
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "RestartModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return typeof(IRestartModule); }
|
||||
}
|
||||
|
||||
public TimeSpan TimeUntilRestart
|
||||
{
|
||||
get { return DateTime.Now - m_RestartBegin; }
|
||||
}
|
||||
|
||||
public void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice)
|
||||
{
|
||||
if (m_CountdownTimer != null)
|
||||
return;
|
||||
|
||||
if (alerts == null)
|
||||
{
|
||||
m_Scene.RestartNow();
|
||||
return;
|
||||
}
|
||||
|
||||
m_Message = message;
|
||||
m_Initiator = initiator;
|
||||
m_Notice = notice;
|
||||
m_Alerts = new List<int>(alerts);
|
||||
m_Alerts.Sort();
|
||||
m_Alerts.Reverse();
|
||||
|
||||
if (m_Alerts[0] == 0)
|
||||
{
|
||||
m_Scene.RestartNow();
|
||||
return;
|
||||
}
|
||||
|
||||
int nextInterval = DoOneNotice();
|
||||
|
||||
SetTimer(nextInterval);
|
||||
}
|
||||
|
||||
public int DoOneNotice()
|
||||
{
|
||||
if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
|
||||
{
|
||||
m_Scene.RestartNow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nextAlert = 0;
|
||||
while (m_Alerts.Count > 1)
|
||||
{
|
||||
if (m_Alerts[1] == m_Alerts[0])
|
||||
{
|
||||
m_Alerts.RemoveAt(0);
|
||||
continue;
|
||||
}
|
||||
nextAlert = m_Alerts[1];
|
||||
break;
|
||||
}
|
||||
|
||||
int currentAlert = m_Alerts[0];
|
||||
|
||||
m_Alerts.RemoveAt(0);
|
||||
|
||||
int minutes = currentAlert / 60;
|
||||
string currentAlertString = String.Empty;
|
||||
if (minutes > 0)
|
||||
{
|
||||
if (minutes == 1)
|
||||
currentAlertString += "1 minute";
|
||||
else
|
||||
currentAlertString += String.Format("{0} minutes", minutes);
|
||||
if ((currentAlert % 60) != 0)
|
||||
currentAlertString += " and ";
|
||||
}
|
||||
if ((currentAlert % 60) != 0)
|
||||
{
|
||||
int seconds = currentAlert % 60;
|
||||
if (seconds == 1)
|
||||
currentAlertString += "1 second";
|
||||
else
|
||||
currentAlertString += String.Format("{0} seconds", seconds);
|
||||
}
|
||||
|
||||
string msg = String.Format(m_Message, currentAlertString);
|
||||
|
||||
if (m_DialogModule != null && msg != String.Empty)
|
||||
{
|
||||
if (m_Notice)
|
||||
m_DialogModule.SendGeneralAlert(msg);
|
||||
else
|
||||
m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
|
||||
}
|
||||
|
||||
return currentAlert - nextAlert;
|
||||
}
|
||||
|
||||
public void SetTimer(int intervalSeconds)
|
||||
{
|
||||
m_CountdownTimer = new Timer();
|
||||
m_CountdownTimer.AutoReset = false;
|
||||
m_CountdownTimer.Interval = intervalSeconds * 1000;
|
||||
m_CountdownTimer.Elapsed += OnTimer;
|
||||
m_CountdownTimer.Start();
|
||||
}
|
||||
|
||||
private void OnTimer(object source, ElapsedEventArgs e)
|
||||
{
|
||||
int nextInterval = DoOneNotice();
|
||||
|
||||
SetTimer(nextInterval);
|
||||
}
|
||||
|
||||
public void AbortRestart(string message)
|
||||
{
|
||||
if (m_CountdownTimer != null)
|
||||
{
|
||||
m_CountdownTimer.Stop();
|
||||
m_CountdownTimer = null;
|
||||
if (m_DialogModule != null && message != String.Empty)
|
||||
m_DialogModule.SendGeneralAlert(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRegionRestart(string module, string[] args)
|
||||
{
|
||||
if (!(MainConsole.Instance.ConsoleScene is Scene))
|
||||
return;
|
||||
|
||||
if (MainConsole.Instance.ConsoleScene != m_Scene)
|
||||
return;
|
||||
|
||||
if (args.Length < 5)
|
||||
{
|
||||
if (args.Length > 2)
|
||||
{
|
||||
if (args[2] == "abort")
|
||||
{
|
||||
string msg = String.Empty;
|
||||
if (args.Length > 3)
|
||||
msg = args[3];
|
||||
|
||||
AbortRestart(msg);
|
||||
|
||||
MainConsole.Instance.Output("Region restart aborted");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output("Error: restart region <mode> <name> <time> ...");
|
||||
return;
|
||||
}
|
||||
|
||||
bool notice = false;
|
||||
if (args[2] == "notice")
|
||||
notice = true;
|
||||
|
||||
List<int> times = new List<int>();
|
||||
for (int i = 4 ; i < args.Length ; i++)
|
||||
times.Add(Convert.ToInt32(args[i]));
|
||||
|
||||
ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user