Compare commits
189 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48a5f10be1 | ||
|
|
ecb759c1e5 | ||
|
|
59a29f5f22 | ||
|
|
356d597296 | ||
|
|
b0facd147a | ||
|
|
b6476eaac3 | ||
|
|
2a85372169 | ||
|
|
1c3b0da74a | ||
|
|
c1667d39a6 | ||
|
|
217f47b0d5 | ||
|
|
ed14dac0a3 | ||
|
|
ee7478fa16 | ||
|
|
5d3723a47f | ||
|
|
84b7ae2573 | ||
|
|
423101b425 | ||
|
|
e3453dd9ca | ||
|
|
b6cd3b625e | ||
|
|
8d59385eea | ||
|
|
ec6a195e40 | ||
|
|
2954ceccae | ||
|
|
884d603cac | ||
|
|
9ccb578721 | ||
|
|
d6f54b25cd | ||
|
|
dda999a22c | ||
|
|
3b3d9967b1 | ||
|
|
75ab9b4b88 | ||
|
|
15283d35f1 | ||
|
|
6a0de355e0 | ||
|
|
65a25ee510 | ||
|
|
ca412032e8 | ||
|
|
743437262e | ||
|
|
916e3bf886 | ||
|
|
9c89ad9154 | ||
|
|
33cff9b9d7 | ||
|
|
0e611c47d3 | ||
|
|
fc24563206 | ||
|
|
14d05dc2a9 | ||
|
|
337ea019bd | ||
|
|
cdea572d2e | ||
|
|
11e0ad6dc8 | ||
|
|
c8f0d476d2 | ||
|
|
69a6f6e3cd | ||
|
|
e8347b7095 | ||
|
|
506437b684 | ||
|
|
9f01c3d408 | ||
|
|
58869e5aa0 | ||
|
|
f3134b5cf6 | ||
|
|
eb5ec4a786 | ||
|
|
c8af20f966 | ||
|
|
d6f563794e | ||
|
|
2eaa6d5ace | ||
|
|
1a2ab7bc69 | ||
|
|
a96ac73302 | ||
|
|
57094bd017 | ||
|
|
112cddc9ca | ||
|
|
16d5b79d57 | ||
|
|
1201307c73 | ||
|
|
a85741ac37 | ||
|
|
3bd134474b | ||
|
|
b19ead5f9e | ||
|
|
7ff4eec79c | ||
|
|
7aff238eee | ||
|
|
af9d8de515 | ||
|
|
f1f390cfdf | ||
|
|
74014a3854 | ||
|
|
e4a6611865 | ||
|
|
056c9a59b2 | ||
|
|
ae1f2114f5 | ||
|
|
1b1f841c6a | ||
|
|
43a2da9edb | ||
|
|
f6e5791ecd | ||
|
|
843112340e | ||
|
|
7e73f609e5 | ||
|
|
db9616f7ba | ||
|
|
8674604ff5 | ||
|
|
462f7bccf9 | ||
|
|
510e809aba | ||
|
|
951b45b80f | ||
|
|
7b327848d0 | ||
|
|
2f998fce1f | ||
|
|
1816ecb747 | ||
|
|
eacba4fc0b | ||
|
|
9fac7fd932 | ||
|
|
f2b0377c28 | ||
|
|
d933bdbd59 | ||
|
|
f9fa34408d | ||
|
|
857494f6bd | ||
|
|
dff7cae2ee | ||
|
|
0e3fce9b5c | ||
|
|
4b2b14dad1 | ||
|
|
3769739ca7 | ||
|
|
3717812ce0 | ||
|
|
ae64d089c6 | ||
|
|
58b13d51a7 | ||
|
|
5691a8b860 | ||
|
|
f7b4802577 | ||
|
|
8183c2926d | ||
|
|
3c9b9a848f | ||
|
|
3399596e0e | ||
|
|
d32cf21576 | ||
|
|
1926de5a05 | ||
|
|
a4551b027b | ||
|
|
56c776066c | ||
|
|
0229e90dcc | ||
|
|
e420f815dc | ||
|
|
1a7be7b00e | ||
|
|
0f6b7b6a41 | ||
|
|
f202c36106 | ||
|
|
bfa6896678 | ||
|
|
571fd966cb | ||
|
|
f263d6a910 | ||
|
|
972b0b52f9 | ||
|
|
25baa2d894 | ||
|
|
f9769a9fcb | ||
|
|
bb48060b44 | ||
|
|
d043213317 | ||
|
|
5bec5bcf71 | ||
|
|
87ca820f9b | ||
|
|
0b29877790 | ||
|
|
97437feb06 | ||
|
|
2524517986 | ||
|
|
99954c1498 | ||
|
|
2b82c421ad | ||
|
|
4329cc7b8a | ||
|
|
32a4ce94f0 | ||
|
|
340005c5bf | ||
|
|
4b6c3fd4bb | ||
|
|
988112d446 | ||
|
|
1f22b29ca3 | ||
|
|
5292b8b8be | ||
|
|
854f2a913c | ||
|
|
f5316984ab | ||
|
|
e5b739aaeb | ||
|
|
5301648cff | ||
|
|
6d3ee8bb39 | ||
|
|
78143769bf | ||
|
|
dca04c7b61 | ||
|
|
80a41e670d | ||
|
|
9f3feeff8d | ||
|
|
f907182ab2 | ||
|
|
4cf49369b5 | ||
|
|
fda39c11bf | ||
|
|
798846c5b6 | ||
|
|
06617ffd06 | ||
|
|
d24122b706 | ||
|
|
afcabf5244 | ||
|
|
5709bed548 | ||
|
|
68ea096f1b | ||
|
|
714db90832 | ||
|
|
b23425c7c4 | ||
|
|
9ec9dafae6 | ||
|
|
6c312bce7f | ||
|
|
7b6c0232a5 | ||
|
|
4cfaa01c0a | ||
|
|
6b3f9fcde0 | ||
|
|
625e5e913a | ||
|
|
881e92a726 | ||
|
|
0fa303b1cf | ||
|
|
9737e6d52e | ||
|
|
e23d7ff9c0 | ||
|
|
ef686ead37 | ||
|
|
bc06f3dcaf | ||
|
|
8e7032ece8 | ||
|
|
5c5b359bcb | ||
|
|
fc1522ab60 | ||
|
|
2ed768cbf5 | ||
|
|
7119de56ff | ||
|
|
ed513fc7be | ||
|
|
22f25dfcab | ||
|
|
aaa30dcebc | ||
|
|
c935f03467 | ||
|
|
94517c8d5c | ||
|
|
257b1b517d | ||
|
|
aeed4d3041 | ||
|
|
478acfff34 | ||
|
|
10e87f9cdc | ||
|
|
6993a26ba5 | ||
|
|
93ba0332c4 | ||
|
|
9825861f4a | ||
|
|
f4b02f8e39 | ||
|
|
2c6555021f | ||
|
|
3888b9a670 | ||
|
|
1aa7469253 | ||
|
|
3c3ea19620 | ||
|
|
0d2243a393 | ||
|
|
917d753f1c | ||
|
|
a4290048e5 | ||
|
|
cba8b4f8b8 | ||
|
|
6a77a65675 |
@@ -301,7 +301,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||
InventoryItemBase linkedItem
|
||||
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
|
||||
|
||||
itemsToReturn.Insert(0, linkedItem);
|
||||
if (linkedItem != null)
|
||||
itemsToReturn.Insert(0, linkedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -393,12 +394,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||
llsdFolder.folder_id = invFolder.ID;
|
||||
llsdFolder.parent_id = invFolder.ParentID;
|
||||
llsdFolder.name = invFolder.Name;
|
||||
|
||||
if (invFolder.Type == (short)AssetType.Unknown || !Enum.IsDefined(typeof(AssetType), (sbyte)invFolder.Type))
|
||||
llsdFolder.type = "-1";
|
||||
else
|
||||
llsdFolder.type = Utils.AssetTypeToString((AssetType)invFolder.Type);
|
||||
llsdFolder.preferred_type = "-1";
|
||||
llsdFolder.type = invFolder.Type;
|
||||
llsdFolder.preferred_type = -1;
|
||||
|
||||
return llsdFolder;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
public UUID folder_id;
|
||||
public UUID parent_id;
|
||||
public string name;
|
||||
public string type;
|
||||
public string preferred_type;
|
||||
public int type;
|
||||
public int preferred_type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +66,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
|
||||
TResponse response = m_method(llsdRequest);
|
||||
|
||||
Encoding encoding = new UTF8Encoding(false);
|
||||
|
||||
return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
|
||||
return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace OpenSim.ConsoleClient
|
||||
|
||||
request.ContentType = "application/x-www-form-urlencoded";
|
||||
|
||||
byte[] buffer = new System.Text.ASCIIEncoding().GetBytes(data);
|
||||
byte[] buffer = Encoding.ASCII.GetBytes(data);
|
||||
int length = (int) buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
|
||||
@@ -1069,8 +1069,6 @@ namespace OpenSim.Data.Tests
|
||||
regionInfo.RegionLocX = 0;
|
||||
regionInfo.RegionLocY = 0;
|
||||
|
||||
Scene scene = new Scene(regionInfo);
|
||||
|
||||
SceneObjectPart sop = new SceneObjectPart();
|
||||
sop.Name = name;
|
||||
sop.Description = name;
|
||||
@@ -1081,7 +1079,7 @@ namespace OpenSim.Data.Tests
|
||||
sop.Shape = PrimitiveBaseShape.Default;
|
||||
|
||||
SceneObjectGroup sog = new SceneObjectGroup(sop);
|
||||
sog.SetScene(scene);
|
||||
// sog.SetScene(scene);
|
||||
|
||||
return sog;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,11 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
public string lastname;
|
||||
|
||||
/// <summary>
|
||||
/// Agent's full name.
|
||||
/// </summary>
|
||||
public string Name { get { return string.Format("{0} {1}", firstname, lastname); } }
|
||||
|
||||
/// <summary>
|
||||
/// Random Unique GUID for this session. Client gets this at login and it's
|
||||
/// only supposed to be disclosed over secure channels
|
||||
|
||||
@@ -79,6 +79,16 @@ namespace OpenSim.Framework.Console
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public void AddColumn(string name, int width)
|
||||
{
|
||||
Columns.Add(new ConsoleDisplayTableColumn(name, width));
|
||||
}
|
||||
|
||||
public void AddRow(params string[] cells)
|
||||
{
|
||||
Rows.Add(new ConsoleDisplayTableRow(cells));
|
||||
}
|
||||
|
||||
public void AddToStringBuilder(StringBuilder sb)
|
||||
{
|
||||
string formatString = GetFormatString();
|
||||
@@ -135,5 +145,10 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
Cells = cells;
|
||||
}
|
||||
|
||||
public ConsoleDisplayTableRow(params string[] cells) : this()
|
||||
{
|
||||
Cells = new List<string>(cells);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1353,7 +1353,6 @@ namespace OpenSim.Framework
|
||||
void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message);
|
||||
|
||||
void SendLogoutPacket();
|
||||
EndPoint GetClientEP();
|
||||
|
||||
// WARNING WARNING WARNING
|
||||
//
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace OpenSim.Framework
|
||||
|
||||
public interface IScene
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of this scene.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
RegionInfo RegionInfo { get; }
|
||||
RegionStatus RegionStatus { get; set; }
|
||||
|
||||
|
||||
@@ -42,9 +42,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// </summary>
|
||||
public class LandDataSerializer
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static Dictionary<string, Action<LandData, XmlTextReader>> m_ldProcessors
|
||||
= new Dictionary<string, Action<LandData, XmlTextReader>>();
|
||||
@@ -163,7 +161,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <exception cref="System.Xml.XmlException"></exception>
|
||||
public static LandData Deserialize(byte[] serializedLandData)
|
||||
{
|
||||
return Deserialize(m_utf8Encoding.GetString(serializedLandData, 0, serializedLandData.Length));
|
||||
return Deserialize(Encoding.UTF8.GetString(serializedLandData, 0, serializedLandData.Length));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -40,8 +40,6 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// </summary>
|
||||
public class RegionSettingsSerializer
|
||||
{
|
||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize settings
|
||||
/// </summary>
|
||||
@@ -50,7 +48,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <exception cref="System.Xml.XmlException"></exception>
|
||||
public static RegionSettings Deserialize(byte[] serializedSettings)
|
||||
{
|
||||
return Deserialize(m_asciiEncoding.GetString(serializedSettings, 0, serializedSettings.Length));
|
||||
return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// </summary>
|
||||
public class UserInventoryItemSerializer
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static Dictionary<string, Action<InventoryItemBase, XmlTextReader>> m_InventoryItemXmlProcessors
|
||||
= new Dictionary<string, Action<InventoryItemBase, XmlTextReader>>();
|
||||
|
||||
@@ -53,8 +53,6 @@ namespace OpenSim.Framework.Serialization
|
||||
TYPE_CONTIGUOUS_FILE = 8,
|
||||
}
|
||||
|
||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
||||
|
||||
/// <summary>
|
||||
/// Binary reader for the underlying stream
|
||||
/// </summary>
|
||||
@@ -120,13 +118,13 @@ namespace OpenSim.Framework.Serialization
|
||||
if (header[156] == (byte)'L')
|
||||
{
|
||||
int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
|
||||
tarHeader.FilePath = m_asciiEncoding.GetString(ReadData(longNameLength));
|
||||
tarHeader.FilePath = Encoding.ASCII.GetString(ReadData(longNameLength));
|
||||
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
|
||||
header = m_br.ReadBytes(512);
|
||||
}
|
||||
else
|
||||
{
|
||||
tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100);
|
||||
tarHeader.FilePath = Encoding.ASCII.GetString(header, 0, 100);
|
||||
tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
|
||||
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
|
||||
}
|
||||
@@ -205,7 +203,7 @@ namespace OpenSim.Framework.Serialization
|
||||
{
|
||||
// Trim leading white space: ancient tars do that instead
|
||||
// of leading 0s :-( don't ask. really.
|
||||
string oString = m_asciiEncoding.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
|
||||
string oString = Encoding.ASCII.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
|
||||
|
||||
int d = 0;
|
||||
|
||||
|
||||
@@ -41,9 +41,6 @@ namespace OpenSim.Framework.Serialization
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
||||
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
|
||||
|
||||
/// <summary>
|
||||
/// Binary writer for the underlying stream
|
||||
/// </summary>
|
||||
@@ -74,7 +71,7 @@ namespace OpenSim.Framework.Serialization
|
||||
/// <param name="data"></param>
|
||||
public void WriteFile(string filePath, string data)
|
||||
{
|
||||
WriteFile(filePath, m_utf8Encoding.GetBytes(data));
|
||||
WriteFile(filePath, Util.UTF8NoBomEncoding.GetBytes(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -85,7 +82,7 @@ namespace OpenSim.Framework.Serialization
|
||||
public void WriteFile(string filePath, byte[] data)
|
||||
{
|
||||
if (filePath.Length > 100)
|
||||
WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
|
||||
WriteEntry("././@LongLink", Encoding.ASCII.GetBytes(filePath), 'L');
|
||||
|
||||
char fileType;
|
||||
|
||||
@@ -137,7 +134,7 @@ namespace OpenSim.Framework.Serialization
|
||||
oString = "0" + oString;
|
||||
}
|
||||
|
||||
byte[] oBytes = m_asciiEncoding.GetBytes(oString);
|
||||
byte[] oBytes = Encoding.ASCII.GetBytes(oString);
|
||||
|
||||
return oBytes;
|
||||
}
|
||||
@@ -156,20 +153,20 @@ namespace OpenSim.Framework.Serialization
|
||||
byte[] header = new byte[512];
|
||||
|
||||
// file path field (100)
|
||||
byte[] nameBytes = m_asciiEncoding.GetBytes(filePath);
|
||||
byte[] nameBytes = Encoding.ASCII.GetBytes(filePath);
|
||||
int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
|
||||
Array.Copy(nameBytes, header, nameSize);
|
||||
|
||||
// file mode (8)
|
||||
byte[] modeBytes = m_asciiEncoding.GetBytes("0000777");
|
||||
byte[] modeBytes = Encoding.ASCII.GetBytes("0000777");
|
||||
Array.Copy(modeBytes, 0, header, 100, 7);
|
||||
|
||||
// owner user id (8)
|
||||
byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764");
|
||||
byte[] ownerIdBytes = Encoding.ASCII.GetBytes("0000764");
|
||||
Array.Copy(ownerIdBytes, 0, header, 108, 7);
|
||||
|
||||
// group user id (8)
|
||||
byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764");
|
||||
byte[] groupIdBytes = Encoding.ASCII.GetBytes("0000764");
|
||||
Array.Copy(groupIdBytes, 0, header, 116, 7);
|
||||
|
||||
// file size in bytes (12)
|
||||
@@ -181,17 +178,17 @@ namespace OpenSim.Framework.Serialization
|
||||
Array.Copy(fileSizeBytes, 0, header, 124, 11);
|
||||
|
||||
// last modification time (12)
|
||||
byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332");
|
||||
byte[] lastModTimeBytes = Encoding.ASCII.GetBytes("11017037332");
|
||||
Array.Copy(lastModTimeBytes, 0, header, 136, 11);
|
||||
|
||||
// entry type indicator (1)
|
||||
header[156] = m_asciiEncoding.GetBytes(new char[] { fileType })[0];
|
||||
header[156] = Encoding.ASCII.GetBytes(new char[] { fileType })[0];
|
||||
|
||||
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7);
|
||||
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7);
|
||||
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 329, 7);
|
||||
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 337, 7);
|
||||
|
||||
// check sum for header block (8) [calculated last]
|
||||
Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8);
|
||||
Array.Copy(Encoding.ASCII.GetBytes(" "), 0, header, 148, 8);
|
||||
|
||||
int checksum = 0;
|
||||
foreach (byte b in header)
|
||||
|
||||
@@ -320,7 +320,9 @@ namespace OpenSim.Framework.Servers
|
||||
|
||||
TimeSpan timeTaken = DateTime.Now - m_startuptime;
|
||||
|
||||
m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds);
|
||||
m_log.InfoFormat(
|
||||
"[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED.",
|
||||
timeTaken.Minutes, timeTaken.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -589,8 +591,8 @@ namespace OpenSim.Framework.Servers
|
||||
{
|
||||
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
|
||||
FileStream fs = File.Create(path);
|
||||
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
||||
Byte[] buf = enc.GetBytes(pidstring);
|
||||
|
||||
Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
|
||||
fs.Write(buf, 0, buf.Length);
|
||||
fs.Close();
|
||||
m_pidFile = path;
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
|
||||
|
||||
public int DebugLevel { get; set; }
|
||||
|
||||
private volatile int NotSocketErrors = 0;
|
||||
public volatile bool HTTPDRunning = false;
|
||||
|
||||
@@ -79,11 +81,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
private PollServiceRequestManager m_PollServiceManager;
|
||||
|
||||
/// <summary>
|
||||
/// Control the printing of certain debug messages.
|
||||
/// </summary>
|
||||
public int DebugLevel { get; set; }
|
||||
|
||||
public uint SSLPort
|
||||
{
|
||||
get { return m_sslport; }
|
||||
@@ -450,7 +447,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
||||
{
|
||||
if (DebugLevel >= 1)
|
||||
if (DebugLevel >= 3)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
|
||||
request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
|
||||
@@ -531,7 +528,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
case null:
|
||||
case "text/html":
|
||||
|
||||
if (DebugLevel >= 1)
|
||||
if (DebugLevel >= 3)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
@@ -543,7 +540,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
case "application/xml+llsd":
|
||||
case "application/llsd+json":
|
||||
|
||||
if (DebugLevel >= 1)
|
||||
if (DebugLevel >= 3)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
@@ -564,7 +561,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
|
||||
if (DoWeHaveALLSDHandler(request.RawUrl))
|
||||
{
|
||||
if (DebugLevel >= 1)
|
||||
if (DebugLevel >= 3)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
@@ -574,7 +571,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
|
||||
else if (DoWeHaveAHTTPHandler(request.RawUrl))
|
||||
{
|
||||
if (DebugLevel >= 1)
|
||||
if (DebugLevel >= 3)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
@@ -583,8 +580,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (DebugLevel >= 1)
|
||||
if (DebugLevel >= 3)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
|
||||
request.HttpMethod, request.Url.PathAndQuery);
|
||||
@@ -786,15 +782,30 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
requestStream.Close();
|
||||
//m_log.Debug(requestBody);
|
||||
requestBody = requestBody.Replace("<base64></base64>", "");
|
||||
string responseString = null;
|
||||
string responseString = String.Empty;
|
||||
XmlRpcRequest xmlRprcRequest = null;
|
||||
|
||||
try
|
||||
{
|
||||
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
|
||||
}
|
||||
catch (XmlException)
|
||||
catch (XmlException e)
|
||||
{
|
||||
if (DebugLevel >= 1)
|
||||
{
|
||||
if (DebugLevel >= 2)
|
||||
m_log.Warn(
|
||||
string.Format(
|
||||
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}. XML was '{1}'. Sending blank response. Exception ",
|
||||
request.RemoteIPEndPoint, requestBody),
|
||||
e);
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}, length {1}. Sending blank response.",
|
||||
request.RemoteIPEndPoint, requestBody.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xmlRprcRequest != null)
|
||||
@@ -1546,6 +1557,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
private void StartHTTP()
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
|
||||
|
||||
try
|
||||
{
|
||||
//m_httpListener = new HttpListener();
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
public delegate void RequestMethod(UUID requestID, Hashtable request);
|
||||
@@ -44,7 +45,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
public NoEventsMethod NoEvents;
|
||||
public RequestMethod Request;
|
||||
public UUID Id;
|
||||
public PollServiceEventArgs(RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId)
|
||||
|
||||
public PollServiceEventArgs(
|
||||
RequestMethod pRequest,
|
||||
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
|
||||
UUID pId)
|
||||
{
|
||||
Request = pRequest;
|
||||
HasEvents = pHasEvents;
|
||||
@@ -53,4 +58,4 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
Id = pId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,6 @@ using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
|
||||
public class PollServiceHttpRequest
|
||||
{
|
||||
public readonly PollServiceEventArgs PollServiceArgs;
|
||||
@@ -39,7 +38,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
public readonly IHttpRequest Request;
|
||||
public readonly int RequestTime;
|
||||
public readonly UUID RequestID;
|
||||
public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
|
||||
|
||||
public PollServiceHttpRequest(
|
||||
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
|
||||
{
|
||||
PollServiceArgs = pPollServiceArgs;
|
||||
HttpContext = pHttpContext;
|
||||
@@ -48,4 +49,4 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
RequestID = UUID.Random();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,9 +129,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
OSHttpResponse response
|
||||
= new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
|
||||
|
||||
byte[] buffer
|
||||
= server.DoHTTPGruntWork(
|
||||
responsedata, new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
|
||||
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
|
||||
|
||||
response.SendChunked = false;
|
||||
response.ContentLength64 = buffer.Length;
|
||||
|
||||
@@ -25,57 +25,209 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Net;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
namespace OpenSim.Framework.Servers
|
||||
{
|
||||
public class MainServer
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static BaseHttpServer instance = null;
|
||||
private static Dictionary<uint, BaseHttpServer> m_Servers =
|
||||
new Dictionary<uint, BaseHttpServer>();
|
||||
private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>();
|
||||
|
||||
/// <summary>
|
||||
/// Control the printing of certain debug messages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If DebugLevel >= 1, then short warnings are logged when receiving bad input data.
|
||||
/// If DebugLevel >= 2, then long warnings are logged when receiving bad input data.
|
||||
/// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged.
|
||||
/// </remarks>
|
||||
public static int DebugLevel
|
||||
{
|
||||
get { return s_debugLevel; }
|
||||
set
|
||||
{
|
||||
s_debugLevel = value;
|
||||
|
||||
lock (m_Servers)
|
||||
foreach (BaseHttpServer server in m_Servers.Values)
|
||||
server.DebugLevel = s_debugLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private static int s_debugLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Set the main HTTP server instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This will be used to register all handlers that listen to the default port.
|
||||
/// </remarks>
|
||||
/// <exception cref='Exception'>
|
||||
/// Thrown if the HTTP server has not already been registered via AddHttpServer()
|
||||
/// </exception>
|
||||
public static BaseHttpServer Instance
|
||||
{
|
||||
get { return instance; }
|
||||
set { instance = value; }
|
||||
|
||||
set
|
||||
{
|
||||
lock (m_Servers)
|
||||
if (!m_Servers.ContainsValue(value))
|
||||
throw new Exception("HTTP server must already have been registered to be set as the main instance");
|
||||
|
||||
instance = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static IHttpServer GetHttpServer(uint port)
|
||||
/// <summary>
|
||||
/// Get all the registered servers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns a copy of the dictionary so this can be iterated through without locking.
|
||||
/// </remarks>
|
||||
/// <value></value>
|
||||
public static Dictionary<uint, BaseHttpServer> Servers
|
||||
{
|
||||
return GetHttpServer(port,null);
|
||||
get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
|
||||
}
|
||||
|
||||
|
||||
public static void RegisterHttpConsoleCommands(ICommandConsole console)
|
||||
{
|
||||
console.Commands.AddCommand(
|
||||
"Debug", false, "debug http", "debug http [<level>]",
|
||||
"Turn on inbound non-poll http request debugging.",
|
||||
"If level <= 0, then no extra logging is done.\n"
|
||||
+ "If level >= 1, then short warnings are logged when receiving bad input data.\n"
|
||||
+ "If level >= 2, then long warnings are logged when receiving bad input data.\n"
|
||||
+ "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n"
|
||||
+ "If no level is specified then the current level is returned.",
|
||||
HandleDebugHttpCommand);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turn on some debugging values for OpenSim.
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
private static void HandleDebugHttpCommand(string module, string[] args)
|
||||
{
|
||||
if (args.Length == 3)
|
||||
{
|
||||
int newDebug;
|
||||
if (int.TryParse(args[2], out newDebug))
|
||||
{
|
||||
MainServer.DebugLevel = newDebug;
|
||||
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
|
||||
}
|
||||
}
|
||||
else if (args.Length == 2)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug http 0..3");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register an already started HTTP server to the collection of known servers.
|
||||
/// </summary>
|
||||
/// <param name='server'></param>
|
||||
public static void AddHttpServer(BaseHttpServer server)
|
||||
{
|
||||
m_Servers.Add(server.Port, server);
|
||||
lock (m_Servers)
|
||||
{
|
||||
if (m_Servers.ContainsKey(server.Port))
|
||||
throw new Exception(string.Format("HTTP server for port {0} already exists.", server.Port));
|
||||
|
||||
m_Servers.Add(server.Port, server);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the http server listening on the given port.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is the responsibility of the caller to do clean up.
|
||||
/// </remarks>
|
||||
/// <param name='port'></param>
|
||||
/// <returns></returns>
|
||||
public static bool RemoveHttpServer(uint port)
|
||||
{
|
||||
lock (m_Servers)
|
||||
return m_Servers.Remove(port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does this collection of servers contain one with the given port?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Unlike GetHttpServer, this will not instantiate a server if one does not exist on that port.
|
||||
/// </remarks>
|
||||
/// <param name='port'></param>
|
||||
/// <returns>true if a server with the given port is registered, false otherwise.</returns>
|
||||
public static bool ContainsHttpServer(uint port)
|
||||
{
|
||||
lock (m_Servers)
|
||||
return m_Servers.ContainsKey(port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the default http server or an http server for a specific port.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
|
||||
public static IHttpServer GetHttpServer(uint port)
|
||||
{
|
||||
return GetHttpServer(port, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the default http server, an http server for a specific port
|
||||
/// and/or an http server bound to a specific address
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
|
||||
/// </remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
|
||||
/// <param name='ipaddr'>A specific IP address to bind to. If null then the default IP address is used.</param>
|
||||
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
|
||||
{
|
||||
if (port == 0)
|
||||
return Instance;
|
||||
|
||||
if (instance != null && port == Instance.Port)
|
||||
return Instance;
|
||||
|
||||
if (m_Servers.ContainsKey(port))
|
||||
lock (m_Servers)
|
||||
{
|
||||
if (m_Servers.ContainsKey(port))
|
||||
return m_Servers[port];
|
||||
|
||||
m_Servers[port] = new BaseHttpServer(port);
|
||||
|
||||
if (ipaddr != null)
|
||||
m_Servers[port].ListenIPAddress = ipaddr;
|
||||
|
||||
m_Servers[port].Start();
|
||||
|
||||
return m_Servers[port];
|
||||
|
||||
m_Servers[port] = new BaseHttpServer(port);
|
||||
|
||||
if (ipaddr != null)
|
||||
m_Servers[port].ListenIPAddress = ipaddr;
|
||||
|
||||
m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port);
|
||||
m_Servers[port].Start();
|
||||
|
||||
return m_Servers[port];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,9 @@ namespace OpenSim.Framework
|
||||
|
||||
private bool _ownerChanged = false;
|
||||
|
||||
// This used ONLY during copy. It can't be relied on at other times!
|
||||
private bool _scriptRunning = true;
|
||||
|
||||
public UUID AssetID {
|
||||
get {
|
||||
return _assetID;
|
||||
@@ -350,6 +353,15 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
public bool ScriptRunning {
|
||||
get {
|
||||
return _scriptRunning;
|
||||
}
|
||||
set {
|
||||
_scriptRunning = value;
|
||||
}
|
||||
}
|
||||
|
||||
// See ICloneable
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
@@ -148,6 +148,7 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
public static Encoding UTF8 = Encoding.UTF8;
|
||||
public static Encoding UTF8NoBomEncoding = new UTF8Encoding(false);
|
||||
|
||||
/// <value>
|
||||
/// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards)
|
||||
@@ -1236,8 +1237,7 @@ namespace OpenSim.Framework
|
||||
|
||||
public static string Base64ToString(string str)
|
||||
{
|
||||
UTF8Encoding encoder = new UTF8Encoding();
|
||||
Decoder utf8Decode = encoder.GetDecoder();
|
||||
Decoder utf8Decode = Encoding.UTF8.GetDecoder();
|
||||
|
||||
byte[] todecode_byte = Convert.FromBase64String(str);
|
||||
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace OpenSim.Framework
|
||||
/// <summary>Timer interval in milliseconds for the watchdog timer</summary>
|
||||
const double WATCHDOG_INTERVAL_MS = 2500.0d;
|
||||
|
||||
/// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
|
||||
public const int WATCHDOG_TIMEOUT_MS = 5000;
|
||||
/// <summary>Default timeout in milliseconds before a thread is considered dead</summary>
|
||||
public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000;
|
||||
|
||||
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
|
||||
public class ThreadWatchdogInfo
|
||||
@@ -101,12 +101,24 @@ namespace OpenSim.Framework
|
||||
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
|
||||
private static System.Timers.Timer m_watchdogTimer;
|
||||
|
||||
/// <summary>
|
||||
/// Last time the watchdog thread ran.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Should run every WATCHDOG_INTERVAL_MS
|
||||
/// </remarks>
|
||||
public static int LastWatchdogThreadTick { get; private set; }
|
||||
|
||||
static Watchdog()
|
||||
{
|
||||
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
|
||||
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
||||
m_watchdogTimer.AutoReset = false;
|
||||
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
|
||||
|
||||
// Set now so we don't get alerted on the first run
|
||||
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
||||
|
||||
m_watchdogTimer.Start();
|
||||
}
|
||||
|
||||
@@ -122,7 +134,7 @@ namespace OpenSim.Framework
|
||||
public static Thread StartThread(
|
||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
|
||||
{
|
||||
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, WATCHDOG_TIMEOUT_MS);
|
||||
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -264,6 +276,16 @@ namespace OpenSim.Framework
|
||||
/// <param name="e"></param>
|
||||
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
int now = Environment.TickCount & Int32.MaxValue;
|
||||
int msElapsed = now - LastWatchdogThreadTick;
|
||||
|
||||
if (msElapsed > WATCHDOG_INTERVAL_MS * 2)
|
||||
m_log.WarnFormat(
|
||||
"[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms",
|
||||
msElapsed, WATCHDOG_INTERVAL_MS);
|
||||
|
||||
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
||||
|
||||
Action<ThreadWatchdogInfo> callback = OnWatchdogTimeout;
|
||||
|
||||
if (callback != null)
|
||||
@@ -272,8 +294,6 @@ namespace OpenSim.Framework
|
||||
|
||||
lock (m_threads)
|
||||
{
|
||||
int now = Environment.TickCount & Int32.MaxValue;
|
||||
|
||||
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
||||
{
|
||||
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
||||
|
||||
@@ -92,9 +92,14 @@ namespace OpenSim
|
||||
m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
|
||||
}
|
||||
|
||||
m_log.DebugFormat(
|
||||
m_log.InfoFormat(
|
||||
"[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
|
||||
|
||||
string monoThreadsPerCpu = System.Environment.GetEnvironmentVariable("MONO_THREADS_PER_CPU");
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
|
||||
|
||||
// Increase the number of IOCP threads available. Mono defaults to a tragically low number
|
||||
int workerThreads, iocpThreads;
|
||||
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
|
||||
@@ -109,7 +114,6 @@ namespace OpenSim
|
||||
|
||||
// Check if the system is compatible with OpenSimulator.
|
||||
// Ensures that the minimum system requirements are met
|
||||
m_log.Info("Performing compatibility checks... \n");
|
||||
string supported = String.Empty;
|
||||
if (Util.IsEnvironmentSupported(ref supported))
|
||||
{
|
||||
|
||||
@@ -231,12 +231,14 @@ namespace OpenSim
|
||||
/// </summary>
|
||||
private void RegisterConsoleCommands()
|
||||
{
|
||||
MainServer.RegisterHttpConsoleCommands(m_console);
|
||||
|
||||
m_console.Commands.AddCommand("Objects", false, "force update",
|
||||
"force update",
|
||||
"Force the update of all objects on clients",
|
||||
HandleForceUpdate);
|
||||
|
||||
m_console.Commands.AddCommand("Comms", false, "debug packet",
|
||||
m_console.Commands.AddCommand("Debug", false, "debug packet",
|
||||
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Turn on packet debugging",
|
||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||
@@ -248,17 +250,9 @@ namespace OpenSim
|
||||
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("Comms", false, "debug http",
|
||||
"debug http <level>",
|
||||
"Turn on inbound http request debugging for everything except the event queue (see debug eq).",
|
||||
"If level >= 2 then the handler used to service the request is logged.\n"
|
||||
+ "If level >= 1 then incoming HTTP requests are logged.\n"
|
||||
+ "If level <= 0 then no extra http logging is done.\n",
|
||||
Debug);
|
||||
m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||
|
||||
m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||
|
||||
m_console.Commands.AddCommand("Regions", false, "debug scene",
|
||||
m_console.Commands.AddCommand("Debug", false, "debug scene",
|
||||
"debug scene <scripting> <collisions> <physics>",
|
||||
"Turn on scene debugging", Debug);
|
||||
|
||||
@@ -415,10 +409,6 @@ namespace OpenSim
|
||||
m_console.Commands.AddCommand("General", false, "modules unload",
|
||||
"modules unload <name>",
|
||||
"Unload a module", HandleModules);
|
||||
|
||||
m_console.Commands.AddCommand("Objects", false, "kill uuid",
|
||||
"kill uuid <UUID>",
|
||||
"Kill an object by UUID", KillUUID);
|
||||
}
|
||||
|
||||
public override void ShutdownSpecific()
|
||||
@@ -914,21 +904,6 @@ namespace OpenSim
|
||||
|
||||
break;
|
||||
|
||||
case "http":
|
||||
if (args.Length == 3)
|
||||
{
|
||||
int newDebug;
|
||||
if (int.TryParse(args[2], out newDebug))
|
||||
{
|
||||
MainServer.Instance.DebugLevel = newDebug;
|
||||
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output("Usage: debug http 0..2");
|
||||
break;
|
||||
|
||||
case "scene":
|
||||
if (args.Length == 4)
|
||||
{
|
||||
@@ -1021,44 +996,11 @@ namespace OpenSim
|
||||
break;
|
||||
|
||||
case "connections":
|
||||
System.Text.StringBuilder connections = new System.Text.StringBuilder("Connections:\n");
|
||||
m_sceneManager.ForEachScene(
|
||||
delegate(Scene scene) {
|
||||
scene.ForEachClient(
|
||||
delegate(IClientAPI client) {
|
||||
connections.AppendFormat(
|
||||
"{0}: {1} ({2}) from {3} on circuit {4}\n",
|
||||
scene.RegionInfo.RegionName,
|
||||
client.Name,
|
||||
client.AgentId,
|
||||
client.RemoteEndPoint,
|
||||
client.CircuitCode
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
MainConsole.Instance.Output(connections.ToString());
|
||||
HandleShowConnections();
|
||||
break;
|
||||
|
||||
case "circuits":
|
||||
System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n");
|
||||
m_sceneManager.ForEachScene(
|
||||
delegate(Scene scene) {
|
||||
//this.HttpServer.
|
||||
acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName);
|
||||
foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.GetAgentCircuits().Values)
|
||||
acd.AppendFormat(
|
||||
"\t{0} {1} ({2})\n",
|
||||
aCircuit.firstname,
|
||||
aCircuit.lastname,
|
||||
(aCircuit.child ? "Child" : "Root")
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
MainConsole.Instance.Output(acd.ToString());
|
||||
HandleShowCircuits();
|
||||
break;
|
||||
|
||||
case "http-handlers":
|
||||
@@ -1163,6 +1105,53 @@ namespace OpenSim
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleShowCircuits()
|
||||
{
|
||||
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||
cdt.AddColumn("Region", 20);
|
||||
cdt.AddColumn("Avatar name", 24);
|
||||
cdt.AddColumn("Type", 5);
|
||||
cdt.AddColumn("Code", 10);
|
||||
cdt.AddColumn("IP", 16);
|
||||
cdt.AddColumn("Viewer Name", 24);
|
||||
|
||||
m_sceneManager.ForEachScene(
|
||||
s =>
|
||||
{
|
||||
foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values)
|
||||
cdt.AddRow(
|
||||
s.Name,
|
||||
aCircuit.Name,
|
||||
aCircuit.child ? "child" : "root",
|
||||
aCircuit.circuitcode.ToString(),
|
||||
aCircuit.IPAddress.ToString(),
|
||||
aCircuit.Viewer);
|
||||
});
|
||||
|
||||
MainConsole.Instance.Output(cdt.ToString());
|
||||
}
|
||||
|
||||
private void HandleShowConnections()
|
||||
{
|
||||
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||
cdt.AddColumn("Region", 20);
|
||||
cdt.AddColumn("Avatar name", 24);
|
||||
cdt.AddColumn("Circuit code", 12);
|
||||
cdt.AddColumn("Endpoint", 23);
|
||||
cdt.AddColumn("Active?", 7);
|
||||
|
||||
m_sceneManager.ForEachScene(
|
||||
s => s.ForEachClient(
|
||||
c => cdt.AddRow(
|
||||
s.Name,
|
||||
c.Name,
|
||||
c.RemoteEndPoint.ToString(),
|
||||
c.CircuitCode.ToString(),
|
||||
c.IsActive.ToString())));
|
||||
|
||||
MainConsole.Instance.Output(cdt.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use XML2 format to serialize data to a file
|
||||
/// </summary>
|
||||
@@ -1330,58 +1319,6 @@ namespace OpenSim
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Kill an object given its UUID.
|
||||
/// </summary>
|
||||
/// <param name="cmdparams"></param>
|
||||
protected void KillUUID(string module, string[] cmdparams)
|
||||
{
|
||||
if (cmdparams.Length > 2)
|
||||
{
|
||||
UUID id = UUID.Zero;
|
||||
SceneObjectGroup grp = null;
|
||||
Scene sc = null;
|
||||
|
||||
if (!UUID.TryParse(cmdparams[2], out id))
|
||||
{
|
||||
MainConsole.Instance.Output("[KillUUID]: Error bad UUID format!");
|
||||
return;
|
||||
}
|
||||
|
||||
m_sceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
SceneObjectPart part = scene.GetSceneObjectPart(id);
|
||||
if (part == null)
|
||||
return;
|
||||
|
||||
grp = part.ParentGroup;
|
||||
sc = scene;
|
||||
});
|
||||
|
||||
if (grp == null)
|
||||
{
|
||||
MainConsole.Instance.Output(String.Format("[KillUUID]: Given UUID {0} not found!", id));
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output(String.Format("[KillUUID]: Found UUID {0} in scene {1}", id, sc.RegionInfo.RegionName));
|
||||
try
|
||||
{
|
||||
sc.DeleteSceneObject(grp, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[KillUUID]: Error while removing objects from scene: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("[KillUUID]: Usage: kill uuid <UUID>");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Comms",
|
||||
"Debug",
|
||||
false,
|
||||
"debug eq",
|
||||
"debug eq [0|1|2]",
|
||||
|
||||
@@ -51,7 +51,16 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
MainServer.Instance = new BaseHttpServer(9999, false, 9998, "");
|
||||
uint port = 9999;
|
||||
uint sslPort = 9998;
|
||||
|
||||
// This is an unfortunate bit of clean up we have to do because MainServer manages things through static
|
||||
// variables and the VM is not restarted between tests.
|
||||
MainServer.RemoveHttpServer(port);
|
||||
|
||||
BaseHttpServer server = new BaseHttpServer(port, false, sslPort, "");
|
||||
MainServer.AddHttpServer(server);
|
||||
MainServer.Instance = server;
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Startup");
|
||||
|
||||
@@ -333,7 +333,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
grp.AbsolutePosition = obj.Position;
|
||||
prim.RotationOffset = obj.Rotation;
|
||||
|
||||
grp.IsAttachment = false;
|
||||
// Required for linking
|
||||
grp.RootPart.ClearUpdateSchedule();
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// Handles new client connections
|
||||
/// Constructor takes a single Packet and authenticates everything
|
||||
/// </summary>
|
||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IClientIPEndpoint, IStatsCollector
|
||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector
|
||||
{
|
||||
/// <value>
|
||||
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
||||
@@ -357,7 +357,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
protected string m_lastName;
|
||||
protected Thread m_clientThread;
|
||||
protected Vector3 m_startpos;
|
||||
protected EndPoint m_userEndPoint;
|
||||
protected UUID m_activeGroupID;
|
||||
protected string m_activeGroupName = String.Empty;
|
||||
protected ulong m_activeGroupPowers;
|
||||
@@ -442,7 +441,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
||||
public LLClientView(Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
||||
UUID agentId, UUID sessionId, uint circuitCode)
|
||||
{
|
||||
// DebugPacketLevel = 1;
|
||||
@@ -450,7 +449,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
RegisterInterface<IClientIM>(this);
|
||||
RegisterInterface<IClientInventory>(this);
|
||||
RegisterInterface<IClientChat>(this);
|
||||
RegisterInterface<IClientIPEndpoint>(this);
|
||||
|
||||
m_scene = scene;
|
||||
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
|
||||
@@ -467,7 +465,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_sessionId = sessionId;
|
||||
m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
|
||||
m_circuitCode = circuitCode;
|
||||
m_userEndPoint = remoteEP;
|
||||
m_firstName = sessionInfo.LoginInfo.First;
|
||||
m_lastName = sessionInfo.LoginInfo.Last;
|
||||
m_startpos = sessionInfo.LoginInfo.StartPos;
|
||||
@@ -2719,6 +2716,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
public void SendAssetNotFound(AssetRequestToClient req)
|
||||
{
|
||||
TransferInfoPacket Transfer = new TransferInfoPacket();
|
||||
Transfer.TransferInfo.ChannelType = 2;
|
||||
Transfer.TransferInfo.Status = -2;
|
||||
Transfer.TransferInfo.TargetType = 0;
|
||||
Transfer.TransferInfo.Params = req.Params;
|
||||
Transfer.TransferInfo.Size = 0;
|
||||
Transfer.TransferInfo.TransferID = req.TransferRequestID;
|
||||
Transfer.Header.Zerocoded = true;
|
||||
OutPacket(Transfer, ThrottleOutPacketType.Asset);
|
||||
}
|
||||
|
||||
public void SendTexture(AssetBase TextureAsset)
|
||||
{
|
||||
|
||||
@@ -3722,8 +3732,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
++updatesThisCall;
|
||||
|
||||
#region UpdateFlags to packet type conversion
|
||||
|
||||
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
|
||||
@@ -3788,7 +3796,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
else
|
||||
{
|
||||
updateBlock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, AgentId);
|
||||
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||
updateBlock = CreatePrimUpdateBlock(part, AgentId);
|
||||
|
||||
// If the part has become a private hud since the update was scheduled then we do not
|
||||
// want to send it to other avatars.
|
||||
if (part.ParentGroup.IsAttachment
|
||||
&& part.ParentGroup.HasPrivateAttachmentPoint
|
||||
&& part.ParentGroup.AttachedAvatar != AgentId)
|
||||
continue;
|
||||
|
||||
// If the part has since been deleted, then drop the update. In the case of attachments,
|
||||
// this is to avoid spurious updates to other viewers since post-processing of attachments
|
||||
// has to change the IsAttachment flag for various reasons (which will end up in a pass
|
||||
// of the test above).
|
||||
//
|
||||
// Actual deletions (kills) happen in another method.
|
||||
if (part.ParentGroup.IsDeleted)
|
||||
continue;
|
||||
}
|
||||
|
||||
objectUpdateBlocks.Value.Add(updateBlock);
|
||||
@@ -3796,7 +3821,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
else if (!canUseImproved)
|
||||
{
|
||||
compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
|
||||
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||
ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
|
||||
= CreateCompressedUpdateBlock(part, updateFlags);
|
||||
|
||||
// If the part has since been deleted, then drop the update. In the case of attachments,
|
||||
// this is to avoid spurious updates to other viewers since post-processing of attachments
|
||||
// has to change the IsAttachment flag for various reasons (which will end up in a pass
|
||||
// of the test above).
|
||||
//
|
||||
// Actual deletions (kills) happen in another method.
|
||||
if (part.ParentGroup.IsDeleted)
|
||||
continue;
|
||||
|
||||
compressedUpdateBlocks.Value.Add(compressedBlock);
|
||||
compressedUpdates.Value.Add(update);
|
||||
}
|
||||
else
|
||||
@@ -3809,11 +3847,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
else
|
||||
{
|
||||
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
|
||||
= CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
|
||||
|
||||
// Everything else goes here
|
||||
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
||||
if (update.Entity is SceneObjectPart)
|
||||
{
|
||||
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||
|
||||
// If the part has become a private hud since the update was scheduled then we do not
|
||||
// want to send it to other avatars.
|
||||
if (part.ParentGroup.IsAttachment
|
||||
&& part.ParentGroup.HasPrivateAttachmentPoint
|
||||
&& part.ParentGroup.AttachedAvatar != AgentId)
|
||||
continue;
|
||||
|
||||
// If the part has since been deleted, then drop the update. In the case of attachments,
|
||||
// this is to avoid spurious updates to other viewers since post-processing of attachments
|
||||
// has to change the IsAttachment flag for various reasons (which will end up in a pass
|
||||
// of the test above).
|
||||
//
|
||||
// Actual deletions (kills) happen in another method.
|
||||
if (part.ParentGroup.IsDeleted)
|
||||
continue;
|
||||
}
|
||||
|
||||
terseUpdateBlocks.Value.Add(terseUpdateBlock);
|
||||
terseUpdates.Value.Add(update);
|
||||
}
|
||||
}
|
||||
|
||||
++updatesThisCall;
|
||||
|
||||
#endregion Block Construction
|
||||
}
|
||||
@@ -11766,7 +11830,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
ClientInfo info = m_udpClient.GetClientInfo();
|
||||
|
||||
info.userEP = m_userEndPoint;
|
||||
info.proxyEP = null;
|
||||
info.agentcircuit = RequestClientInfo();
|
||||
|
||||
@@ -11778,11 +11841,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_udpClient.SetClientInfo(info);
|
||||
}
|
||||
|
||||
public EndPoint GetClientEP()
|
||||
{
|
||||
return m_userEndPoint;
|
||||
}
|
||||
|
||||
#region Media Parcel Members
|
||||
|
||||
public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
|
||||
@@ -11980,14 +12038,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <param name="asset"></param>
|
||||
protected void AssetReceived(string id, Object sender, AssetBase asset)
|
||||
{
|
||||
if (asset == null)
|
||||
return;
|
||||
|
||||
TransferRequestPacket transferRequest = (TransferRequestPacket)sender;
|
||||
|
||||
UUID requestID = UUID.Zero;
|
||||
byte source = (byte)SourceType.Asset;
|
||||
|
||||
AssetRequestToClient req = new AssetRequestToClient();
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
req.AssetInf = null;
|
||||
req.AssetRequestSource = source;
|
||||
req.IsTextureRequest = false;
|
||||
req.NumPackets = 0;
|
||||
req.Params = transferRequest.TransferInfo.Params;
|
||||
req.RequestAssetID = requestID;
|
||||
req.TransferRequestID = transferRequest.TransferInfo.TransferID;
|
||||
|
||||
SendAssetNotFound(req);
|
||||
return;
|
||||
}
|
||||
|
||||
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
|
||||
{
|
||||
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
||||
@@ -12004,7 +12075,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return;
|
||||
|
||||
// The asset is known to exist and is in our cache, so add it to the AssetRequests list
|
||||
AssetRequestToClient req = new AssetRequestToClient();
|
||||
req.AssetInf = asset;
|
||||
req.AssetRequestSource = source;
|
||||
req.IsTextureRequest = false;
|
||||
@@ -12040,24 +12110,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return numPackets;
|
||||
}
|
||||
|
||||
#region IClientIPEndpoint Members
|
||||
|
||||
public IPAddress EndPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_userEndPoint is IPEndPoint)
|
||||
{
|
||||
IPEndPoint ep = (IPEndPoint)m_userEndPoint;
|
||||
|
||||
return ep.Address;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SendRebakeAvatarTextures(UUID textureID)
|
||||
{
|
||||
RebakeAvatarTexturesPacket pack =
|
||||
|
||||
@@ -270,7 +270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
false,
|
||||
true,
|
||||
GetWatchdogIncomingAlarmData,
|
||||
Watchdog.WATCHDOG_TIMEOUT_MS);
|
||||
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||
|
||||
Watchdog.StartThread(
|
||||
OutgoingPacketHandler,
|
||||
@@ -279,7 +279,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
false,
|
||||
true,
|
||||
GetWatchdogOutgoingAlarmData,
|
||||
Watchdog.WATCHDOG_TIMEOUT_MS);
|
||||
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||
|
||||
m_elapsedMSSinceLastStatReport = Environment.TickCount;
|
||||
}
|
||||
@@ -986,8 +986,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} from {1}",
|
||||
uccp.CircuitCode.Code, buffer.RemoteEndPoint);
|
||||
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
|
||||
uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint);
|
||||
|
||||
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||
|
||||
@@ -1016,8 +1016,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
||||
"[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
|
||||
uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
@@ -1103,7 +1103,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||
|
||||
client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client.OnLogout += LogoutHandler;
|
||||
|
||||
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
||||
|
||||
@@ -44,9 +44,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
}
|
||||
protected int m_objectNameCallsReceived;
|
||||
|
||||
public MockScene()
|
||||
public MockScene() : base(new RegionInfo(1000, 1000, null, null))
|
||||
{
|
||||
m_regInfo = new RegionInfo(1000, 1000, null, null);
|
||||
m_regStatus = RegionStatus.Up;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,22 +94,19 @@ namespace OpenSim.Region.ClientStack
|
||||
m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0}", m_httpServerPort);
|
||||
m_httpServer.Start();
|
||||
|
||||
MainServer.AddHttpServer(m_httpServer);
|
||||
MainServer.Instance = m_httpServer;
|
||||
|
||||
// "OOB" Server
|
||||
if (m_networkServersInfo.ssl_listener)
|
||||
{
|
||||
BaseHttpServer server = null;
|
||||
server = new BaseHttpServer(
|
||||
BaseHttpServer server = new BaseHttpServer(
|
||||
m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path,
|
||||
m_networkServersInfo.cert_pass);
|
||||
// Add the server to m_Servers
|
||||
if(server != null)
|
||||
{
|
||||
m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port);
|
||||
MainServer.AddHttpServer(server);
|
||||
server.Start();
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port);
|
||||
MainServer.AddHttpServer(server);
|
||||
server.Start();
|
||||
}
|
||||
|
||||
base.StartupSpecific();
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
IConfig assetConfig = source.Configs["AssetCache"];
|
||||
if (assetConfig == null)
|
||||
{
|
||||
m_log.Warn(
|
||||
m_log.Debug(
|
||||
"[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
|
||||
}
|
||||
else
|
||||
|
||||
@@ -100,6 +100,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
#region IAttachmentsModule
|
||||
|
||||
public void CopyAttachments(IScenePresence sp, AgentData ad)
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
// Attachment objects
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
if (attachments.Count > 0)
|
||||
{
|
||||
ad.AttachmentObjects = new List<ISceneObject>();
|
||||
ad.AttachmentObjectStates = new List<string>();
|
||||
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
||||
sp.InTransitScriptStates.Clear();
|
||||
|
||||
foreach (SceneObjectGroup sog in attachments)
|
||||
{
|
||||
// We need to make a copy and pass that copy
|
||||
// because of transfers withn the same sim
|
||||
ISceneObject clone = sog.CloneForNewScene();
|
||||
// Attachment module assumes that GroupPosition holds the offsets...!
|
||||
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
|
||||
((SceneObjectGroup)clone).IsAttachment = false;
|
||||
ad.AttachmentObjects.Add(clone);
|
||||
string state = sog.GetStateSnapshot();
|
||||
ad.AttachmentObjectStates.Add(state);
|
||||
sp.InTransitScriptStates.Add(state);
|
||||
// Let's remove the scripts of the original object here
|
||||
sog.RemoveScriptInstances(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyAttachments(AgentData ad, IScenePresence sp)
|
||||
{
|
||||
if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0)
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
sp.ClearAttachments();
|
||||
|
||||
int i = 0;
|
||||
foreach (ISceneObject so in ad.AttachmentObjects)
|
||||
{
|
||||
((SceneObjectGroup)so).LocalId = 0;
|
||||
((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
|
||||
so.SetState(ad.AttachmentObjectStates[i++], m_scene);
|
||||
m_scene.IncomingCreateObject(Vector3.Zero, so);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RezAttachments. This should only be called upon login on the first region.
|
||||
/// Attachment rezzings on crossings and TPs are done in a different way.
|
||||
@@ -152,31 +202,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted)
|
||||
public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted)
|
||||
{
|
||||
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
|
||||
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
foreach (SceneObjectGroup grp in sp.GetAttachments())
|
||||
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
|
||||
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
grp.IsAttachment = false;
|
||||
grp.AbsolutePosition = grp.RootPart.AttachedPos;
|
||||
UpdateKnownItem(sp, grp, saveAllScripted);
|
||||
grp.IsAttachment = true;
|
||||
foreach (SceneObjectGroup so in sp.GetAttachments())
|
||||
{
|
||||
// We can only remove the script instances from the script engine after we've retrieved their xml state
|
||||
// when we update the attachment item.
|
||||
m_scene.DeleteSceneObject(so, false, false);
|
||||
|
||||
if (saveChanged || saveAllScripted)
|
||||
{
|
||||
so.IsAttachment = false;
|
||||
so.AbsolutePosition = so.RootPart.AttachedPos;
|
||||
UpdateKnownItem(sp, so, saveAllScripted);
|
||||
}
|
||||
|
||||
so.RemoveScriptInstances(true);
|
||||
}
|
||||
|
||||
sp.ClearAttachments();
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
|
||||
// m_scene.RegionInfo.RegionName, sp.Name, silent);
|
||||
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
|
||||
// m_scene.RegionInfo.RegionName, sp.Name, silent);
|
||||
|
||||
foreach (SceneObjectGroup sop in sp.GetAttachments())
|
||||
{
|
||||
sop.Scene.DeleteSceneObject(sop, silent);
|
||||
@@ -192,6 +255,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
|
||||
// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
|
||||
|
||||
if (group.GetSittingAvatarsCount() != 0)
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
|
||||
// group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sp.GetAttachments(attachmentPt).Contains(group))
|
||||
{
|
||||
@@ -233,33 +305,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
group.AttachmentPoint = attachmentPt;
|
||||
group.AbsolutePosition = attachPos;
|
||||
|
||||
// We also don't want to do any of the inventory operations for an NPC.
|
||||
|
||||
if (sp.PresenceType != PresenceType.Npc)
|
||||
{
|
||||
// Remove any previous attachments
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
||||
|
||||
// At the moment we can only deal with a single attachment
|
||||
if (attachments.Count != 0)
|
||||
{
|
||||
UUID oldAttachmentItemID = attachments[0].FromItemID;
|
||||
|
||||
if (oldAttachmentItemID != UUID.Zero)
|
||||
DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID);
|
||||
else
|
||||
m_log.WarnFormat(
|
||||
"[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
||||
attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
||||
}
|
||||
|
||||
// Add the new attachment to inventory if we don't already have it.
|
||||
UUID newAttachmentItemID = group.FromItemID;
|
||||
if (newAttachmentItemID == UUID.Zero)
|
||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||
|
||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
||||
}
|
||||
UpdateUserInventoryWithAttachment(sp, group, attachmentPt);
|
||||
|
||||
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
||||
}
|
||||
@@ -267,7 +315,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
return true;
|
||||
}
|
||||
|
||||
public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
|
||||
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt)
|
||||
{
|
||||
// Remove any previous attachments
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
||||
|
||||
// At the moment we can only deal with a single attachment
|
||||
if (attachments.Count != 0)
|
||||
{
|
||||
if (attachments[0].FromItemID != UUID.Zero)
|
||||
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
|
||||
else
|
||||
m_log.WarnFormat(
|
||||
"[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
||||
attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
||||
}
|
||||
|
||||
// Add the new attachment to inventory if we don't already have it.
|
||||
UUID newAttachmentItemID = group.FromItemID;
|
||||
if (newAttachmentItemID == UUID.Zero)
|
||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||
|
||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
||||
}
|
||||
|
||||
public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
|
||||
{
|
||||
if (!Enabled)
|
||||
return null;
|
||||
@@ -306,12 +378,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
return null;
|
||||
}
|
||||
|
||||
SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt);
|
||||
|
||||
if (att == null)
|
||||
DetachSingleAttachmentToInv(sp, itemID);
|
||||
|
||||
return att;
|
||||
return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt);
|
||||
}
|
||||
|
||||
public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
|
||||
@@ -388,18 +455,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
|
||||
}
|
||||
|
||||
public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID)
|
||||
public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
// Save avatar attachment information
|
||||
// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
|
||||
|
||||
bool changed = sp.Appearance.DetachAttachment(itemID);
|
||||
if (so.AttachedAvatar != sp.UUID)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}",
|
||||
so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool changed = sp.Appearance.DetachAttachment(so.FromItemID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||
|
||||
DetachSingleAttachmentToInvInternal(sp, itemID);
|
||||
DetachSingleAttachmentToInvInternal(sp, so);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,17 +484,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
// First we save the
|
||||
// attachment point information, then we update the relative
|
||||
// positioning. Then we have to mark the object as NOT an
|
||||
// attachment. This is necessary in order to correctly save
|
||||
// and retrieve GroupPosition information for the attachment.
|
||||
// Finally, we restore the object's attachment status.
|
||||
uint attachmentPoint = sog.AttachmentPoint;
|
||||
sog.UpdateGroupPosition(pos);
|
||||
sog.IsAttachment = false;
|
||||
sog.AbsolutePosition = sog.RootPart.AttachedPos;
|
||||
sog.AttachmentPoint = attachmentPoint;
|
||||
sog.HasGroupChanged = true;
|
||||
}
|
||||
|
||||
@@ -461,6 +527,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
/// </remarks>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="grp"></param>
|
||||
/// <param name="saveAllScripted"></param>
|
||||
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted)
|
||||
{
|
||||
// Saving attachments for NPCs messes them up for the real owner!
|
||||
@@ -500,10 +567,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
m_scene.InventoryService.UpdateItem(item);
|
||||
|
||||
// this gets called when the agent logs off!
|
||||
// If the name of the object has been changed whilst attached then we want to update the inventory
|
||||
// item in the viewer.
|
||||
if (sp.ControllingClient != null)
|
||||
sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
|
||||
}
|
||||
|
||||
grp.HasGroupChanged = false; // Prevent it being saved over and over
|
||||
}
|
||||
// else
|
||||
@@ -562,6 +631,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
{
|
||||
m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId });
|
||||
}
|
||||
else if (so.HasPrivateAttachmentPoint)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
|
||||
// so.Name, sp.Name, so.AttachmentPoint);
|
||||
|
||||
// As this scene object can now only be seen by the attaching avatar, tell everybody else in the
|
||||
// scene that it's no longer in their awareness.
|
||||
m_scene.ForEachClient(
|
||||
client =>
|
||||
{ if (client.AgentId != so.AttachedAvatar)
|
||||
client.SendKillObject(m_scene.RegionInfo.RegionHandle, new List<uint>() { so.LocalId });
|
||||
});
|
||||
}
|
||||
|
||||
so.IsSelected = false; // fudge....
|
||||
so.ScheduleGroupForFullUpdate();
|
||||
@@ -587,11 +670,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
|
||||
// grp.Name, grp.LocalId, remoteClient.Name);
|
||||
|
||||
InventoryItemBase newItem = m_invAccessModule.CopyToInventory(
|
||||
DeRezAction.TakeCopy,
|
||||
m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
|
||||
new List<SceneObjectGroup> { grp },
|
||||
sp.ControllingClient, true)[0];
|
||||
InventoryItemBase newItem
|
||||
= m_invAccessModule.CopyToInventory(
|
||||
DeRezAction.TakeCopy,
|
||||
m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
|
||||
new List<SceneObjectGroup> { grp },
|
||||
sp.ControllingClient, true)[0];
|
||||
|
||||
// sets itemID so client can show item as 'attached' in inventory
|
||||
grp.FromItemID = newItem.ID;
|
||||
@@ -599,46 +683,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
return newItem;
|
||||
}
|
||||
|
||||
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
|
||||
// To LocalId or UUID, *THAT* is the question. How now Brown UUID??
|
||||
private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID)
|
||||
private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
|
||||
{
|
||||
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
|
||||
|
||||
if (itemID == UUID.Zero) // If this happened, someone made a mistake....
|
||||
return;
|
||||
m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
|
||||
sp.RemoveAttachment(so);
|
||||
|
||||
// We can NOT use the dictionries here, as we are looking
|
||||
// for an entity by the fromAssetID, which is NOT the prim UUID
|
||||
EntityBase[] detachEntities = m_scene.GetEntities();
|
||||
SceneObjectGroup group;
|
||||
// We can only remove the script instances from the script engine after we've retrieved their xml state
|
||||
// when we update the attachment item.
|
||||
m_scene.DeleteSceneObject(so, false, false);
|
||||
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
foreach (EntityBase entity in detachEntities)
|
||||
{
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
group = (SceneObjectGroup)entity;
|
||||
if (group.FromItemID == itemID)
|
||||
{
|
||||
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
|
||||
sp.RemoveAttachment(group);
|
||||
// Prepare sog for storage
|
||||
so.AttachedAvatar = UUID.Zero;
|
||||
so.RootPart.SetParentLocalId(0);
|
||||
so.IsAttachment = false;
|
||||
so.AbsolutePosition = so.RootPart.AttachedPos;
|
||||
|
||||
// Prepare sog for storage
|
||||
group.AttachedAvatar = UUID.Zero;
|
||||
group.RootPart.SetParentLocalId(0);
|
||||
group.IsAttachment = false;
|
||||
group.AbsolutePosition = group.RootPart.AttachedPos;
|
||||
|
||||
UpdateKnownItem(sp, group, true);
|
||||
m_scene.DeleteSceneObject(group, false);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateKnownItem(sp, so, true);
|
||||
so.RemoveScriptInstances(true);
|
||||
}
|
||||
|
||||
private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
|
||||
@@ -660,18 +723,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, sp.UUID, true);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
|
||||
// objatt.Name, remoteClient.Name, AttachmentPt);
|
||||
|
||||
if (objatt != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}",
|
||||
// objatt.Name, sp.Name, attachmentPt, m_scene.Name);
|
||||
|
||||
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
|
||||
objatt.HasGroupChanged = false;
|
||||
bool tainted = false;
|
||||
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
|
||||
tainted = true;
|
||||
|
||||
// FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
|
||||
// course of events. If not, then it's probably not worth trying to recover the situation
|
||||
// since this is more likely to trigger further exceptions and confuse later debugging. If
|
||||
// exceptions can be thrown in expected error conditions (not NREs) then make this consistent
|
||||
// since other normal error conditions will simply return false instead.
|
||||
// This will throw if the attachment fails
|
||||
try
|
||||
{
|
||||
@@ -742,7 +810,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
item = m_scene.InventoryService.GetItem(item);
|
||||
bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()",
|
||||
// sp.Name, att.Name, AttachmentPt);
|
||||
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -846,8 +920,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
|
||||
|
||||
if (sp != null && group != null)
|
||||
DetachSingleAttachmentToInv(sp, group.FromItemID);
|
||||
DetachSingleAttachmentToInv(sp, group);
|
||||
}
|
||||
|
||||
private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient)
|
||||
@@ -857,7 +932,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
if (sp != null)
|
||||
DetachSingleAttachmentToInv(sp, itemID);
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
|
||||
foreach (SceneObjectGroup group in attachments)
|
||||
{
|
||||
if (group.FromItemID == itemID)
|
||||
{
|
||||
DetachSingleAttachmentToInv(sp, group);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient)
|
||||
|
||||
@@ -31,6 +31,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
using System.Xml;
|
||||
using Timer=System.Timers.Timer;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
@@ -38,11 +39,16 @@ using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Region.CoreModules.Avatar.Attachments;
|
||||
using OpenSim.Region.CoreModules.Framework;
|
||||
using OpenSim.Region.CoreModules.Framework.EntityTransfer;
|
||||
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
|
||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||
using OpenSim.Region.CoreModules.Scripting.WorldComm;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.XEngine;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
@@ -52,11 +58,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
/// Attachment tests
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class AttachmentsModuleTests
|
||||
public class AttachmentsModuleTests : OpenSimTestCase
|
||||
{
|
||||
private Scene scene;
|
||||
private AttachmentsModule m_attMod;
|
||||
private ScenePresence m_presence;
|
||||
private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
|
||||
private OSChatMessage m_osChatMessageReceived;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
@@ -65,18 +70,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.None;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
scene = new SceneHelpers().SetupScene();
|
||||
m_attMod = new AttachmentsModule();
|
||||
SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
@@ -85,14 +78,100 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the standard presence for a test.
|
||||
/// </summary>
|
||||
private void AddPresence()
|
||||
private void OnChatFromWorld(object sender, OSChatMessage oscm)
|
||||
{
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
m_presence = SceneHelpers.AddScenePresence(scene, userId);
|
||||
// Console.WriteLine("Got chat [{0}]", oscm.Message);
|
||||
|
||||
m_osChatMessageReceived = oscm;
|
||||
m_chatEvent.Set();
|
||||
}
|
||||
|
||||
private Scene CreateTestScene()
|
||||
{
|
||||
IConfigSource config = new IniConfigSource();
|
||||
List<object> modules = new List<object>();
|
||||
|
||||
AddCommonConfig(config, modules);
|
||||
|
||||
Scene scene
|
||||
= new SceneHelpers().SetupScene(
|
||||
"attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
|
||||
SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
private Scene CreateScriptingEnabledTestScene()
|
||||
{
|
||||
IConfigSource config = new IniConfigSource();
|
||||
List<object> modules = new List<object>();
|
||||
|
||||
AddCommonConfig(config, modules);
|
||||
AddScriptingConfig(config, modules);
|
||||
|
||||
Scene scene
|
||||
= new SceneHelpers().SetupScene(
|
||||
"attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
|
||||
SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
|
||||
|
||||
scene.StartScripts();
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
private void AddCommonConfig(IConfigSource config, List<object> modules)
|
||||
{
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
modules.Add(new AttachmentsModule());
|
||||
modules.Add(new BasicInventoryAccessModule());
|
||||
}
|
||||
|
||||
private void AddScriptingConfig(IConfigSource config, List<object> modules)
|
||||
{
|
||||
IConfig startupConfig = config.AddConfig("Startup");
|
||||
startupConfig.Set("DefaultScriptEngine", "XEngine");
|
||||
|
||||
IConfig xEngineConfig = config.AddConfig("XEngine");
|
||||
xEngineConfig.Set("Enabled", "true");
|
||||
xEngineConfig.Set("StartDelay", "0");
|
||||
|
||||
// These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
|
||||
// to AssemblyResolver.OnAssemblyResolve fails.
|
||||
xEngineConfig.Set("AppDomainLoading", "false");
|
||||
|
||||
modules.Add(new XEngine());
|
||||
|
||||
// Necessary to stop serialization complaining
|
||||
// FIXME: Stop this being necessary if at all possible
|
||||
// modules.Add(new WorldCommModule());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an attachment item in the given user's inventory. Does not attach.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A user with the given ID and an inventory must already exist.
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// The attachment item.
|
||||
/// </returns>
|
||||
/// <param name='scene'></param>
|
||||
/// <param name='userId'></param>
|
||||
/// <param name='attName'></param>
|
||||
/// <param name='rawItemId'></param>
|
||||
/// <param name='rawAssetId'></param>
|
||||
private InventoryItemBase CreateAttachmentItem(
|
||||
Scene scene, UUID userId, string attName, int rawItemId, int rawAssetId)
|
||||
{
|
||||
return UserInventoryHelpers.CreateInventoryItem(
|
||||
scene,
|
||||
attName,
|
||||
TestHelpers.ParseTail(rawItemId),
|
||||
TestHelpers.ParseTail(rawAssetId),
|
||||
userId,
|
||||
InventoryType.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -101,16 +180,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
AddPresence();
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
|
||||
|
||||
string attName = "att";
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup;
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
|
||||
|
||||
m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(sp.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
@@ -121,51 +203,107 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
|
||||
// Check item status
|
||||
Assert.That(
|
||||
m_presence.Appearance.GetAttachpoint(attSo.FromItemID),
|
||||
sp.Appearance.GetAttachpoint(attSo.FromItemID),
|
||||
Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
|
||||
InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
|
||||
Assert.That(attachmentItem, Is.Not.Null);
|
||||
Assert.That(attachmentItem.Name, Is.EqualTo(attName));
|
||||
|
||||
InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object);
|
||||
InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
|
||||
Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
|
||||
|
||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
|
||||
// TestHelpers.DisableLogging();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that we do not attempt to attach an in-world object that someone else is sitting on.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestAddAttachmentFromInventory()
|
||||
public void TestAddSatOnAttachmentFromGround()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
|
||||
|
||||
string attName = "att";
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
|
||||
|
||||
UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2);
|
||||
ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2);
|
||||
|
||||
// Put avatar within 10m of the prim so that sit doesn't fail.
|
||||
sp2.AbsolutePosition = new Vector3(0, 0, 0);
|
||||
sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
|
||||
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
Assert.That(sp.HasAttachments(), Is.False);
|
||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRezAttachmentFromInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence, attItemId, (uint)AttachmentPoint.Chest);
|
||||
scene.AttachmentsModule.RezSingleAttachmentFromInventory(
|
||||
sp, attItem.ID, (uint)AttachmentPoint.Chest);
|
||||
|
||||
// Check scene presence status
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(sp.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check appearance status
|
||||
Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1));
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
|
||||
Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
|
||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test specific conditions associated with rezzing a scripted attachment from inventory.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestRezScriptedAttachmentFromInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
|
||||
TaskInventoryHelpers.AddScript(scene, so.RootPart);
|
||||
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
|
||||
|
||||
scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
|
||||
|
||||
// TODO: Need to have a test that checks the script is actually started but this involves a lot more
|
||||
// plumbing of the script engine and either pausing for events or more infrastructure to turn off various
|
||||
// script engine delays/asychronicity that isn't helpful in an automated regression testing context.
|
||||
SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name);
|
||||
Assert.That(attSo.ContainsScripts(), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -174,29 +312,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId);
|
||||
ISceneEntity so
|
||||
= scene.AttachmentsModule.RezSingleAttachmentFromInventory(
|
||||
sp, attItem.ID, (uint)AttachmentPoint.Chest);
|
||||
scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId);
|
||||
|
||||
// Check scene presence status
|
||||
Assert.That(m_presence.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(sp.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(0));
|
||||
|
||||
// Check appearance status
|
||||
Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
|
||||
Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(0));
|
||||
|
||||
// Check item status
|
||||
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
|
||||
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null);
|
||||
|
||||
// Check object in scene
|
||||
Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
|
||||
@@ -206,28 +342,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
public void TestDetachAttachmentToInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId);
|
||||
SceneObjectGroup so
|
||||
= (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(
|
||||
sp, attItem.ID, (uint)AttachmentPoint.Chest);
|
||||
scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(m_presence.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(sp.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(0));
|
||||
|
||||
// Check item status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
|
||||
Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0));
|
||||
|
||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test specific conditions associated with detaching a scripted attachment from inventory.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDetachScriptedAttachmentToInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
Scene scene = CreateScriptingEnabledTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
|
||||
TaskInventoryHelpers.AddScript(scene, so.RootPart);
|
||||
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
|
||||
|
||||
// FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
|
||||
// In the future, we need to be able to do this programatically more predicably.
|
||||
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
|
||||
|
||||
SceneObjectGroup soRezzed
|
||||
= scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
|
||||
|
||||
// Wait for chat to signal rezzed script has been started.
|
||||
m_chatEvent.WaitOne(60000);
|
||||
|
||||
scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, soRezzed);
|
||||
|
||||
InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem);
|
||||
AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString());
|
||||
|
||||
XmlDocument soXml = new XmlDocument();
|
||||
soXml.LoadXml(Encoding.UTF8.GetString(asset.Data));
|
||||
|
||||
XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState");
|
||||
Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -239,17 +413,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
InventoryItemBase attItem
|
||||
= UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
|
||||
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
|
||||
acd.Appearance = new AvatarAppearance();
|
||||
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
|
||||
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
|
||||
@@ -268,17 +436,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
InventoryItemBase attItem
|
||||
= UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
|
||||
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
|
||||
acd.Appearance = new AvatarAppearance();
|
||||
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
|
||||
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
|
||||
@@ -288,7 +450,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.Name, Is.EqualTo(attItem.Name));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
@@ -298,9 +460,125 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
|
||||
Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
|
||||
Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId));
|
||||
Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId));
|
||||
Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID));
|
||||
Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
|
||||
Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
|
||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpdateAttachmentPosition()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
|
||||
acd.Appearance = new AvatarAppearance();
|
||||
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd);
|
||||
|
||||
SceneObjectGroup attSo = sp.GetAttachments()[0];
|
||||
|
||||
Vector3 newPosition = new Vector3(1, 2, 4);
|
||||
|
||||
scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient);
|
||||
|
||||
Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition));
|
||||
Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSameSimulatorNeighbouringRegionsTeleport()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
AttachmentsModule attModA = new AttachmentsModule();
|
||||
AttachmentsModule attModB = new AttachmentsModule();
|
||||
EntityTransferModule etmA = new EntityTransferModule();
|
||||
EntityTransferModule etmB = new EntityTransferModule();
|
||||
LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
IConfig modulesConfig = config.AddConfig("Modules");
|
||||
modulesConfig.Set("EntityTransferModule", etmA.Name);
|
||||
modulesConfig.Set("SimulationServices", lscm.Name);
|
||||
IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
|
||||
|
||||
// In order to run a single threaded regression test we do not want the entity transfer module waiting
|
||||
// for a callback from the destination scene before removing its avatar data.
|
||||
entityTransferConfig.Set("wait_for_callback", false);
|
||||
|
||||
modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
SceneHelpers sh = new SceneHelpers();
|
||||
TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
|
||||
TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
|
||||
|
||||
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
|
||||
SceneHelpers.SetupSceneModules(
|
||||
sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule());
|
||||
SceneHelpers.SetupSceneModules(
|
||||
sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
|
||||
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
|
||||
ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager);
|
||||
beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
|
||||
|
||||
InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
|
||||
|
||||
sceneA.AttachmentsModule.RezSingleAttachmentFromInventory(
|
||||
beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest);
|
||||
|
||||
Vector3 teleportPosition = new Vector3(10, 11, 12);
|
||||
Vector3 teleportLookAt = new Vector3(20, 21, 22);
|
||||
|
||||
sceneA.RequestTeleportLocation(
|
||||
beforeTeleportSp.ControllingClient,
|
||||
sceneB.RegionInfo.RegionHandle,
|
||||
teleportPosition,
|
||||
teleportLookAt,
|
||||
(uint)TeleportFlags.ViaLocation);
|
||||
|
||||
((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide();
|
||||
|
||||
// Check attachments have made it into sceneB
|
||||
ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
|
||||
|
||||
// This is appearance data, as opposed to actually rezzed attachments
|
||||
List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments();
|
||||
Assert.That(sceneBAttachments.Count, Is.EqualTo(1));
|
||||
Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID));
|
||||
Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
|
||||
Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
|
||||
// This is the actual attachment
|
||||
List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments();
|
||||
Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
|
||||
Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
|
||||
Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
|
||||
|
||||
Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
|
||||
// Check attachments have been removed from sceneA
|
||||
ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID);
|
||||
|
||||
// Since this is appearance data, it is still present on the child avatar!
|
||||
List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments();
|
||||
Assert.That(sceneAAttachments.Count, Is.EqualTo(1));
|
||||
Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
|
||||
// This is the actual attachment, which should no longer exist
|
||||
List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
|
||||
Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
|
||||
|
||||
Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
// I'm commenting this test because scene setup NEEDS InventoryService to
|
||||
|
||||
@@ -128,7 +128,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
// m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
|
||||
// sp.Name, textureEntry, visualParams);
|
||||
|
||||
// TODO: This is probably not necessary any longer, just assume the
|
||||
// textureEntry set implies that the appearance transaction is complete
|
||||
|
||||
@@ -137,13 +137,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||
// toAgentID.ToString(), scene.RegionInfo.RegionName);
|
||||
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
{
|
||||
// Local message
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
||||
m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);
|
||||
|
||||
sp.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
@@ -155,13 +157,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
// try child avatar second
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
|
||||
m_log.DebugFormat(
|
||||
"[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
|
||||
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if (sp != null)
|
||||
{
|
||||
// Local message
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
|
||||
m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID);
|
||||
|
||||
sp.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
@@ -170,10 +174,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
|
||||
SendGridInstantMessageViaXMLRPC(im, result);
|
||||
m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
|
||||
|
||||
return;
|
||||
SendGridInstantMessageViaXMLRPC(im, result);
|
||||
}
|
||||
|
||||
private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
|
||||
|
||||
@@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock;
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class InventoryArchiveTestCase
|
||||
public class InventoryArchiveTestCase : OpenSimTestCase
|
||||
{
|
||||
protected ManualResetEvent mre = new ManualResetEvent(false);
|
||||
|
||||
@@ -84,8 +84,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
protected string m_coaItemName = "Coalesced Item";
|
||||
|
||||
[SetUp]
|
||||
public virtual void SetUp()
|
||||
public override void SetUp()
|
||||
{
|
||||
base.SetUp();
|
||||
m_iarStream = new MemoryStream(m_iarStreamBytes);
|
||||
}
|
||||
|
||||
|
||||
@@ -297,7 +297,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
|
||||
else if (
|
||||
im.dialog == (byte)InstantMessageDialog.InventoryDeclined
|
||||
|| im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined)
|
||||
{
|
||||
// Here, the recipient is local and we can assume that the
|
||||
// inventory is loaded. Courtesy of the above bulk update,
|
||||
|
||||
@@ -709,6 +709,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
agent.CallbackURI, region.RegionName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up operations once an agent has moved away through cross or teleport.
|
||||
/// </summary>
|
||||
/// <param name='sp'></param>
|
||||
/// <param name='logout'></param>
|
||||
protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
|
||||
{
|
||||
if (sp.Scene.AttachmentsModule != null)
|
||||
@@ -1666,6 +1671,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
#endregion
|
||||
|
||||
#region Object Transfers
|
||||
|
||||
/// <summary>
|
||||
/// Move the given scene object into a new region depending on which region its absolute position has moved
|
||||
/// into.
|
||||
@@ -1967,35 +1973,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
return successYN;
|
||||
}
|
||||
|
||||
protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent)
|
||||
/// <summary>
|
||||
/// Cross the attachments for an avatar into the destination region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is only invoked for simulators released prior to April 2011. Versions of OpenSimulator since then
|
||||
/// transfer attachments in one go as part of the ChildAgentDataUpdate data passed in the update agent call.
|
||||
/// </remarks>
|
||||
/// <param name='destination'></param>
|
||||
/// <param name='sp'></param>
|
||||
/// <param name='silent'></param>
|
||||
protected void CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent)
|
||||
{
|
||||
List<SceneObjectGroup> m_attachments = sp.GetAttachments();
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
|
||||
// Validate
|
||||
// foreach (SceneObjectGroup gobj in m_attachments)
|
||||
// {
|
||||
// if (gobj == null || gobj.IsDeleted)
|
||||
// return false;
|
||||
// }
|
||||
// m_log.DebugFormat(
|
||||
// "[ENTITY TRANSFER MODULE]: Crossing {0} attachments into {1} for {2}",
|
||||
// m_attachments.Count, destination.RegionName, sp.Name);
|
||||
|
||||
foreach (SceneObjectGroup gobj in m_attachments)
|
||||
foreach (SceneObjectGroup gobj in attachments)
|
||||
{
|
||||
// If the prim group is null then something must have happened to it!
|
||||
if (gobj != null && !gobj.IsDeleted)
|
||||
{
|
||||
// Set the parent localID to 0 so it transfers over properly.
|
||||
gobj.RootPart.SetParentLocalId(0);
|
||||
gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
|
||||
gobj.IsAttachment = false;
|
||||
SceneObjectGroup clone = (SceneObjectGroup)gobj.CloneForNewScene();
|
||||
clone.RootPart.GroupPosition = gobj.RootPart.AttachedPos;
|
||||
clone.IsAttachment = false;
|
||||
|
||||
//gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
|
||||
CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, gobj, silent);
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}",
|
||||
clone.UUID, destination.RegionName);
|
||||
|
||||
CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent);
|
||||
}
|
||||
}
|
||||
|
||||
sp.ClearAttachments();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
<RegionModule id="AuthenticationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication.AuthenticationServiceInConnectorModule" />
|
||||
<RegionModule id="AccessModule" type="OpenSim.Region.CoreModules.World.AccessModule" /> \
|
||||
<RegionModule id="MapImageModule" type="OpenSim.Region.CoreModules.World.LegacyMap.MapImageModule" /> \
|
||||
<RegionModule id="Warp3DImageModule" type="OpenSim.Region.CoreModules.World.Warp3DMap.Warp3DImageModule" /> \
|
||||
|
||||
</Extension>
|
||||
|
||||
|
||||
@@ -41,13 +41,39 @@ using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
{
|
||||
/// <summary>
|
||||
/// Data describing an external URL set up by a script.
|
||||
/// </summary>
|
||||
public class UrlData
|
||||
{
|
||||
/// <summary>
|
||||
/// Scene object part hosting the script
|
||||
/// </summary>
|
||||
public UUID hostID;
|
||||
|
||||
/// <summary>
|
||||
/// The item ID of the script that requested the URL.
|
||||
/// </summary>
|
||||
public UUID itemID;
|
||||
|
||||
/// <summary>
|
||||
/// The script engine that runs the script.
|
||||
/// </summary>
|
||||
public IScriptModule engine;
|
||||
|
||||
/// <summary>
|
||||
/// The generated URL.
|
||||
/// </summary>
|
||||
public string url;
|
||||
|
||||
/// <summary>
|
||||
/// The random UUID component of the generated URL.
|
||||
/// </summary>
|
||||
public UUID urlcode;
|
||||
|
||||
/// <summary>
|
||||
/// The external requests currently being processed or awaiting retrieval for this URL.
|
||||
/// </summary>
|
||||
public Dictionary<UUID, RequestData> requests;
|
||||
}
|
||||
|
||||
@@ -64,19 +90,33 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
public string uri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This module provides external URLs for in-world scripts.
|
||||
/// </summary>
|
||||
public class UrlModule : ISharedRegionModule, IUrlModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Dictionary<UUID, UrlData> m_RequestMap =
|
||||
new Dictionary<UUID, UrlData>();
|
||||
|
||||
private Dictionary<string, UrlData> m_UrlMap =
|
||||
new Dictionary<string, UrlData>();
|
||||
/// <summary>
|
||||
/// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the request ID
|
||||
/// randomly generated when a request is received for this URL.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Manipulation or retrieval from this dictionary must be locked on m_UrlMap to preserve consistency with
|
||||
/// m_UrlMap
|
||||
/// </remarks>
|
||||
private Dictionary<UUID, UrlData> m_RequestMap = new Dictionary<UUID, UrlData>();
|
||||
|
||||
/// <summary>
|
||||
/// Indexs the URL request metadata (which script requested it, outstanding requests, etc.) by the full URL
|
||||
/// </summary>
|
||||
private Dictionary<string, UrlData> m_UrlMap = new Dictionary<string, UrlData>();
|
||||
|
||||
/// <summary>
|
||||
/// Maximum number of external urls that can be set up by this module.
|
||||
/// </summary>
|
||||
private int m_TotalUrls = 100;
|
||||
|
||||
private uint https_port = 0;
|
||||
@@ -103,10 +143,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
{
|
||||
m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName);
|
||||
bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false);
|
||||
|
||||
if (ssl_enabled)
|
||||
{
|
||||
https_port = (uint) config.Configs["Network"].GetInt("https_port",0);
|
||||
}
|
||||
|
||||
IConfig llFunctionsConfig = config.Configs["LL-Functions"];
|
||||
|
||||
if (llFunctionsConfig != null)
|
||||
m_TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", m_TotalUrls);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
@@ -217,7 +261,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
urlData.urlcode = urlcode;
|
||||
urlData.requests = new Dictionary<UUID, RequestData>();
|
||||
|
||||
|
||||
m_UrlMap[url] = urlData;
|
||||
|
||||
string uri = "/lslhttps/" + urlcode.ToString() + "/";
|
||||
@@ -261,39 +304,47 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
|
||||
public void HttpResponse(UUID request, int status, string body)
|
||||
{
|
||||
if (m_RequestMap.ContainsKey(request))
|
||||
lock (m_UrlMap)
|
||||
{
|
||||
UrlData urlData = m_RequestMap[request];
|
||||
urlData.requests[request].responseCode = status;
|
||||
urlData.requests[request].responseBody = body;
|
||||
//urlData.requests[request].ev.Set();
|
||||
urlData.requests[request].requestDone =true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
|
||||
if (m_RequestMap.ContainsKey(request))
|
||||
{
|
||||
UrlData urlData = m_RequestMap[request];
|
||||
urlData.requests[request].responseCode = status;
|
||||
urlData.requests[request].responseBody = body;
|
||||
//urlData.requests[request].ev.Set();
|
||||
urlData.requests[request].requestDone =true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetHttpHeader(UUID requestId, string header)
|
||||
{
|
||||
if (m_RequestMap.ContainsKey(requestId))
|
||||
lock (m_UrlMap)
|
||||
{
|
||||
UrlData urlData=m_RequestMap[requestId];
|
||||
string value;
|
||||
if (urlData.requests[requestId].headers.TryGetValue(header,out value))
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
|
||||
if (m_RequestMap.ContainsKey(requestId))
|
||||
{
|
||||
UrlData urlData = m_RequestMap[requestId];
|
||||
string value;
|
||||
if (urlData.requests[requestId].headers.TryGetValue(header, out value))
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[HttpRequestHandler] There was no http-in request with id " + requestId);
|
||||
}
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public int GetFreeUrls()
|
||||
{
|
||||
return m_TotalUrls - m_UrlMap.Count;
|
||||
lock (m_UrlMap)
|
||||
return m_TotalUrls - m_UrlMap.Count;
|
||||
}
|
||||
|
||||
public void ScriptRemoved(UUID itemID)
|
||||
@@ -332,6 +383,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
{
|
||||
RemoveUrl(url.Value);
|
||||
removeURLs.Add(url.Key);
|
||||
|
||||
foreach (UUID req in url.Value.requests.Keys)
|
||||
m_RequestMap.Remove(req);
|
||||
}
|
||||
@@ -342,145 +394,165 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void RemoveUrl(UrlData data)
|
||||
{
|
||||
m_HttpServer.RemoveHTTPHandler("", "/lslhttp/"+data.urlcode.ToString()+"/");
|
||||
m_HttpServer.RemoveHTTPHandler("", "/lslhttp/" + data.urlcode.ToString() + "/");
|
||||
}
|
||||
|
||||
private Hashtable NoEvents(UUID requestID, UUID sessionID)
|
||||
{
|
||||
Hashtable response = new Hashtable();
|
||||
UrlData url;
|
||||
lock (m_RequestMap)
|
||||
UrlData urlData;
|
||||
|
||||
lock (m_UrlMap)
|
||||
{
|
||||
// We need to return a 404 here in case the request URL was removed at exactly the same time that a
|
||||
// request was made. In this case, the request thread can outrace llRemoveURL() and still be polling
|
||||
// for the request ID.
|
||||
if (!m_RequestMap.ContainsKey(requestID))
|
||||
return response;
|
||||
url = m_RequestMap[requestID];
|
||||
}
|
||||
|
||||
if (System.Environment.TickCount - url.requests[requestID].startTime > 25000)
|
||||
{
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
//remove from map
|
||||
lock (url)
|
||||
{
|
||||
url.requests.Remove(requestID);
|
||||
m_RequestMap.Remove(requestID);
|
||||
response["int_response_code"] = 404;
|
||||
response["str_response_string"] = "";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
return response;
|
||||
urlData = m_RequestMap[requestID];
|
||||
|
||||
if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
|
||||
{
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
//remove from map
|
||||
urlData.requests.Remove(requestID);
|
||||
m_RequestMap.Remove(requestID);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private bool HasEvents(UUID requestID, UUID sessionID)
|
||||
{
|
||||
UrlData url=null;
|
||||
|
||||
lock (m_RequestMap)
|
||||
lock (m_UrlMap)
|
||||
{
|
||||
// We return true here because an external URL request that happened at the same time as an llRemoveURL()
|
||||
// can still make it through to HttpRequestHandler(). That will return without setting up a request
|
||||
// when it detects that the URL has been removed. The poller, however, will continue to ask for
|
||||
// events for that request, so here we will signal that there are events and in GetEvents we will
|
||||
// return a 404.
|
||||
if (!m_RequestMap.ContainsKey(requestID))
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
url = m_RequestMap[requestID];
|
||||
if (!url.requests.ContainsKey(requestID))
|
||||
|
||||
UrlData urlData = m_RequestMap[requestID];
|
||||
|
||||
if (!urlData.requests.ContainsKey(requestID))
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Trigger return of timeout response.
|
||||
if (System.Environment.TickCount - urlData.requests[requestID].startTime > 25000)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return urlData.requests[requestID].requestDone;
|
||||
}
|
||||
|
||||
if (System.Environment.TickCount-url.requests[requestID].startTime>25000)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (url.requests[requestID].requestDone)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
|
||||
{
|
||||
UrlData url = null;
|
||||
RequestData requestData = null;
|
||||
Hashtable response;
|
||||
|
||||
lock (m_RequestMap)
|
||||
lock (m_UrlMap)
|
||||
{
|
||||
UrlData url = null;
|
||||
RequestData requestData = null;
|
||||
|
||||
if (!m_RequestMap.ContainsKey(requestID))
|
||||
return NoEvents(requestID,sessionID);
|
||||
return NoEvents(requestID, sessionID);
|
||||
|
||||
url = m_RequestMap[requestID];
|
||||
requestData = url.requests[requestID];
|
||||
}
|
||||
|
||||
if (!requestData.requestDone)
|
||||
return NoEvents(requestID,sessionID);
|
||||
|
||||
Hashtable response = new Hashtable();
|
||||
if (!requestData.requestDone)
|
||||
return NoEvents(requestID, sessionID);
|
||||
|
||||
if (System.Environment.TickCount - requestData.startTime > 25000)
|
||||
{
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response = new Hashtable();
|
||||
|
||||
if (System.Environment.TickCount - requestData.startTime > 25000)
|
||||
{
|
||||
response["int_response_code"] = 500;
|
||||
response["str_response_string"] = "Script timeout";
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
return response;
|
||||
}
|
||||
|
||||
//put response
|
||||
response["int_response_code"] = requestData.responseCode;
|
||||
response["str_response_string"] = requestData.responseBody;
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
return response;
|
||||
}
|
||||
//put response
|
||||
response["int_response_code"] = requestData.responseCode;
|
||||
response["str_response_string"] = requestData.responseBody;
|
||||
response["content_type"] = "text/plain";
|
||||
response["keepalive"] = false;
|
||||
response["reusecontext"] = false;
|
||||
|
||||
//remove from map
|
||||
lock (url)
|
||||
{
|
||||
|
||||
//remove from map
|
||||
url.requests.Remove(requestID);
|
||||
m_RequestMap.Remove(requestID);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public void HttpRequestHandler(UUID requestID, Hashtable request)
|
||||
{
|
||||
lock (request)
|
||||
{
|
||||
string uri = request["uri"].ToString();
|
||||
bool is_ssl = uri.Contains("lslhttps");
|
||||
string uri = request["uri"].ToString();
|
||||
bool is_ssl = uri.Contains("lslhttps");
|
||||
|
||||
try
|
||||
{
|
||||
Hashtable headers = (Hashtable)request["headers"];
|
||||
try
|
||||
{
|
||||
Hashtable headers = (Hashtable)request["headers"];
|
||||
|
||||
// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
|
||||
|
||||
int pos1 = uri.IndexOf("/");// /lslhttp
|
||||
int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
|
||||
int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
|
||||
string uri_tmp = uri.Substring(0, pos3 + 1);
|
||||
//HTTP server code doesn't provide us with QueryStrings
|
||||
string pathInfo;
|
||||
string queryString;
|
||||
queryString = "";
|
||||
int pos1 = uri.IndexOf("/");// /lslhttp
|
||||
int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/
|
||||
int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp/<UUID>/
|
||||
string uri_tmp = uri.Substring(0, pos3 + 1);
|
||||
//HTTP server code doesn't provide us with QueryStrings
|
||||
string pathInfo;
|
||||
string queryString;
|
||||
queryString = "";
|
||||
|
||||
pathInfo = uri.Substring(pos3);
|
||||
pathInfo = uri.Substring(pos3);
|
||||
|
||||
UrlData url = null;
|
||||
if (!is_ssl)
|
||||
url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp];
|
||||
UrlData urlData = null;
|
||||
|
||||
lock (m_UrlMap)
|
||||
{
|
||||
string url;
|
||||
|
||||
if (is_ssl)
|
||||
url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp;
|
||||
else
|
||||
url = m_UrlMap["https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp];
|
||||
url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp;
|
||||
|
||||
// Avoid a race - the request URL may have been released via llRequestUrl() whilst this
|
||||
// request was being processed.
|
||||
if (!m_UrlMap.TryGetValue(url, out urlData))
|
||||
return;
|
||||
|
||||
//for llGetHttpHeader support we need to store original URI here
|
||||
//to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
|
||||
@@ -500,6 +572,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
string value = (string)header.Value;
|
||||
requestData.headers.Add(key, value);
|
||||
}
|
||||
|
||||
foreach (DictionaryEntry de in request)
|
||||
{
|
||||
if (de.Key.ToString() == "querystringkeys")
|
||||
@@ -513,11 +586,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
queryString = queryString + key + "=" + val + "&";
|
||||
}
|
||||
}
|
||||
|
||||
if (queryString.Length > 1)
|
||||
queryString = queryString.Substring(0, queryString.Length - 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//if this machine is behind DNAT/port forwarding, currently this is being
|
||||
@@ -525,34 +597,23 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
requestData.headers["x-remote-ip"] = requestData.headers["remote_addr"];
|
||||
requestData.headers["x-path-info"] = pathInfo;
|
||||
requestData.headers["x-query-string"] = queryString;
|
||||
requestData.headers["x-script-url"] = url.url;
|
||||
|
||||
//requestData.ev = new ManualResetEvent(false);
|
||||
lock (url.requests)
|
||||
{
|
||||
url.requests.Add(requestID, requestData);
|
||||
}
|
||||
lock (m_RequestMap)
|
||||
{
|
||||
//add to request map
|
||||
m_RequestMap.Add(requestID, url);
|
||||
}
|
||||
|
||||
url.engine.PostScriptEvent(url.itemID, "http_request", new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
|
||||
|
||||
//send initial response?
|
||||
// Hashtable response = new Hashtable();
|
||||
|
||||
return;
|
||||
requestData.headers["x-script-url"] = urlData.url;
|
||||
|
||||
urlData.requests.Add(requestID, requestData);
|
||||
m_RequestMap.Add(requestID, urlData);
|
||||
}
|
||||
catch (Exception we)
|
||||
{
|
||||
//Hashtable response = new Hashtable();
|
||||
m_log.Warn("[HttpRequestHandler]: http-in request failed");
|
||||
m_log.Warn(we.Message);
|
||||
m_log.Warn(we.StackTrace);
|
||||
}
|
||||
|
||||
urlData.engine.PostScriptEvent(
|
||||
urlData.itemID,
|
||||
"http_request",
|
||||
new Object[] { requestID.ToString(), request["http-method"].ToString(), request["body"].ToString() });
|
||||
}
|
||||
catch (Exception we)
|
||||
{
|
||||
//Hashtable response = new Hashtable();
|
||||
m_log.Warn("[HttpRequestHandler]: http-in request failed");
|
||||
m_log.Warn(we.Message);
|
||||
m_log.Warn(we.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,4 +622,4 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||
ScriptRemoved(itemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,11 +131,12 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
|
||||
{
|
||||
// Start http server
|
||||
// Attach xmlrpc handlers
|
||||
m_log.Info("[XML RPC MODULE]: " +
|
||||
"Starting up XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
|
||||
BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort);
|
||||
// m_log.InfoFormat(
|
||||
// "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.",
|
||||
// m_remoteDataPort);
|
||||
|
||||
IHttpServer httpServer = MainServer.GetHttpServer((uint)m_remoteDataPort);
|
||||
httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
|
||||
httpServer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.Info("[LAND IN CONNECTOR]: Starting...");
|
||||
// m_log.Info("[LAND IN CONNECTOR]: Starting...");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting...");
|
||||
// m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting...");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
|
||||
@@ -41,8 +41,7 @@ using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
{
|
||||
public class LocalGridServicesConnector :
|
||||
ISharedRegionModule, IGridService
|
||||
public class LocalGridServicesConnector : ISharedRegionModule, IGridService
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
@@ -51,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
private IGridService m_GridService;
|
||||
private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>();
|
||||
|
||||
private bool m_Enabled = false;
|
||||
private bool m_Enabled;
|
||||
|
||||
public LocalGridServicesConnector()
|
||||
{
|
||||
@@ -59,7 +58,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
public LocalGridServicesConnector(IConfigSource source)
|
||||
{
|
||||
m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated");
|
||||
m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector instantiated directly.");
|
||||
InitialiseService(source);
|
||||
}
|
||||
|
||||
@@ -84,8 +83,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
if (name == Name)
|
||||
{
|
||||
InitialiseService(source);
|
||||
m_Enabled = true;
|
||||
m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled");
|
||||
m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,7 +93,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
IConfig assetConfig = source.Configs["GridService"];
|
||||
if (assetConfig == null)
|
||||
{
|
||||
m_log.Error("[LOCAL GRID CONNECTOR]: GridService missing from OpenSim.ini");
|
||||
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,7 +102,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
if (serviceDll == String.Empty)
|
||||
{
|
||||
m_log.Error("[LOCAL GRID CONNECTOR]: No LocalServiceModule named in section GridService");
|
||||
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -115,16 +113,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
if (m_GridService == null)
|
||||
{
|
||||
m_log.Error("[LOCAL GRID CONNECTOR]: Can't load grid service");
|
||||
m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service");
|
||||
return;
|
||||
}
|
||||
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
// FIXME: We will still add this command even if we aren't enabled since RemoteGridServiceConnector
|
||||
// will have instantiated us directly.
|
||||
MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours",
|
||||
"show neighbours",
|
||||
"Shows the local regions' neighbours", NeighboursCommand);
|
||||
"Shows the local regions' neighbours", HandleShowNeighboursCommand);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@@ -133,17 +135,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (m_Enabled)
|
||||
scene.RegisterModuleInterface<IGridService>(this);
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
scene.RegisterModuleInterface<IGridService>(this);
|
||||
|
||||
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
|
||||
m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
|
||||
m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
|
||||
else
|
||||
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_LocalCache[scene.RegionInfo.RegionID].Clear();
|
||||
m_LocalCache.Remove(scene.RegionInfo.RegionID);
|
||||
}
|
||||
@@ -232,7 +239,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
#endregion
|
||||
|
||||
public void NeighboursCommand(string module, string[] cmdparams)
|
||||
public void HandleShowNeighboursCommand(string module, string[] cmdparams)
|
||||
{
|
||||
System.Text.StringBuilder caps = new System.Text.StringBuilder();
|
||||
|
||||
|
||||
@@ -125,13 +125,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour
|
||||
uint x, y;
|
||||
Utils.LongToUInts(regionHandle, out x, out y);
|
||||
|
||||
m_log.DebugFormat("[NEIGHBOUR CONNECTOR]: HelloNeighbour from region {0} to region at {1}-{2}",
|
||||
thisRegion.RegionName, x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
|
||||
foreach (Scene s in m_Scenes)
|
||||
{
|
||||
if (s.RegionInfo.RegionHandle == regionHandle)
|
||||
{
|
||||
m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}",
|
||||
thisRegion.RegionName, s.Name, x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
|
||||
//m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour");
|
||||
return s.IncomingHelloNeighbour(thisRegion);
|
||||
}
|
||||
|
||||
@@ -354,24 +354,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
|
||||
{
|
||||
if (destination == null)
|
||||
return false;
|
||||
|
||||
if (m_scenes.ContainsKey(destination.RegionID))
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
|
||||
// s.RegionInfo.RegionName, destination.RegionHandle);
|
||||
|
||||
return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endregion /* IInterregionComms */
|
||||
|
||||
#region Misc
|
||||
|
||||
@@ -300,13 +300,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CreateObject(GridRegion destination, UUID userID, UUID itemID)
|
||||
{
|
||||
// Not Implemented
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion /* IInterregionComms */
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,8 +46,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
||||
|
||||
/// <summary>
|
||||
/// Store for asset data we received before we get the metadata
|
||||
/// </summary>
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
MediaEntry me = new MediaEntry();
|
||||
|
||||
m_module.SetMediaEntry(part, 1, me);
|
||||
@@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests
|
||||
|
||||
string homeUrl = "opensimulator.org";
|
||||
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
MediaEntry me = new MediaEntry() { HomeURL = homeUrl };
|
||||
|
||||
m_module.SetMediaEntry(part, 1, me);
|
||||
|
||||
@@ -98,7 +98,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
|
||||
m_console.Commands.AddCommand(
|
||||
"Objects", false, "delete object name",
|
||||
"delete object name [--regex] <name>",
|
||||
"Delete a scene object by name.\nIf --regex is specified then the name is treatead as a regular expression",
|
||||
"Delete a scene object by name.",
|
||||
"If --regex is specified then the name is treatead as a regular expression",
|
||||
HandleDeleteObject);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
@@ -118,7 +119,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
|
||||
false,
|
||||
"show object name",
|
||||
"show object name [--regex] <name>",
|
||||
"Show details of scene objects with the given name.\nIf --regex is specified then the name is treatead as a regular expression",
|
||||
"Show details of scene objects with the given name.",
|
||||
"If --regex is specified then the name is treatead as a regular expression",
|
||||
HandleShowObjectByName);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
@@ -133,7 +135,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
|
||||
false,
|
||||
"show part name",
|
||||
"show part name [--regex] <name>",
|
||||
"Show details of scene object parts with the given name.\nIf --regex is specified then the name is treatead as a regular expression",
|
||||
"Show details of scene object parts with the given name.",
|
||||
"If --regex is specified then the name is treatead as a regular expression",
|
||||
HandleShowPartByName);
|
||||
}
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
"Force permissions on or off",
|
||||
HandleForcePermissions);
|
||||
|
||||
m_scene.AddCommand("Users", this, "debug permissions",
|
||||
m_scene.AddCommand("Debug", this, "debug permissions",
|
||||
"debug permissions <true / false>",
|
||||
"Turn on permissions debugging",
|
||||
HandleDebugPermissions);
|
||||
@@ -348,12 +348,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
|
||||
|
||||
if (m_friendsModule == null)
|
||||
m_log.Warn("[PERMISSIONS]: Friends module not found, friend permissions will not work");
|
||||
m_log.Debug("[PERMISSIONS]: Friends module not found, friend permissions will not work");
|
||||
|
||||
m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||
|
||||
if (m_groupsModule == null)
|
||||
m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work");
|
||||
m_log.Debug("[PERMISSIONS]: Groups module not found, group permissions will not work");
|
||||
|
||||
m_moapModule = m_scene.RequestModuleInterface<IMoapModule>();
|
||||
|
||||
|
||||
@@ -78,11 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Sound
|
||||
|
||||
if (grp.IsAttachment)
|
||||
{
|
||||
if (grp.AttachmentPoint > 30) // HUD
|
||||
{
|
||||
if (sp.ControllingClient.AgentId != grp.OwnerID)
|
||||
return;
|
||||
}
|
||||
if (grp.HasPrivateAttachmentPoint && sp.ControllingClient.AgentId != grp.OwnerID)
|
||||
return;
|
||||
|
||||
if (sp.ControllingClient.AgentId == grp.OwnerID)
|
||||
dis = 0;
|
||||
|
||||
@@ -252,7 +252,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
if (horizontalScale < 0.01d)
|
||||
horizontalScale = 0.01d;
|
||||
|
||||
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
||||
Encoding enc = Encoding.ASCII;
|
||||
|
||||
bs.Write(enc.GetBytes("TERRAGENTERRAIN "));
|
||||
|
||||
|
||||
@@ -1108,6 +1108,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceMinTerrain(Object[] args)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < m_channel.Width; x++)
|
||||
{
|
||||
for (y = 0; y < m_channel.Height; y++)
|
||||
{
|
||||
m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]);
|
||||
}
|
||||
}
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceMaxTerrain(Object[] args)
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < m_channel.Width; x++)
|
||||
{
|
||||
for (y = 0; y < m_channel.Height; y++)
|
||||
{
|
||||
m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]);
|
||||
}
|
||||
}
|
||||
CheckForTerrainUpdates();
|
||||
}
|
||||
|
||||
private void InterfaceShowDebugStats(Object[] args)
|
||||
{
|
||||
double max = Double.MinValue;
|
||||
@@ -1248,6 +1274,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
rescaleCommand.AddArgument("min", "min terrain height after rescaling", "Double");
|
||||
rescaleCommand.AddArgument("max", "max terrain height after rescaling", "Double");
|
||||
|
||||
Command minCommand = new Command("min", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMinTerrain, "Sets the minimum terrain height to the specified value.");
|
||||
minCommand.AddArgument("min", "terrain height to use as minimum", "Double");
|
||||
|
||||
Command maxCommand = new Command("max", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMaxTerrain, "Sets the maximum terrain height to the specified value.");
|
||||
maxCommand.AddArgument("min", "terrain height to use as maximum", "Double");
|
||||
|
||||
|
||||
// Debug
|
||||
Command showDebugStatsCommand =
|
||||
@@ -1279,6 +1311,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
m_commander.RegisterCommand("effect", pluginRunCommand);
|
||||
m_commander.RegisterCommand("flip", flipCommand);
|
||||
m_commander.RegisterCommand("rescale", rescaleCommand);
|
||||
m_commander.RegisterCommand("min", minCommand);
|
||||
m_commander.RegisterCommand("max", maxCommand);
|
||||
|
||||
// Add this to our scene so scripts can call these functions
|
||||
m_scene.RegisterModuleCommander(m_commander);
|
||||
|
||||
@@ -111,6 +111,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||
asset = assetService.GetCached(cacheID.ToString());
|
||||
if (asset != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[TERRAIN SPLAT]: Got asset service cached terrain texture {0} {1}", i, asset.ID);
|
||||
|
||||
try
|
||||
{
|
||||
using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data))
|
||||
@@ -129,6 +132,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||
asset = assetService.Get(textureIDs[i].ToString());
|
||||
if (asset != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID);
|
||||
|
||||
try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -137,15 +143,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||
}
|
||||
|
||||
if (detailTexture[i] != null)
|
||||
{
|
||||
Bitmap bitmap = detailTexture[i];
|
||||
|
||||
{
|
||||
// Make sure this texture is the correct size, otherwise resize
|
||||
if (bitmap.Width != 256 || bitmap.Height != 256)
|
||||
if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256)
|
||||
{
|
||||
using (Bitmap origBitmap = bitmap)
|
||||
using (Bitmap origBitmap = detailTexture[i])
|
||||
{
|
||||
bitmap = ImageUtils.ResizeImage(origBitmap, 256, 256);
|
||||
detailTexture[i] = ImageUtils.ResizeImage(origBitmap, 256, 256);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +157,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||
byte[] data;
|
||||
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
|
||||
{
|
||||
bitmap.Save(stream, ImageFormat.Png);
|
||||
detailTexture[i].Save(stream, ImageFormat.Png);
|
||||
data = stream.ToArray();
|
||||
}
|
||||
|
||||
@@ -185,6 +189,9 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||
{
|
||||
if (detailTexture[i] == null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[TERRAIN SPLAT]: Generating solid colour for missing texture {0}", i);
|
||||
|
||||
// Create a solid color texture for this layer
|
||||
detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
|
||||
using (Graphics gfx = Graphics.FromImage(detailTexture[i]))
|
||||
|
||||
@@ -730,7 +730,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||
{
|
||||
if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout))
|
||||
{
|
||||
m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle);
|
||||
m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted region {0}", regionhandle);
|
||||
|
||||
m_blacklistedregions.Remove(regionhandle);
|
||||
}
|
||||
@@ -781,7 +781,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||
{
|
||||
if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout))
|
||||
{
|
||||
m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver);
|
||||
m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted URL {0}", httpserver);
|
||||
|
||||
m_blacklistedurls.Remove(httpserver);
|
||||
}
|
||||
@@ -1343,7 +1343,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||
if (terrain == null)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[WORLDMAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName);
|
||||
m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName);
|
||||
|
||||
byte[] data = terrain.WriteJpeg2000Image();
|
||||
if (data == null)
|
||||
@@ -1365,7 +1365,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
|
||||
asset.Flags = AssetFlags.Maptile;
|
||||
|
||||
// Store the new one
|
||||
m_log.DebugFormat("[WORLDMAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName);
|
||||
m_log.DebugFormat("[WORLD MAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName);
|
||||
|
||||
m_scene.AssetService.Store(asset);
|
||||
|
||||
|
||||
@@ -35,6 +35,20 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
{
|
||||
public interface IAttachmentsModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Copy attachment data from a ScenePresence into the AgentData structure for transmission to another simulator
|
||||
/// </summary>
|
||||
/// <param name='sp'></param>
|
||||
/// <param name='ad'></param>
|
||||
void CopyAttachments(IScenePresence sp, AgentData ad);
|
||||
|
||||
/// <summary>
|
||||
/// Copy attachment data from an AgentData structure into a ScenePresence.
|
||||
/// </summary>
|
||||
/// <param name='ad'></param>
|
||||
/// <param name='sp'></param>
|
||||
void CopyAttachments(AgentData ad, IScenePresence sp);
|
||||
|
||||
/// <summary>
|
||||
/// RezAttachments. This should only be called upon login on the first region.
|
||||
/// Attachment rezzings on crossings and TPs are done in a different way.
|
||||
@@ -43,10 +57,15 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
void RezAttachments(IScenePresence sp);
|
||||
|
||||
/// <summary>
|
||||
/// Save the attachments that have change on this presence.
|
||||
/// Derez the attachements for a scene presence that is closing.
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted);
|
||||
/// <remarks>
|
||||
/// Attachment changes are saved.
|
||||
/// </remarks>
|
||||
/// <param name="sp">The presence closing</param>
|
||||
/// <param name="saveChanged">Save changed attachments.</param>
|
||||
/// <param name="saveAllScripted">Save attachments with scripts even if they haven't changed.</para>
|
||||
void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted);
|
||||
|
||||
/// <summary>
|
||||
/// Delete all the presence's attachments from the scene
|
||||
@@ -73,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name="itemID"></param>
|
||||
/// <param name="AttachmentPt"></param>
|
||||
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
|
||||
ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt);
|
||||
SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt);
|
||||
|
||||
/// <summary>
|
||||
/// Rez multiple attachments from a user's inventory
|
||||
@@ -90,11 +109,11 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID);
|
||||
|
||||
/// <summary>
|
||||
/// Detach the given item so that it remains in the user's inventory.
|
||||
/// Detach the given attachment so that it remains in the user's inventory.
|
||||
/// </summary>
|
||||
/// <param name="sp">/param>
|
||||
/// <param name="itemID"></param>
|
||||
void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID);
|
||||
/// <param name="grp">The attachment to detach.</param>
|
||||
void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup grp);
|
||||
|
||||
/// <summary>
|
||||
/// Update the position of an attachment.
|
||||
|
||||
@@ -81,13 +81,18 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <summary>
|
||||
/// Start all the scripts contained in this entity's inventory
|
||||
/// </summary>
|
||||
void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
|
||||
/// <param name="startParam"></param>
|
||||
/// <param name="postOnRez"></param>
|
||||
/// <param name="engine"></param>
|
||||
/// <param name="stateSource"></param>
|
||||
/// <returns>Number of scripts started.</returns>
|
||||
int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
|
||||
|
||||
ArrayList GetScriptErrors(UUID itemID);
|
||||
void ResumeScripts();
|
||||
|
||||
/// <summary>
|
||||
/// Stop all the scripts in this entity.
|
||||
/// Stop and remove all the scripts in this entity from the scene.
|
||||
/// </summary>
|
||||
/// <param name="sceneObjectBeingDeleted">
|
||||
/// Should be true if these scripts are being removed because the scene
|
||||
@@ -95,6 +100,11 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// </param>
|
||||
void RemoveScriptInstances(bool sceneObjectBeingDeleted);
|
||||
|
||||
/// <summary>
|
||||
/// Stop all the scripts in this entity.
|
||||
/// </summary>
|
||||
void StopScriptInstances();
|
||||
|
||||
/// <summary>
|
||||
/// Start a script which is in this entity's inventory.
|
||||
/// </summary>
|
||||
@@ -102,7 +112,11 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name="postOnRez"></param>
|
||||
/// <param name="engine"></param>
|
||||
/// <param name="stateSource"></param>
|
||||
void CreateScriptInstance(
|
||||
/// <returns>
|
||||
/// true if the script instance was valid for starting, false otherwise. This does not guarantee
|
||||
/// that the script was actually started, just that the script was valid (i.e. its asset data could be found, etc.)
|
||||
/// </returns>
|
||||
bool CreateScriptInstance(
|
||||
TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource);
|
||||
|
||||
/// <summary>
|
||||
@@ -113,10 +127,14 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <param name="postOnRez"></param>
|
||||
/// <param name="engine"></param>
|
||||
/// <param name="stateSource"></param>
|
||||
void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
|
||||
/// <returns>
|
||||
/// true if the script instance was valid for starting, false otherwise. This does not guarantee
|
||||
/// that the script was actually started, just that the script was valid (i.e. its asset data could be found, etc.)
|
||||
/// </returns>
|
||||
bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
|
||||
|
||||
/// <summary>
|
||||
/// Stop a script which is in this prim's inventory.
|
||||
/// Stop and remove a script which is in this prim's inventory from the scene.
|
||||
/// </summary>
|
||||
/// <param name="itemId"></param>
|
||||
/// <param name="sceneObjectBeingDeleted">
|
||||
@@ -125,6 +143,12 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// </param>
|
||||
void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted);
|
||||
|
||||
/// <summary>
|
||||
/// Stop a script which is in this prim's inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemId"></param>
|
||||
void StopScriptInstance(UUID itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
|
||||
/// name is chosen.
|
||||
|
||||
@@ -183,6 +183,14 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <returns>true if the stand succeeded, false if not</returns>
|
||||
bool Stand(UUID agentID, Scene scene);
|
||||
|
||||
/// <summary>
|
||||
/// Get the NPC to touch an object.
|
||||
/// </summary>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="partID"></param>
|
||||
/// <returns>true if the touch is actually attempted, false if not</returns>
|
||||
bool Touch(UUID agentID, UUID partID);
|
||||
|
||||
/// <summary>
|
||||
/// Delete an NPC.
|
||||
/// </summary>
|
||||
|
||||
@@ -40,6 +40,12 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// </remarks>
|
||||
public interface IScenePresence : ISceneAgent
|
||||
{
|
||||
/// <summary>
|
||||
/// Copy of the script states while the agent is in transit. This state may
|
||||
/// need to be placed back in case of transfer fail.
|
||||
/// </summary>
|
||||
List<string> InTransitScriptStates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments.
|
||||
/// </summary>
|
||||
@@ -66,6 +72,10 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// <returns></returns>
|
||||
List<SceneObjectGroup> GetAttachments(uint attachmentPoint);
|
||||
|
||||
/// <summary>
|
||||
/// Does this avatar have any attachments?
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool HasAttachments();
|
||||
|
||||
// Don't use these methods directly. Instead, use the AttachmentsModule
|
||||
|
||||
@@ -69,6 +69,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
|
||||
ArrayList GetScriptErrors(UUID itemID);
|
||||
|
||||
bool HasScript(UUID itemID, out bool running);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a script is running.
|
||||
/// </summary>
|
||||
@@ -99,4 +101,4 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// </returns>
|
||||
Dictionary<uint, float> GetObjectScriptsExecutionTimes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,19 +60,32 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <summary>
|
||||
/// Creates all the scripts in the scene which should be started.
|
||||
/// </summary>
|
||||
public void CreateScriptInstances()
|
||||
/// <returns>
|
||||
/// Number of scripts that were valid for starting. This does not guarantee that all these scripts
|
||||
/// were actually started, but just that the start could be attempt (e.g. the asset data for the script could be found)
|
||||
/// </returns>
|
||||
public int CreateScriptInstances()
|
||||
{
|
||||
m_log.Info("[PRIM INVENTORY]: Creating scripts in scene");
|
||||
m_log.InfoFormat("[SCENE]: Initializing script instances in {0}", RegionInfo.RegionName);
|
||||
|
||||
int scriptsValidForStarting = 0;
|
||||
|
||||
EntityBase[] entities = Entities.GetEntities();
|
||||
foreach (EntityBase group in entities)
|
||||
{
|
||||
if (group is SceneObjectGroup)
|
||||
{
|
||||
((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
|
||||
scriptsValidForStarting
|
||||
+= ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
|
||||
((SceneObjectGroup) group).ResumeScripts();
|
||||
}
|
||||
}
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[SCENE]: Initialized {0} script instances in {1}",
|
||||
scriptsValidForStarting, RegionInfo.RegionName);
|
||||
|
||||
return scriptsValidForStarting;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void StartScripts()
|
||||
{
|
||||
m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
|
||||
m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
|
||||
|
||||
IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
|
||||
|
||||
|
||||
@@ -120,6 +120,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
get { return m_defaultDrawDistance; }
|
||||
}
|
||||
|
||||
private List<string> m_AllowedViewers = new List<string>();
|
||||
private List<string> m_BannedViewers = new List<string>();
|
||||
|
||||
// TODO: need to figure out how allow client agents but deny
|
||||
// root agents when ACL denies access to root agent
|
||||
@@ -500,6 +503,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public IAttachmentsModule AttachmentsModule { get; set; }
|
||||
public IEntityTransferModule EntityTransferModule { get; private set; }
|
||||
public IAgentAssetTransactions AgentTransactionsModule { get; private set; }
|
||||
public IUserManagement UserManagementModule { get; private set; }
|
||||
|
||||
public IAvatarFactoryModule AvatarFactory
|
||||
{
|
||||
@@ -613,8 +617,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_sceneGridService = sceneGridService;
|
||||
m_SimulationDataService = simDataService;
|
||||
m_EstateDataService = estateDataService;
|
||||
m_regionHandle = m_regInfo.RegionHandle;
|
||||
m_regionName = m_regInfo.RegionName;
|
||||
m_regionHandle = RegionInfo.RegionHandle;
|
||||
|
||||
m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
|
||||
m_asyncSceneObjectDeleter.Enabled = true;
|
||||
@@ -629,7 +632,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// resave.
|
||||
// FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
|
||||
// region is set up and avoid these gyrations.
|
||||
RegionSettings rs = simDataService.LoadRegionSettings(m_regInfo.RegionID);
|
||||
RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
|
||||
bool updatedTerrainTextures = false;
|
||||
if (rs.TerrainTexture1 == UUID.Zero)
|
||||
{
|
||||
@@ -658,10 +661,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (updatedTerrainTextures)
|
||||
rs.Save();
|
||||
|
||||
m_regInfo.RegionSettings = rs;
|
||||
RegionInfo.RegionSettings = rs;
|
||||
|
||||
if (estateDataService != null)
|
||||
m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
|
||||
RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
|
||||
|
||||
#endregion Region Settings
|
||||
|
||||
@@ -779,6 +782,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
string grant = startupConfig.GetString("AllowedClients", String.Empty);
|
||||
if (grant.Length > 0)
|
||||
{
|
||||
foreach (string viewer in grant.Split('|'))
|
||||
{
|
||||
m_AllowedViewers.Add(viewer.Trim().ToLower());
|
||||
}
|
||||
}
|
||||
|
||||
grant = startupConfig.GetString("BannedClients", String.Empty);
|
||||
if (grant.Length > 0)
|
||||
{
|
||||
foreach (string viewer in grant.Split('|'))
|
||||
{
|
||||
m_BannedViewers.Add(viewer.Trim().ToLower());
|
||||
}
|
||||
}
|
||||
|
||||
MinFrameTime = startupConfig.GetFloat( "MinFrameTime", MinFrameTime);
|
||||
m_update_backup = startupConfig.GetInt( "UpdateStorageEveryNFrames", m_update_backup);
|
||||
m_update_coarse_locations = startupConfig.GetInt( "UpdateCoarseLocationsEveryNFrames", m_update_coarse_locations);
|
||||
@@ -827,7 +848,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats;
|
||||
}
|
||||
|
||||
public Scene(RegionInfo regInfo)
|
||||
public Scene(RegionInfo regInfo) : base(regInfo)
|
||||
{
|
||||
PhysicalPrims = true;
|
||||
CollidablePrims = true;
|
||||
@@ -854,7 +875,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
WestBorders.Add(westBorder);
|
||||
BordersLocked = false;
|
||||
|
||||
m_regInfo = regInfo;
|
||||
m_eventManager = new EventManager();
|
||||
|
||||
m_permissions = new ScenePermissions(this);
|
||||
@@ -1198,8 +1218,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
m_sceneGraph.Close();
|
||||
|
||||
if (!GridService.DeregisterRegion(m_regInfo.RegionID))
|
||||
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName);
|
||||
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
|
||||
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
|
||||
|
||||
// call the base class Close method.
|
||||
base.Close();
|
||||
@@ -1243,6 +1263,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
EntityTransferModule = RequestModuleInterface<IEntityTransferModule>();
|
||||
m_groupsModule = RequestModuleInterface<IGroupsModule>();
|
||||
AgentTransactionsModule = RequestModuleInterface<IAgentAssetTransactions>();
|
||||
UserManagementModule = RequestModuleInterface<IUserManagement>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1474,11 +1495,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
LoginLock = false;
|
||||
EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
|
||||
}
|
||||
m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
|
||||
|
||||
// For RegionReady lockouts
|
||||
if(LoginLock == false)
|
||||
if (!LoginLock)
|
||||
{
|
||||
m_log.InfoFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
|
||||
LoginsDisabled = false;
|
||||
}
|
||||
|
||||
@@ -1718,14 +1739,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void StoreWindlightProfile(RegionLightShareData wl)
|
||||
{
|
||||
m_regInfo.WindlightSettings = wl;
|
||||
RegionInfo.WindlightSettings = wl;
|
||||
SimulationDataService.StoreRegionWindlightSettings(wl);
|
||||
m_eventManager.TriggerOnSaveNewWindlightProfile();
|
||||
}
|
||||
|
||||
public void LoadWindlightProfile()
|
||||
{
|
||||
m_regInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID);
|
||||
RegionInfo.WindlightSettings = SimulationDataService.LoadRegionWindlightSettings(RegionInfo.RegionID);
|
||||
m_eventManager.TriggerOnSaveNewWindlightProfile();
|
||||
}
|
||||
|
||||
@@ -2021,9 +2042,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
sceneObject.SetGroup(groupID, null);
|
||||
}
|
||||
|
||||
IUserManagement uman = RequestModuleInterface<IUserManagement>();
|
||||
if (uman != null)
|
||||
sceneObject.RootPart.CreatorIdentification = uman.GetUserUUI(ownerID);
|
||||
if (UserManagementModule != null)
|
||||
sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID);
|
||||
|
||||
sceneObject.ScheduleGroupForFullUpdate();
|
||||
|
||||
@@ -2163,13 +2183,30 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <summary>
|
||||
/// Synchronously delete the given object from the scene.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Scripts are also removed.
|
||||
/// </remarks>
|
||||
/// <param name="group">Object Id</param>
|
||||
/// <param name="silent">Suppress broadcasting changes to other clients.</param>
|
||||
public void DeleteSceneObject(SceneObjectGroup group, bool silent)
|
||||
{
|
||||
DeleteSceneObject(group, silent, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Synchronously delete the given object from the scene.
|
||||
/// </summary>
|
||||
/// <param name="group">Object Id</param>
|
||||
/// <param name="silent">Suppress broadcasting changes to other clients.</param>
|
||||
/// <param name="removeScripts">If true, then scripts are removed. If false, then they are only stopped.</para>
|
||||
public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
|
||||
{
|
||||
// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
|
||||
|
||||
group.RemoveScriptInstances(true);
|
||||
if (removeScripts)
|
||||
group.RemoveScriptInstances(true);
|
||||
else
|
||||
group.StopScriptInstances();
|
||||
|
||||
SceneObjectPart[] partList = group.Parts;
|
||||
|
||||
@@ -2217,7 +2254,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
ForceSceneObjectBackup(so);
|
||||
|
||||
so.DetachFromBackup();
|
||||
SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID);
|
||||
SimulationDataService.RemoveObject(so.UUID, RegionInfo.RegionID);
|
||||
}
|
||||
|
||||
// We need to keep track of this state in case this group is still queued for further backup.
|
||||
@@ -2475,7 +2512,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[SCENE]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace);
|
||||
m_log.WarnFormat("[INTERREGION]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the user is banned, we won't let any of their objects
|
||||
// enter. Period.
|
||||
//
|
||||
if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID))
|
||||
{
|
||||
m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2484,33 +2530,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (!AddSceneObject(newObject))
|
||||
{
|
||||
m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
|
||||
m_log.DebugFormat(
|
||||
"[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// For attachments, we need to wait until the agent is root
|
||||
// before we restart the scripts, or else some functions won't work.
|
||||
if (!newObject.IsAttachment)
|
||||
{
|
||||
// FIXME: It would be better to never add the scene object at all rather than add it and then delete
|
||||
// it
|
||||
if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition))
|
||||
{
|
||||
// Deny non attachments based on parcel settings
|
||||
//
|
||||
m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
|
||||
|
||||
DeleteSceneObject(newObject, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// For attachments, we need to wait until the agent is root
|
||||
// before we restart the scripts, or else some functions won't work.
|
||||
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
|
||||
newObject.ResumeScripts();
|
||||
}
|
||||
else
|
||||
{
|
||||
ScenePresence sp;
|
||||
if (TryGetScenePresence(newObject.OwnerID, out sp))
|
||||
{
|
||||
// If the scene presence is here and already a root
|
||||
// agent, we came from a ;egacy region. Start the scripts
|
||||
// here as they used to start.
|
||||
// TODO: Remove in 0.7.3
|
||||
if (!sp.IsChildAgent)
|
||||
{
|
||||
newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
|
||||
newObject.ResumeScripts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do this as late as possible so that listeners have full access to the incoming object
|
||||
EventManager.TriggerOnIncomingSceneObject(newObject);
|
||||
@@ -2518,28 +2562,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attachment rezzing
|
||||
/// </summary>
|
||||
/// <param name="userID">Agent Unique ID</param>
|
||||
/// <param name="itemID">Object ID</param>
|
||||
/// <returns>False</returns>
|
||||
public virtual bool IncomingCreateObject(UUID userID, UUID itemID)
|
||||
{
|
||||
m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
|
||||
|
||||
// Commented out since this is as yet unused and is arguably not the appropriate place to do this, as
|
||||
// attachments are being rezzed elsewhere in AddNewClient()
|
||||
// ScenePresence sp = GetScenePresence(userID);
|
||||
// if (sp != null && AttachmentsModule != null)
|
||||
// {
|
||||
// uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
|
||||
// AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a Scene Object group to the Scene.
|
||||
/// Verifies that the creator of the object is not banned from the simulator.
|
||||
@@ -2549,18 +2571,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
|
||||
public bool AddSceneObject(SceneObjectGroup sceneObject)
|
||||
{
|
||||
// If the user is banned, we won't let any of their objects
|
||||
// enter. Period.
|
||||
//
|
||||
if (m_regInfo.EstateSettings.IsBanned(sceneObject.OwnerID))
|
||||
{
|
||||
m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sceneObject.SetScene(this);
|
||||
|
||||
// Force allocation of new LocalId
|
||||
//
|
||||
SceneObjectPart[] parts = sceneObject.Parts;
|
||||
@@ -2605,18 +2615,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
else
|
||||
{
|
||||
AddRestoredSceneObject(sceneObject, true, false);
|
||||
|
||||
if (!Permissions.CanObjectEntry(sceneObject.UUID,
|
||||
true, sceneObject.AbsolutePosition))
|
||||
{
|
||||
// Deny non attachments based on parcel settings
|
||||
//
|
||||
m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
|
||||
|
||||
DeleteSceneObject(sceneObject, false);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -2711,14 +2709,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="aCircuit"></param>
|
||||
private void CacheUserName(ScenePresence sp, AgentCircuitData aCircuit)
|
||||
{
|
||||
IUserManagement uMan = RequestModuleInterface<IUserManagement>();
|
||||
if (uMan != null)
|
||||
if (UserManagementModule != null)
|
||||
{
|
||||
string first = aCircuit.firstname, last = aCircuit.lastname;
|
||||
|
||||
if (sp.PresenceType == PresenceType.Npc)
|
||||
{
|
||||
uMan.AddUser(aCircuit.AgentID, first, last);
|
||||
UserManagementModule.AddUser(aCircuit.AgentID, first, last);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2737,7 +2734,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
uMan.AddUser(aCircuit.AgentID, first, last, homeURL);
|
||||
UserManagementModule.AddUser(aCircuit.AgentID, first, last, homeURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3292,17 +3289,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (!isChildAgent)
|
||||
{
|
||||
if (AttachmentsModule != null && avatar.PresenceType != PresenceType.Npc)
|
||||
if (AttachmentsModule != null)
|
||||
{
|
||||
IUserManagement uMan = RequestModuleInterface<IUserManagement>();
|
||||
// Don't save attachments for HG visitors, it
|
||||
// messes up their inventory. When a HG visitor logs
|
||||
// out on a foreign grid, their attachments will be
|
||||
// reloaded in the state they were in when they left
|
||||
// the home grid. This is best anyway as the visited
|
||||
// grid may use an incompatible script engine.
|
||||
if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
|
||||
AttachmentsModule.SaveChangedAttachments(avatar, false);
|
||||
bool saveChanged
|
||||
= avatar.PresenceType != PresenceType.Npc
|
||||
&& (UserManagementModule == null || UserManagementModule.IsLocalGridUser(avatar.UUID));
|
||||
|
||||
AttachmentsModule.DeRezAttachments(avatar, saveChanged, false);
|
||||
}
|
||||
|
||||
ForEachClient(
|
||||
@@ -3455,6 +3454,50 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check if the viewer is banned or in the viewer access list
|
||||
//We check if the substring is listed for higher flexebility
|
||||
bool ViewerDenied = true;
|
||||
|
||||
//Check if the specific viewer is listed in the allowed viewer list
|
||||
if (m_AllowedViewers.Count > 0)
|
||||
{
|
||||
foreach (string viewer in m_AllowedViewers)
|
||||
{
|
||||
if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower())
|
||||
{
|
||||
ViewerDenied = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewerDenied = false;
|
||||
}
|
||||
|
||||
//Check if the viewer is in the banned list
|
||||
if (m_BannedViewers.Count > 0)
|
||||
{
|
||||
foreach (string viewer in m_BannedViewers)
|
||||
{
|
||||
if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower())
|
||||
{
|
||||
ViewerDenied = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ViewerDenied)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Access denied for {0} {1} using {2}",
|
||||
agent.firstname, agent.lastname, agent.Viewer);
|
||||
reason = "Access denied, your viewer is banned by the region owner";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ScenePresence sp = GetScenePresence(agent.AgentID);
|
||||
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
@@ -3732,9 +3775,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
if (m_regInfo.EstateSettings != null)
|
||||
if (RegionInfo.EstateSettings != null)
|
||||
{
|
||||
if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
|
||||
if (RegionInfo.EstateSettings.IsBanned(agent.AgentID))
|
||||
{
|
||||
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
|
||||
agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
|
||||
@@ -3766,7 +3809,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
bool groupAccess = false;
|
||||
UUID[] estateGroups = m_regInfo.EstateSettings.EstateGroups;
|
||||
UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups;
|
||||
|
||||
if (estateGroups != null)
|
||||
{
|
||||
@@ -3784,8 +3827,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
|
||||
}
|
||||
|
||||
if (!m_regInfo.EstateSettings.PublicAccess &&
|
||||
!m_regInfo.EstateSettings.HasAccess(agent.AgentID) &&
|
||||
if (!RegionInfo.EstateSettings.PublicAccess &&
|
||||
!RegionInfo.EstateSettings.HasAccess(agent.AgentID) &&
|
||||
!groupAccess)
|
||||
{
|
||||
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
|
||||
@@ -3858,7 +3901,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// if (loggingOffUser != null)
|
||||
// {
|
||||
// UUID localRegionSecret = UUID.Zero;
|
||||
// bool parsedsecret = UUID.TryParse(m_regInfo.regionSecret, out localRegionSecret);
|
||||
// bool parsedsecret = UUID.TryParse(RegionInfo.regionSecret, out localRegionSecret);
|
||||
//
|
||||
// // Region Secret is used here in case a new sessionid overwrites an old one on the user server.
|
||||
// // Will update the user server in a few revisions to use it.
|
||||
@@ -4077,13 +4120,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
ScenePresence sp = GetScenePresence(remoteClient.AgentId);
|
||||
if (sp != null)
|
||||
{
|
||||
uint regionX = m_regInfo.RegionLocX;
|
||||
uint regionY = m_regInfo.RegionLocY;
|
||||
uint regionX = RegionInfo.RegionLocX;
|
||||
uint regionY = RegionInfo.RegionLocY;
|
||||
|
||||
Utils.LongToUInts(regionHandle, out regionX, out regionY);
|
||||
|
||||
int shiftx = (int) regionX - (int) m_regInfo.RegionLocX * (int)Constants.RegionSize;
|
||||
int shifty = (int) regionY - (int) m_regInfo.RegionLocY * (int)Constants.RegionSize;
|
||||
int shiftx = (int) regionX - (int) RegionInfo.RegionLocX * (int)Constants.RegionSize;
|
||||
int shifty = (int) regionY - (int) RegionInfo.RegionLocY * (int)Constants.RegionSize;
|
||||
|
||||
position.X += shiftx;
|
||||
position.Y += shifty;
|
||||
@@ -4106,7 +4149,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (!result)
|
||||
{
|
||||
regionHandle = m_regInfo.RegionHandle;
|
||||
regionHandle = RegionInfo.RegionHandle;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4433,6 +4476,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_sceneGraph.ForEachScenePresence(action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all the scene object groups.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The scene object groups. If the scene is empty then an empty list is returned.
|
||||
/// </returns>
|
||||
public List<SceneObjectGroup> GetSceneObjectGroups()
|
||||
{
|
||||
return m_sceneGraph.GetSceneObjectGroups();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a group via its UUID
|
||||
/// </summary>
|
||||
@@ -4612,7 +4666,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void DeleteFromStorage(UUID uuid)
|
||||
{
|
||||
SimulationDataService.RemoveObject(uuid, m_regInfo.RegionID);
|
||||
SimulationDataService.RemoveObject(uuid, RegionInfo.RegionID);
|
||||
}
|
||||
|
||||
public int GetHealth()
|
||||
@@ -5037,7 +5091,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
IEstateDataService estateDataService = EstateDataService;
|
||||
if (estateDataService != null)
|
||||
{
|
||||
m_regInfo.EstateSettings = estateDataService.LoadEstateSettings(m_regInfo.RegionID, false);
|
||||
RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
|
||||
TriggerEstateSunUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
public string Name { get { return RegionInfo.RegionName; } }
|
||||
|
||||
public IConfigSource Config
|
||||
{
|
||||
@@ -146,6 +148,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
#endregion
|
||||
|
||||
public SceneBase(RegionInfo regInfo)
|
||||
{
|
||||
RegionInfo = regInfo;
|
||||
}
|
||||
|
||||
#region Update Methods
|
||||
|
||||
/// <summary>
|
||||
@@ -209,10 +216,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual RegionInfo RegionInfo
|
||||
{
|
||||
get { return m_regInfo; }
|
||||
}
|
||||
public virtual RegionInfo RegionInfo { get; private set; }
|
||||
|
||||
#region admin stuff
|
||||
|
||||
|
||||
@@ -84,16 +84,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (neighbourService != null)
|
||||
neighbour = neighbourService.HelloNeighbour(regionhandle, region);
|
||||
else
|
||||
m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: No neighbour service provided for informing neigbhours of this region");
|
||||
m_log.DebugFormat(
|
||||
"[SCENE COMMUNICATION SERVICE]: No neighbour service provided for region {0} to inform neigbhours of status",
|
||||
m_scene.Name);
|
||||
|
||||
if (neighbour != null)
|
||||
{
|
||||
m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
m_log.DebugFormat(
|
||||
"[SCENE COMMUNICATION SERVICE]: Region {0} successfully informed neighbour {1} at {2}-{3} that it is up",
|
||||
m_scene.Name, neighbour.RegionName, x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
|
||||
m_scene.EventManager.TriggerOnRegionUp(neighbour);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[SCENE COMMUNICATION SERVICE]: Failed to inform neighbour {0}-{1} that I'm here.", x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
m_log.WarnFormat(
|
||||
"[SCENE COMMUNICATION SERVICE]: Region {0} failed to inform neighbour at {1}-{2} that it is up.",
|
||||
x / Constants.RegionSize, y / Constants.RegionSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,8 +108,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
|
||||
|
||||
List<GridRegion> neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID);
|
||||
m_log.DebugFormat("[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that this region is up", neighbours.Count);
|
||||
List<GridRegion> neighbours
|
||||
= m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[SCENE COMMUNICATION SERVICE]: Informing {0} neighbours that region {1} is up",
|
||||
neighbours.Count, m_scene.Name);
|
||||
|
||||
foreach (GridRegion n in neighbours)
|
||||
{
|
||||
InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync;
|
||||
|
||||
@@ -355,9 +355,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (Entities.ContainsKey(sceneObject.UUID))
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
|
||||
// m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
|
||||
m_log.DebugFormat(
|
||||
"[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
|
||||
m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -957,6 +957,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all the scene object groups.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The scene object groups. If the scene is empty then an empty list is returned.
|
||||
/// </returns>
|
||||
protected internal List<SceneObjectGroup> GetSceneObjectGroups()
|
||||
{
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
return new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a group in the scene
|
||||
/// </summary>
|
||||
@@ -1100,11 +1112,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="action"></param>
|
||||
protected internal void ForEachSOG(Action<SceneObjectGroup> action)
|
||||
{
|
||||
List<SceneObjectGroup> objlist;
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
|
||||
|
||||
foreach (SceneObjectGroup obj in objlist)
|
||||
foreach (SceneObjectGroup obj in GetSceneObjectGroups())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -54,20 +54,32 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <summary>
|
||||
/// Start the scripts contained in all the prims in this group.
|
||||
/// </summary>
|
||||
public void CreateScriptInstances(int startParam, bool postOnRez,
|
||||
string engine, int stateSource)
|
||||
/// <param name="startParam"></param>
|
||||
/// <param name="postOnRez"></param>
|
||||
/// <param name="engine"></param>
|
||||
/// <param name="stateSource"></param>
|
||||
/// <returns>
|
||||
/// Number of scripts that were valid for starting. This does not guarantee that all these scripts
|
||||
/// were actually started, but just that the start could be attempt (e.g. the asset data for the script could be found)
|
||||
/// </returns>
|
||||
public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
|
||||
{
|
||||
int scriptsStarted = 0;
|
||||
|
||||
// Don't start scripts if they're turned off in the region!
|
||||
if (!m_scene.RegionInfo.RegionSettings.DisableScripts)
|
||||
{
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource);
|
||||
scriptsStarted
|
||||
+= parts[i].Inventory.CreateScriptInstances(startParam, postOnRez, engine, stateSource);
|
||||
}
|
||||
|
||||
return scriptsStarted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the scripts contained in all the prims in this group
|
||||
/// Stop and remove the scripts contained in all the prims in this group
|
||||
/// </summary>
|
||||
/// <param name="sceneObjectBeingDeleted">
|
||||
/// Should be true if these scripts are being removed because the scene
|
||||
@@ -80,6 +92,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
parts[i].Inventory.RemoveScriptInstances(sceneObjectBeingDeleted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the scripts contained in all the prims in this group
|
||||
/// </summary>
|
||||
public void StopScriptInstances()
|
||||
{
|
||||
Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => p.Inventory.StopScriptInstances());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an inventory item from a user's inventory to a prim in this scene object.
|
||||
/// </summary>
|
||||
|
||||
@@ -108,6 +108,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private long timeFirstChanged;
|
||||
private long timeLastChanged;
|
||||
|
||||
/// <summary>
|
||||
/// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
|
||||
/// (the database).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ultimately, this should be managed such that region modules can change it at the end of a set of operations
|
||||
/// so that either all changes are preserved or none at all. However, currently, a large amount of internal
|
||||
/// code will set this anyway when some object properties are changed.
|
||||
/// </remarks>
|
||||
public bool HasGroupChanged
|
||||
{
|
||||
set
|
||||
@@ -180,6 +189,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this scene object has an attachment point then indicate whether there is a point where
|
||||
/// attachments are perceivable by avatars other than the avatar to which this object is attached.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// HUDs are not perceivable by other avatars.
|
||||
/// </remarks>
|
||||
public bool HasPrivateAttachmentPoint
|
||||
{
|
||||
get
|
||||
{
|
||||
return AttachmentPoint >= (uint)OpenMetaverse.AttachmentPoint.HUDCenter2
|
||||
&& AttachmentPoint <= (uint)OpenMetaverse.AttachmentPoint.HUDBottomRight;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearPartAttachmentData()
|
||||
{
|
||||
AttachmentPoint = 0;
|
||||
@@ -426,6 +451,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
// Restuff the new GroupPosition into each SOP of the linkset.
|
||||
// This has the affect of resetting and tainting the physics actors.
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i].GroupPosition = val;
|
||||
@@ -1030,16 +1057,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Added as a way for the storage provider to reset the scene,
|
||||
/// most likely a better way to do this sort of thing but for now...
|
||||
/// </summary>
|
||||
/// <param name="scene"></param>
|
||||
public void SetScene(Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a part to act as the root part for this scene object
|
||||
@@ -1118,6 +1135,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void ResetChildPrimPhysicsPositions()
|
||||
{
|
||||
// Setting this SOG's absolute position also loops through and sets the positions
|
||||
// of the SOP's in this SOG's linkset. This has the side affect of making sure
|
||||
// the physics world matches the simulated world.
|
||||
AbsolutePosition = AbsolutePosition; // could someone in the know please explain how this works?
|
||||
|
||||
// teravus: AbsolutePosition is NOT a normal property!
|
||||
@@ -1189,8 +1209,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
part.ClearUpdateSchedule();
|
||||
if (part == m_rootPart)
|
||||
{
|
||||
if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) ||
|
||||
(AttachmentPoint < 31) || (AttachmentPoint > 38))
|
||||
if (!IsAttachment
|
||||
|| AttachedAvatar == avatar.ControllingClient.AgentId
|
||||
|| !HasPrivateAttachmentPoint)
|
||||
avatar.ControllingClient.SendKillObject(m_regionHandle, new List<uint> { part.LocalId });
|
||||
}
|
||||
}
|
||||
@@ -1800,8 +1821,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedule a full update for this scene object
|
||||
/// Schedule a full update for this scene object to all interested viewers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ultimately, this should be managed such that region modules can invoke it at the end of a set of operations
|
||||
/// so that either all changes are sent at once. However, currently, a large amount of internal
|
||||
/// code will set this anyway when some object properties are changed.
|
||||
/// </remarks>
|
||||
public void ScheduleGroupForFullUpdate()
|
||||
{
|
||||
// if (IsAttachment)
|
||||
@@ -1820,8 +1846,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedule a terse update for this scene object
|
||||
/// Schedule a terse update for this scene object to all interested viewers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Ultimately, this should be managed such that region modules can invoke it at the end of a set of operations
|
||||
/// so that either all changes are sent at once. However, currently, a large amount of internal
|
||||
/// code will set this anyway when some object properties are changed.
|
||||
/// </remarks>
|
||||
public void ScheduleGroupForTerseUpdate()
|
||||
{
|
||||
// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID);
|
||||
@@ -1961,6 +1992,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
LinkToGroup(objectGroup, false);
|
||||
}
|
||||
|
||||
// Link an existing group to this group.
|
||||
// The group being linked need not be a linkset -- it can have just one prim.
|
||||
public void LinkToGroup(SceneObjectGroup objectGroup, bool insert)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
@@ -1971,35 +2004,51 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (objectGroup == this)
|
||||
return;
|
||||
|
||||
// 'linkPart' == the root of the group being linked into this group
|
||||
SceneObjectPart linkPart = objectGroup.m_rootPart;
|
||||
|
||||
// physics flags from group to be applied to linked parts
|
||||
bool grpusephys = UsesPhysics;
|
||||
bool grptemporary = IsTemporary;
|
||||
|
||||
// Remember where the group being linked thought it was
|
||||
Vector3 oldGroupPosition = linkPart.GroupPosition;
|
||||
Quaternion oldRootRotation = linkPart.RotationOffset;
|
||||
|
||||
linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
|
||||
linkPart.ParentID = m_rootPart.LocalId;
|
||||
linkPart.GroupPosition = AbsolutePosition;
|
||||
Vector3 axPos = linkPart.OffsetPosition;
|
||||
// A linked SOP remembers its location and rotation relative to the root of a group.
|
||||
// Convert the root of the group being linked to be relative to the
|
||||
// root of the group being linked to.
|
||||
// Note: Some of the assignments have complex side effects.
|
||||
|
||||
// First move the new group's root SOP's position to be relative to ours
|
||||
// (radams1: Not sure if the multiple setting of OffsetPosition is required. If not,
|
||||
// this code can be reordered to have a more logical flow.)
|
||||
linkPart.OffsetPosition = linkPart.GroupPosition - AbsolutePosition;
|
||||
// Assign the new parent to the root of the old group
|
||||
linkPart.ParentID = m_rootPart.LocalId;
|
||||
// Now that it's a child, it's group position is our root position
|
||||
linkPart.GroupPosition = AbsolutePosition;
|
||||
|
||||
Vector3 axPos = linkPart.OffsetPosition;
|
||||
// Rotate the linking root SOP's position to be relative to the new root prim
|
||||
Quaternion parentRot = m_rootPart.RotationOffset;
|
||||
axPos *= Quaternion.Inverse(parentRot);
|
||||
|
||||
linkPart.OffsetPosition = axPos;
|
||||
|
||||
// Make the linking root SOP's rotation relative to the new root prim
|
||||
Quaternion oldRot = linkPart.RotationOffset;
|
||||
Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot;
|
||||
linkPart.RotationOffset = newRot;
|
||||
|
||||
linkPart.ParentID = m_rootPart.LocalId;
|
||||
|
||||
// If there is only one SOP in a SOG, the LinkNum is zero. I.e., not a linkset.
|
||||
// Now that we know this SOG has at least two SOPs in it, the new root
|
||||
// SOP becomes the first in the linkset.
|
||||
if (m_rootPart.LinkNum == 0)
|
||||
m_rootPart.LinkNum = 1;
|
||||
|
||||
lock (m_parts.SyncRoot)
|
||||
{
|
||||
// Calculate the new link number for the old root SOP
|
||||
int linkNum;
|
||||
if (insert)
|
||||
{
|
||||
@@ -2015,6 +2064,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
linkNum = PrimCount + 1;
|
||||
}
|
||||
|
||||
// Add the old root SOP as a part in our group's list
|
||||
m_parts.Add(linkPart.UUID, linkPart);
|
||||
|
||||
linkPart.SetParent(this);
|
||||
@@ -2022,6 +2072,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
// let physics know preserve part volume dtc messy since UpdatePrimFlags doesn't look to parent changes for now
|
||||
linkPart.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (linkPart.Flags & PrimFlags.Phantom) != 0), linkPart.VolumeDetectActive);
|
||||
|
||||
// If the added SOP is physical, also tell the physics engine about the link relationship.
|
||||
if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
|
||||
{
|
||||
linkPart.PhysActor.link(m_rootPart.PhysActor);
|
||||
@@ -2030,20 +2082,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
linkPart.LinkNum = linkNum++;
|
||||
|
||||
// Get a list of the SOP's in the old group in order of their linknum's.
|
||||
SceneObjectPart[] ogParts = objectGroup.Parts;
|
||||
Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
|
||||
{
|
||||
return a.LinkNum - b.LinkNum;
|
||||
});
|
||||
|
||||
// Add each of the SOP's from the old linkset to our linkset
|
||||
for (int i = 0; i < ogParts.Length; i++)
|
||||
{
|
||||
SceneObjectPart part = ogParts[i];
|
||||
if (part.UUID != objectGroup.m_rootPart.UUID)
|
||||
{
|
||||
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
|
||||
// let physics know
|
||||
|
||||
// Update the physics flags for the newly added SOP
|
||||
// (Is this necessary? LinkNonRootPart() has already called UpdatePrimFlags but with different flags!??)
|
||||
part.UpdatePrimFlags(grpusephys, grptemporary, (IsPhantom || (part.Flags & PrimFlags.Phantom) != 0), part.VolumeDetectActive);
|
||||
|
||||
// If the added SOP is physical, also tell the physics engine about the link relationship.
|
||||
if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
|
||||
{
|
||||
part.PhysActor.link(m_rootPart.PhysActor);
|
||||
@@ -2054,6 +2112,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we've aquired all of the old SOG's parts, remove the old SOG from the scene.
|
||||
m_scene.UnlinkSceneObject(objectGroup, true);
|
||||
objectGroup.IsDeleted = true;
|
||||
|
||||
@@ -2126,7 +2185,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <remarks>
|
||||
/// FIXME: This method should not be called directly since it bypasses update locking, allowing a potential race
|
||||
/// condition. But currently there is no
|
||||
/// alternative method that does take a lonk to delink a single prim.
|
||||
/// alternative method that does take a lock to delink a single prim.
|
||||
/// </remarks>
|
||||
/// <param name="partID"></param>
|
||||
/// <param name="sendEvents"></param>
|
||||
@@ -2139,6 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
linkPart.ClearUndoState();
|
||||
|
||||
Vector3 worldPos = linkPart.GetWorldPosition();
|
||||
Quaternion worldRot = linkPart.GetWorldRotation();
|
||||
|
||||
// Remove the part from this object
|
||||
@@ -2148,6 +2208,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
|
||||
// Rejigger the linknum's of the remaining SOP's to fill any gap
|
||||
if (parts.Length == 1 && RootPart != null)
|
||||
{
|
||||
// Single prim left
|
||||
@@ -2169,22 +2230,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
PhysicsActor linkPartPa = linkPart.PhysActor;
|
||||
|
||||
// Remove the SOP from the physical scene.
|
||||
// If the new SOG is physical, it is re-created later.
|
||||
// (There is a problem here in that we have not yet told the physics
|
||||
// engine about the delink. Someday, linksets should be made first
|
||||
// class objects in the physics engine interface).
|
||||
if (linkPartPa != null)
|
||||
m_scene.PhysicsScene.RemovePrim(linkPartPa);
|
||||
|
||||
// We need to reset the child part's position
|
||||
// ready for life as a separate object after being a part of another object
|
||||
|
||||
/* This commented out code seems to recompute what GetWorldPosition already does.
|
||||
* Replace with a call to GetWorldPosition (before unlinking)
|
||||
Quaternion parentRot = m_rootPart.RotationOffset;
|
||||
|
||||
Vector3 axPos = linkPart.OffsetPosition;
|
||||
|
||||
axPos *= parentRot;
|
||||
linkPart.OffsetPosition = new Vector3(axPos.X, axPos.Y, axPos.Z);
|
||||
linkPart.GroupPosition = AbsolutePosition + linkPart.OffsetPosition;
|
||||
linkPart.OffsetPosition = new Vector3(0, 0, 0);
|
||||
|
||||
*/
|
||||
linkPart.GroupPosition = worldPos;
|
||||
linkPart.OffsetPosition = Vector3.Zero;
|
||||
linkPart.RotationOffset = worldRot;
|
||||
|
||||
// Create a new SOG to go around this unlinked and unattached SOP
|
||||
SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);
|
||||
|
||||
m_scene.AddNewSceneObject(objectGroup, true);
|
||||
@@ -2213,42 +2283,56 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_isBackedUp = false;
|
||||
}
|
||||
|
||||
// This links an SOP from a previous linkset into my linkset.
|
||||
// The trick is that the SOP's position and rotation are relative to the old root SOP's
|
||||
// so we are passed in the position and rotation of the old linkset so this can
|
||||
// unjigger this SOP's position and rotation from the previous linkset and
|
||||
// then make them relative to my linkset root.
|
||||
private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum)
|
||||
{
|
||||
Quaternion parentRot = oldGroupRotation;
|
||||
Quaternion oldRot = part.RotationOffset;
|
||||
Quaternion worldRot = parentRot * oldRot;
|
||||
|
||||
parentRot = oldGroupRotation;
|
||||
|
||||
// Move our position to not be relative to the old parent
|
||||
Vector3 axPos = part.OffsetPosition;
|
||||
|
||||
axPos *= parentRot;
|
||||
part.OffsetPosition = axPos;
|
||||
part.GroupPosition = oldGroupPosition + part.OffsetPosition;
|
||||
part.OffsetPosition = Vector3.Zero;
|
||||
|
||||
// Compution our rotation to be not relative to the old parent
|
||||
Quaternion worldRot = parentRot * oldRot;
|
||||
part.RotationOffset = worldRot;
|
||||
|
||||
// Add this SOP to our linkset
|
||||
part.SetParent(this);
|
||||
part.ParentID = m_rootPart.LocalId;
|
||||
|
||||
m_parts.Add(part.UUID, part);
|
||||
|
||||
part.LinkNum = linkNum;
|
||||
|
||||
// Compute the new position of this SOP relative to the group position
|
||||
part.OffsetPosition = part.GroupPosition - AbsolutePosition;
|
||||
|
||||
Quaternion rootRotation = m_rootPart.RotationOffset;
|
||||
// (radams1 20120711: I don't know why part.OffsetPosition is set multiple times.
|
||||
// It would have the affect of setting the physics engine position multiple
|
||||
// times. In theory, that is not necessary but I don't have a good linkset
|
||||
// test to know that cleaning up this code wouldn't break things.)
|
||||
|
||||
// Rotate the relative position by the rotation of the group
|
||||
Quaternion rootRotation = m_rootPart.RotationOffset;
|
||||
Vector3 pos = part.OffsetPosition;
|
||||
pos *= Quaternion.Inverse(rootRotation);
|
||||
part.OffsetPosition = pos;
|
||||
|
||||
// Compute the SOP's rotation relative to the rotation of the group.
|
||||
parentRot = m_rootPart.RotationOffset;
|
||||
oldRot = part.RotationOffset;
|
||||
Quaternion newRot = Quaternion.Inverse(parentRot) * oldRot;
|
||||
part.RotationOffset = newRot;
|
||||
|
||||
// Since this SOP's state has changed, push those changes into the physics engine
|
||||
// and the simulator.
|
||||
part.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect);
|
||||
}
|
||||
|
||||
@@ -2894,6 +2978,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||
}
|
||||
|
||||
if (IsAttachment)
|
||||
{
|
||||
m_rootPart.AttachedPos = pos;
|
||||
}
|
||||
|
||||
AbsolutePosition = pos;
|
||||
|
||||
HasGroupChanged = true;
|
||||
@@ -3370,6 +3459,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of sitting avatars.
|
||||
/// </summary>
|
||||
/// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
|
||||
/// <returns></returns>
|
||||
public int GetSittingAvatarsCount()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount());
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition);
|
||||
|
||||
@@ -135,6 +135,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
get { return ParentGroup.RootPart == this; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is an explicit sit target set for this part?
|
||||
/// </summary>
|
||||
public bool IsSitTargetSet
|
||||
{
|
||||
get
|
||||
{
|
||||
return
|
||||
!(SitTargetPosition == Vector3.Zero
|
||||
&& (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
|
||||
|| SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 1f && SitTargetOrientation.W == 0f // W-Z Mapping was invalid at one point
|
||||
|| SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f && SitTargetOrientation.W == 0f)); // Invalid Quaternion
|
||||
}
|
||||
}
|
||||
|
||||
#region Fields
|
||||
|
||||
public bool AllowedDrop;
|
||||
@@ -374,7 +389,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private uint _category;
|
||||
private Int32 _creationDate;
|
||||
private uint _parentID = 0;
|
||||
private UUID m_sitTargetAvatar = UUID.Zero;
|
||||
private uint _baseMask = (uint)PermissionMask.All;
|
||||
private uint _ownerMask = (uint)PermissionMask.All;
|
||||
private uint _groupMask = (uint)PermissionMask.None;
|
||||
@@ -679,9 +693,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
// If this is a linkset, we don't want the physics engine mucking up our group position here.
|
||||
PhysicsActor actor = PhysActor;
|
||||
// If physical and the root prim of a linkset, the position of the group is what physics thinks.
|
||||
if (actor != null && ParentID == 0)
|
||||
m_groupPosition = actor.Position;
|
||||
|
||||
// If I'm an attachment, my position is reported as the position of who I'm attached to
|
||||
if (ParentGroup.IsAttachment)
|
||||
{
|
||||
ScenePresence sp = ParentGroup.Scene.GetScenePresence(ParentGroup.AttachedAvatar);
|
||||
@@ -707,7 +723,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
{
|
||||
// To move the child prim in respect to the group position and rotation we have to calculate
|
||||
// The physics engine always sees all objects (root or linked) in world coordinates.
|
||||
actor.Position = GetWorldPosition();
|
||||
actor.Orientation = GetWorldRotation();
|
||||
}
|
||||
@@ -781,6 +797,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
// We don't want the physics engine mucking up the rotations in a linkset
|
||||
PhysicsActor actor = PhysActor;
|
||||
// If this is a root of a linkset, the real rotation is what the physics engine thinks.
|
||||
// If not a root prim, the offset rotation is computed by SOG and is relative to the root.
|
||||
if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null)
|
||||
{
|
||||
if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f
|
||||
@@ -1233,13 +1251,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero
|
||||
/// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero
|
||||
/// </summary>
|
||||
public UUID SitTargetAvatar
|
||||
{
|
||||
get { return m_sitTargetAvatar; }
|
||||
set { m_sitTargetAvatar = value; }
|
||||
}
|
||||
public UUID SitTargetAvatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IDs of all avatars start on this object part.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We need to track this so that we can stop sat upon prims from being attached.
|
||||
/// </remarks>
|
||||
/// <value>
|
||||
/// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene.
|
||||
/// </value>
|
||||
private HashSet<UUID> m_sittingAvatars;
|
||||
|
||||
public virtual UUID RegionID
|
||||
{
|
||||
@@ -1625,7 +1650,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
else
|
||||
m_log.WarnFormat(
|
||||
"[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
|
||||
Name, LocalId, id);
|
||||
Name, UUID, id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1959,14 +1984,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns>A Linked Child Prim objects position in world</returns>
|
||||
public Vector3 GetWorldPosition()
|
||||
{
|
||||
Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
|
||||
Vector3 axPos = OffsetPosition;
|
||||
axPos *= parentRot;
|
||||
Vector3 translationOffsetPosition = axPos;
|
||||
if(_parentID == 0)
|
||||
return GroupPosition;
|
||||
Vector3 ret;
|
||||
if (_parentID == 0)
|
||||
// if a root SOP, my position is what it is
|
||||
ret = GroupPosition;
|
||||
else
|
||||
return ParentGroup.AbsolutePosition + translationOffsetPosition;
|
||||
{
|
||||
// If a child SOP, my position is relative to the root SOP so take
|
||||
// my info and add the root's position and rotation to
|
||||
// get my world position.
|
||||
Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
|
||||
Vector3 translationOffsetPosition = OffsetPosition * parentRot;
|
||||
ret = ParentGroup.AbsolutePosition + translationOffsetPosition;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1983,6 +2014,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
{
|
||||
// A child SOP's rotation is relative to the root SOP's rotation.
|
||||
// Combine them to get my absolute rotation.
|
||||
Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
|
||||
Quaternion oldRot = RotationOffset;
|
||||
newRot = parentRot * oldRot;
|
||||
@@ -2573,8 +2606,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (ParentGroup.IsDeleted)
|
||||
return;
|
||||
|
||||
if (ParentGroup.IsAttachment && (ParentGroup.AttachedAvatar != remoteClient.AgentId) &&
|
||||
(ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38))
|
||||
if (ParentGroup.IsAttachment
|
||||
&& ParentGroup.AttachedAvatar != remoteClient.AgentId
|
||||
&& ParentGroup.HasPrivateAttachmentPoint)
|
||||
return;
|
||||
|
||||
if (remoteClient.AgentId == OwnerID)
|
||||
@@ -4430,8 +4464,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (ParentGroup.IsDeleted)
|
||||
return;
|
||||
|
||||
if (ParentGroup.IsAttachment && ((ParentGroup.RootPart != this) ||
|
||||
((ParentGroup.AttachedAvatar != remoteClient.AgentId) && (ParentGroup.AttachmentPoint >= 31) && (ParentGroup.AttachmentPoint <= 38))))
|
||||
if (ParentGroup.IsAttachment
|
||||
&& (ParentGroup.RootPart != this
|
||||
|| ParentGroup.AttachedAvatar != remoteClient.AgentId && ParentGroup.HasPrivateAttachmentPoint))
|
||||
return;
|
||||
|
||||
// Causes this thread to dig into the Client Thread Data.
|
||||
@@ -4491,5 +4526,99 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Color color = Color;
|
||||
return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Record an avatar sitting on this part.
|
||||
/// </summary>
|
||||
/// <remarks>This is called for all the sitting avatars whether there is a sit target set or not.</remarks>
|
||||
/// <returns>
|
||||
/// true if the avatar was not already recorded, false otherwise.
|
||||
/// </returns>
|
||||
/// <param name='avatarId'></param>
|
||||
protected internal bool AddSittingAvatar(UUID avatarId)
|
||||
{
|
||||
if (IsSitTargetSet && SitTargetAvatar == UUID.Zero)
|
||||
SitTargetAvatar = avatarId;
|
||||
|
||||
HashSet<UUID> sittingAvatars = m_sittingAvatars;
|
||||
|
||||
if (sittingAvatars == null)
|
||||
sittingAvatars = new HashSet<UUID>();
|
||||
|
||||
lock (sittingAvatars)
|
||||
{
|
||||
m_sittingAvatars = sittingAvatars;
|
||||
return m_sittingAvatars.Add(avatarId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove an avatar recorded as sitting on this part.
|
||||
/// </summary>
|
||||
/// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
|
||||
/// <returns>
|
||||
/// true if the avatar was present and removed, false if it was not present.
|
||||
/// </returns>
|
||||
/// <param name='avatarId'></param>
|
||||
protected internal bool RemoveSittingAvatar(UUID avatarId)
|
||||
{
|
||||
if (SitTargetAvatar == avatarId)
|
||||
SitTargetAvatar = UUID.Zero;
|
||||
|
||||
HashSet<UUID> sittingAvatars = m_sittingAvatars;
|
||||
|
||||
// This can occur under a race condition where another thread
|
||||
if (sittingAvatars == null)
|
||||
return false;
|
||||
|
||||
lock (sittingAvatars)
|
||||
{
|
||||
if (sittingAvatars.Remove(avatarId))
|
||||
{
|
||||
if (sittingAvatars.Count == 0)
|
||||
m_sittingAvatars = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a copy of the list of sitting avatars.
|
||||
/// </summary>
|
||||
/// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
|
||||
/// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns>
|
||||
public HashSet<UUID> GetSittingAvatars()
|
||||
{
|
||||
HashSet<UUID> sittingAvatars = m_sittingAvatars;
|
||||
|
||||
if (sittingAvatars == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (sittingAvatars)
|
||||
return new HashSet<UUID>(sittingAvatars);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of sitting avatars.
|
||||
/// </summary>
|
||||
/// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
|
||||
/// <returns></returns>
|
||||
public int GetSittingAvatarsCount()
|
||||
{
|
||||
HashSet<UUID> sittingAvatars = m_sittingAvatars;
|
||||
|
||||
if (sittingAvatars == null)
|
||||
return 0;
|
||||
|
||||
lock (sittingAvatars)
|
||||
return sittingAvatars.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_items = value;
|
||||
m_inventorySerial++;
|
||||
QueryScriptStates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,14 +218,46 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start all the scripts contained in this prim's inventory
|
||||
/// </summary>
|
||||
public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
|
||||
private void QueryScriptStates()
|
||||
{
|
||||
if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null)
|
||||
return;
|
||||
|
||||
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
|
||||
if (engines == null) // No engine at all
|
||||
return;
|
||||
|
||||
lock (Items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in Items.Values)
|
||||
{
|
||||
if (item.InvType == (int)InventoryType.LSL)
|
||||
{
|
||||
foreach (IScriptModule e in engines)
|
||||
{
|
||||
bool running;
|
||||
|
||||
if (e.HasScript(item.ItemID, out running))
|
||||
{
|
||||
item.ScriptRunning = running;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
|
||||
{
|
||||
int scriptsValidForStarting = 0;
|
||||
|
||||
List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
|
||||
foreach (TaskInventoryItem item in scripts)
|
||||
CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
|
||||
if (CreateScriptInstance(item, startParam, postOnRez, engine, stateSource))
|
||||
scriptsValidForStarting++;
|
||||
|
||||
return scriptsValidForStarting;
|
||||
}
|
||||
|
||||
public ArrayList GetScriptErrors(UUID itemID)
|
||||
@@ -247,7 +280,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop all the scripts in this prim.
|
||||
/// Stop and remove all the scripts in this prim.
|
||||
/// </summary>
|
||||
/// <param name="sceneObjectBeingDeleted">
|
||||
/// Should be true if these scripts are being removed because the scene
|
||||
@@ -260,65 +293,80 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop all the scripts in this prim.
|
||||
/// </summary>
|
||||
public void StopScriptInstances()
|
||||
{
|
||||
GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a script which is in this prim's inventory.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource)
|
||||
/// <returns>true if the script instance was created, false otherwise</returns>
|
||||
public bool CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, string engine, int stateSource)
|
||||
{
|
||||
// m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}",
|
||||
// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
|
||||
if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
|
||||
return;
|
||||
return false;
|
||||
|
||||
m_part.AddFlag(PrimFlags.Scripted);
|
||||
|
||||
if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts)
|
||||
if (m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts)
|
||||
return false;
|
||||
|
||||
if (stateSource == 2 && // Prim crossing
|
||||
m_part.ParentGroup.Scene.m_trustBinaries)
|
||||
{
|
||||
if (stateSource == 2 && // Prim crossing
|
||||
m_part.ParentGroup.Scene.m_trustBinaries)
|
||||
lock (m_items)
|
||||
{
|
||||
lock (m_items)
|
||||
{
|
||||
m_items[item.ItemID].PermsMask = 0;
|
||||
m_items[item.ItemID].PermsGranter = UUID.Zero;
|
||||
}
|
||||
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
|
||||
m_part.ParentGroup.AddActiveScriptCount(1);
|
||||
m_part.ScheduleFullUpdate();
|
||||
return;
|
||||
m_items[item.ItemID].PermsMask = 0;
|
||||
m_items[item.ItemID].PermsGranter = UUID.Zero;
|
||||
}
|
||||
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
|
||||
m_part.ParentGroup.AddActiveScriptCount(1);
|
||||
m_part.ScheduleFullUpdate();
|
||||
return true;
|
||||
}
|
||||
|
||||
AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
|
||||
if (null == asset)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
|
||||
item.Name, item.ItemID, m_part.AbsolutePosition,
|
||||
m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_part.ParentGroup.m_savedScriptState != null)
|
||||
item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
|
||||
|
||||
lock (m_items)
|
||||
{
|
||||
m_items[item.ItemID].OldItemID = item.OldItemID;
|
||||
m_items[item.ItemID].PermsMask = 0;
|
||||
m_items[item.ItemID].PermsGranter = UUID.Zero;
|
||||
}
|
||||
|
||||
AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
|
||||
if (null == asset)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
|
||||
item.Name, item.ItemID, m_part.AbsolutePosition,
|
||||
m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_part.ParentGroup.m_savedScriptState != null)
|
||||
item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
|
||||
string script = Utils.BytesToString(asset.Data);
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
|
||||
if (!item.ScriptRunning)
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
|
||||
m_part.LocalId, item.ItemID);
|
||||
m_part.ParentGroup.AddActiveScriptCount(1);
|
||||
m_part.ScheduleFullUpdate();
|
||||
|
||||
lock (m_items)
|
||||
{
|
||||
m_items[item.ItemID].OldItemID = item.OldItemID;
|
||||
m_items[item.ItemID].PermsMask = 0;
|
||||
m_items[item.ItemID].PermsGranter = UUID.Zero;
|
||||
}
|
||||
|
||||
string script = Utils.BytesToString(asset.Data);
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
|
||||
m_part.ParentGroup.AddActiveScriptCount(1);
|
||||
m_part.ScheduleFullUpdate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,26 +432,26 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return stateID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a script which is in this prim's inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemId">
|
||||
/// A <see cref="UUID"/>
|
||||
/// </param>
|
||||
public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
||||
public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
||||
{
|
||||
TaskInventoryItem item = GetInventoryItem(itemId);
|
||||
if (item != null)
|
||||
CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
|
||||
{
|
||||
return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
|
||||
itemId, m_part.Name, m_part.UUID,
|
||||
m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop a script which is in this prim's inventory.
|
||||
/// Stop and remove a script which is in this prim's inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemId"></param>
|
||||
/// <param name="sceneObjectBeingDeleted">
|
||||
@@ -430,7 +478,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
m_log.WarnFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
|
||||
itemId, m_part.Name, m_part.UUID,
|
||||
@@ -438,6 +486,51 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop a script which is in this prim's inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemId"></param>
|
||||
/// <param name="sceneObjectBeingDeleted">
|
||||
/// Should be true if this script is being removed because the scene
|
||||
/// object is being deleted. This will prevent spurious updates to the client.
|
||||
/// </param>
|
||||
public void StopScriptInstance(UUID itemId)
|
||||
{
|
||||
TaskInventoryItem scriptItem;
|
||||
|
||||
lock (m_items)
|
||||
m_items.TryGetValue(itemId, out scriptItem);
|
||||
|
||||
if (scriptItem != null)
|
||||
{
|
||||
StopScriptInstance(scriptItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[PRIM INVENTORY]: " +
|
||||
"Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
|
||||
itemId, m_part.Name, m_part.UUID,
|
||||
m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop a script which is in this prim's inventory.
|
||||
/// </summary>
|
||||
/// <param name="itemId"></param>
|
||||
/// <param name="sceneObjectBeingDeleted">
|
||||
/// Should be true if this script is being removed because the scene
|
||||
/// object is being deleted. This will prevent spurious updates to the client.
|
||||
/// </param>
|
||||
public void StopScriptInstance(TaskInventoryItem item)
|
||||
{
|
||||
m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
|
||||
|
||||
// At the moment, even stopped scripts are counted as active, which is probably wrong.
|
||||
// m_part.ParentGroup.AddActiveScriptCount(-1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the inventory holds an item with a given name.
|
||||
/// </summary>
|
||||
@@ -1202,6 +1295,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[PRIM INVENTORY]: Getting script state from engine {0} for {1} in part {2} in group {3} in {4}",
|
||||
// e.Name, item.Name, m_part.Name, m_part.ParentGroup.Name, m_part.ParentGroup.Scene.Name);
|
||||
|
||||
string n = e.GetXMLState(item.ItemID);
|
||||
if (n != String.Empty)
|
||||
{
|
||||
@@ -1245,4 +1342,4 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,6 +577,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public uint ParentID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Are we sitting on an object?
|
||||
/// </summary>
|
||||
/// <remarks>A more readable way of testing presence sit status than ParentID == 0</remarks>
|
||||
public bool IsSatOnObject { get { return ParentID != 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
|
||||
/// </summary>
|
||||
@@ -1793,10 +1799,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
// Reset sit target.
|
||||
if (part.SitTargetAvatar == UUID)
|
||||
part.SitTargetAvatar = UUID.Zero;
|
||||
|
||||
ParentPosition = part.GetWorldPosition();
|
||||
ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
|
||||
|
||||
@@ -1808,6 +1810,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
SendAvatarDataToAllAgents();
|
||||
m_requestedSitTargetID = 0;
|
||||
|
||||
part.RemoveSittingAvatar(UUID);
|
||||
|
||||
if (part != null)
|
||||
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||
}
|
||||
@@ -1838,15 +1842,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
//look for prims with explicit sit targets that are available
|
||||
foreach (SceneObjectPart part in partArray)
|
||||
{
|
||||
// Is a sit target available?
|
||||
Vector3 avSitOffset = part.SitTargetPosition;
|
||||
Quaternion avSitOrientation = part.SitTargetOrientation;
|
||||
UUID avOnTargetAlready = part.SitTargetAvatar;
|
||||
|
||||
bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero;
|
||||
bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity;
|
||||
|
||||
if (SitTargetisSet && SitTargetUnOccupied)
|
||||
if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
|
||||
{
|
||||
//switch the target to this prim
|
||||
return part;
|
||||
@@ -1857,10 +1853,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return targetPart;
|
||||
}
|
||||
|
||||
private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation)
|
||||
private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation)
|
||||
{
|
||||
Vector3 pos = new Vector3();
|
||||
Quaternion sitOrientation = pSitOrientation;
|
||||
Vector3 cameraEyeOffset = Vector3.Zero;
|
||||
Vector3 cameraAtOffset = Vector3.Zero;
|
||||
bool forceMouselook = false;
|
||||
@@ -1872,42 +1866,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// TODO: determine position to sit at based on scene geometry; don't trust offset from client
|
||||
// see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
|
||||
|
||||
// Is a sit target available?
|
||||
Vector3 avSitOffSet = part.SitTargetPosition;
|
||||
Quaternion avSitOrientation = part.SitTargetOrientation;
|
||||
UUID avOnTargetAlready = part.SitTargetAvatar;
|
||||
|
||||
bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
|
||||
bool SitTargetisSet =
|
||||
(!(avSitOffSet == Vector3.Zero &&
|
||||
(
|
||||
avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
|
||||
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
|
||||
|| avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
|
||||
)
|
||||
));
|
||||
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
|
||||
|
||||
if (PhysicsActor != null)
|
||||
m_sitAvatarHeight = PhysicsActor.Size.Z;
|
||||
|
||||
bool canSit = false;
|
||||
pos = part.AbsolutePosition + offset;
|
||||
Vector3 pos = part.AbsolutePosition + offset;
|
||||
|
||||
if (SitTargetisSet)
|
||||
if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
|
||||
{
|
||||
if (SitTargetUnOccupied)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
|
||||
// Name, part.Name, part.LocalId);
|
||||
|
||||
part.SitTargetAvatar = UUID;
|
||||
offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
|
||||
sitOrientation = avSitOrientation;
|
||||
canSit = true;
|
||||
}
|
||||
offset = part.SitTargetPosition;
|
||||
sitOrientation = part.SitTargetOrientation;
|
||||
canSit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1920,6 +1893,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
|
||||
canSit = true;
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
|
||||
// Name, part.Name, part.LocalId);
|
||||
// }
|
||||
}
|
||||
|
||||
if (canSit)
|
||||
@@ -1930,6 +1909,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
RemoveFromPhysicalScene();
|
||||
}
|
||||
|
||||
part.AddSittingAvatar(UUID);
|
||||
|
||||
cameraAtOffset = part.GetCameraAtOffset();
|
||||
cameraEyeOffset = part.GetCameraEyeOffset();
|
||||
forceMouselook = part.GetForceMouselook();
|
||||
@@ -2203,6 +2184,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (part != null)
|
||||
{
|
||||
if (part.ParentGroup.IsAttachment)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[SCENE PRESENCE]: Avatar {0} tried to sit on part {1} from object {2} in {3} but this is an attachment for avatar id {4}",
|
||||
Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (part.SitTargetAvatar == UUID)
|
||||
{
|
||||
Vector3 sitTargetPos = part.SitTargetPosition;
|
||||
@@ -3084,31 +3074,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Attachment objects
|
||||
List<SceneObjectGroup> attachments = GetAttachments();
|
||||
if (attachments.Count > 0)
|
||||
{
|
||||
cAgent.AttachmentObjects = new List<ISceneObject>();
|
||||
cAgent.AttachmentObjectStates = new List<string>();
|
||||
// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
|
||||
InTransitScriptStates.Clear();
|
||||
|
||||
foreach (SceneObjectGroup sog in attachments)
|
||||
{
|
||||
// We need to make a copy and pass that copy
|
||||
// because of transfers withn the same sim
|
||||
ISceneObject clone = sog.CloneForNewScene();
|
||||
// Attachment module assumes that GroupPosition holds the offsets...!
|
||||
((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
|
||||
((SceneObjectGroup)clone).IsAttachment = false;
|
||||
cAgent.AttachmentObjects.Add(clone);
|
||||
string state = sog.GetStateSnapshot();
|
||||
cAgent.AttachmentObjectStates.Add(state);
|
||||
InTransitScriptStates.Add(state);
|
||||
// Let's remove the scripts of the original object here
|
||||
sog.RemoveScriptInstances(true);
|
||||
}
|
||||
}
|
||||
if (Scene.AttachmentsModule != null)
|
||||
Scene.AttachmentsModule.CopyAttachments(this, cAgent);
|
||||
}
|
||||
|
||||
private void CopyFrom(AgentData cAgent)
|
||||
@@ -3178,18 +3145,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (cAgent.Anims != null)
|
||||
Animator.Animations.FromArray(cAgent.Anims);
|
||||
|
||||
if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0)
|
||||
{
|
||||
m_attachments = new List<SceneObjectGroup>();
|
||||
int i = 0;
|
||||
foreach (ISceneObject so in cAgent.AttachmentObjects)
|
||||
{
|
||||
((SceneObjectGroup)so).LocalId = 0;
|
||||
((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
|
||||
so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
|
||||
m_scene.IncomingCreateObject(Vector3.Zero, so);
|
||||
}
|
||||
}
|
||||
if (Scene.AttachmentsModule != null)
|
||||
Scene.AttachmentsModule.CopyAttachments(cAgent, this);
|
||||
}
|
||||
|
||||
public bool CopyAgent(out IAgentData agent)
|
||||
@@ -3416,9 +3373,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (!IsChildAgent && m_scene.AttachmentsModule != null)
|
||||
m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
|
||||
|
||||
// Clear known regions
|
||||
KnownRegions = new Dictionary<ulong, string>();
|
||||
|
||||
|
||||
@@ -186,10 +186,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
TestHelpers.InMethod();
|
||||
|
||||
TestScene scene = new SceneHelpers().SetupScene();
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
|
||||
scene.DeleteSceneObject(part.ParentGroup, false);
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
|
||||
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
|
||||
Assert.That(so.IsDeleted, Is.False);
|
||||
|
||||
scene.DeleteSceneObject(so, false);
|
||||
|
||||
Assert.That(so.IsDeleted, Is.True);
|
||||
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
|
||||
Assert.That(retrievedPart, Is.Null);
|
||||
}
|
||||
|
||||
@@ -210,18 +215,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter;
|
||||
sogd.Enabled = false;
|
||||
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
|
||||
|
||||
IClientAPI client = SceneHelpers.AddScenePresence(scene, agentId).ControllingClient;
|
||||
scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero);
|
||||
scene.DeRezObjects(client, new System.Collections.Generic.List<uint>() { so.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero);
|
||||
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(so.LocalId);
|
||||
|
||||
Assert.That(retrievedPart, Is.Not.Null);
|
||||
|
||||
Assert.That(so.IsDeleted, Is.False);
|
||||
|
||||
sogd.InventoryDeQueueAndDelete();
|
||||
|
||||
SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(part.LocalId);
|
||||
Assert.That(so.IsDeleted, Is.True);
|
||||
|
||||
SceneObjectPart retrievedPart2 = scene.GetSceneObjectPart(so.LocalId);
|
||||
Assert.That(retrievedPart2, Is.Null);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
bool debugtest = false;
|
||||
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectGroup grp1 = part1.ParentGroup;
|
||||
SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectGroup grp2 = part2.ParentGroup;
|
||||
SceneObjectGroup grp1 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectPart part1 = grp1.RootPart;
|
||||
SceneObjectGroup grp2 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectPart part2 = grp2.RootPart;
|
||||
|
||||
grp1.AbsolutePosition = new Vector3(10, 10, 10);
|
||||
grp2.AbsolutePosition = Vector3.Zero;
|
||||
@@ -154,14 +154,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
bool debugtest = false;
|
||||
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
SceneObjectPart part1 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectGroup grp1 = part1.ParentGroup;
|
||||
SceneObjectPart part2 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectGroup grp2 = part2.ParentGroup;
|
||||
SceneObjectPart part3 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectGroup grp3 = part3.ParentGroup;
|
||||
SceneObjectPart part4 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectGroup grp4 = part4.ParentGroup;
|
||||
SceneObjectGroup grp1 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectPart part1 = grp1.RootPart;
|
||||
SceneObjectGroup grp2 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectPart part2 = grp2.RootPart;
|
||||
SceneObjectGroup grp3 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectPart part3 = grp3.RootPart;
|
||||
SceneObjectGroup grp4 = SceneHelpers.AddSceneObject(scene);
|
||||
SceneObjectPart part4 = grp4.RootPart;
|
||||
|
||||
grp1.AbsolutePosition = new Vector3(10, 10, 10);
|
||||
grp2.AbsolutePosition = Vector3.Zero;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene).ParentGroup;
|
||||
SceneObjectGroup g1 = SceneHelpers.AddSceneObject(scene);
|
||||
|
||||
g1.GroupResize(new Vector3(2, 3, 4));
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
@@ -64,11 +65,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
Vector3 startPos = new Vector3(10.1f, 0, 0);
|
||||
m_sp.AbsolutePosition = startPos;
|
||||
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
|
||||
m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
|
||||
|
||||
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
|
||||
Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
|
||||
Assert.That(part.GetSittingAvatars(), Is.Null);
|
||||
Assert.That(m_sp.ParentID, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
@@ -82,11 +85,17 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
Vector3 startPos = new Vector3(9.9f, 0, 0);
|
||||
m_sp.AbsolutePosition = startPos;
|
||||
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
|
||||
m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
|
||||
|
||||
Assert.That(m_sp.PhysicsActor, Is.Null);
|
||||
|
||||
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
|
||||
Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));
|
||||
HashSet<UUID> sittingAvatars = part.GetSittingAvatars();
|
||||
Assert.That(sittingAvatars.Count, Is.EqualTo(1));
|
||||
Assert.That(sittingAvatars.Contains(m_sp.UUID));
|
||||
Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
|
||||
}
|
||||
|
||||
@@ -100,14 +109,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
Vector3 startPos = new Vector3(1, 1, 1);
|
||||
m_sp.AbsolutePosition = startPos;
|
||||
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
|
||||
m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
|
||||
|
||||
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
|
||||
Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
|
||||
Assert.That(m_sp.PhysicsActor, Is.Null);
|
||||
|
||||
// FIXME: This is different for live avatars - z position is adjusted. This is half the height of the
|
||||
// default avatar.
|
||||
// Curiously, Vector3.ToString() will not display the last two places of the float. For example,
|
||||
@@ -119,6 +124,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
m_sp.StandUp();
|
||||
|
||||
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
|
||||
Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
|
||||
Assert.That(part.GetSittingAvatars(), Is.Null);
|
||||
Assert.That(m_sp.ParentID, Is.EqualTo(0));
|
||||
Assert.That(m_sp.PhysicsActor, Is.Not.Null);
|
||||
}
|
||||
@@ -133,7 +140,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
Vector3 startPos = new Vector3(128, 128, 30);
|
||||
m_sp.AbsolutePosition = startPos;
|
||||
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
part.SitTargetPosition = new Vector3(0, 0, 1);
|
||||
|
||||
m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
|
||||
@@ -145,11 +152,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
|
||||
Assert.That(m_sp.PhysicsActor, Is.Null);
|
||||
|
||||
Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));
|
||||
HashSet<UUID> sittingAvatars = part.GetSittingAvatars();
|
||||
Assert.That(sittingAvatars.Count, Is.EqualTo(1));
|
||||
Assert.That(sittingAvatars.Contains(m_sp.UUID));
|
||||
|
||||
m_sp.StandUp();
|
||||
|
||||
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
|
||||
Assert.That(m_sp.ParentID, Is.EqualTo(0));
|
||||
Assert.That(m_sp.PhysicsActor, Is.Not.Null);
|
||||
|
||||
Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
|
||||
Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
|
||||
Assert.That(part.GetSittingAvatars(), Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -128,7 +128,9 @@ namespace OpenSim.Region.Framework.Tests
|
||||
UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
|
||||
SceneObjectPart sop1 = sog1.RootPart;
|
||||
TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1);
|
||||
TaskInventoryItem sopItem1
|
||||
= TaskInventoryHelpers.AddNotecard(
|
||||
scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900));
|
||||
|
||||
InventoryFolderBase folder
|
||||
= InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0];
|
||||
@@ -156,8 +158,11 @@ namespace OpenSim.Region.Framework.Tests
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, user1.PrincipalID);
|
||||
|
||||
SceneObjectPart sop1 = sog1.RootPart;
|
||||
TaskInventoryItem sopItem1 = TaskInventoryHelpers.AddNotecard(scene, sop1);
|
||||
TaskInventoryItem sopItem1
|
||||
= TaskInventoryHelpers.AddNotecard(
|
||||
scene, sop1, "ncItem", TestHelpers.ParseTail(0x800), TestHelpers.ParseTail(0x900));
|
||||
|
||||
// Perform test
|
||||
scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID);
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
{
|
||||
public delegate void OnIRCClientReadyDelegate(IRCClientView cv);
|
||||
|
||||
public class IRCClientView : IClientAPI, IClientCore, IClientIPEndpoint
|
||||
public class IRCClientView : IClientAPI, IClientCore
|
||||
{
|
||||
public event OnIRCClientReadyDelegate OnIRCReady;
|
||||
|
||||
@@ -1431,11 +1431,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
public EndPoint GetClientEP()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public ClientInfo GetClientInfo()
|
||||
{
|
||||
return new ClientInfo();
|
||||
@@ -1633,15 +1628,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IClientIPEndpoint
|
||||
|
||||
public IPAddress EndPoint
|
||||
{
|
||||
get { return ((IPEndPoint) m_client.Client.RemoteEndPoint).Address; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SendRebakeAvatarTextures(UUID textureID)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -823,11 +823,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
|
||||
m_log.DebugFormat("[FreeSwitchVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}",
|
||||
landName, land.LocalID, landUUID);
|
||||
}
|
||||
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
|
||||
|
||||
// slvoice handles the sip address differently if it begins with confctl, hiding it from the user in the friends list. however it also disables
|
||||
// the personal speech indicators as well unless some siren14-3d codec magic happens. we dont have siren143d so we'll settle for the personal speech indicator.
|
||||
channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(encoding.GetBytes(landUUID)), m_freeSwitchRealm);
|
||||
channelUri = String.Format("sip:conf-{0}@{1}", "x" + Convert.ToBase64String(Encoding.ASCII.GetBytes(landUUID)), m_freeSwitchRealm);
|
||||
|
||||
lock (m_ParcelAddress)
|
||||
{
|
||||
|
||||
@@ -1120,7 +1120,6 @@ namespace Nwc.XmlRpc
|
||||
/// <summary>Class supporting the request side of an XML-RPC transaction.</summary>
|
||||
public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest
|
||||
{
|
||||
private Encoding _encoding = new ASCIIEncoding();
|
||||
private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer();
|
||||
private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer();
|
||||
private bool _disableKeepAlive = true;
|
||||
@@ -1153,7 +1152,7 @@ namespace Nwc.XmlRpc
|
||||
request.KeepAlive = !_disableKeepAlive;
|
||||
|
||||
Stream stream = request.GetRequestStream();
|
||||
XmlTextWriter xml = new XmlTextWriter(stream, _encoding);
|
||||
XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII);
|
||||
_serializer.Serialize(xml, this);
|
||||
xml.Flush();
|
||||
xml.Close();
|
||||
|
||||
@@ -425,10 +425,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||
|
||||
try
|
||||
{
|
||||
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
|
||||
string jsondata = SLUtil.ParseNotecardToString(enc.GetString(a.Data));
|
||||
int result = m_store.SetValue(storeID,path,jsondata,true) ? 1 : 0;
|
||||
m_comms.DispatchReply(scriptID,result,"",reqID.ToString());
|
||||
string jsondata = SLUtil.ParseNotecardToString(Encoding.UTF8.GetString(a.Data));
|
||||
int result = m_store.SetValue(storeID, path, jsondata,true) ? 1 : 0;
|
||||
m_comms.DispatchReply(scriptID,result, "", reqID.ToString());
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -482,10 +482,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
|
||||
// Convert to base64
|
||||
//
|
||||
string filetext = Convert.ToBase64String(data);
|
||||
|
||||
ASCIIEncoding enc = new ASCIIEncoding();
|
||||
|
||||
Byte[] buf = enc.GetBytes(filetext);
|
||||
Byte[] buf = Encoding.ASCII.GetBytes(filetext);
|
||||
|
||||
m_log.Info("MRM 9");
|
||||
|
||||
|
||||
@@ -228,9 +228,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||
// m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
|
||||
// m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
|
||||
|
||||
m_log.InfoFormat("[RegionReady]: Initialization complete - logins enabled for {0}", m_scene.RegionInfo.RegionName);
|
||||
m_log.InfoFormat(
|
||||
"[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name);
|
||||
|
||||
if ( m_uri != string.Empty )
|
||||
if (m_uri != string.Empty)
|
||||
{
|
||||
RRAlert("enabled");
|
||||
}
|
||||
|
||||
@@ -104,6 +104,45 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
OnMoneyTransferRequest(m_uuid, target, amount, 1, "Payment");
|
||||
}
|
||||
|
||||
public bool Touch(UUID target)
|
||||
{
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(target);
|
||||
if (part == null)
|
||||
return false;
|
||||
bool objectTouchable = hasTouchEvents(part); // Only touch an object that is scripted to respond
|
||||
if (!objectTouchable && !part.IsRoot)
|
||||
objectTouchable = hasTouchEvents(part.ParentGroup.RootPart);
|
||||
if (!objectTouchable)
|
||||
return false;
|
||||
// Set up the surface args as if the touch is from a client that does not support this
|
||||
SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs();
|
||||
surfaceArgs.FaceIndex = -1; // TOUCH_INVALID_FACE
|
||||
surfaceArgs.Binormal = Vector3.Zero; // TOUCH_INVALID_VECTOR
|
||||
surfaceArgs.Normal = Vector3.Zero; // TOUCH_INVALID_VECTOR
|
||||
surfaceArgs.STCoord = new Vector3(-1.0f, -1.0f, 0.0f); // TOUCH_INVALID_TEXCOORD
|
||||
surfaceArgs.UVCoord = surfaceArgs.STCoord; // TOUCH_INVALID_TEXCOORD
|
||||
List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
|
||||
touchArgs.Add(surfaceArgs);
|
||||
Vector3 offset = part.OffsetPosition * -1.0f;
|
||||
if (OnGrabObject == null)
|
||||
return false;
|
||||
OnGrabObject(part.LocalId, offset, this, touchArgs);
|
||||
if (OnGrabUpdate != null)
|
||||
OnGrabUpdate(part.UUID, offset, part.ParentGroup.RootPart.GroupPosition, this, touchArgs);
|
||||
if (OnDeGrabObject != null)
|
||||
OnDeGrabObject(part.LocalId, this, touchArgs);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool hasTouchEvents(SceneObjectPart part)
|
||||
{
|
||||
if ((part.ScriptEvents & scriptEvents.touch) != 0 ||
|
||||
(part.ScriptEvents & scriptEvents.touch_start) != 0 ||
|
||||
(part.ScriptEvents & scriptEvents.touch_end) != 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void InstantMessage(UUID target, string message)
|
||||
{
|
||||
OnInstantMessage(this, new GridInstantMessage(m_scene,
|
||||
@@ -153,6 +192,14 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
|
||||
private void SendOnChatFromClient(int channel, string message, ChatTypeEnum chatType)
|
||||
{
|
||||
if (channel == 0)
|
||||
{
|
||||
message = message.Trim();
|
||||
if (string.IsNullOrEmpty(message))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
OSChatMessage chatFromClient = new OSChatMessage();
|
||||
chatFromClient.Channel = channel;
|
||||
chatFromClient.From = Name;
|
||||
@@ -898,11 +945,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
{
|
||||
}
|
||||
|
||||
public EndPoint GetClientEP()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public ClientInfo GetClientInfo()
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -305,6 +305,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Touch(UUID agentID, UUID objectID)
|
||||
{
|
||||
lock (m_avatars)
|
||||
{
|
||||
if (m_avatars.ContainsKey(agentID))
|
||||
return m_avatars[agentID].Touch(objectID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public UUID GetOwner(UUID agentID)
|
||||
{
|
||||
lock (m_avatars)
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
|
||||
UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
|
||||
|
||||
ScenePresence npc = m_scene.GetScenePresence(npcId);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
|
||||
part.SitTargetPosition = new Vector3(0, 0, 1);
|
||||
m_npcMod.Sit(npc.UUID, part.UUID, m_scene);
|
||||
@@ -333,7 +333,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
|
||||
UUID npcId = m_npcMod.CreateNPC("John", "Smith", startPos, UUID.Zero, true, m_scene, sp.Appearance);
|
||||
|
||||
ScenePresence npc = m_scene.GetScenePresence(npcId);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene);
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart;
|
||||
|
||||
m_npcMod.Sit(npc.UUID, part.UUID, m_scene);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
||||
public class BasicPhysicsPrim : PhysicsActor
|
||||
{
|
||||
private Vector3 _size;
|
||||
private PrimitiveBaseShape _shape;
|
||||
// private PrimitiveBaseShape _shape;
|
||||
|
||||
public BasicPhysicsPrim(
|
||||
string name, uint localId, Vector3 position, Vector3 size, Quaternion orientation, PrimitiveBaseShape shape)
|
||||
@@ -136,7 +136,8 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
||||
|
||||
public override PrimitiveBaseShape Shape
|
||||
{
|
||||
set { _shape = value; }
|
||||
// set { _shape = value; }
|
||||
set {}
|
||||
}
|
||||
|
||||
public override float Mass
|
||||
|
||||
@@ -74,7 +74,7 @@ public class BSCharacter : PhysicsActor
|
||||
private float _buoyancy;
|
||||
|
||||
private int _subscribedEventsMs = 0;
|
||||
private int _lastCollisionTime = 0;
|
||||
private int _nextCollisionOkTime = 0;
|
||||
|
||||
private Vector3 _PIDTarget;
|
||||
private bool _usePID;
|
||||
@@ -360,17 +360,22 @@ public class BSCharacter : PhysicsActor
|
||||
}
|
||||
//m_lastUpdateSent = false;
|
||||
}
|
||||
|
||||
public override void AddAngularForce(Vector3 force, bool pushforce) {
|
||||
}
|
||||
public override void SetMomentum(Vector3 momentum) {
|
||||
}
|
||||
|
||||
// Turn on collision events at a rate no faster than one every the given milliseconds
|
||||
public override void SubscribeEvents(int ms) {
|
||||
_subscribedEventsMs = ms;
|
||||
_lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
|
||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
|
||||
}
|
||||
// Stop collision events
|
||||
public override void UnSubscribeEvents() {
|
||||
_subscribedEventsMs = 0;
|
||||
}
|
||||
// Return 'true' if someone has subscribed to events
|
||||
public override bool SubscribedEvents() {
|
||||
return (_subscribedEventsMs > 0);
|
||||
}
|
||||
@@ -386,47 +391,57 @@ public class BSCharacter : PhysicsActor
|
||||
_mass = _density * _avatarVolume;
|
||||
}
|
||||
|
||||
// Set to 'true' if the individual changed items should be checked
|
||||
// (someday RequestPhysicsTerseUpdate() will take a bitmap of changed properties)
|
||||
const bool SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES = false;
|
||||
|
||||
// The physics engine says that properties have updated. Update same and inform
|
||||
// the world that things have changed.
|
||||
public void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
bool changed = false;
|
||||
// we assign to the local variables so the normal set action does not happen
|
||||
if (_position != entprop.Position)
|
||||
{
|
||||
if (SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES) {
|
||||
// we assign to the local variables so the normal set action does not happen
|
||||
if (_position != entprop.Position) {
|
||||
_position = entprop.Position;
|
||||
changed = true;
|
||||
}
|
||||
if (_orientation != entprop.Rotation) {
|
||||
_orientation = entprop.Rotation;
|
||||
changed = true;
|
||||
}
|
||||
if (_velocity != entprop.Velocity) {
|
||||
_velocity = entprop.Velocity;
|
||||
changed = true;
|
||||
}
|
||||
if (_acceleration != entprop.Acceleration) {
|
||||
_acceleration = entprop.Acceleration;
|
||||
changed = true;
|
||||
}
|
||||
if (_rotationalVelocity != entprop.RotationalVelocity) {
|
||||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
|
||||
// Avatar movement is not done by generating this event. There is code in the heartbeat
|
||||
// loop that updates avatars.
|
||||
// base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
}
|
||||
else {
|
||||
_position = entprop.Position;
|
||||
changed = true;
|
||||
}
|
||||
if (_orientation != entprop.Rotation)
|
||||
{
|
||||
_orientation = entprop.Rotation;
|
||||
changed = true;
|
||||
}
|
||||
if (_velocity != entprop.Velocity)
|
||||
{
|
||||
_velocity = entprop.Velocity;
|
||||
changed = true;
|
||||
}
|
||||
if (_acceleration != entprop.Acceleration)
|
||||
{
|
||||
_acceleration = entprop.Acceleration;
|
||||
changed = true;
|
||||
}
|
||||
if (_rotationalVelocity != entprop.RotationalVelocity)
|
||||
{
|
||||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
|
||||
// Avatar movement is not done by generating this event. There is a system that
|
||||
// checks for avatar updates each heartbeat loop.
|
||||
// base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
// Called by the scene when a collision with this object is reported
|
||||
// The collision, if it should be reported to the character, is placed in a collection
|
||||
// that will later be sent to the simulator when SendCollisions() is called.
|
||||
CollisionEventUpdate collisionCollection = null;
|
||||
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
@@ -440,29 +455,34 @@ public class BSCharacter : PhysicsActor
|
||||
}
|
||||
|
||||
// throttle collisions to the rate specified in the subscription
|
||||
if (_subscribedEventsMs == 0) return; // don't want collisions
|
||||
int nowTime = _scene.SimulationNowTime;
|
||||
if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
|
||||
_lastCollisionTime = nowTime;
|
||||
if (_subscribedEventsMs != 0) {
|
||||
int nowTime = _scene.SimulationNowTime;
|
||||
if (nowTime >= _nextCollisionOkTime) {
|
||||
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
||||
|
||||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendCollisions()
|
||||
{
|
||||
// if (collisionCollection != null)
|
||||
// {
|
||||
// base.SendCollisionUpdate(collisionCollection);
|
||||
// collisionCollection = null;
|
||||
// }
|
||||
/*
|
||||
if (collisionCollection != null && collisionCollection.Count > 0)
|
||||
{
|
||||
base.SendCollisionUpdate(collisionCollection);
|
||||
collisionCollection = null;
|
||||
}
|
||||
*/
|
||||
// Kludge to make a collision call even if there are no collisions.
|
||||
// This causes the avatar animation to get updated.
|
||||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
base.SendCollisionUpdate(collisionCollection);
|
||||
collisionCollection = null;
|
||||
collisionCollection.Clear();
|
||||
// End kludge
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,6 +32,14 @@ using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Entry for a port of Bullet (http://bulletphysics.org/) to OpenSim.
|
||||
/// This module interfaces to an unmanaged C++ library which makes the
|
||||
/// actual calls into the Bullet physics engine.
|
||||
/// The unmanaged library is found in opensim-libs::trunk/unmanaged/BulletSim/.
|
||||
/// The unmanaged library is compiled and linked statically with Bullet
|
||||
/// to create BulletSim.dll and libBulletSim.so (for both 32 and 64 bit).
|
||||
/// </summary>
|
||||
public class BSPlugin : IPhysicsPlugin
|
||||
{
|
||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
@@ -53,6 +61,9 @@ public class BSPlugin : IPhysicsPlugin
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("BulletSim.dll");
|
||||
// If not Windows, loading is performed by the
|
||||
// Mono loader as specified in
|
||||
// "bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config".
|
||||
|
||||
_mScene = new BSScene(sceneIdentifier);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public sealed class BSPrim : PhysicsActor
|
||||
private BSPrim _parentPrim;
|
||||
|
||||
private int _subscribedEventsMs = 0;
|
||||
private int _lastCollisionTime = 0;
|
||||
private int _nextCollisionOkTime = 0;
|
||||
long _collidingStep;
|
||||
long _collidingGroundStep;
|
||||
|
||||
@@ -597,7 +597,8 @@ public sealed class BSPrim : PhysicsActor
|
||||
}
|
||||
public override void SubscribeEvents(int ms) {
|
||||
_subscribedEventsMs = ms;
|
||||
_lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
|
||||
// make sure first collision happens
|
||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
||||
}
|
||||
public override void UnSubscribeEvents() {
|
||||
_subscribedEventsMs = 0;
|
||||
@@ -1338,23 +1339,27 @@ public sealed class BSPrim : PhysicsActor
|
||||
_collidingGroundStep = _scene.SimulationStep;
|
||||
}
|
||||
|
||||
if (_subscribedEventsMs == 0) return; // nothing in the object is waiting for collision events
|
||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||
int nowTime = _scene.SimulationNowTime;
|
||||
if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
|
||||
_lastCollisionTime = nowTime;
|
||||
// if someone is subscribed to collision events....
|
||||
if (_subscribedEventsMs != 0) {
|
||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||
int nowTime = _scene.SimulationNowTime;
|
||||
if (nowTime >= _nextCollisionOkTime) {
|
||||
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
||||
|
||||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The scene is telling us it's time to pass our collected collisions into the simulator
|
||||
public void SendCollisions()
|
||||
{
|
||||
if (collisionCollection != null)
|
||||
if (collisionCollection != null && collisionCollection.Count > 0)
|
||||
{
|
||||
base.SendCollisionUpdate(collisionCollection);
|
||||
collisionCollection = null;
|
||||
collisionCollection.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ using OpenSim.Region.Framework;
|
||||
// Should prim.link() and prim.delink() membership checking happen at taint time?
|
||||
// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
|
||||
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
||||
// Use collision masks for collision with terrain and phantom objects
|
||||
// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
|
||||
// Implement LockAngularMotion
|
||||
// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
|
||||
@@ -62,9 +63,6 @@ using OpenSim.Region.Framework;
|
||||
// Multiple contact points on collision?
|
||||
// See code in ode::near... calls to collision_accounting_events()
|
||||
// (This might not be a problem. ODE collects all the collisions with one object in one tick.)
|
||||
// Use collision masks for collision with terrain and phantom objects
|
||||
// Figure out how to not allocate a new Dictionary and List for every collision
|
||||
// in BSPrim.Collide() and BSCharacter.Collide(). Can the same ones be reused?
|
||||
// Raycast
|
||||
//
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
@@ -405,6 +403,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
// prevent simulation until we've been initialized
|
||||
if (!m_initialized) return 10.0f;
|
||||
|
||||
long simulateStartTime = Util.EnvironmentTickCount();
|
||||
|
||||
// update the prim states while we know the physics engine is not busy
|
||||
ProcessTaints();
|
||||
|
||||
@@ -437,13 +437,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
}
|
||||
}
|
||||
|
||||
// The SendCollision's batch up the collisions on the objects. Now push the collisions into the simulator.
|
||||
// The above SendCollision's batch up the collisions on the objects.
|
||||
// Now push the collisions into the simulator.
|
||||
foreach (BSPrim bsp in m_primsWithCollisions)
|
||||
bsp.SendCollisions();
|
||||
m_primsWithCollisions.Clear();
|
||||
|
||||
// This is a kludge to get avatar movement updated.
|
||||
// Don't send collisions only if there were collisions -- send everytime.
|
||||
// ODE sends collisions even if there are none and this is used to update
|
||||
// avatar animations and stuff.
|
||||
// foreach (BSCharacter bsc in m_avatarsWithCollisions)
|
||||
// bsc.SendCollisions();
|
||||
// This is a kludge to get avatar movement updated. ODE sends collisions even if there isn't any
|
||||
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
|
||||
kvp.Value.SendCollisions();
|
||||
m_avatarsWithCollisions.Clear();
|
||||
@@ -465,10 +470,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
if (m_avatars.TryGetValue(entprop.ID, out actor))
|
||||
{
|
||||
actor.UpdateProperties(entprop);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If enabled, call into the physics engine to dump statistics
|
||||
if (m_detailedStatsStep > 0)
|
||||
{
|
||||
if ((m_simulationStep % m_detailedStatsStep) == 0)
|
||||
@@ -477,6 +484,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
}
|
||||
}
|
||||
|
||||
// this is a waste since the outside routine also calcuates the physics simulation
|
||||
// period. TODO: There should be a way of computing physics frames from simulator computation.
|
||||
// long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||
// return (timeStep * (float)simulateTotalTime);
|
||||
|
||||
// TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
|
||||
return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
|
||||
}
|
||||
@@ -528,6 +540,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||
public override void SetWaterLevel(float baseheight)
|
||||
{
|
||||
m_waterLevel = baseheight;
|
||||
// TODO: pass to physics engine so things will float?
|
||||
}
|
||||
public float GetWaterLevel()
|
||||
{
|
||||
|
||||
@@ -236,6 +236,13 @@ namespace PrimMesher
|
||||
this.U = u;
|
||||
this.V = v;
|
||||
}
|
||||
|
||||
public UVCoord Flip()
|
||||
{
|
||||
this.U = 1.0f - this.U;
|
||||
this.V = 1.0f - this.V;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Face
|
||||
@@ -603,40 +610,40 @@ namespace PrimMesher
|
||||
/// <summary>
|
||||
/// generates a profile for extrusion
|
||||
/// </summary>
|
||||
internal class Profile
|
||||
public class Profile
|
||||
{
|
||||
private const float twoPi = 2.0f * (float)Math.PI;
|
||||
|
||||
internal string errorMessage = null;
|
||||
public string errorMessage = null;
|
||||
|
||||
internal List<Coord> coords;
|
||||
internal List<Face> faces;
|
||||
internal List<Coord> vertexNormals;
|
||||
internal List<float> us;
|
||||
internal List<UVCoord> faceUVs;
|
||||
internal List<int> faceNumbers;
|
||||
public List<Coord> coords;
|
||||
public List<Face> faces;
|
||||
public List<Coord> vertexNormals;
|
||||
public List<float> us;
|
||||
public List<UVCoord> faceUVs;
|
||||
public List<int> faceNumbers;
|
||||
|
||||
// use these for making individual meshes for each prim face
|
||||
internal List<int> outerCoordIndices = null;
|
||||
internal List<int> hollowCoordIndices = null;
|
||||
internal List<int> cut1CoordIndices = null;
|
||||
internal List<int> cut2CoordIndices = null;
|
||||
public List<int> outerCoordIndices = null;
|
||||
public List<int> hollowCoordIndices = null;
|
||||
public List<int> cut1CoordIndices = null;
|
||||
public List<int> cut2CoordIndices = null;
|
||||
|
||||
internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f);
|
||||
internal Coord cutNormal1 = new Coord();
|
||||
internal Coord cutNormal2 = new Coord();
|
||||
public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f);
|
||||
public Coord cutNormal1 = new Coord();
|
||||
public Coord cutNormal2 = new Coord();
|
||||
|
||||
internal int numOuterVerts = 0;
|
||||
internal int numHollowVerts = 0;
|
||||
public int numOuterVerts = 0;
|
||||
public int numHollowVerts = 0;
|
||||
|
||||
internal int outerFaceNumber = -1;
|
||||
internal int hollowFaceNumber = -1;
|
||||
public int outerFaceNumber = -1;
|
||||
public int hollowFaceNumber = -1;
|
||||
|
||||
internal bool calcVertexNormals = false;
|
||||
internal int bottomFaceNumber = 0;
|
||||
internal int numPrimFaces = 0;
|
||||
public bool calcVertexNormals = false;
|
||||
public int bottomFaceNumber = 0;
|
||||
public int numPrimFaces = 0;
|
||||
|
||||
internal Profile()
|
||||
public Profile()
|
||||
{
|
||||
this.coords = new List<Coord>();
|
||||
this.faces = new List<Face>();
|
||||
@@ -646,7 +653,7 @@ namespace PrimMesher
|
||||
this.faceNumbers = new List<int>();
|
||||
}
|
||||
|
||||
internal Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals)
|
||||
public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals)
|
||||
{
|
||||
this.calcVertexNormals = calcVertexNormals;
|
||||
this.coords = new List<Coord>();
|
||||
@@ -657,7 +664,6 @@ namespace PrimMesher
|
||||
this.faceNumbers = new List<int>();
|
||||
|
||||
Coord center = new Coord(0.0f, 0.0f, 0.0f);
|
||||
//bool hasCenter = false;
|
||||
|
||||
List<Coord> hollowCoords = new List<Coord>();
|
||||
List<Coord> hollowNormals = new List<Coord>();
|
||||
@@ -682,8 +688,8 @@ namespace PrimMesher
|
||||
float yScale = 0.5f;
|
||||
if (sides == 4) // corners of a square are sqrt(2) from center
|
||||
{
|
||||
xScale = 0.707f;
|
||||
yScale = 0.707f;
|
||||
xScale = 0.707107f;
|
||||
yScale = 0.707107f;
|
||||
}
|
||||
|
||||
float startAngle = profileStart * twoPi;
|
||||
@@ -724,7 +730,6 @@ namespace PrimMesher
|
||||
else if (!simpleFace)
|
||||
{
|
||||
this.coords.Add(center);
|
||||
//hasCenter = true;
|
||||
if (this.calcVertexNormals)
|
||||
this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
|
||||
this.us.Add(0.0f);
|
||||
@@ -752,7 +757,10 @@ namespace PrimMesher
|
||||
else
|
||||
hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
|
||||
|
||||
hollowUs.Add(angle.angle * hollow);
|
||||
if (hollowSides == 4)
|
||||
hollowUs.Add(angle.angle * hollow * 0.707107f);
|
||||
else
|
||||
hollowUs.Add(angle.angle * hollow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -829,9 +837,6 @@ namespace PrimMesher
|
||||
|
||||
if (createFaces)
|
||||
{
|
||||
//int numOuterVerts = this.coords.Count;
|
||||
//numOuterVerts = this.coords.Count;
|
||||
//int numHollowVerts = hollowCoords.Count;
|
||||
int numTotalVerts = this.numOuterVerts + this.numHollowVerts;
|
||||
|
||||
if (this.numOuterVerts == this.numHollowVerts)
|
||||
@@ -993,11 +998,7 @@ namespace PrimMesher
|
||||
if (startVert > 0)
|
||||
this.faceNumbers.Add(-1);
|
||||
for (int i = 0; i < this.numOuterVerts - 1; i++)
|
||||
//this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum);
|
||||
this.faceNumbers.Add(sides < 5 && i < sides ? faceNum++ : faceNum);
|
||||
|
||||
//if (!hasHollow && !hasProfileCut)
|
||||
// this.bottomFaceNumber = faceNum++;
|
||||
this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum);
|
||||
|
||||
this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++);
|
||||
|
||||
@@ -1014,8 +1015,7 @@ namespace PrimMesher
|
||||
|
||||
this.hollowFaceNumber = faceNum++;
|
||||
}
|
||||
//if (hasProfileCut || hasHollow)
|
||||
// this.bottomFaceNumber = faceNum++;
|
||||
|
||||
this.bottomFaceNumber = faceNum++;
|
||||
|
||||
if (hasHollow && hasProfileCut)
|
||||
@@ -1030,19 +1030,19 @@ namespace PrimMesher
|
||||
|
||||
}
|
||||
|
||||
internal void MakeFaceUVs()
|
||||
public void MakeFaceUVs()
|
||||
{
|
||||
this.faceUVs = new List<UVCoord>();
|
||||
foreach (Coord c in this.coords)
|
||||
this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y));
|
||||
this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y)));
|
||||
}
|
||||
|
||||
internal Profile Copy()
|
||||
public Profile Copy()
|
||||
{
|
||||
return this.Copy(true);
|
||||
}
|
||||
|
||||
internal Profile Copy(bool needFaces)
|
||||
public Profile Copy(bool needFaces)
|
||||
{
|
||||
Profile copy = new Profile();
|
||||
|
||||
@@ -1071,12 +1071,12 @@ namespace PrimMesher
|
||||
return copy;
|
||||
}
|
||||
|
||||
internal void AddPos(Coord v)
|
||||
public void AddPos(Coord v)
|
||||
{
|
||||
this.AddPos(v.X, v.Y, v.Z);
|
||||
}
|
||||
|
||||
internal void AddPos(float x, float y, float z)
|
||||
public void AddPos(float x, float y, float z)
|
||||
{
|
||||
int i;
|
||||
int numVerts = this.coords.Count;
|
||||
@@ -1092,7 +1092,7 @@ namespace PrimMesher
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddRot(Quat q)
|
||||
public void AddRot(Quat q)
|
||||
{
|
||||
int i;
|
||||
int numVerts = this.coords.Count;
|
||||
@@ -1113,7 +1113,7 @@ namespace PrimMesher
|
||||
}
|
||||
}
|
||||
|
||||
internal void Scale(float x, float y)
|
||||
public void Scale(float x, float y)
|
||||
{
|
||||
int i;
|
||||
int numVerts = this.coords.Count;
|
||||
@@ -1131,7 +1131,7 @@ namespace PrimMesher
|
||||
/// <summary>
|
||||
/// Changes order of the vertex indices and negates the center vertex normal. Does not alter vertex normals of radial vertices
|
||||
/// </summary>
|
||||
internal void FlipNormals()
|
||||
public void FlipNormals()
|
||||
{
|
||||
int i;
|
||||
int numFaces = this.faces.Count;
|
||||
@@ -1171,7 +1171,7 @@ namespace PrimMesher
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddValue2FaceVertexIndices(int num)
|
||||
public void AddValue2FaceVertexIndices(int num)
|
||||
{
|
||||
int numFaces = this.faces.Count;
|
||||
Face tmpFace;
|
||||
@@ -1186,7 +1186,7 @@ namespace PrimMesher
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddValue2FaceNormalIndices(int num)
|
||||
public void AddValue2FaceNormalIndices(int num)
|
||||
{
|
||||
if (this.calcVertexNormals)
|
||||
{
|
||||
@@ -1204,7 +1204,7 @@ namespace PrimMesher
|
||||
}
|
||||
}
|
||||
|
||||
internal void DumpRaw(String path, String name, String title)
|
||||
public void DumpRaw(String path, String name, String title)
|
||||
{
|
||||
if (path == null)
|
||||
return;
|
||||
@@ -1261,6 +1261,15 @@ namespace PrimMesher
|
||||
|
||||
public void Create(PathType pathType, int steps)
|
||||
{
|
||||
if (this.taperX > 0.999f)
|
||||
this.taperX = 0.999f;
|
||||
if (this.taperX < -0.999f)
|
||||
this.taperX = -0.999f;
|
||||
if (this.taperY > 0.999f)
|
||||
this.taperY = 0.999f;
|
||||
if (this.taperY < -0.999f)
|
||||
this.taperY = -0.999f;
|
||||
|
||||
if (pathType == PathType.Linear || pathType == PathType.Flexible)
|
||||
{
|
||||
int step = 0;
|
||||
@@ -1273,12 +1282,12 @@ namespace PrimMesher
|
||||
|
||||
float start = -0.5f;
|
||||
float stepSize = length / (float)steps;
|
||||
float percentOfPathMultiplier = stepSize;
|
||||
float xOffset = 0.0f;
|
||||
float yOffset = 0.0f;
|
||||
float percentOfPathMultiplier = stepSize * 0.999999f;
|
||||
float xOffset = this.topShearX * this.pathCutBegin;
|
||||
float yOffset = this.topShearY * this.pathCutBegin;
|
||||
float zOffset = start;
|
||||
float xOffsetStepIncrement = this.topShearX / steps;
|
||||
float yOffsetStepIncrement = this.topShearY / steps;
|
||||
float xOffsetStepIncrement = this.topShearX * length / steps;
|
||||
float yOffsetStepIncrement = this.topShearY * length / steps;
|
||||
|
||||
float percentOfPath = this.pathCutBegin;
|
||||
zOffset += percentOfPath;
|
||||
@@ -1573,13 +1582,6 @@ namespace PrimMesher
|
||||
this.hollow = 0.99f;
|
||||
if (hollow < 0.0f)
|
||||
this.hollow = 0.0f;
|
||||
|
||||
//if (sphereMode)
|
||||
// this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f;
|
||||
//else
|
||||
// //this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f);
|
||||
// this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f;
|
||||
//this.hasHollow = (this.hollow > 0.001f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1614,10 +1616,9 @@ namespace PrimMesher
|
||||
steps = (int)(steps * 4.5 * length);
|
||||
}
|
||||
|
||||
if (sphereMode)
|
||||
if (this.sphereMode)
|
||||
this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f;
|
||||
else
|
||||
//this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f);
|
||||
this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f;
|
||||
this.hasHollow = (this.hollow > 0.001f);
|
||||
|
||||
@@ -1630,6 +1631,22 @@ namespace PrimMesher
|
||||
|
||||
float hollow = this.hollow;
|
||||
|
||||
if (pathType == PathType.Circular)
|
||||
{
|
||||
needEndFaces = false;
|
||||
if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f)
|
||||
needEndFaces = true;
|
||||
else if (this.taperX != 0.0f || this.taperY != 0.0f)
|
||||
needEndFaces = true;
|
||||
else if (this.skew != 0.0f)
|
||||
needEndFaces = true;
|
||||
else if (twistTotal != 0.0f)
|
||||
needEndFaces = true;
|
||||
else if (this.radius != 0.0f)
|
||||
needEndFaces = true;
|
||||
}
|
||||
else needEndFaces = true;
|
||||
|
||||
// sanity checks
|
||||
float initialProfileRot = 0.0f;
|
||||
if (pathType == PathType.Circular)
|
||||
@@ -1689,20 +1706,13 @@ namespace PrimMesher
|
||||
|
||||
this.numPrimFaces = profile.numPrimFaces;
|
||||
|
||||
//profileOuterFaceNumber = profile.faceNumbers[0];
|
||||
//if (!needEndFaces)
|
||||
// profileOuterFaceNumber--;
|
||||
//profileOuterFaceNumber = needEndFaces ? 1 : 0;
|
||||
|
||||
|
||||
//if (hasHollow)
|
||||
//{
|
||||
// if (needEndFaces)
|
||||
// profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts + 1];
|
||||
// else
|
||||
// profileHollowFaceNumber = profile.faceNumbers[profile.numOuterVerts] - 1;
|
||||
//}
|
||||
|
||||
int cut1FaceNumber = profile.bottomFaceNumber + 1;
|
||||
int cut2FaceNumber = cut1FaceNumber + 1;
|
||||
if (!needEndFaces)
|
||||
{
|
||||
cut1FaceNumber -= 2;
|
||||
cut2FaceNumber -= 2;
|
||||
}
|
||||
|
||||
profileOuterFaceNumber = profile.outerFaceNumber;
|
||||
if (!needEndFaces)
|
||||
@@ -1732,7 +1742,8 @@ namespace PrimMesher
|
||||
|
||||
Coord lastCutNormal1 = new Coord();
|
||||
Coord lastCutNormal2 = new Coord();
|
||||
float lastV = 1.0f;
|
||||
float thisV = 0.0f;
|
||||
float lastV = 0.0f;
|
||||
|
||||
Path path = new Path();
|
||||
path.twistBegin = twistBegin;
|
||||
@@ -1754,23 +1765,6 @@ namespace PrimMesher
|
||||
|
||||
path.Create(pathType, steps);
|
||||
|
||||
|
||||
if (pathType == PathType.Circular)
|
||||
{
|
||||
needEndFaces = false;
|
||||
if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f)
|
||||
needEndFaces = true;
|
||||
else if (this.taperX != 0.0f || this.taperY != 0.0f)
|
||||
needEndFaces = true;
|
||||
else if (this.skew != 0.0f)
|
||||
needEndFaces = true;
|
||||
else if (twistTotal != 0.0f)
|
||||
needEndFaces = true;
|
||||
else if (this.radius != 0.0f)
|
||||
needEndFaces = true;
|
||||
}
|
||||
else needEndFaces = true;
|
||||
|
||||
for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++)
|
||||
{
|
||||
PathNode node = path.pathNodes[nodeIndex];
|
||||
@@ -1784,7 +1778,7 @@ namespace PrimMesher
|
||||
{
|
||||
newLayer.FlipNormals();
|
||||
|
||||
// add the top faces to the viewerFaces list here
|
||||
// add the bottom faces to the viewerFaces list
|
||||
if (this.viewerMode)
|
||||
{
|
||||
Coord faceNormal = newLayer.faceNormal;
|
||||
@@ -1811,6 +1805,13 @@ namespace PrimMesher
|
||||
newViewerFace.uv2 = newLayer.faceUVs[face.v2];
|
||||
newViewerFace.uv3 = newLayer.faceUVs[face.v3];
|
||||
|
||||
if (pathType == PathType.Linear)
|
||||
{
|
||||
newViewerFace.uv1.Flip();
|
||||
newViewerFace.uv2.Flip();
|
||||
newViewerFace.uv3.Flip();
|
||||
}
|
||||
|
||||
this.viewerFaces.Add(newViewerFace);
|
||||
}
|
||||
}
|
||||
@@ -1835,7 +1836,10 @@ namespace PrimMesher
|
||||
// fill faces between layers
|
||||
|
||||
int numVerts = newLayer.coords.Count;
|
||||
Face newFace = new Face();
|
||||
Face newFace1 = new Face();
|
||||
Face newFace2 = new Face();
|
||||
|
||||
thisV = 1.0f - node.percentOfPath;
|
||||
|
||||
if (nodeIndex > 0)
|
||||
{
|
||||
@@ -1853,14 +1857,23 @@ namespace PrimMesher
|
||||
|
||||
int whichVert = i - startVert;
|
||||
|
||||
newFace.v1 = i;
|
||||
newFace.v2 = i - numVerts;
|
||||
newFace.v3 = iNext - numVerts;
|
||||
this.faces.Add(newFace);
|
||||
newFace1.v1 = i;
|
||||
newFace1.v2 = i - numVerts;
|
||||
newFace1.v3 = iNext;
|
||||
|
||||
newFace.v2 = iNext - numVerts;
|
||||
newFace.v3 = iNext;
|
||||
this.faces.Add(newFace);
|
||||
newFace1.n1 = newFace1.v1;
|
||||
newFace1.n2 = newFace1.v2;
|
||||
newFace1.n3 = newFace1.v3;
|
||||
this.faces.Add(newFace1);
|
||||
|
||||
newFace2.v1 = iNext;
|
||||
newFace2.v2 = i - numVerts;
|
||||
newFace2.v3 = iNext - numVerts;
|
||||
|
||||
newFace2.n1 = newFace2.v1;
|
||||
newFace2.n2 = newFace2.v2;
|
||||
newFace2.n3 = newFace2.v3;
|
||||
this.faces.Add(newFace2);
|
||||
|
||||
if (this.viewerMode)
|
||||
{
|
||||
@@ -1873,10 +1886,16 @@ namespace PrimMesher
|
||||
ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
|
||||
ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
|
||||
|
||||
float u1 = newLayer.us[whichVert];
|
||||
int uIndex = whichVert;
|
||||
if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1)
|
||||
{
|
||||
uIndex++;
|
||||
}
|
||||
|
||||
float u1 = newLayer.us[uIndex];
|
||||
float u2 = 1.0f;
|
||||
if (whichVert < newLayer.us.Count - 1)
|
||||
u2 = newLayer.us[whichVert + 1];
|
||||
if (uIndex < (int)newLayer.us.Count - 1)
|
||||
u2 = newLayer.us[uIndex + 1];
|
||||
|
||||
if (whichVert == cut1Vert || whichVert == cut2Vert)
|
||||
{
|
||||
@@ -1894,13 +1913,22 @@ namespace PrimMesher
|
||||
u1 -= (int)u1;
|
||||
if (u2 < 0.1f)
|
||||
u2 = 1.0f;
|
||||
//this.profileOuterFaceNumber = primFaceNum;
|
||||
}
|
||||
else if (whichVert > profile.coords.Count - profile.numHollowVerts - 1)
|
||||
}
|
||||
|
||||
if (this.sphereMode)
|
||||
{
|
||||
if (whichVert != cut1Vert && whichVert != cut2Vert)
|
||||
{
|
||||
u1 *= 2.0f;
|
||||
u2 *= 2.0f;
|
||||
//this.profileHollowFaceNumber = primFaceNum;
|
||||
u1 = u1 * 2.0f - 1.0f;
|
||||
u2 = u2 * 2.0f - 1.0f;
|
||||
|
||||
if (whichVert >= newLayer.numOuterVerts)
|
||||
{
|
||||
u1 -= hollow;
|
||||
u2 -= hollow;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1908,37 +1936,39 @@ namespace PrimMesher
|
||||
newViewerFace1.uv2.U = u1;
|
||||
newViewerFace1.uv3.U = u2;
|
||||
|
||||
newViewerFace1.uv1.V = 1.0f - node.percentOfPath;
|
||||
newViewerFace1.uv1.V = thisV;
|
||||
newViewerFace1.uv2.V = lastV;
|
||||
newViewerFace1.uv3.V = lastV;
|
||||
newViewerFace1.uv3.V = thisV;
|
||||
|
||||
newViewerFace2.uv1.U = u1;
|
||||
newViewerFace2.uv2.U = u2;
|
||||
newViewerFace2.uv1.U = u2;
|
||||
newViewerFace2.uv2.U = u1;
|
||||
newViewerFace2.uv3.U = u2;
|
||||
|
||||
newViewerFace2.uv1.V = 1.0f - node.percentOfPath;
|
||||
newViewerFace2.uv1.V = thisV;
|
||||
newViewerFace2.uv2.V = lastV;
|
||||
newViewerFace2.uv3.V = 1.0f - node.percentOfPath;
|
||||
newViewerFace2.uv3.V = lastV;
|
||||
|
||||
newViewerFace1.v1 = this.coords[i];
|
||||
newViewerFace1.v2 = this.coords[i - numVerts];
|
||||
newViewerFace1.v3 = this.coords[iNext - numVerts];
|
||||
newViewerFace1.v1 = this.coords[newFace1.v1];
|
||||
newViewerFace1.v2 = this.coords[newFace1.v2];
|
||||
newViewerFace1.v3 = this.coords[newFace1.v3];
|
||||
|
||||
newViewerFace2.v1 = this.coords[i];
|
||||
newViewerFace2.v2 = this.coords[iNext - numVerts];
|
||||
newViewerFace2.v3 = this.coords[iNext];
|
||||
newViewerFace2.v1 = this.coords[newFace2.v1];
|
||||
newViewerFace2.v2 = this.coords[newFace2.v2];
|
||||
newViewerFace2.v3 = this.coords[newFace2.v3];
|
||||
|
||||
newViewerFace1.coordIndex1 = i;
|
||||
newViewerFace1.coordIndex2 = i - numVerts;
|
||||
newViewerFace1.coordIndex3 = iNext - numVerts;
|
||||
newViewerFace1.coordIndex1 = newFace1.v1;
|
||||
newViewerFace1.coordIndex2 = newFace1.v2;
|
||||
newViewerFace1.coordIndex3 = newFace1.v3;
|
||||
|
||||
newViewerFace2.coordIndex1 = i;
|
||||
newViewerFace2.coordIndex2 = iNext - numVerts;
|
||||
newViewerFace2.coordIndex3 = iNext;
|
||||
newViewerFace2.coordIndex1 = newFace2.v1;
|
||||
newViewerFace2.coordIndex2 = newFace2.v2;
|
||||
newViewerFace2.coordIndex3 = newFace2.v3;
|
||||
|
||||
// profile cut faces
|
||||
if (whichVert == cut1Vert)
|
||||
{
|
||||
newViewerFace1.primFaceNumber = cut1FaceNumber;
|
||||
newViewerFace2.primFaceNumber = cut1FaceNumber;
|
||||
newViewerFace1.n1 = newLayer.cutNormal1;
|
||||
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
|
||||
|
||||
@@ -1947,10 +1977,14 @@ namespace PrimMesher
|
||||
}
|
||||
else if (whichVert == cut2Vert)
|
||||
{
|
||||
newViewerFace1.primFaceNumber = cut2FaceNumber;
|
||||
newViewerFace2.primFaceNumber = cut2FaceNumber;
|
||||
newViewerFace1.n1 = newLayer.cutNormal2;
|
||||
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
|
||||
newViewerFace1.n2 = lastCutNormal2;
|
||||
newViewerFace1.n3 = lastCutNormal2;
|
||||
|
||||
newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
|
||||
newViewerFace2.n1 = newLayer.cutNormal2;
|
||||
newViewerFace2.n3 = newLayer.cutNormal2;
|
||||
newViewerFace2.n2 = lastCutNormal2;
|
||||
}
|
||||
|
||||
@@ -1963,13 +1997,13 @@ namespace PrimMesher
|
||||
}
|
||||
else
|
||||
{
|
||||
newViewerFace1.n1 = this.normals[i];
|
||||
newViewerFace1.n2 = this.normals[i - numVerts];
|
||||
newViewerFace1.n3 = this.normals[iNext - numVerts];
|
||||
newViewerFace1.n1 = this.normals[newFace1.n1];
|
||||
newViewerFace1.n2 = this.normals[newFace1.n2];
|
||||
newViewerFace1.n3 = this.normals[newFace1.n3];
|
||||
|
||||
newViewerFace2.n1 = this.normals[i];
|
||||
newViewerFace2.n2 = this.normals[iNext - numVerts];
|
||||
newViewerFace2.n3 = this.normals[iNext];
|
||||
newViewerFace2.n1 = this.normals[newFace2.n1];
|
||||
newViewerFace2.n2 = this.normals[newFace2.n2];
|
||||
newViewerFace2.n3 = this.normals[newFace2.n3];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1982,14 +2016,13 @@ namespace PrimMesher
|
||||
|
||||
lastCutNormal1 = newLayer.cutNormal1;
|
||||
lastCutNormal2 = newLayer.cutNormal2;
|
||||
lastV = 1.0f - node.percentOfPath;
|
||||
lastV = thisV;
|
||||
|
||||
if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode)
|
||||
{
|
||||
// add the top faces to the viewerFaces list here
|
||||
Coord faceNormal = newLayer.faceNormal;
|
||||
ViewerFace newViewerFace = new ViewerFace();
|
||||
newViewerFace.primFaceNumber = 0;
|
||||
ViewerFace newViewerFace = new ViewerFace(0);
|
||||
int numFaces = newLayer.faces.Count;
|
||||
List<Face> faces = newLayer.faces;
|
||||
|
||||
@@ -2012,6 +2045,13 @@ namespace PrimMesher
|
||||
newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
|
||||
newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
|
||||
|
||||
if (pathType == PathType.Linear)
|
||||
{
|
||||
newViewerFace.uv1.Flip();
|
||||
newViewerFace.uv2.Flip();
|
||||
newViewerFace.uv3.Flip();
|
||||
}
|
||||
|
||||
this.viewerFaces.Add(newViewerFace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1270,7 +1270,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
public override void UnSubscribeEvents()
|
||||
{
|
||||
CollisionEventsThisFrame.Clear();
|
||||
_parent_scene.RemoveCollisionEventReporting(this);
|
||||
|
||||
// Don't clear collision event reporting here. This is called directly from scene code and so can lead
|
||||
// to a race condition with the simulate loop
|
||||
|
||||
@@ -387,12 +387,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
/// <summary>
|
||||
/// A dictionary of actors that should receive collision events.
|
||||
/// </summary>
|
||||
private readonly Dictionary<uint, PhysicsActor> _collisionEventPrim = new Dictionary<uint, PhysicsActor>();
|
||||
private readonly Dictionary<uint, PhysicsActor> m_collisionEventActors = new Dictionary<uint, PhysicsActor>();
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of collision event changes that are waiting to be processed.
|
||||
/// </summary>
|
||||
private readonly Dictionary<uint, PhysicsActor> _collisionEventPrimChanges = new Dictionary<uint, PhysicsActor>();
|
||||
private readonly Dictionary<uint, PhysicsActor> m_collisionEventActorsChanges = new Dictionary<uint, PhysicsActor>();
|
||||
|
||||
/// <summary>
|
||||
/// Maps a unique geometry id (a memory location) to a physics actor name.
|
||||
@@ -1908,8 +1908,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
// m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID);
|
||||
|
||||
lock (_collisionEventPrimChanges)
|
||||
_collisionEventPrimChanges[obj.LocalID] = obj;
|
||||
lock (m_collisionEventActorsChanges)
|
||||
m_collisionEventActorsChanges[obj.LocalID] = obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1920,8 +1920,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
// m_log.DebugFormat("[PHYSICS]: Removing {0} {1} from collision event reporting", obj.SOPName, obj.LocalID);
|
||||
|
||||
lock (_collisionEventPrimChanges)
|
||||
_collisionEventPrimChanges[obj.LocalID] = null;
|
||||
lock (m_collisionEventActorsChanges)
|
||||
m_collisionEventActorsChanges[obj.LocalID] = null;
|
||||
}
|
||||
|
||||
#region Add/Remove Entities
|
||||
@@ -2930,17 +2930,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
// We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential
|
||||
// deadlock if the collision event tries to lock something else later on which is already locked by a
|
||||
// caller that is adding or removing the collision event.
|
||||
lock (_collisionEventPrimChanges)
|
||||
lock (m_collisionEventActorsChanges)
|
||||
{
|
||||
foreach (KeyValuePair<uint, PhysicsActor> kvp in _collisionEventPrimChanges)
|
||||
foreach (KeyValuePair<uint, PhysicsActor> kvp in m_collisionEventActorsChanges)
|
||||
{
|
||||
if (kvp.Value == null)
|
||||
_collisionEventPrim.Remove(kvp.Key);
|
||||
m_collisionEventActors.Remove(kvp.Key);
|
||||
else
|
||||
_collisionEventPrim[kvp.Key] = kvp.Value;
|
||||
m_collisionEventActors[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
_collisionEventPrimChanges.Clear();
|
||||
m_collisionEventActorsChanges.Clear();
|
||||
}
|
||||
|
||||
if (SupportsNINJAJoints)
|
||||
@@ -3092,7 +3092,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
tempTick = tempTick2;
|
||||
}
|
||||
|
||||
foreach (PhysicsActor obj in _collisionEventPrim.Values)
|
||||
foreach (PhysicsActor obj in m_collisionEventActors.Values)
|
||||
{
|
||||
// m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID);
|
||||
|
||||
@@ -3227,10 +3227,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
|
||||
tickCountFrameRun = Util.EnvironmentTickCount();
|
||||
}
|
||||
|
||||
if (CollectStats)
|
||||
m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick);
|
||||
if (CollectStats)
|
||||
m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick);
|
||||
}
|
||||
|
||||
return fps;
|
||||
}
|
||||
|
||||
@@ -233,17 +233,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
m_Timer[engine].UnSetTimerEvents(localID, itemID);
|
||||
|
||||
// Remove from: HttpRequest
|
||||
IHttpRequestModule iHttpReq =
|
||||
engine.World.RequestModuleInterface<IHttpRequestModule>();
|
||||
iHttpReq.StopHttpRequest(localID, itemID);
|
||||
IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>();
|
||||
if (iHttpReq != null)
|
||||
iHttpReq.StopHttpRequest(localID, itemID);
|
||||
|
||||
IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
|
||||
if (comms != null)
|
||||
comms.DeleteListener(itemID);
|
||||
|
||||
IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
|
||||
xmlrpc.DeleteChannels(itemID);
|
||||
xmlrpc.CancelSRDRequests(itemID);
|
||||
if (xmlrpc != null)
|
||||
{
|
||||
xmlrpc.DeleteChannels(itemID);
|
||||
xmlrpc.CancelSRDRequests(itemID);
|
||||
}
|
||||
|
||||
// Remove Sensors
|
||||
m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
|
||||
@@ -305,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
List<Object> data = new List<Object>();
|
||||
|
||||
Object[] listeners=m_Listener[engine].GetSerializationData(itemID);
|
||||
Object[] listeners = m_Listener[engine].GetSerializationData(itemID);
|
||||
if (listeners.Length > 0)
|
||||
{
|
||||
data.Add("listener");
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if ((item = ScriptByName(name)) != UUID.Zero)
|
||||
if ((item = GetScriptByName(name)) != UUID.Zero)
|
||||
m_ScriptEngine.ResetScript(item);
|
||||
else
|
||||
ShoutError("llResetOtherScript: script "+name+" not found");
|
||||
@@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if ((item = ScriptByName(name)) != UUID.Zero)
|
||||
if ((item = GetScriptByName(name)) != UUID.Zero)
|
||||
{
|
||||
return m_ScriptEngine.GetScriptState(item) ?1:0;
|
||||
}
|
||||
@@ -226,7 +226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
// These functions are supposed to be robust,
|
||||
// so get the state one step at a time.
|
||||
|
||||
if ((item = ScriptByName(name)) != UUID.Zero)
|
||||
if ((item = GetScriptByName(name)) != UUID.Zero)
|
||||
{
|
||||
m_ScriptEngine.SetScriptState(item, run == 0 ? false : true);
|
||||
}
|
||||
@@ -421,15 +421,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return LSL_Vector.Norm(v);
|
||||
}
|
||||
|
||||
public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b)
|
||||
private double VecDist(LSL_Vector a, LSL_Vector b)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
double dx = a.x - b.x;
|
||||
double dy = a.y - b.y;
|
||||
double dz = a.z - b.z;
|
||||
return Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
return VecDist(a, b);
|
||||
}
|
||||
|
||||
//Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
|
||||
|
||||
/// <summary>
|
||||
@@ -1242,6 +1247,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsPhysical()
|
||||
{
|
||||
return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics);
|
||||
}
|
||||
|
||||
public LSL_Integer llGetStatus(int status)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
@@ -1249,11 +1259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
switch (status)
|
||||
{
|
||||
case ScriptBaseClass.STATUS_PHYSICS:
|
||||
if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return IsPhysical() ? 1 : 0;
|
||||
|
||||
case ScriptBaseClass.STATUS_PHANTOM:
|
||||
if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom)
|
||||
@@ -1917,11 +1923,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
SetPos(m_host, pos);
|
||||
SetPos(m_host, pos, true);
|
||||
|
||||
ScriptSleep(200);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to move the entire object so that the root prim is within 0.1m of position. http://wiki.secondlife.com/wiki/LlSetRegionPos
|
||||
/// Documentation indicates that the use of x/y coordinates up to 10 meters outside the bounds of a region will work but do not specify what happens if there is no adjacent region for the object to move into.
|
||||
/// Uses the RegionSize constant here rather than hard-coding 266.0 to alert any developer modifying OpenSim to support variable-sized regions that this method will need tweaking.
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
/// <returns>1 if successful, 0 otherwise.</returns>
|
||||
public LSL_Integer llSetRegionPos(LSL_Vector pos)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
// BEGIN WORKAROUND
|
||||
// IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND.
|
||||
//
|
||||
// This workaround is to prevent silent failure of this function.
|
||||
// According to the specification on the SL Wiki, providing a position outside of the
|
||||
if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// END WORK AROUND
|
||||
else if ( // this is not part of the workaround if-block because it's not related to the workaround.
|
||||
IsPhysical() ||
|
||||
m_host.ParentGroup.IsAttachment || // return FALSE if attachment
|
||||
(
|
||||
pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region.
|
||||
pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region.
|
||||
pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region.
|
||||
pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region.
|
||||
pos.z > 4096 // return FALSE if altitude than 4096m
|
||||
)
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if we reach this point, then the object is not physical, it's not an attachment, and the destination is within the valid range.
|
||||
// this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read.
|
||||
|
||||
Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition;
|
||||
LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y);
|
||||
LandData there = World.GetLandData((float)pos.x, (float)pos.y);
|
||||
|
||||
// we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits.
|
||||
|
||||
bool sameParcel = here.GlobalID == there.GlobalID;
|
||||
|
||||
if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetPos(m_host.ParentGroup.RootPart, pos, false);
|
||||
|
||||
return VecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0;
|
||||
}
|
||||
|
||||
// Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
|
||||
// note linked setpos is capped "differently"
|
||||
private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end)
|
||||
@@ -1953,7 +2016,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return real_vec;
|
||||
}
|
||||
|
||||
protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
|
||||
/// <summary>
|
||||
/// set object position, optionally capping the distance.
|
||||
/// </summary>
|
||||
/// <param name="part"></param>
|
||||
/// <param name="targetPos"></param>
|
||||
/// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
|
||||
protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
|
||||
{
|
||||
// Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
|
||||
LSL_Vector currentPos = GetPartLocalPos(part);
|
||||
@@ -1966,12 +2035,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
|
||||
targetPos.z = ground;
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
|
||||
LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos);
|
||||
parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
|
||||
}
|
||||
else
|
||||
{
|
||||
LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos);
|
||||
LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos);
|
||||
part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
parent.HasGroupChanged = true;
|
||||
@@ -2738,67 +2807,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
Util.FireAndForget(delegate (object x)
|
||||
Util.FireAndForget(x =>
|
||||
{
|
||||
if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
|
||||
return;
|
||||
|
||||
float dist = (float)llVecDist(llGetPos(), pos);
|
||||
|
||||
if (dist > m_ScriptDistanceFactor * 10.0f)
|
||||
return;
|
||||
|
||||
//Clone is thread-safe
|
||||
TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
|
||||
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
|
||||
if (item == null)
|
||||
{
|
||||
if (inv.Value.Name == inventory)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// need the magnitude later
|
||||
// float velmag = (float)Util.GetMagnitude(llvel);
|
||||
|
||||
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;
|
||||
|
||||
// objects rezzed with this method are die_at_edge by default.
|
||||
new_group.RootPart.SetDieAtEdge(true);
|
||||
|
||||
new_group.ResumeScripts();
|
||||
|
||||
m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
|
||||
"object_rez", new Object[] {
|
||||
new LSL_String(
|
||||
new_group.RootPart.UUID.ToString()) },
|
||||
new DetectParams[0]));
|
||||
|
||||
float groupmass = new_group.GetMass();
|
||||
|
||||
PhysicsActor pa = new_group.RootPart.PhysActor;
|
||||
|
||||
if (pa != null && pa.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)
|
||||
return;
|
||||
}
|
||||
llSay(0, "Could not find object " + inventory);
|
||||
return;
|
||||
}
|
||||
|
||||
llSay(0, "Could not find object " + inventory);
|
||||
if (item.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);
|
||||
|
||||
// need the magnitude later
|
||||
// float velmag = (float)Util.GetMagnitude(llvel);
|
||||
|
||||
SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param);
|
||||
|
||||
// If either of these are null, then there was an unknown error.
|
||||
if (new_group == null)
|
||||
return;
|
||||
|
||||
// objects rezzed with this method are die_at_edge by default.
|
||||
new_group.RootPart.SetDieAtEdge(true);
|
||||
|
||||
new_group.ResumeScripts();
|
||||
|
||||
m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
|
||||
"object_rez", new Object[] {
|
||||
new LSL_String(
|
||||
new_group.RootPart.UUID.ToString()) },
|
||||
new DetectParams[0]));
|
||||
|
||||
float groupmass = new_group.GetMass();
|
||||
|
||||
PhysicsActor pa = new_group.RootPart.PhysActor;
|
||||
|
||||
if (pa != null && pa.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));
|
||||
@@ -2990,15 +3055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
private void DetachWrapper(object o)
|
||||
{
|
||||
SceneObjectPart host = (SceneObjectPart)o;
|
||||
|
||||
SceneObjectGroup grp = host.ParentGroup;
|
||||
UUID itemID = grp.FromItemID;
|
||||
ScenePresence presence = World.GetScenePresence(host.OwnerID);
|
||||
|
||||
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
|
||||
if (attachmentsModule != null)
|
||||
attachmentsModule.DetachSingleAttachmentToInv(presence, itemID);
|
||||
if (World.AttachmentsModule != null)
|
||||
{
|
||||
SceneObjectPart host = (SceneObjectPart)o;
|
||||
ScenePresence presence = World.GetScenePresence(host.OwnerID);
|
||||
World.AttachmentsModule.DetachSingleAttachmentToInv(presence, host.ParentGroup);
|
||||
}
|
||||
}
|
||||
|
||||
public void llAttachToAvatar(int attachmentPoint)
|
||||
@@ -3863,11 +3925,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
public void llGiveInventory(string destination, string inventory)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
bool found = false;
|
||||
|
||||
UUID destId = UUID.Zero;
|
||||
UUID objId = UUID.Zero;
|
||||
int assetType = 0;
|
||||
string objName = String.Empty;
|
||||
|
||||
if (!UUID.TryParse(destination, out destId))
|
||||
{
|
||||
@@ -3875,28 +3934,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return;
|
||||
}
|
||||
|
||||
// move the first object found with this inventory name
|
||||
lock (m_host.TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
if (inv.Value.Name == inventory)
|
||||
{
|
||||
found = true;
|
||||
objId = inv.Key;
|
||||
assetType = inv.Value.Type;
|
||||
objName = inv.Value.Name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
|
||||
|
||||
if (!found)
|
||||
if (item == null)
|
||||
{
|
||||
llSay(0, String.Format("Could not find object '{0}'", inventory));
|
||||
throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
|
||||
}
|
||||
|
||||
UUID objId = item.ItemID;
|
||||
|
||||
// check if destination is an object
|
||||
if (World.GetSceneObjectPart(destId) != null)
|
||||
{
|
||||
@@ -3926,22 +3973,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (agentItem == null)
|
||||
return;
|
||||
|
||||
byte[] bucket = new byte[17];
|
||||
bucket[0] = (byte)assetType;
|
||||
byte[] objBytes = agentItem.ID.GetBytes();
|
||||
Array.Copy(objBytes, 0, bucket, 1, 16);
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage(World,
|
||||
m_host.UUID, m_host.Name+", an object owned by "+
|
||||
resolveName(m_host.OwnerID)+",", destId,
|
||||
(byte)InstantMessageDialog.TaskInventoryOffered,
|
||||
false, objName+"\n"+m_host.Name+" is located at "+
|
||||
World.RegionInfo.RegionName+" "+
|
||||
m_host.AbsolutePosition.ToString(),
|
||||
agentItem.ID, true, m_host.AbsolutePosition,
|
||||
bucket);
|
||||
if (m_TransferModule != null)
|
||||
{
|
||||
byte[] bucket = new byte[] { (byte)item.Type };
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage(World,
|
||||
m_host.UUID, m_host.Name + ", an object owned by " +
|
||||
resolveName(m_host.OwnerID) + ",", destId,
|
||||
(byte)InstantMessageDialog.TaskInventoryOffered,
|
||||
false, item.Name + "\n" + m_host.Name + " is located at " +
|
||||
World.RegionInfo.RegionName+" "+
|
||||
m_host.AbsolutePosition.ToString(),
|
||||
agentItem.ID, true, m_host.AbsolutePosition,
|
||||
bucket);
|
||||
|
||||
m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
|
||||
}
|
||||
|
||||
ScriptSleep(3000);
|
||||
}
|
||||
}
|
||||
@@ -3950,20 +3998,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
lock (m_host.TaskInventory)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
|
||||
{
|
||||
if (item.Name == name)
|
||||
{
|
||||
if (item.ItemID == m_item.ItemID)
|
||||
throw new ScriptDeleteException();
|
||||
else
|
||||
m_host.Inventory.RemoveInventoryItem(item.ItemID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
|
||||
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
if (item.ItemID == m_item.ItemID)
|
||||
throw new ScriptDeleteException();
|
||||
else
|
||||
m_host.Inventory.RemoveInventoryItem(item.ItemID);
|
||||
}
|
||||
|
||||
public void llSetText(string text, LSL_Vector color, double alpha)
|
||||
@@ -4105,9 +4148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
|
||||
|
||||
foreach (TaskInventoryItem item in itemDictionary.Values)
|
||||
foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems())
|
||||
{
|
||||
if (item.Type == 3 && item.Name == name)
|
||||
{
|
||||
@@ -4139,6 +4180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return tid.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptSleep(1000);
|
||||
return String.Empty;
|
||||
}
|
||||
@@ -4311,18 +4353,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
UUID soundId = UUID.Zero;
|
||||
if (!UUID.TryParse(impact_sound, out soundId))
|
||||
{
|
||||
lock (m_host.TaskInventory)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
|
||||
{
|
||||
if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
|
||||
{
|
||||
soundId = item.AssetID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(impact_sound);
|
||||
|
||||
if (item != null && item.Type == (int)AssetType.Sound)
|
||||
soundId = item.AssetID;
|
||||
}
|
||||
|
||||
m_host.CollisionSound = soundId;
|
||||
m_host.CollisionSoundVolume = (float)impact_volume;
|
||||
}
|
||||
@@ -4361,9 +4397,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
UUID partItemID;
|
||||
foreach (SceneObjectPart part in parts)
|
||||
{
|
||||
TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
|
||||
|
||||
foreach (TaskInventoryItem item in itemsDictionary.Values)
|
||||
foreach (TaskInventoryItem item in part.Inventory.GetInventoryItems())
|
||||
{
|
||||
if (item.Type == ScriptBaseClass.INVENTORY_SCRIPT)
|
||||
{
|
||||
@@ -4733,22 +4767,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
lock (m_host.TaskInventory)
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
|
||||
|
||||
if (item == null)
|
||||
return UUID.Zero.ToString();
|
||||
|
||||
if ((item.CurrentPermissions
|
||||
& (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
|
||||
== (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
if (inv.Value.Name == name)
|
||||
{
|
||||
if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
|
||||
{
|
||||
return inv.Value.AssetID.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return UUID.Zero.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return item.AssetID.ToString();
|
||||
}
|
||||
|
||||
return UUID.Zero.ToString();
|
||||
@@ -6332,20 +6360,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
}
|
||||
}
|
||||
|
||||
protected UUID GetTaskInventoryItem(string name)
|
||||
{
|
||||
lock (m_host.TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
if (inv.Value.Name == name)
|
||||
return inv.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
public void llGiveInventoryList(string destination, string category, LSL_List inventory)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
@@ -6358,16 +6372,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
foreach (Object item in inventory.Data)
|
||||
{
|
||||
string rawItemString = item.ToString();
|
||||
|
||||
UUID itemID;
|
||||
if (UUID.TryParse(item.ToString(), out itemID))
|
||||
if (UUID.TryParse(rawItemString, out itemID))
|
||||
{
|
||||
itemList.Add(itemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemID = GetTaskInventoryItem(item.ToString());
|
||||
if (itemID != UUID.Zero)
|
||||
itemList.Add(itemID);
|
||||
TaskInventoryItem taskItem = m_host.Inventory.GetInventoryItem(rawItemString);
|
||||
|
||||
if (taskItem != null)
|
||||
itemList.Add(taskItem.ItemID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6379,23 +6396,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (folderID == UUID.Zero)
|
||||
return;
|
||||
|
||||
byte[] bucket = new byte[17];
|
||||
bucket[0] = (byte)AssetType.Folder;
|
||||
byte[] objBytes = folderID.GetBytes();
|
||||
Array.Copy(objBytes, 0, bucket, 1, 16);
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage(World,
|
||||
m_host.UUID, m_host.Name+", an object owned by "+
|
||||
resolveName(m_host.OwnerID)+",", destID,
|
||||
(byte)InstantMessageDialog.InventoryOffered,
|
||||
false, category+"\n"+m_host.Name+" is located at "+
|
||||
World.RegionInfo.RegionName+" "+
|
||||
m_host.AbsolutePosition.ToString(),
|
||||
folderID, true, m_host.AbsolutePosition,
|
||||
bucket);
|
||||
|
||||
if (m_TransferModule != null)
|
||||
{
|
||||
byte[] bucket = new byte[] { (byte)AssetType.Folder };
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage(World,
|
||||
m_host.UUID, m_host.Name + ", an object owned by " +
|
||||
resolveName(m_host.OwnerID) + ",", destID,
|
||||
(byte)InstantMessageDialog.TaskInventoryOffered,
|
||||
false, category + "\n" + m_host.Name + " is located at " +
|
||||
World.RegionInfo.RegionName + " " +
|
||||
m_host.AbsolutePosition.ToString(),
|
||||
folderID, true, m_host.AbsolutePosition,
|
||||
bucket);
|
||||
|
||||
m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
|
||||
}
|
||||
}
|
||||
|
||||
public void llSetVehicleType(int type)
|
||||
@@ -6691,9 +6707,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
bool found = false;
|
||||
|
||||
UUID destId = UUID.Zero;
|
||||
UUID srcId = UUID.Zero;
|
||||
|
||||
if (!UUID.TryParse(target, out destId))
|
||||
{
|
||||
@@ -6708,31 +6723,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
}
|
||||
|
||||
// copy the first script found with this inventory name
|
||||
lock (m_host.TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
if (inv.Value.Name == name)
|
||||
{
|
||||
// make sure the object is a script
|
||||
if (10 == inv.Value.Type)
|
||||
{
|
||||
found = true;
|
||||
srcId = inv.Key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
|
||||
|
||||
if (!found)
|
||||
// make sure the object is a script
|
||||
if (item == null || item.Type != 10)
|
||||
{
|
||||
llSay(0, "Could not find script " + name);
|
||||
return;
|
||||
}
|
||||
|
||||
// the rest of the permission checks are done in RezScript, so check the pin there as well
|
||||
World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
|
||||
World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
|
||||
|
||||
// this will cause the delay even if the script pin or permissions were wrong - seems ok
|
||||
ScriptSleep(3000);
|
||||
@@ -9094,92 +9095,81 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
}
|
||||
}
|
||||
|
||||
public LSL_Integer llGetInventoryPermMask(string item, int mask)
|
||||
public LSL_Integer llGetInventoryPermMask(string itemName, int mask)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
lock (m_host.TaskInventory)
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
|
||||
|
||||
if (item == null)
|
||||
return -1;
|
||||
|
||||
switch (mask)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
if (inv.Value.Name == item)
|
||||
{
|
||||
switch (mask)
|
||||
{
|
||||
case 0:
|
||||
return (int)inv.Value.BasePermissions;
|
||||
case 1:
|
||||
return (int)inv.Value.CurrentPermissions;
|
||||
case 2:
|
||||
return (int)inv.Value.GroupPermissions;
|
||||
case 3:
|
||||
return (int)inv.Value.EveryonePermissions;
|
||||
case 4:
|
||||
return (int)inv.Value.NextPermissions;
|
||||
}
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
return (int)item.BasePermissions;
|
||||
case 1:
|
||||
return (int)item.CurrentPermissions;
|
||||
case 2:
|
||||
return (int)item.GroupPermissions;
|
||||
case 3:
|
||||
return (int)item.EveryonePermissions;
|
||||
case 4:
|
||||
return (int)item.NextPermissions;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void llSetInventoryPermMask(string item, int mask, int value)
|
||||
public void llSetInventoryPermMask(string itemName, int mask, int value)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
|
||||
{
|
||||
if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
|
||||
{
|
||||
lock (m_host.TaskInventory)
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
switch (mask)
|
||||
{
|
||||
if (inv.Value.Name == item)
|
||||
{
|
||||
switch (mask)
|
||||
{
|
||||
case 0:
|
||||
inv.Value.BasePermissions = (uint)value;
|
||||
break;
|
||||
case 1:
|
||||
inv.Value.CurrentPermissions = (uint)value;
|
||||
break;
|
||||
case 2:
|
||||
inv.Value.GroupPermissions = (uint)value;
|
||||
break;
|
||||
case 3:
|
||||
inv.Value.EveryonePermissions = (uint)value;
|
||||
break;
|
||||
case 4:
|
||||
inv.Value.NextPermissions = (uint)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
item.BasePermissions = (uint)value;
|
||||
break;
|
||||
case 1:
|
||||
item.CurrentPermissions = (uint)value;
|
||||
break;
|
||||
case 2:
|
||||
item.GroupPermissions = (uint)value;
|
||||
break;
|
||||
case 3:
|
||||
item.EveryonePermissions = (uint)value;
|
||||
break;
|
||||
case 4:
|
||||
item.NextPermissions = (uint)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public LSL_String llGetInventoryCreator(string item)
|
||||
public LSL_String llGetInventoryCreator(string itemName)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
lock (m_host.TaskInventory)
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
if (inv.Value.Name == item)
|
||||
{
|
||||
return inv.Value.CreatorID.ToString();
|
||||
}
|
||||
}
|
||||
llSay(0, "No item name '" + item + "'");
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
llSay(0, "No item name '" + item + "'");
|
||||
|
||||
return String.Empty;
|
||||
return item.CreatorID.ToString();
|
||||
}
|
||||
|
||||
public void llOwnerSay(string msg)
|
||||
@@ -9729,18 +9719,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
lock (m_host.TaskInventory)
|
||||
{
|
||||
foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
|
||||
{
|
||||
if (inv.Value.Name == name)
|
||||
{
|
||||
return inv.Value.Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
|
||||
|
||||
return -1;
|
||||
if (item == null)
|
||||
return -1;
|
||||
|
||||
return item.Type;
|
||||
}
|
||||
|
||||
public void llSetPayPrice(int price, LSL_List quick_pay_buttons)
|
||||
@@ -10534,18 +10518,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return new LSL_List();
|
||||
}
|
||||
|
||||
internal UUID ScriptByName(string name)
|
||||
internal UUID GetScriptByName(string name)
|
||||
{
|
||||
lock (m_host.TaskInventory)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
|
||||
{
|
||||
if (item.Type == 10 && item.Name == name)
|
||||
return item.ItemID;
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
|
||||
|
||||
return UUID.Zero;
|
||||
if (item == null || item.Type != 10)
|
||||
return UUID.Zero;
|
||||
|
||||
return item.ItemID;
|
||||
}
|
||||
|
||||
internal void ShoutError(string msg)
|
||||
@@ -10585,20 +10565,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
|
||||
|
||||
UUID assetID = UUID.Zero;
|
||||
|
||||
if (!UUID.TryParse(name, out assetID))
|
||||
{
|
||||
foreach (TaskInventoryItem item in itemsDictionary.Values)
|
||||
{
|
||||
if (item.Type == 7 && item.Name == name)
|
||||
{
|
||||
assetID = item.AssetID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
|
||||
|
||||
if (item != null && item.Type == 7)
|
||||
assetID = item.AssetID;
|
||||
}
|
||||
|
||||
if (assetID == UUID.Zero)
|
||||
@@ -10629,9 +10603,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return;
|
||||
}
|
||||
|
||||
System.Text.UTF8Encoding enc =
|
||||
new System.Text.UTF8Encoding();
|
||||
string data = enc.GetString(a.Data);
|
||||
string data = Encoding.UTF8.GetString(a.Data);
|
||||
//m_log.Debug(data);
|
||||
NotecardCache.Cache(id, data);
|
||||
AsyncCommands.
|
||||
@@ -10647,20 +10619,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
|
||||
|
||||
UUID assetID = UUID.Zero;
|
||||
|
||||
if (!UUID.TryParse(name, out assetID))
|
||||
{
|
||||
foreach (TaskInventoryItem item in itemsDictionary.Values)
|
||||
{
|
||||
if (item.Type == 7 && item.Name == name)
|
||||
{
|
||||
assetID = item.AssetID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
|
||||
|
||||
if (item != null && item.Type == 7)
|
||||
assetID = item.AssetID;
|
||||
}
|
||||
|
||||
if (assetID == UUID.Zero)
|
||||
@@ -10690,9 +10656,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return;
|
||||
}
|
||||
|
||||
System.Text.UTF8Encoding enc =
|
||||
new System.Text.UTF8Encoding();
|
||||
string data = enc.GetString(a.Data);
|
||||
string data = Encoding.UTF8.GetString(a.Data);
|
||||
//m_log.Debug(data);
|
||||
NotecardCache.Cache(id, data);
|
||||
AsyncCommands.DataserverPlugin.DataserverReply(id.ToString(),
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
[Serializable]
|
||||
public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public const string GridInfoServiceConfigSectionName = "GridInfoService";
|
||||
|
||||
@@ -874,13 +874,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (World.Entities.ContainsKey((UUID)agent) && World.Entities[avatarID] is ScenePresence)
|
||||
{
|
||||
ScenePresence target = (ScenePresence)World.Entities[avatarID];
|
||||
EndPoint ep = target.ControllingClient.GetClientEP();
|
||||
if (ep is IPEndPoint)
|
||||
{
|
||||
IPEndPoint ip = (IPEndPoint)ep;
|
||||
return ip.Address.ToString();
|
||||
}
|
||||
return target.ControllingClient.RemoteEndPoint.Address.ToString();
|
||||
}
|
||||
|
||||
// fall through case, just return nothing
|
||||
return "";
|
||||
}
|
||||
@@ -1668,9 +1664,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
CheckThreatLevel(ThreatLevel.Low, "osMessageObject");
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
UUID objUUID;
|
||||
if (!UUID.TryParse(objectUUID, out objUUID)) // prior to patching, a thrown exception regarding invalid GUID format would be shouted instead.
|
||||
{
|
||||
OSSLShoutError("osMessageObject() cannot send messages to objects with invalid UUIDs");
|
||||
return;
|
||||
}
|
||||
|
||||
object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) };
|
||||
|
||||
SceneObjectPart sceneOP = World.GetSceneObjectPart(new UUID(objectUUID));
|
||||
SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID);
|
||||
|
||||
if (sceneOP == null) // prior to patching, PostObjectEvent() would cause a throw exception to be shouted instead.
|
||||
{
|
||||
OSSLShoutError("osMessageObject() cannot send message to " + objUUID.ToString() + ", object was not found in scene.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_ScriptEngine.PostObjectEvent(
|
||||
sceneOP.LocalId, new EventParams(
|
||||
@@ -1811,8 +1820,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (a == null)
|
||||
return UUID.Zero;
|
||||
|
||||
System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
|
||||
string data = enc.GetString(a.Data);
|
||||
string data = Encoding.UTF8.GetString(a.Data);
|
||||
NotecardCache.Cache(assetID, data);
|
||||
};
|
||||
|
||||
@@ -2125,7 +2133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
public LSL_String osFormatString(string str, LSL_List strings)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.Low, "osFormatString");
|
||||
CheckThreatLevel(ThreatLevel.VeryLow, "osFormatString");
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
return String.Format(str, strings.Data);
|
||||
@@ -2133,7 +2141,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
public LSL_List osMatchString(string src, string pattern, int start)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High, "osMatchString");
|
||||
CheckThreatLevel(ThreatLevel.VeryLow, "osMatchString");
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
LSL_List result = new LSL_List();
|
||||
@@ -2175,7 +2183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
public LSL_String osReplaceString(string src, string pattern, string replace, int count, int start)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High, "osReplaceString");
|
||||
CheckThreatLevel(ThreatLevel.VeryLow, "osReplaceString");
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
// Normalize indices (if negative).
|
||||
@@ -2677,6 +2685,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
}
|
||||
}
|
||||
|
||||
public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High, "osNpcTouch");
|
||||
m_host.AddScriptLPS(1);
|
||||
INPCModule module = World.RequestModuleInterface<INPCModule>();
|
||||
int linkNum = link_num.value;
|
||||
if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
|
||||
{
|
||||
UUID npcId;
|
||||
if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID))
|
||||
return;
|
||||
SceneObjectPart part = null;
|
||||
UUID objectId;
|
||||
if (UUID.TryParse(LSL_String.ToString(object_key), out objectId))
|
||||
part = World.GetSceneObjectPart(objectId);
|
||||
if (part == null)
|
||||
return;
|
||||
if (linkNum != ScriptBaseClass.LINK_THIS)
|
||||
{
|
||||
if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT)
|
||||
{ // 0 and 1 are treated as root, find the root if the current part isnt it
|
||||
if (!part.IsRoot)
|
||||
part = part.ParentGroup.RootPart;
|
||||
}
|
||||
else
|
||||
{ // Find the prim with the given link number if not found then fail silently
|
||||
part = part.ParentGroup.GetLinkNumPart(linkNum);
|
||||
if (part == null)
|
||||
return;
|
||||
}
|
||||
}
|
||||
module.Touch(npcId, part.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the current appearance of the script owner permanently to the named notecard.
|
||||
/// </summary>
|
||||
@@ -3151,6 +3194,77 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint);
|
||||
}
|
||||
|
||||
public void osForceAttachToAvatarFromInventory(string itemName, int attachmentPoint)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory");
|
||||
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint);
|
||||
}
|
||||
|
||||
public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.Severe, "osForceAttachToOtherAvatarFromInventory");
|
||||
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
UUID avatarId;
|
||||
|
||||
if (!UUID.TryParse(rawAvatarId, out avatarId))
|
||||
return;
|
||||
|
||||
ForceAttachToAvatarFromInventory(avatarId, itemName, attachmentPoint);
|
||||
}
|
||||
|
||||
public void ForceAttachToAvatarFromInventory(UUID avatarId, string itemName, int attachmentPoint)
|
||||
{
|
||||
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
|
||||
|
||||
if (attachmentsModule == null)
|
||||
return;
|
||||
|
||||
InitLSL();
|
||||
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
((LSL_Api)m_LSL_Api).llSay(0, string.Format("Could not find object '{0}'", itemName));
|
||||
throw new Exception(String.Format("The inventory item '{0}' could not be found", itemName));
|
||||
}
|
||||
|
||||
if (item.InvType != (int)InventoryType.Object)
|
||||
{
|
||||
// FIXME: Temporary null check for regression tests since they dont' have the infrastructure to set
|
||||
// up the api reference.
|
||||
if (m_LSL_Api != null)
|
||||
((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName));
|
||||
|
||||
throw new Exception(String.Format("The inventory item '{0}' is not an object", itemName));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ScenePresence sp = World.GetScenePresence(avatarId);
|
||||
|
||||
if (sp == null)
|
||||
return;
|
||||
|
||||
InventoryItemBase newItem = World.MoveTaskInventoryItem(sp.UUID, UUID.Zero, m_host, item.ItemID);
|
||||
|
||||
if (newItem == null)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[OSSL API]: Could not create user inventory item {0} for {1}, attach point {2} in {3}",
|
||||
itemName, m_host.Name, attachmentPoint, World.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
attachmentsModule.RezSingleAttachmentFromInventory(sp, newItem.ID, (uint)attachmentPoint);
|
||||
}
|
||||
|
||||
public void osForceDetachFromAvatar()
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar");
|
||||
|
||||
@@ -88,13 +88,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
|
||||
public Object[] GetSerializationData(UUID itemID)
|
||||
{
|
||||
return m_commsPlugin.GetSerializationData(itemID);
|
||||
if (m_commsPlugin != null)
|
||||
return m_commsPlugin.GetSerializationData(itemID);
|
||||
else
|
||||
return new Object[]{};
|
||||
}
|
||||
|
||||
public void CreateFromData(uint localID, UUID itemID, UUID hostID,
|
||||
Object[] data)
|
||||
{
|
||||
m_commsPlugin.CreateFromData(localID, itemID, hostID, data);
|
||||
if (m_commsPlugin != null)
|
||||
m_commsPlugin.CreateFromData(localID, itemID, hostID, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -359,6 +359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
void llSetPrimitiveParams(LSL_List rules);
|
||||
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
|
||||
void llSetPrimURL(string url);
|
||||
LSL_Integer llSetRegionPos(LSL_Vector pos);
|
||||
void llSetRemoteScriptAccessPin(int pin);
|
||||
void llSetRot(LSL_Rotation rot);
|
||||
void llSetScale(LSL_Vector scale);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user