Compare commits
300 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df031fe8be | ||
|
|
dce98acb69 | ||
|
|
075f718f3f | ||
|
|
9cdd38d0cf | ||
|
|
fc878a33ed | ||
|
|
af0a851eba | ||
|
|
9934e2c545 | ||
|
|
746defa094 | ||
|
|
52370ac94d | ||
|
|
87d5da86a1 | ||
|
|
a13022c296 | ||
|
|
44e0a2f906 | ||
|
|
5c13980eb7 | ||
|
|
a4209d2df4 | ||
|
|
c5cd93db81 | ||
|
|
d20aeefef2 | ||
|
|
10d09e287c | ||
|
|
679eaec22f | ||
|
|
a142edec03 | ||
|
|
c73e62ea3a | ||
|
|
1d33a40f59 | ||
|
|
a5eabdade3 | ||
|
|
c8f5add2fc | ||
|
|
bb5e2e1f02 | ||
|
|
13e2af7525 | ||
|
|
968b588bb9 | ||
|
|
51eb8facd6 | ||
|
|
4c5fbf8b0a | ||
|
|
12daa3c3d9 | ||
|
|
f0fd2fa325 | ||
|
|
e144958e03 | ||
|
|
b9b483151f | ||
|
|
7d30bb13be | ||
|
|
8d72145112 | ||
|
|
7bababaab6 | ||
|
|
23561239ee | ||
|
|
cfc4055991 | ||
|
|
5b6fb7245a | ||
|
|
d3ed5de77d | ||
|
|
9fb3065d33 | ||
|
|
859b1c5ba4 | ||
|
|
c5a0f0ba36 | ||
|
|
41cc73233c | ||
|
|
12108bf6e9 | ||
|
|
7813780eba | ||
|
|
0997ce8629 | ||
|
|
5bc389ff71 | ||
|
|
8d3cb424a8 | ||
|
|
27512f3b42 | ||
|
|
cfaf904a3b | ||
|
|
c155656349 | ||
|
|
3247a7cb3e | ||
|
|
7a2c77e7ea | ||
|
|
bdebd525db | ||
|
|
67e56872f3 | ||
|
|
b9f870fa73 | ||
|
|
d3b43a96fb | ||
|
|
6a8353af36 | ||
|
|
1a02e5d2db | ||
|
|
32293cfd6b | ||
|
|
5aa8ba1b45 | ||
|
|
89cb07eb49 | ||
|
|
5e34727b7e | ||
|
|
4123b0fdbd | ||
|
|
f1fc557715 | ||
|
|
ac051ef4ab | ||
|
|
f084320976 | ||
|
|
a05be7bd65 | ||
|
|
23fb4f2221 | ||
|
|
26606190e5 | ||
|
|
466657375a | ||
|
|
ff62b90636 | ||
|
|
b463870914 | ||
|
|
c995b07818 | ||
|
|
94250b6836 | ||
|
|
c8664e8907 | ||
|
|
b7550c947b | ||
|
|
04612f41a7 | ||
|
|
8a93d97320 | ||
|
|
b45c929d66 | ||
|
|
5c9ef4d083 | ||
|
|
231cdc2dc1 | ||
|
|
1812cecdb7 | ||
|
|
a6f8f9d003 | ||
|
|
300e78bfd5 | ||
|
|
7af878a4f4 | ||
|
|
00b23e51ae | ||
|
|
5acbbcb33f | ||
|
|
79a4d1ea8d | ||
|
|
5db3f08871 | ||
|
|
c7a11899f6 | ||
|
|
29a05cdeb5 | ||
|
|
458ccd26ff | ||
|
|
8d4c1945c2 | ||
|
|
cbd428cff3 | ||
|
|
c496bd57b4 | ||
|
|
43520b3e8b | ||
|
|
05508b5c56 | ||
|
|
2a9528fa22 | ||
|
|
57e75d7c03 | ||
|
|
afa85e6b3c | ||
|
|
1a24b7fa93 | ||
|
|
4e28a06f3c | ||
|
|
763c22b28e | ||
|
|
f0218258d1 | ||
|
|
530b0cbbf1 | ||
|
|
31c8b7fd1a | ||
|
|
36a1f1c70c | ||
|
|
23a0946e36 | ||
|
|
9fcee73326 | ||
|
|
d3578e2662 | ||
|
|
7852bae78f | ||
|
|
6ac12a42ec | ||
|
|
c015cb3134 | ||
|
|
bde60cc92e | ||
|
|
1e22091193 | ||
|
|
5bc3bbbcf3 | ||
|
|
08675d44a7 | ||
|
|
3bde737f76 | ||
|
|
c73b02d583 | ||
|
|
8d177296ad | ||
|
|
c4cd98bc34 | ||
|
|
94619cba58 | ||
|
|
2ed3a918bd | ||
|
|
519c753e46 | ||
|
|
96a2449122 | ||
|
|
1f40630a9a | ||
|
|
427240f935 | ||
|
|
376fab1402 | ||
|
|
af286d5fcb | ||
|
|
2d3072f053 | ||
|
|
3f35c5a421 | ||
|
|
70953dbfcd | ||
|
|
a3bd708e77 | ||
|
|
b4ce71df1e | ||
|
|
e271607bef | ||
|
|
e5b269e9a0 | ||
|
|
41f2f3132b | ||
|
|
e4d16e6795 | ||
|
|
47ac103df7 | ||
|
|
73e20b7f5f | ||
|
|
0692ebfbc6 | ||
|
|
4b04d22899 | ||
|
|
6e6512eb4a | ||
|
|
29400538b7 | ||
|
|
b08ab1e375 | ||
|
|
e19d1ecce8 | ||
|
|
40c579addf | ||
|
|
3e5bc75f89 | ||
|
|
e8ca900ef8 | ||
|
|
ac866a1c46 | ||
|
|
d582db6132 | ||
|
|
3d65d22138 | ||
|
|
473c559478 | ||
|
|
bb7c88805a | ||
|
|
4d8bc007e2 | ||
|
|
0cc3cdfb4e | ||
|
|
a02dae566c | ||
|
|
099212167b | ||
|
|
1b75ec5647 | ||
|
|
3555c0c3f3 | ||
|
|
305c3e668a | ||
|
|
1a3ffda852 | ||
|
|
f132f642b2 | ||
|
|
b1ff78f4d8 | ||
|
|
bafa82eb12 | ||
|
|
42bb122232 | ||
|
|
64f640f901 | ||
|
|
b3e423303f | ||
|
|
aeadddf77a | ||
|
|
fabab7414f | ||
|
|
0cb805a64c | ||
|
|
709038aa2a | ||
|
|
d899bdcb9b | ||
|
|
f129b824c3 | ||
|
|
7ba3b88fb6 | ||
|
|
28ef6f83fc | ||
|
|
674be72225 | ||
|
|
4e03d352c3 | ||
|
|
298376d5c7 | ||
|
|
ce74418c20 | ||
|
|
88b2fc61ff | ||
|
|
84cea46c10 | ||
|
|
b375f86f11 | ||
|
|
64cf75866e | ||
|
|
321816b32c | ||
|
|
3a643e2456 | ||
|
|
1d2933ca51 | ||
|
|
e0c6bfa81e | ||
|
|
91e1aaa5d4 | ||
|
|
626536b8cc | ||
|
|
4c781db572 | ||
|
|
6ea82ad48a | ||
|
|
dabb8e62f4 | ||
|
|
bc0895c758 | ||
|
|
0d2a25b477 | ||
|
|
0db6f3a2bd | ||
|
|
21176a3a90 | ||
|
|
f1f935ed95 | ||
|
|
f1cec684e2 | ||
|
|
fbdf507e98 | ||
|
|
37921c66e5 | ||
|
|
8738445eb7 | ||
|
|
30f1b424bb | ||
|
|
36f01dce2d | ||
|
|
91f3be71e3 | ||
|
|
a483525016 | ||
|
|
2924d250ab | ||
|
|
10a8d2852e | ||
|
|
e36e416637 | ||
|
|
78ccadb27e | ||
|
|
961cb9cc77 | ||
|
|
dc2471fedd | ||
|
|
0e71e3889c | ||
|
|
fcc665a567 | ||
|
|
e57e9e95d4 | ||
|
|
d6890d78ad | ||
|
|
de3421b408 | ||
|
|
7cec4997db | ||
|
|
dfd0c2a54a | ||
|
|
6ab463a446 | ||
|
|
cac910d401 | ||
|
|
50ed97aa1a | ||
|
|
6c4eed5539 | ||
|
|
3ec695e05b | ||
|
|
e0d8f42e6b | ||
|
|
a4107cb6c7 | ||
|
|
fcf5fb5dfd | ||
|
|
0f87a99e54 | ||
|
|
5cd21516a4 | ||
|
|
f54fccba1e | ||
|
|
3654ae8d8c | ||
|
|
df816b38ac | ||
|
|
f6f7585ec5 | ||
|
|
9c804466e5 | ||
|
|
327632dc66 | ||
|
|
56a623ac0c | ||
|
|
1e3027afb1 | ||
|
|
c0c92a95bf | ||
|
|
8c5c9806d7 | ||
|
|
46781253c3 | ||
|
|
e85291329b | ||
|
|
cc61681484 | ||
|
|
086bc6f748 | ||
|
|
3a87cce2e0 | ||
|
|
36920adb96 | ||
|
|
3c6becd524 | ||
|
|
3355bedaeb | ||
|
|
200dcee1b7 | ||
|
|
1a9c14b041 | ||
|
|
4a9282e681 | ||
|
|
899bcb7acd | ||
|
|
712c50e0bf | ||
|
|
feacae173e | ||
|
|
4804edf77f | ||
|
|
2d034e20c4 | ||
|
|
11031abf26 | ||
|
|
6b57b61836 | ||
|
|
4c5d7d4683 | ||
|
|
b481711fa6 | ||
|
|
05cacf6eb6 | ||
|
|
f94b3bbe0f | ||
|
|
3cb31e9685 | ||
|
|
46c1d4e319 | ||
|
|
470161ae2e | ||
|
|
af3498efdb | ||
|
|
5d53412766 | ||
|
|
0d70033a5d | ||
|
|
528704bc04 | ||
|
|
a57b4b81b9 | ||
|
|
f6ea5088f4 | ||
|
|
48d1cca303 | ||
|
|
9fa8d84598 | ||
|
|
99ac770abb | ||
|
|
b81187db5a | ||
|
|
aa8b44c001 | ||
|
|
738c60459c | ||
|
|
d1b7c2ece3 | ||
|
|
29d5950838 | ||
|
|
4dc0aaa03f | ||
|
|
1bdf0bed9c | ||
|
|
6048dfcd71 | ||
|
|
a26d1ffc66 | ||
|
|
9be935ac6d | ||
|
|
f0853139d5 | ||
|
|
cfbfca6447 | ||
|
|
1daec26ba0 | ||
|
|
e455374a4b | ||
|
|
8cd7ca568d | ||
|
|
d62acc7e37 | ||
|
|
0c8f3dddd8 | ||
|
|
e008d54cd4 | ||
|
|
4e92b55231 | ||
|
|
2766bf3fef | ||
|
|
15b38f0036 | ||
|
|
d7b9260496 | ||
|
|
6d3b409af2 | ||
|
|
fea18a909f | ||
|
|
a8860d79d8 | ||
|
|
8ae5ab809f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -54,6 +54,7 @@ bin/Regions/*
|
||||
bin/UserAssets
|
||||
bin/assetcache
|
||||
bin/maptiles
|
||||
bin/bakes
|
||||
bin/estate_settings.xml
|
||||
bin/config-include/CenomeCache.ini
|
||||
bin/config-include/FlotsamCache.ini
|
||||
|
||||
@@ -72,10 +72,12 @@ what it is today.
|
||||
* Allen Kerensky
|
||||
* BigFootAg
|
||||
* BlueWall Slade
|
||||
* bobshaffer2
|
||||
* brianw/Sir_Ahzz
|
||||
* CharlieO
|
||||
* ChrisDown
|
||||
* Chris Yeoh (IBM)
|
||||
* cinderblocks
|
||||
* controlbreak
|
||||
* coyled
|
||||
* ctrlaltdavid (David Rowe)
|
||||
@@ -88,6 +90,7 @@ what it is today.
|
||||
* DoranZemlja
|
||||
* dr0b3rts
|
||||
* dslake
|
||||
* eeyore
|
||||
* FredoChaplin
|
||||
* Garmin Kawaguichi
|
||||
* Gerhard
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace OpenSim.Groups
|
||||
if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
|
||||
grec.ServiceLocation = dict["ServiceLocation"].ToString();
|
||||
else
|
||||
grec.GroupName = string.Empty;
|
||||
grec.ServiceLocation = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
|
||||
grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
|
||||
|
||||
@@ -325,6 +325,13 @@ namespace OpenSim.Groups
|
||||
im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
|
||||
}
|
||||
|
||||
if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
|
||||
{
|
||||
ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null);
|
||||
if (groupInfo != null)
|
||||
im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName);
|
||||
}
|
||||
|
||||
// Send to self first of all
|
||||
im.toAgentID = im.fromAgentID;
|
||||
im.fromGroup = true;
|
||||
|
||||
@@ -1296,7 +1296,7 @@ namespace OpenSim.Groups
|
||||
presence.Grouptitle = Title;
|
||||
|
||||
if (! presence.IsChildAgent)
|
||||
presence.SendAvatarDataToAllAgents();
|
||||
presence.SendAvatarDataToAllClients();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
@@ -560,7 +561,7 @@ namespace OpenSim.Groups
|
||||
|
||||
// so we have the list of urls to send the notice to
|
||||
// this may take a long time...
|
||||
Util.RunThreadNoTimeout(delegate
|
||||
Watchdog.RunInThread(delegate
|
||||
{
|
||||
foreach (string u in urls)
|
||||
{
|
||||
@@ -571,7 +572,7 @@ namespace OpenSim.Groups
|
||||
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
|
||||
}
|
||||
}
|
||||
}, "AddGroupNotice", null);
|
||||
}, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID) , null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -209,11 +209,13 @@ namespace OpenSim.Groups
|
||||
string agentID = request["AgentID"].ToString();
|
||||
string token = request["AccessToken"].ToString();
|
||||
|
||||
m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token);
|
||||
if (!m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token))
|
||||
NullResult(result, "Internal error");
|
||||
else
|
||||
result["RESULT"] = "true";
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
result["RESULT"] = "true";
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
|
||||
@@ -285,11 +285,13 @@ namespace OpenSim.Groups
|
||||
string agentID = request["AgentID"].ToString();
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
|
||||
m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID);
|
||||
if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
|
||||
NullResult(result, string.Format("Insufficient permissions.", agentID));
|
||||
else
|
||||
result["RESULT"] = "true";
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
result["RESULT"] = "true";
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace OpenSim.Groups
|
||||
GroupPowers.DeleteRole |
|
||||
GroupPowers.Eject |
|
||||
GroupPowers.FindPlaces |
|
||||
GroupPowers.HostEvent |
|
||||
GroupPowers.Invite |
|
||||
GroupPowers.JoinChat |
|
||||
GroupPowers.LandChangeIdentity |
|
||||
@@ -150,7 +151,8 @@ namespace OpenSim.Groups
|
||||
data.Data["ShowInList"] = showInList ? "1" : "0";
|
||||
data.Data["AllowPublish"] = allowPublish ? "1" : "0";
|
||||
data.Data["MaturePublish"] = maturePublish ? "1" : "0";
|
||||
data.Data["OwnerRoleID"] = UUID.Random().ToString();
|
||||
UUID roleID = UUID.Random();
|
||||
data.Data["OwnerRoleID"] = roleID.ToString();
|
||||
|
||||
if (!m_Database.StoreGroup(data))
|
||||
return UUID.Zero;
|
||||
@@ -159,7 +161,6 @@ namespace OpenSim.Groups
|
||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
|
||||
|
||||
// Create Owner role
|
||||
UUID roleID = UUID.Random();
|
||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
|
||||
|
||||
// Add founder to group
|
||||
@@ -247,6 +248,9 @@ namespace OpenSim.Groups
|
||||
if (group == null)
|
||||
return members;
|
||||
|
||||
// Unfortunately this doesn't quite work on legacy group data because of a bug
|
||||
// that's also being fixed here on CreateGroup. The OwnerRoleID sent to the DB was wrong.
|
||||
// See how to find the ownerRoleID a few lines below.
|
||||
UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
|
||||
|
||||
RoleData[] roles = m_Database.RetrieveRoles(GroupID);
|
||||
@@ -255,6 +259,11 @@ namespace OpenSim.Groups
|
||||
return members;
|
||||
List<RoleData> rolesList = new List<RoleData>(roles);
|
||||
|
||||
// Let's find the "real" ownerRoleID
|
||||
RoleData ownerRole = rolesList.Find(r => r.Data["Powers"] == ((long)OwnerPowers).ToString());
|
||||
if (ownerRole != null)
|
||||
ownerRoleID = ownerRole.RoleID;
|
||||
|
||||
// Check visibility?
|
||||
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
|
||||
bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
|
||||
@@ -291,17 +300,17 @@ namespace OpenSim.Groups
|
||||
{
|
||||
m.Title = selected.Data["Title"];
|
||||
m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
|
||||
|
||||
m.AgentID = d.PrincipalID;
|
||||
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
|
||||
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
||||
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
|
||||
|
||||
// Is this person an owner of the group?
|
||||
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
||||
|
||||
members.Add(m);
|
||||
}
|
||||
|
||||
m.AgentID = d.PrincipalID;
|
||||
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
|
||||
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
||||
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
|
||||
|
||||
// Is this person an owner of the group?
|
||||
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
||||
|
||||
members.Add(m);
|
||||
}
|
||||
|
||||
return members;
|
||||
@@ -393,13 +402,15 @@ namespace OpenSim.Groups
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
// check perms
|
||||
if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
|
||||
return;
|
||||
return false;
|
||||
|
||||
_RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
||||
|
||||
@@ -131,19 +131,27 @@ namespace OpenSim.Groups
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
||||
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
||||
{
|
||||
// check the token
|
||||
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
||||
if (membership != null)
|
||||
{
|
||||
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
||||
RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
{
|
||||
return RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)
|
||||
|
||||
@@ -215,18 +215,7 @@ namespace OpenSim.OfflineIM
|
||||
|
||||
rootElement.AppendChild(result);
|
||||
|
||||
return DocToBytes(doc);
|
||||
}
|
||||
|
||||
private byte[] DocToBytes(XmlDocument doc)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||
xw.Formatting = Formatting.Indented;
|
||||
doc.WriteTo(xw);
|
||||
xw.Flush();
|
||||
|
||||
return ms.ToArray();
|
||||
return Util.DocToBytes(doc);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -37,7 +37,6 @@ using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||
{
|
||||
@@ -52,7 +51,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||
// Overkill - we only really need the asset service, not a whole scene.
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
|
||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null, null);
|
||||
GetTextureHandler handler = new GetTextureHandler("/gettexture", scene.AssetService, "TestGetTexture", null, null);
|
||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
||||
|
||||
@@ -68,7 +68,10 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// <returns></returns>
|
||||
public static object LLSDDeserialize(byte[] b)
|
||||
{
|
||||
return LLSDDeserialize(new MemoryStream(b, false));
|
||||
using (MemoryStream ms = new MemoryStream(b, false))
|
||||
{
|
||||
return LLSDDeserialize(ms);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -78,21 +81,23 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// <returns></returns>
|
||||
public static object LLSDDeserialize(Stream st)
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader(st);
|
||||
reader.Read();
|
||||
SkipWS(reader);
|
||||
using (XmlTextReader reader = new XmlTextReader(st))
|
||||
{
|
||||
reader.Read();
|
||||
SkipWS(reader);
|
||||
|
||||
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
|
||||
throw new LLSDParseException("Expected <llsd>");
|
||||
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
|
||||
throw new LLSDParseException("Expected <llsd>");
|
||||
|
||||
reader.Read();
|
||||
object ret = LLSDParseOne(reader);
|
||||
SkipWS(reader);
|
||||
reader.Read();
|
||||
object ret = LLSDParseOne(reader);
|
||||
SkipWS(reader);
|
||||
|
||||
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
|
||||
throw new LLSDParseException("Expected </llsd>");
|
||||
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
|
||||
throw new LLSDParseException("Expected </llsd>");
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -52,12 +52,12 @@ namespace OpenSim.Data
|
||||
public int sizeY;
|
||||
|
||||
/// <summary>
|
||||
/// Return the x-coordinate of this region.
|
||||
/// Return the x-coordinate of this region in region units.
|
||||
/// </summary>
|
||||
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the y-coordinate of this region.
|
||||
/// Return the y-coordinate of this region in region units.
|
||||
/// </summary>
|
||||
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ namespace OpenSim.Data.MySQL
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_connectionString;
|
||||
private object m_dbLock = new object();
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
@@ -107,47 +106,46 @@ namespace OpenSim.Data.MySQL
|
||||
override public AssetBase GetAsset(UUID assetID)
|
||||
{
|
||||
AssetBase asset = null;
|
||||
lock (m_dbLock)
|
||||
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(
|
||||
"SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id",
|
||||
dbcon))
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.Parameters.AddWithValue("?id", assetID.ToString());
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(
|
||||
"SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id",
|
||||
dbcon))
|
||||
try
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", assetID.ToString());
|
||||
|
||||
try
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
if (dbReader.Read())
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString());
|
||||
asset.Data = (byte[])dbReader["data"];
|
||||
asset.Description = (string)dbReader["description"];
|
||||
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString());
|
||||
asset.Data = (byte[])dbReader["data"];
|
||||
asset.Description = (string)dbReader["description"];
|
||||
|
||||
string local = dbReader["local"].ToString();
|
||||
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
|
||||
asset.Local = true;
|
||||
else
|
||||
asset.Local = false;
|
||||
string local = dbReader["local"].ToString();
|
||||
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
|
||||
asset.Local = true;
|
||||
else
|
||||
asset.Local = false;
|
||||
|
||||
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
|
||||
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
}
|
||||
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
|
||||
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
@@ -158,100 +156,94 @@ namespace OpenSim.Data.MySQL
|
||||
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
|
||||
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
|
||||
dbcon))
|
||||
using (MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
|
||||
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
|
||||
dbcon))
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?name", assetName);
|
||||
cmd.Parameters.AddWithValue("?description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?assetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?create_time", now);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
|
||||
asset.FullID, asset.Name)
|
||||
, e);
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?name", assetName);
|
||||
cmd.Parameters.AddWithValue("?description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?assetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?create_time", now);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
|
||||
asset.FullID, asset.Name)
|
||||
, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAccessTime(AssetBase asset)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
using (cmd)
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
|
||||
asset.FullID, asset.Name),
|
||||
e);
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
|
||||
asset.FullID, asset.Name),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,20 +263,17 @@ namespace OpenSim.Data.MySQL
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
{
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
while (dbReader.Read())
|
||||
{
|
||||
while (dbReader.Read())
|
||||
{
|
||||
UUID id = DBGuid.FromDB(dbReader["id"]);
|
||||
exist.Add(id);
|
||||
}
|
||||
UUID id = DBGuid.FromDB(dbReader["id"]);
|
||||
exist.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,50 +298,47 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
List<AssetMetadata> retList = new List<AssetMetadata>(count);
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand(
|
||||
"SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
|
||||
dbcon))
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand(
|
||||
"SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
|
||||
dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?start", start);
|
||||
cmd.Parameters.AddWithValue("?count", count);
|
||||
|
||||
try
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?start", start);
|
||||
cmd.Parameters.AddWithValue("?count", count);
|
||||
|
||||
try
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
while (dbReader.Read())
|
||||
{
|
||||
while (dbReader.Read())
|
||||
{
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["name"];
|
||||
metadata.Description = (string)dbReader["description"];
|
||||
metadata.Type = (sbyte)dbReader["assetType"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
|
||||
metadata.CreatorID = dbReader["CreatorID"].ToString();
|
||||
|
||||
// Current SHA1s are not stored/computed.
|
||||
metadata.SHA1 = new byte[] { };
|
||||
|
||||
retList.Add(metadata);
|
||||
}
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["name"];
|
||||
metadata.Description = (string)dbReader["description"];
|
||||
metadata.Type = (sbyte)dbReader["assetType"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
|
||||
metadata.CreatorID = dbReader["CreatorID"].ToString();
|
||||
|
||||
// Current SHA1s are not stored/computed.
|
||||
metadata.SHA1 = new byte[] { };
|
||||
|
||||
retList.Add(metadata);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
|
||||
start, count),
|
||||
e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
|
||||
start, count),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,17 +348,14 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public override bool Delete(string id)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,38 +45,29 @@ namespace OpenSim.Data.MySQL
|
||||
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected string m_connectionString;
|
||||
protected object m_dbLock = new object();
|
||||
|
||||
protected MySqlFramework(string connectionString)
|
||||
{
|
||||
m_connectionString = connectionString;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// All non queries are funneled through one connection
|
||||
// to increase performance a little
|
||||
//
|
||||
protected int ExecuteNonQuery(MySqlCommand cmd)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.Connection = dbcon;
|
||||
dbcon.Open();
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
try
|
||||
{
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.Message, e);
|
||||
return 0;
|
||||
}
|
||||
try
|
||||
{
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.Message, e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,15 @@ namespace OpenSim.Data.MySQL
|
||||
private static string LogHeader = "[REGION DB MYSQL]";
|
||||
|
||||
private string m_connectionString;
|
||||
|
||||
/// <summary>
|
||||
/// This lock was being used to serialize database operations when the connection was shared, but this has
|
||||
/// been unnecessary for a long time after we switched to using MySQL's underlying connection pooling instead.
|
||||
/// FIXME: However, the locks remain in many places since they are effectively providing a level of
|
||||
/// transactionality. This should be replaced by more efficient database transactions which would not require
|
||||
/// unrelated operations to block each other or unrelated operations on the same tables from blocking each
|
||||
/// other.
|
||||
/// </summary>
|
||||
private object m_dbLock = new object();
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
@@ -738,95 +747,92 @@ namespace OpenSim.Data.MySQL
|
||||
RegionLightShareData nWP = new RegionLightShareData();
|
||||
nWP.OnSave += StoreRegionWindlightSettings;
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionwindlight` where region_id = ?regionID";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionwindlight` where region_id = ?regionID";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
|
||||
|
||||
IDataReader result = ExecuteReader(cmd);
|
||||
if (!result.Read())
|
||||
{
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
|
||||
|
||||
IDataReader result = ExecuteReader(cmd);
|
||||
if (!result.Read())
|
||||
{
|
||||
//No result, so store our default windlight profile and return it
|
||||
nWP.regionID = regionUUID;
|
||||
//No result, so store our default windlight profile and return it
|
||||
nWP.regionID = regionUUID;
|
||||
// StoreRegionWindlightSettings(nWP);
|
||||
return nWP;
|
||||
}
|
||||
else
|
||||
{
|
||||
nWP.regionID = DBGuid.FromDB(result["region_id"]);
|
||||
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
|
||||
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
|
||||
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
|
||||
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
|
||||
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
|
||||
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
|
||||
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
|
||||
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
|
||||
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
|
||||
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
|
||||
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
|
||||
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
|
||||
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
|
||||
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
|
||||
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
|
||||
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
|
||||
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
|
||||
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
|
||||
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
|
||||
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
|
||||
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
|
||||
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
|
||||
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
|
||||
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
|
||||
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
|
||||
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
|
||||
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
|
||||
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
|
||||
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
|
||||
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
|
||||
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
|
||||
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
|
||||
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
|
||||
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
|
||||
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
|
||||
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
|
||||
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
|
||||
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
|
||||
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
|
||||
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
|
||||
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
|
||||
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
|
||||
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
|
||||
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
|
||||
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
|
||||
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
|
||||
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
|
||||
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
|
||||
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
|
||||
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
|
||||
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
|
||||
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
|
||||
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
|
||||
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
|
||||
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
|
||||
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
|
||||
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
|
||||
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
|
||||
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
|
||||
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
|
||||
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
|
||||
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
|
||||
nWP.valid = true;
|
||||
}
|
||||
return nWP;
|
||||
}
|
||||
else
|
||||
{
|
||||
nWP.regionID = DBGuid.FromDB(result["region_id"]);
|
||||
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
|
||||
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
|
||||
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
|
||||
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
|
||||
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
|
||||
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
|
||||
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
|
||||
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
|
||||
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
|
||||
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
|
||||
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
|
||||
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
|
||||
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
|
||||
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
|
||||
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
|
||||
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
|
||||
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
|
||||
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
|
||||
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
|
||||
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
|
||||
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
|
||||
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
|
||||
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
|
||||
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
|
||||
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
|
||||
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
|
||||
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
|
||||
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
|
||||
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
|
||||
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
|
||||
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
|
||||
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
|
||||
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
|
||||
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
|
||||
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
|
||||
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
|
||||
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
|
||||
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
|
||||
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
|
||||
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
|
||||
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
|
||||
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
|
||||
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
|
||||
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
|
||||
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
|
||||
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
|
||||
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
|
||||
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
|
||||
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
|
||||
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
|
||||
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
|
||||
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
|
||||
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
|
||||
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
|
||||
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
|
||||
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
|
||||
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
|
||||
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
|
||||
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
|
||||
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
|
||||
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
|
||||
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
|
||||
nWP.valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -876,124 +882,118 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
|
||||
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
|
||||
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
|
||||
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
|
||||
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
|
||||
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
|
||||
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
|
||||
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
|
||||
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
|
||||
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
|
||||
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
|
||||
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
|
||||
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
|
||||
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
|
||||
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
|
||||
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
|
||||
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
|
||||
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
|
||||
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
|
||||
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
|
||||
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
|
||||
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
|
||||
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
|
||||
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
|
||||
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
|
||||
|
||||
cmd.Parameters.AddWithValue("region_id", wl.regionID);
|
||||
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
|
||||
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
|
||||
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
|
||||
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
|
||||
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
|
||||
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
|
||||
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
|
||||
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
|
||||
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
|
||||
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
|
||||
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
|
||||
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
|
||||
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
|
||||
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
|
||||
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
|
||||
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
|
||||
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
|
||||
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
|
||||
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
|
||||
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
|
||||
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
|
||||
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
|
||||
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
|
||||
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
|
||||
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
|
||||
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
|
||||
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
|
||||
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
|
||||
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
|
||||
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
|
||||
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
|
||||
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
|
||||
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
|
||||
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
|
||||
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
|
||||
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
|
||||
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
|
||||
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
|
||||
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
|
||||
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
|
||||
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
|
||||
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
|
||||
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
|
||||
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
|
||||
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
|
||||
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
|
||||
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
|
||||
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
|
||||
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
|
||||
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
|
||||
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
|
||||
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
|
||||
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
|
||||
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
|
||||
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
|
||||
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
|
||||
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
|
||||
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
|
||||
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
|
||||
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
|
||||
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
|
||||
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
|
||||
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
|
||||
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
|
||||
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
|
||||
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
|
||||
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
|
||||
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
|
||||
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
|
||||
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
|
||||
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
|
||||
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
|
||||
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
|
||||
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
|
||||
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
|
||||
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
|
||||
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
|
||||
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
|
||||
|
||||
cmd.Parameters.AddWithValue("region_id", wl.regionID);
|
||||
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
|
||||
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
|
||||
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
|
||||
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
|
||||
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
|
||||
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
|
||||
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
|
||||
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
|
||||
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
|
||||
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
|
||||
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
|
||||
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
|
||||
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
|
||||
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
|
||||
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
|
||||
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
|
||||
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
|
||||
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
|
||||
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
|
||||
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
|
||||
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
|
||||
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
|
||||
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
|
||||
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
|
||||
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
|
||||
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
|
||||
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
|
||||
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
|
||||
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
|
||||
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
|
||||
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
|
||||
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
|
||||
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
|
||||
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
|
||||
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
|
||||
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
|
||||
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
|
||||
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
|
||||
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
|
||||
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
|
||||
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
|
||||
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
|
||||
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
|
||||
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
|
||||
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
|
||||
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
|
||||
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
|
||||
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
|
||||
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
|
||||
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
|
||||
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
|
||||
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
|
||||
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
|
||||
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
|
||||
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
|
||||
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegionWindlightSettings(UUID regionID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
|
||||
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
|
||||
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1001,29 +1001,26 @@ namespace OpenSim.Data.MySQL
|
||||
#region RegionEnvironmentSettings
|
||||
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionenvironment` where region_id = ?region_id";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
string command = "select * from `regionenvironment` where region_id = ?region_id";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
|
||||
IDataReader result = ExecuteReader(cmd);
|
||||
if (!result.Read())
|
||||
{
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
|
||||
IDataReader result = ExecuteReader(cmd);
|
||||
if (!result.Read())
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToString(result["llsd_settings"]);
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToString(result["llsd_settings"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1031,39 +1028,33 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
|
||||
|
||||
cmd.Parameters.AddWithValue("region_id", regionUUID);
|
||||
cmd.Parameters.AddWithValue("llsd_settings", settings);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
|
||||
|
||||
cmd.Parameters.AddWithValue("region_id", regionUUID);
|
||||
cmd.Parameters.AddWithValue("llsd_settings", settings);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
|
||||
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1071,57 +1062,55 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public void StoreRegionSettings(RegionSettings rs)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.CommandText = "replace into regionsettings (regionUUID, " +
|
||||
"block_terraform, block_fly, allow_damage, " +
|
||||
"restrict_pushing, allow_land_resell, " +
|
||||
"allow_land_join_divide, block_show_in_search, " +
|
||||
"agent_limit, object_bonus, maturity, " +
|
||||
"disable_scripts, disable_collisions, " +
|
||||
"disable_physics, terrain_texture_1, " +
|
||||
"terrain_texture_2, terrain_texture_3, " +
|
||||
"terrain_texture_4, elevation_1_nw, " +
|
||||
"elevation_2_nw, elevation_1_ne, " +
|
||||
"elevation_2_ne, elevation_1_se, " +
|
||||
"elevation_2_se, elevation_1_sw, " +
|
||||
"elevation_2_sw, water_height, " +
|
||||
"terrain_raise_limit, terrain_lower_limit, " +
|
||||
"use_estate_sun, fixed_sun, sun_position, " +
|
||||
"covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
|
||||
"sunvectorz, loaded_creation_datetime, " +
|
||||
"loaded_creation_id, map_tile_ID, " +
|
||||
"TelehubObject, parcel_tile_ID) " +
|
||||
"values (?RegionUUID, ?BlockTerraform, " +
|
||||
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
|
||||
"?AllowLandResell, ?AllowLandJoinDivide, " +
|
||||
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
|
||||
"?Maturity, ?DisableScripts, ?DisableCollisions, " +
|
||||
"?DisablePhysics, ?TerrainTexture1, " +
|
||||
"?TerrainTexture2, ?TerrainTexture3, " +
|
||||
"?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
|
||||
"?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
|
||||
"?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
|
||||
"?WaterHeight, ?TerrainRaiseLimit, " +
|
||||
"?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
|
||||
"?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " +
|
||||
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
|
||||
"?LoadedCreationDateTime, ?LoadedCreationID, " +
|
||||
"?TerrainImageID, " +
|
||||
"?TelehubObject, ?ParcelImageID)";
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "replace into regionsettings (regionUUID, " +
|
||||
"block_terraform, block_fly, allow_damage, " +
|
||||
"restrict_pushing, allow_land_resell, " +
|
||||
"allow_land_join_divide, block_show_in_search, " +
|
||||
"agent_limit, object_bonus, maturity, " +
|
||||
"disable_scripts, disable_collisions, " +
|
||||
"disable_physics, terrain_texture_1, " +
|
||||
"terrain_texture_2, terrain_texture_3, " +
|
||||
"terrain_texture_4, elevation_1_nw, " +
|
||||
"elevation_2_nw, elevation_1_ne, " +
|
||||
"elevation_2_ne, elevation_1_se, " +
|
||||
"elevation_2_se, elevation_1_sw, " +
|
||||
"elevation_2_sw, water_height, " +
|
||||
"terrain_raise_limit, terrain_lower_limit, " +
|
||||
"use_estate_sun, fixed_sun, sun_position, " +
|
||||
"covenant, covenant_datetime, Sandbox, sunvectorx, sunvectory, " +
|
||||
"sunvectorz, loaded_creation_datetime, " +
|
||||
"loaded_creation_id, map_tile_ID, " +
|
||||
"TelehubObject, parcel_tile_ID) " +
|
||||
"values (?RegionUUID, ?BlockTerraform, " +
|
||||
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
|
||||
"?AllowLandResell, ?AllowLandJoinDivide, " +
|
||||
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
|
||||
"?Maturity, ?DisableScripts, ?DisableCollisions, " +
|
||||
"?DisablePhysics, ?TerrainTexture1, " +
|
||||
"?TerrainTexture2, ?TerrainTexture3, " +
|
||||
"?TerrainTexture4, ?Elevation1NW, ?Elevation2NW, " +
|
||||
"?Elevation1NE, ?Elevation2NE, ?Elevation1SE, " +
|
||||
"?Elevation2SE, ?Elevation1SW, ?Elevation2SW, " +
|
||||
"?WaterHeight, ?TerrainRaiseLimit, " +
|
||||
"?TerrainLowerLimit, ?UseEstateSun, ?FixedSun, " +
|
||||
"?SunPosition, ?Covenant, ?CovenantChangedDateTime, ?Sandbox, " +
|
||||
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
|
||||
"?LoadedCreationDateTime, ?LoadedCreationID, " +
|
||||
"?TerrainImageID, " +
|
||||
"?TelehubObject, ?ParcelImageID)";
|
||||
FillRegionSettingsCommand(cmd, rs);
|
||||
|
||||
FillRegionSettingsCommand(cmd, rs);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
SaveSpawnPoints(rs);
|
||||
}
|
||||
|
||||
@@ -2043,41 +2032,35 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string val)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
cmd.Parameters.AddWithValue("?value", val);
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
cmd.Parameters.AddWithValue("?value", val);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2086,22 +2069,19 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
Dictionary<string, string> ret = new Dictionary<string, string>();
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
using (IDataReader r = cmd.ExecuteReader())
|
||||
{
|
||||
cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
using (IDataReader r = cmd.ExecuteReader())
|
||||
while (r.Read())
|
||||
{
|
||||
while (r.Read())
|
||||
{
|
||||
ret[r["Name"].ToString()] = r["value"].ToString();
|
||||
}
|
||||
ret[r["Name"].ToString()] = r["value"].ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,6 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
protected object Lock
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
@@ -116,7 +111,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UserAccount exception {0}", e.Message);
|
||||
}
|
||||
n.Add("classifieduuid", OSD.FromUUID(Id));
|
||||
@@ -237,7 +232,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": ClassifiedesUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -250,7 +245,7 @@ namespace OpenSim.Data.MySQL
|
||||
string query = string.Empty;
|
||||
|
||||
query += "DELETE FROM classifieds WHERE ";
|
||||
query += "classifieduuid = ?ClasifiedId";
|
||||
query += "classifieduuid = ?recordId";
|
||||
|
||||
try
|
||||
{
|
||||
@@ -260,18 +255,14 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?ClassifiedId", recordId.ToString());
|
||||
|
||||
lock(Lock)
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.Parameters.AddWithValue("?recordId", recordId.ToString());
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": DeleteClassifiedRecord exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -321,7 +312,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetPickInfo exception {0}", e.Message);
|
||||
}
|
||||
return true;
|
||||
@@ -365,7 +356,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarPicks exception {0}", e.Message);
|
||||
}
|
||||
return data;
|
||||
@@ -406,6 +397,7 @@ namespace OpenSim.Data.MySQL
|
||||
UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId);
|
||||
UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId);
|
||||
pick.GlobalPos = (string)reader["posglobal"];
|
||||
pick.Gatekeeper = (string)reader["gatekeeper"];
|
||||
bool.TryParse((string)reader["toppick"], out pick.TopPick);
|
||||
bool.TryParse((string)reader["enabled"], out pick.Enabled);
|
||||
pick.Name = (string)reader["name"];
|
||||
@@ -422,7 +414,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetPickInfo exception {0}", e.Message);
|
||||
}
|
||||
return pick;
|
||||
@@ -445,14 +437,16 @@ namespace OpenSim.Data.MySQL
|
||||
query += "?SimName,";
|
||||
query += "?GlobalPos,";
|
||||
query += "?SortOrder,";
|
||||
query += "?Enabled) ";
|
||||
query += "?Enabled,";
|
||||
query += "?Gatekeeper)";
|
||||
query += "ON DUPLICATE KEY UPDATE ";
|
||||
query += "parceluuid=?ParcelId,";
|
||||
query += "name=?Name,";
|
||||
query += "description=?Desc,";
|
||||
query += "snapshotuuid=?SnapshotId,";
|
||||
query += "pickuuid=?PickId,";
|
||||
query += "posglobal=?GlobalPos";
|
||||
query += "posglobal=?GlobalPos,";
|
||||
query += "gatekeeper=?Gatekeeper";
|
||||
|
||||
try
|
||||
{
|
||||
@@ -472,6 +466,7 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.Parameters.AddWithValue("?Original", pick.OriginalName.ToString());
|
||||
cmd.Parameters.AddWithValue("?SimName",pick.SimName.ToString());
|
||||
cmd.Parameters.AddWithValue("?GlobalPos", pick.GlobalPos);
|
||||
cmd.Parameters.AddWithValue("?Gatekeeper",pick.Gatekeeper);
|
||||
cmd.Parameters.AddWithValue("?SortOrder", pick.SortOrder.ToString ());
|
||||
cmd.Parameters.AddWithValue("?Enabled", pick.Enabled.ToString());
|
||||
|
||||
@@ -481,7 +476,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UpdateAvatarNotes exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -511,7 +506,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": DeleteUserPickRecord exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -556,7 +551,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarNotes exception {0}", e.Message);
|
||||
}
|
||||
return true;
|
||||
@@ -604,7 +599,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UpdateAvatarNotes exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -722,7 +717,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Requst properties exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -762,7 +757,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentPropertiesUpdate exception {0}", e.Message);
|
||||
|
||||
return false;
|
||||
@@ -804,7 +799,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentInterestsUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -887,7 +882,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarNotes exception {0}", e.Message);
|
||||
}
|
||||
return data;
|
||||
@@ -920,7 +915,7 @@ namespace OpenSim.Data.MySQL
|
||||
reader.Read();
|
||||
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
|
||||
bool.TryParse((string)reader["visible"], out pref.Visible);
|
||||
pref.EMail = (string)reader["email"];
|
||||
pref.EMail = (string)reader["email"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -945,7 +940,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Get preferences exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -959,7 +954,8 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
query += "UPDATE usersettings SET ";
|
||||
query += "imviaemail=?ImViaEmail, ";
|
||||
query += "visible=?Visible ";
|
||||
query += "visible=?Visible, ";
|
||||
query += "email=?EMail ";
|
||||
query += "WHERE useruuid=?uuid";
|
||||
|
||||
try
|
||||
@@ -971,7 +967,8 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail.ToString().ToLower());
|
||||
cmd.Parameters.AddWithValue("?Visible", pref.Visible.ToString().ToLower());
|
||||
cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
|
||||
cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
|
||||
cmd.Parameters.AddWithValue("?EMail", pref.EMail.ToString().ToLower());
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@@ -979,8 +976,8 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": AgentInterestsUpdate exception {0}", e.Message);
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException);
|
||||
result = e.Message;
|
||||
return false;
|
||||
}
|
||||
@@ -1029,11 +1026,8 @@ namespace OpenSim.Data.MySQL
|
||||
put.Parameters.AddWithValue("?TagId", props.TagId.ToString());
|
||||
put.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
|
||||
put.Parameters.AddWithValue("?DataVal", props.DataVal.ToString());
|
||||
|
||||
lock(Lock)
|
||||
{
|
||||
put.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
put.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1042,7 +1036,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Requst application data exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -1069,20 +1063,17 @@ namespace OpenSim.Data.MySQL
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?UserId", props.UserId.ToString());
|
||||
cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString ());
|
||||
cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString ());
|
||||
cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString ());
|
||||
|
||||
lock(Lock)
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.Parameters.AddWithValue("?TagId", props.TagId.ToString());
|
||||
cmd.Parameters.AddWithValue("?DataKey", props.DataKey.ToString());
|
||||
cmd.Parameters.AddWithValue("?DataVal", props.DataKey.ToString());
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": SetUserData exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -1090,5 +1081,4 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
#endregion Integration
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -57,7 +57,6 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
private bool m_enableCompression = false;
|
||||
private string m_connectionString;
|
||||
private object m_dbLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock
|
||||
@@ -131,60 +130,58 @@ namespace OpenSim.Data.MySQL
|
||||
// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
|
||||
|
||||
AssetBase asset = null;
|
||||
lock (m_dbLock)
|
||||
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(
|
||||
"SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID",
|
||||
dbcon))
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.Parameters.AddWithValue("?ID", assetID.ToString());
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(
|
||||
"SELECT Name, Description, AccessTime, AssetType, Local, Temporary, AssetFlags, CreatorID, Data FROM XAssetsMeta JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ID=?ID",
|
||||
dbcon))
|
||||
try
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?ID", assetID.ToString());
|
||||
|
||||
try
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
if (dbReader.Read())
|
||||
{
|
||||
if (dbReader.Read())
|
||||
asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
|
||||
asset.Data = (byte[])dbReader["Data"];
|
||||
asset.Description = (string)dbReader["Description"];
|
||||
|
||||
string local = dbReader["Local"].ToString();
|
||||
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
|
||||
asset.Local = true;
|
||||
else
|
||||
asset.Local = false;
|
||||
|
||||
asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
|
||||
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
|
||||
|
||||
if (m_enableCompression)
|
||||
{
|
||||
asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
|
||||
asset.Data = (byte[])dbReader["Data"];
|
||||
asset.Description = (string)dbReader["Description"];
|
||||
|
||||
string local = dbReader["Local"].ToString();
|
||||
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
|
||||
asset.Local = true;
|
||||
else
|
||||
asset.Local = false;
|
||||
|
||||
asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
|
||||
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
|
||||
|
||||
if (m_enableCompression)
|
||||
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
|
||||
{
|
||||
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
|
||||
{
|
||||
MemoryStream outputStream = new MemoryStream();
|
||||
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
|
||||
// int compressedLength = asset.Data.Length;
|
||||
asset.Data = outputStream.ToArray();
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
|
||||
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
|
||||
}
|
||||
}
|
||||
MemoryStream outputStream = new MemoryStream();
|
||||
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
|
||||
// int compressedLength = asset.Data.Length;
|
||||
asset.Data = outputStream.ToArray();
|
||||
|
||||
UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
|
||||
// m_log.DebugFormat(
|
||||
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
|
||||
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,113 +198,110 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
// m_log.DebugFormat("[XASSETS DB]: Storing asset {0} {1}", asset.Name, asset.ID);
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlTransaction transaction = dbcon.BeginTransaction())
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlTransaction transaction = dbcon.BeginTransaction())
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
m_log.WarnFormat(
|
||||
"[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
m_log.WarnFormat(
|
||||
"[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
}
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
m_log.WarnFormat(
|
||||
"[XASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||
}
|
||||
|
||||
if (m_enableCompression)
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
m_log.WarnFormat(
|
||||
"[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
}
|
||||
|
||||
if (m_enableCompression)
|
||||
{
|
||||
MemoryStream outputStream = new MemoryStream();
|
||||
|
||||
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
|
||||
{
|
||||
MemoryStream outputStream = new MemoryStream();
|
||||
|
||||
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
|
||||
{
|
||||
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
|
||||
// We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
|
||||
compressionStream.Close();
|
||||
byte[] compressedData = outputStream.ToArray();
|
||||
asset.Data = compressedData;
|
||||
}
|
||||
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
|
||||
// We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
|
||||
compressionStream.Close();
|
||||
byte[] compressedData = outputStream.ToArray();
|
||||
asset.Data = compressedData;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] hash = hasher.ComputeHash(asset.Data);
|
||||
byte[] hash = hasher.ComputeHash(asset.Data);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
|
||||
// asset.ID, asset.Name, hash, compressedData.Length);
|
||||
|
||||
try
|
||||
{
|
||||
using (MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" +
|
||||
"VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)",
|
||||
dbcon))
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?ID", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?Hash", hash);
|
||||
cmd.Parameters.AddWithValue("?Name", assetName);
|
||||
cmd.Parameters.AddWithValue("?Description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?AssetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?Local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?Temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?CreateTime", now);
|
||||
cmd.Parameters.AddWithValue("?AccessTime", now);
|
||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
|
||||
transaction.Rollback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ExistsData(dbcon, transaction, hash))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"replace INTO XAssetsMeta(ID, Hash, Name, Description, AssetType, Local, Temporary, CreateTime, AccessTime, AssetFlags, CreatorID)" +
|
||||
"VALUES(?ID, ?Hash, ?Name, ?Description, ?AssetType, ?Local, ?Temporary, ?CreateTime, ?AccessTime, ?AssetFlags, ?CreatorID)",
|
||||
"INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)",
|
||||
dbcon))
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?ID", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?Hash", hash);
|
||||
cmd.Parameters.AddWithValue("?Name", assetName);
|
||||
cmd.Parameters.AddWithValue("?Description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?AssetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?Local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?Temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?CreateTime", now);
|
||||
cmd.Parameters.AddWithValue("?AccessTime", now);
|
||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?AssetFlags", (int)asset.Flags);
|
||||
cmd.Parameters.AddWithValue("?Data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
|
||||
m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
|
||||
transaction.Rollback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ExistsData(dbcon, transaction, hash))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"INSERT INTO XAssetsData(Hash, Data) VALUES(?Hash, ?Data)",
|
||||
dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?Hash", hash);
|
||||
cmd.Parameters.AddWithValue("?Data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
|
||||
transaction.Rollback();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,31 +322,28 @@ namespace OpenSim.Data.MySQL
|
||||
if ((now - Utils.UnixTimeToDateTime(accessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
|
||||
return;
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd =
|
||||
new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon);
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd =
|
||||
new MySqlCommand("update XAssetsMeta set AccessTime=?AccessTime where ID=?ID", dbcon);
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// create unix epoch time
|
||||
cmd.Parameters.AddWithValue("?ID", assetMetadata.ID);
|
||||
cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
|
||||
assetMetadata.ID, assetMetadata.Name);
|
||||
// create unix epoch time
|
||||
cmd.Parameters.AddWithValue("?ID", assetMetadata.ID);
|
||||
cmd.Parameters.AddWithValue("?AccessTime", (int)Utils.DateTimeToUnixTime(now));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
|
||||
assetMetadata.ID, assetMetadata.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,20 +402,17 @@ namespace OpenSim.Data.MySQL
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids);
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
{
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
while (dbReader.Read())
|
||||
{
|
||||
while (dbReader.Read())
|
||||
{
|
||||
UUID id = DBGuid.FromDB(dbReader["ID"]);
|
||||
exists.Add(id);
|
||||
}
|
||||
UUID id = DBGuid.FromDB(dbReader["ID"]);
|
||||
exists.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,43 +437,40 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
List<AssetMetadata> retList = new List<AssetMetadata>(count);
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count", dbcon);
|
||||
cmd.Parameters.AddWithValue("?start", start);
|
||||
cmd.Parameters.AddWithValue("?count", count);
|
||||
|
||||
try
|
||||
{
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("SELECT Name, Description, AccessTime, AssetType, Temporary, ID, AssetFlags, CreatorID FROM XAssetsMeta LIMIT ?start, ?count", dbcon);
|
||||
cmd.Parameters.AddWithValue("?start", start);
|
||||
cmd.Parameters.AddWithValue("?count", count);
|
||||
|
||||
try
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
while (dbReader.Read())
|
||||
{
|
||||
while (dbReader.Read())
|
||||
{
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["Name"];
|
||||
metadata.Description = (string)dbReader["Description"];
|
||||
metadata.Type = (sbyte)dbReader["AssetType"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
|
||||
metadata.CreatorID = dbReader["CreatorID"].ToString();
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["Name"];
|
||||
metadata.Description = (string)dbReader["Description"];
|
||||
metadata.Type = (sbyte)dbReader["AssetType"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
|
||||
metadata.CreatorID = dbReader["CreatorID"].ToString();
|
||||
|
||||
// We'll ignore this for now - it appears unused!
|
||||
// We'll ignore this for now - it appears unused!
|
||||
// metadata.SHA1 = dbReader["hash"]);
|
||||
|
||||
UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
|
||||
UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
|
||||
|
||||
retList.Add(metadata);
|
||||
}
|
||||
retList.Add(metadata);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,21 +481,18 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
// m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id);
|
||||
|
||||
lock (m_dbLock)
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand("delete from XAssetsMeta where ID=?ID", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?ID", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
|
||||
// keep a reference count (?)
|
||||
cmd.Parameters.AddWithValue("?ID", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
|
||||
// keep a reference count (?)
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -90,4 +90,9 @@ CREATE TABLE IF NOT EXISTS `usersettings` (
|
||||
`email` varchar(254) NOT NULL,
|
||||
PRIMARY KEY (`useruuid`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||
commit;
|
||||
commit;
|
||||
|
||||
:VERSION 4 # -------------------------------
|
||||
begin;
|
||||
ALTER TABLE userpicks ADD COLUMN gatekeeper varchar(255);
|
||||
commit;
|
||||
|
||||
@@ -298,22 +298,26 @@ namespace OpenSim.Data.PGSQL
|
||||
return new UserAccountData[0];
|
||||
|
||||
string sql = "";
|
||||
UUID scope_id;
|
||||
UUID.TryParse(scopeID.ToString(), out scope_id);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
{
|
||||
if (words.Length == 1)
|
||||
{
|
||||
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""='00000000-0000-0000-0000-000000000000') and (""FirstName"" ilike :search or ""LastName"" ilike :search)", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("scopeID", scopeID));
|
||||
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""=:UUIDZero) and (""FirstName"" ilike :search or ""LastName"" ilike :search)", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("scopeID", (UUID)scope_id));
|
||||
cmd.Parameters.Add (m_database.CreateParameter("UUIDZero", (UUID)UUID.Zero));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("search", "%" + words[0] + "%"));
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""='00000000-0000-0000-0000-000000000000') and (""FirstName"" ilike :searchFirst or ""LastName"" ilike :searchLast)", m_Realm);
|
||||
sql = String.Format(@"select * from {0} where (""ScopeID""=:ScopeID or ""ScopeID""=:UUIDZero) and (""FirstName"" ilike :searchFirst or ""LastName"" ilike :searchLast)", m_Realm);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("searchFirst", "%" + words[0] + "%"));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("searchLast", "%" + words[1] + "%"));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ScopeID", scopeID.ToString()));
|
||||
cmd.Parameters.Add (m_database.CreateParameter("UUIDZero", (UUID)UUID.Zero));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ScopeID", (UUID)scope_id));
|
||||
}
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
@@ -40,6 +40,8 @@ namespace OpenSim.Data.PGSQL
|
||||
public class UserProfilesData: IProfilesData
|
||||
{
|
||||
static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected PGSQLManager m_database;
|
||||
|
||||
#region Properites
|
||||
string ConnectionString
|
||||
@@ -74,6 +76,7 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
Migration m = new Migration(dbcon, Assembly, "UserProfiles");
|
||||
m.Update();
|
||||
m_database = new PGSQLManager(ConnectionString);
|
||||
}
|
||||
}
|
||||
#endregion Member Functions
|
||||
@@ -94,11 +97,11 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(ConnectionString))
|
||||
{
|
||||
string query = @"SELECT ""classifieduuid"", ""name"" FROM classifieds WHERE ""creatoruuid"" = :Id";
|
||||
string query = @"SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = :Id";
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", creatorId);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", creatorId));
|
||||
using( NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default))
|
||||
{
|
||||
if(reader.HasRows)
|
||||
@@ -111,12 +114,12 @@ namespace OpenSim.Data.PGSQL
|
||||
string Name = null;
|
||||
try
|
||||
{
|
||||
UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id);
|
||||
Id = DBGuid.FromDB(reader["classifieduuid"]);
|
||||
Name = Convert.ToString(reader["name"]);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UserAccount exception {0}", e.Message);
|
||||
}
|
||||
n.Add("classifieduuid", OSD.FromUUID(Id));
|
||||
@@ -132,28 +135,25 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result)
|
||||
{
|
||||
string query = @"INSERT INTO classifieds ( ""classifieduuid"",""creatoruuid"", ""creationdate"", ""expirationdate"", ""category"",
|
||||
""name"", ""description"", ""parceluuid"", ""parentestate"", ""snapshotuuid"", ""simname"",
|
||||
""posglobal"", ""parcelname"", ""classifiedflags"", ""priceforlisting"")
|
||||
Select :ClassifiedId, :CreatorId, :CreatedDate, :ExpirationDate, :Category,
|
||||
:Name, :Description, :ParcelId, :ParentEstate, :SnapshotId, :SimName
|
||||
:GlobalPos, :ParcelName, :Flags, :ListingPrice
|
||||
Where not exists( Select ""classifieduuid"" from classifieds where ""classifieduuid"" = :ClassifiedId );
|
||||
string query = string.Empty;
|
||||
|
||||
query = @"WITH upsert AS (
|
||||
UPDATE classifieds SET
|
||||
classifieduuid = :ClassifiedId, creatoruuid = :CreatorId, creationdate = :CreatedDate,
|
||||
expirationdate = :ExpirationDate,category =:Category, name = :Name, description = :Description,
|
||||
parceluuid = :ParcelId, parentestate = :ParentEstate, snapshotuuid = :SnapshotId,
|
||||
simname = :SimName, posglobal = :GlobalPos, parcelname = :ParcelName, classifiedflags = :Flags,
|
||||
priceforlisting = :ListingPrice
|
||||
RETURNING * )
|
||||
INSERT INTO classifieds (classifieduuid,creatoruuid,creationdate,expirationdate,category,name,
|
||||
description,parceluuid,parentestate,snapshotuuid,simname,posglobal,parcelname,classifiedflags,
|
||||
priceforlisting)
|
||||
SELECT
|
||||
:ClassifiedId,:CreatorId,:CreatedDate,:ExpirationDate,:Category,:Name,:Description,
|
||||
:ParcelId,:ParentEstate,:SnapshotId,:SimName,:GlobalPos,:ParcelName,:Flags,:ListingPrice
|
||||
WHERE NOT EXISTS (
|
||||
SELECT * FROM upsert )";
|
||||
|
||||
update classifieds
|
||||
set category =:Category,
|
||||
expirationdate = :ExpirationDate,
|
||||
name = :Name,
|
||||
description = :Description,
|
||||
parentestate = :ParentEstate,
|
||||
posglobal = :GlobalPos,
|
||||
parcelname = :ParcelName,
|
||||
classifiedflags = :Flags,
|
||||
priceforlisting = :ListingPrice,
|
||||
snapshotuuid = :SnapshotId
|
||||
where classifieduuid = :ClassifiedId ;
|
||||
";
|
||||
|
||||
if(string.IsNullOrEmpty(ad.ParcelName))
|
||||
ad.ParcelName = "Unknown";
|
||||
if(ad.ParcelId == null)
|
||||
@@ -190,21 +190,21 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("ClassifiedId", ad.ClassifiedId.ToString());
|
||||
cmd.Parameters.AddWithValue("CreatorId", ad.CreatorId.ToString());
|
||||
cmd.Parameters.AddWithValue("CreatedDate", ad.CreationDate.ToString());
|
||||
cmd.Parameters.AddWithValue("ExpirationDate", ad.ExpirationDate.ToString());
|
||||
cmd.Parameters.AddWithValue("Category", ad.Category.ToString());
|
||||
cmd.Parameters.AddWithValue("Name", ad.Name.ToString());
|
||||
cmd.Parameters.AddWithValue("Description", ad.Description.ToString());
|
||||
cmd.Parameters.AddWithValue("ParcelId", ad.ParcelId.ToString());
|
||||
cmd.Parameters.AddWithValue("ParentEstate", ad.ParentEstate.ToString());
|
||||
cmd.Parameters.AddWithValue("SnapshotId", ad.SnapshotId.ToString ());
|
||||
cmd.Parameters.AddWithValue("SimName", ad.SimName.ToString());
|
||||
cmd.Parameters.AddWithValue("GlobalPos", ad.GlobalPos.ToString());
|
||||
cmd.Parameters.AddWithValue("ParcelName", ad.ParcelName.ToString());
|
||||
cmd.Parameters.AddWithValue("Flags", ad.Flags.ToString());
|
||||
cmd.Parameters.AddWithValue("ListingPrice", ad.Price.ToString ());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ClassifiedId", ad.ClassifiedId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("CreatorId", ad.CreatorId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("CreatedDate", (int)ad.CreationDate));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ExpirationDate", (int)ad.ExpirationDate));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Category", ad.Category.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Name", ad.Name.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Description", ad.Description.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ParcelId", ad.ParcelId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ParentEstate", (int)ad.ParentEstate));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SnapshotId", ad.SnapshotId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SimName", ad.SimName.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("GlobalPos", ad.GlobalPos.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ParcelName", ad.ParcelName.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Flags", (int)Convert.ToInt32(ad.Flags)));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ListingPrice", (int)Convert.ToInt32(ad.Price)));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@@ -212,7 +212,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": ClassifiedesUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -235,7 +235,7 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("ClassifiedId", recordId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ClassifiedId", recordId));
|
||||
|
||||
lock(Lock)
|
||||
{
|
||||
@@ -246,7 +246,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": DeleteClassifiedRecord exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -267,15 +267,15 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("AdId", ad.ClassifiedId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("AdId", ad.ClassifiedId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if(reader.Read ())
|
||||
{
|
||||
ad.CreatorId = GetUUID(reader["creatoruuid"]);
|
||||
ad.ParcelId = GetUUID(reader["parceluuid"]);
|
||||
ad.SnapshotId = GetUUID(reader["snapshotuuid"]);
|
||||
ad.CreatorId = DBGuid.FromDB(reader["creatoruuid"]);
|
||||
ad.ParcelId = DBGuid.FromDB(reader["parceluuid"]);
|
||||
ad.SnapshotId = DBGuid.FromDB(reader["snapshotuuid"]);
|
||||
ad.CreationDate = Convert.ToInt32(reader["creationdate"]);
|
||||
ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]);
|
||||
ad.ParentEstate = Convert.ToInt32(reader["parentestate"]);
|
||||
@@ -287,7 +287,6 @@ namespace OpenSim.Data.PGSQL
|
||||
ad.SimName = reader["simname"].ToString();
|
||||
ad.GlobalPos = reader["posglobal"].ToString();
|
||||
ad.ParcelName = reader["parcelname"].ToString();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,8 +295,8 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": GetPickInfo exception {0}", e.Message);
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetClassifiedInfo exception {0}", e.Message);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -330,7 +329,7 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
@@ -340,7 +339,7 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
OSDMap record = new OSDMap();
|
||||
|
||||
record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"]));
|
||||
record.Add("pickuuid",OSD.FromUUID(DBGuid.FromDB(reader["pickuuid"])));
|
||||
record.Add("name",OSD.FromString((string)reader["name"]));
|
||||
data.Add(record);
|
||||
}
|
||||
@@ -351,7 +350,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarPicks exception {0}", e.Message);
|
||||
}
|
||||
return data;
|
||||
@@ -373,8 +372,8 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("CreatorId", avatarId.ToString());
|
||||
cmd.Parameters.AddWithValue("PickId", pickId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("CreatorId", avatarId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("PickId", pickId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
@@ -387,18 +386,18 @@ namespace OpenSim.Data.PGSQL
|
||||
if (string.IsNullOrEmpty(description))
|
||||
description = "No description given.";
|
||||
|
||||
UUID.TryParse((string)reader["pickuuid"], out pick.PickId);
|
||||
UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId);
|
||||
UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId);
|
||||
UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId);
|
||||
pick.GlobalPos = (string)reader["posglobal"];
|
||||
bool.TryParse((string)reader["toppick"], out pick.TopPick);
|
||||
bool.TryParse((string)reader["enabled"], out pick.Enabled);
|
||||
pick.Name = (string)reader["name"];
|
||||
pick.Desc = description;
|
||||
pick.User = (string)reader["user"];
|
||||
pick.OriginalName = (string)reader["originalname"];
|
||||
pick.SimName = (string)reader["simname"];
|
||||
pick.PickId = DBGuid.FromDB(reader["pickuuid"]);
|
||||
pick.CreatorId = DBGuid.FromDB(reader["creatoruuid"]);
|
||||
pick.ParcelId = DBGuid.FromDB(reader["parceluuid"]);
|
||||
pick.SnapshotId = DBGuid.FromDB(reader["snapshotuuid"]);
|
||||
pick.GlobalPos = (string)reader["posglobal"].ToString();
|
||||
pick.TopPick = Convert.ToBoolean(reader["toppick"]);
|
||||
pick.Enabled = Convert.ToBoolean(reader["enabled"]);
|
||||
pick.Name = reader["name"].ToString ();
|
||||
pick.Desc = reader["description"].ToString();
|
||||
pick.User = reader["user"].ToString();
|
||||
pick.OriginalName = reader["originalname"].ToString();
|
||||
pick.SimName = reader["simname"].ToString();
|
||||
pick.SortOrder = (int)reader["sortorder"];
|
||||
}
|
||||
}
|
||||
@@ -408,7 +407,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetPickInfo exception {0}", e.Message);
|
||||
}
|
||||
return pick;
|
||||
@@ -418,20 +417,22 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
string query = string.Empty;
|
||||
|
||||
query = @"INSERT INTO userpicks VALUES ( :PickId, :CreatorId, :TopPick, :ParcelId,:Name, :Desc, :SnapshotId,:User,
|
||||
:Original, :SimName, :GlobalPos, :SortOrder, :Enabled)
|
||||
where not exists ( select pickid from userpicks where pickid = :pickid);
|
||||
|
||||
Update userpicks
|
||||
set parceluuid = :ParcelId,
|
||||
name = :Name,
|
||||
description = :Desc,
|
||||
snapshotuuid = :SnapshotId,
|
||||
pickuuid = :PickId,
|
||||
posglobal = :GlobalPos
|
||||
where pickid = :PickId;
|
||||
";
|
||||
|
||||
query = @"WITH upsert AS (
|
||||
UPDATE userpicks SET
|
||||
pickuuid = :PickId, creatoruuid = :CreatorId, toppick = :TopPick, parceluuid = :ParcelId,
|
||||
name = :Name, description = :Desc, snapshotuuid = :SnapshotId, ""user"" = :User,
|
||||
originalname = :Original, simname = :SimName, posglobal = :GlobalPos,
|
||||
sortorder = :SortOrder, enabled = :Enabled
|
||||
RETURNING * )
|
||||
INSERT INTO userpicks (pickuuid,creatoruuid,toppick,parceluuid,name,description,
|
||||
snapshotuuid,""user"",originalname,simname,posglobal,sortorder,enabled)
|
||||
SELECT
|
||||
:PickId,:CreatorId,:TopPick,:ParcelId,:Name,:Desc,:SnapshotId,:User,
|
||||
:Original,:SimName,:GlobalPos,:SortOrder,:Enabled
|
||||
WHERE NOT EXISTS (
|
||||
SELECT * FROM upsert )";
|
||||
|
||||
try
|
||||
{
|
||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(ConnectionString))
|
||||
@@ -439,19 +440,19 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("PickId", pick.PickId.ToString());
|
||||
cmd.Parameters.AddWithValue("CreatorId", pick.CreatorId.ToString());
|
||||
cmd.Parameters.AddWithValue("TopPick", pick.TopPick.ToString());
|
||||
cmd.Parameters.AddWithValue("ParcelId", pick.ParcelId.ToString());
|
||||
cmd.Parameters.AddWithValue("Name", pick.Name.ToString());
|
||||
cmd.Parameters.AddWithValue("Desc", pick.Desc.ToString());
|
||||
cmd.Parameters.AddWithValue("SnapshotId", pick.SnapshotId.ToString());
|
||||
cmd.Parameters.AddWithValue("User", pick.User.ToString());
|
||||
cmd.Parameters.AddWithValue("Original", pick.OriginalName.ToString());
|
||||
cmd.Parameters.AddWithValue("SimName",pick.SimName.ToString());
|
||||
cmd.Parameters.AddWithValue("GlobalPos", pick.GlobalPos);
|
||||
cmd.Parameters.AddWithValue("SortOrder", pick.SortOrder.ToString ());
|
||||
cmd.Parameters.AddWithValue("Enabled", pick.Enabled.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("PickId", pick.PickId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("CreatorId", pick.CreatorId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("TopPick", pick.TopPick));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ParcelId", pick.ParcelId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Name", pick.Name));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Desc", pick.Desc));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SnapshotId", pick.SnapshotId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("User", pick.User));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Original", pick.OriginalName));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SimName",pick.SimName));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("GlobalPos", pick.GlobalPos));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SortOrder", pick.SortOrder));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Enabled", pick.Enabled));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@@ -459,7 +460,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UpdateAvatarNotes exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -481,7 +482,7 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("PickId", pickId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("PickId", pickId));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@@ -489,7 +490,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": DeleteUserPickRecord exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -514,8 +515,8 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", notes.UserId.ToString());
|
||||
cmd.Parameters.AddWithValue("TargetId", notes.TargetId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", notes.UserId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("TargetId", notes.TargetId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
@@ -530,7 +531,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarNotes exception {0}", e.Message);
|
||||
}
|
||||
return true;
|
||||
@@ -551,14 +552,14 @@ namespace OpenSim.Data.PGSQL
|
||||
else
|
||||
{
|
||||
remove = false;
|
||||
query = @"INSERT INTO usernotes VALUES ( :UserId, :TargetId, :Notes )
|
||||
where not exists ( Select useruuid from usernotes where useruuid = :UserId and targetuuid = :TargetId );
|
||||
|
||||
update usernotes
|
||||
set notes = :Notes
|
||||
where useruuid = :UserId
|
||||
and targetuuid = :TargetId;
|
||||
";
|
||||
query = @"WITH upsert AS (
|
||||
UPDATE usernotes SET notes = :Notes, useruuid = :UserId, targetuuid = :TargetId RETURNING * )
|
||||
INSERT INTO usernotes (notes,useruuid,targetuuid)
|
||||
SELECT :Notes,:UserId,:TargetId
|
||||
WHERE NOT EXISTS (
|
||||
SELECT * FROM upsert
|
||||
)";
|
||||
}
|
||||
|
||||
try
|
||||
@@ -569,9 +570,9 @@ namespace OpenSim.Data.PGSQL
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
if(!remove)
|
||||
cmd.Parameters.AddWithValue("Notes", note.Notes);
|
||||
cmd.Parameters.AddWithValue("TargetId", note.TargetId.ToString ());
|
||||
cmd.Parameters.AddWithValue("UserId", note.UserId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Notes", note.Notes));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("TargetId", note.TargetId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("UserId", note.UserId));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@@ -579,7 +580,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UpdateAvatarNotes exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -603,21 +604,21 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", props.UserId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", props.UserId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
if(reader.HasRows)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": Getting data for {0}.", props.UserId);
|
||||
// m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
// ": Getting data for {0}.", props.UserId);
|
||||
reader.Read();
|
||||
props.WebUrl = (string)reader["profileURL"];
|
||||
UUID.TryParse((string)reader["profileImage"], out props.ImageId);
|
||||
props.WebUrl = (string)reader["profileURL"].ToString();
|
||||
props.ImageId = DBGuid.FromDB(reader["profileImage"]);
|
||||
props.AboutText = (string)reader["profileAboutText"];
|
||||
UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId);
|
||||
props.FirstLifeImageId = DBGuid.FromDB(reader["profileFirstImage"]);
|
||||
props.FirstLifeText = (string)reader["profileFirstText"];
|
||||
UUID.TryParse((string)reader["profilePartner"], out props.PartnerId);
|
||||
props.PartnerId = DBGuid.FromDB(reader["profilePartner"]);
|
||||
props.WantToMask = (int)reader["profileWantToMask"];
|
||||
props.WantToText = (string)reader["profileWantToText"];
|
||||
props.SkillsMask = (int)reader["profileSkillsMask"];
|
||||
@@ -626,8 +627,8 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": No data for {0}", props.UserId);
|
||||
//m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
// ": No data for {0}", props.UserId);
|
||||
|
||||
props.WebUrl = string.Empty;
|
||||
props.ImageId = UUID.Zero;
|
||||
@@ -645,19 +646,19 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
query = "INSERT INTO userprofile (";
|
||||
query += "useruuid, ";
|
||||
query += "profilePartner, ";
|
||||
query += "profileAllowPublish, ";
|
||||
query += "profileMaturePublish, ";
|
||||
query += "profileURL, ";
|
||||
query += "profileWantToMask, ";
|
||||
query += "profileWantToText, ";
|
||||
query += "profileSkillsMask, ";
|
||||
query += "profileSkillsText, ";
|
||||
query += "profileLanguages, ";
|
||||
query += "profileImage, ";
|
||||
query += "profileAboutText, ";
|
||||
query += "profileFirstImage, ";
|
||||
query += "profileFirstText) VALUES (";
|
||||
query += "\"profilePartner\", ";
|
||||
query += "\"profileAllowPublish\", ";
|
||||
query += "\"profileMaturePublish\", ";
|
||||
query += "\"profileURL\", ";
|
||||
query += "\"profileWantToMask\", ";
|
||||
query += "\"profileWantToText\", ";
|
||||
query += "\"profileSkillsMask\", ";
|
||||
query += "\"profileSkillsText\", ";
|
||||
query += "\"profileLanguages\", ";
|
||||
query += "\"profileImage\", ";
|
||||
query += "\"profileAboutText\", ";
|
||||
query += "\"profileFirstImage\", ";
|
||||
query += "\"profileFirstText\") VALUES (";
|
||||
query += ":userId, ";
|
||||
query += ":profilePartner, ";
|
||||
query += ":profileAllowPublish, ";
|
||||
@@ -678,20 +679,23 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlCommand put = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
put.Parameters.AddWithValue("userId", props.UserId.ToString());
|
||||
put.Parameters.AddWithValue("profilePartner", props.PartnerId.ToString());
|
||||
put.Parameters.AddWithValue("profileAllowPublish", props.PublishProfile);
|
||||
put.Parameters.AddWithValue("profileMaturePublish", props.PublishMature);
|
||||
put.Parameters.AddWithValue("profileURL", props.WebUrl);
|
||||
put.Parameters.AddWithValue("profileWantToMask", props.WantToMask);
|
||||
put.Parameters.AddWithValue("profileWantToText", props.WantToText);
|
||||
put.Parameters.AddWithValue("profileSkillsMask", props.SkillsMask);
|
||||
put.Parameters.AddWithValue("profileSkillsText", props.SkillsText);
|
||||
put.Parameters.AddWithValue("profileLanguages", props.Language);
|
||||
put.Parameters.AddWithValue("profileImage", props.ImageId.ToString());
|
||||
put.Parameters.AddWithValue("profileAboutText", props.AboutText);
|
||||
put.Parameters.AddWithValue("profileFirstImage", props.FirstLifeImageId.ToString());
|
||||
put.Parameters.AddWithValue("profileFirstText", props.FirstLifeText);
|
||||
//m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
// ": Adding new data for {0}", props.UserId);
|
||||
|
||||
put.Parameters.Add(m_database.CreateParameter("userId", props.UserId));
|
||||
put.Parameters.Add(m_database.CreateParameter("profilePartner", props.PartnerId));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileAllowPublish", props.PublishProfile));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileMaturePublish", props.PublishMature));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileURL", props.WebUrl));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileWantToMask", props.WantToMask));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileWantToText", props.WantToText));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileSkillsMask", props.SkillsMask));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileSkillsText", props.SkillsText));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileLanguages", props.Language));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileImage", props.ImageId));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileAboutText", props.AboutText));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileFirstImage", props.FirstLifeImageId));
|
||||
put.Parameters.Add(m_database.CreateParameter("profileFirstText", props.FirstLifeText));
|
||||
|
||||
put.ExecuteNonQuery();
|
||||
}
|
||||
@@ -702,8 +706,8 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": Requst properties exception {0}", e.Message);
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Requst properties exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
}
|
||||
@@ -715,12 +719,12 @@ namespace OpenSim.Data.PGSQL
|
||||
string query = string.Empty;
|
||||
|
||||
query += "UPDATE userprofile SET ";
|
||||
query += "profileURL=:profileURL, ";
|
||||
query += "profileImage=:image, ";
|
||||
query += "profileAboutText=:abouttext,";
|
||||
query += "profileFirstImage=:firstlifeimage,";
|
||||
query += "profileFirstText=:firstlifetext ";
|
||||
query += "WHERE useruuid=:uuid";
|
||||
query += "\"profileURL\"=:profileURL, ";
|
||||
query += "\"profileImage\"=:image, ";
|
||||
query += "\"profileAboutText\"=:abouttext,";
|
||||
query += "\"profileFirstImage\"=:firstlifeimage,";
|
||||
query += "\"profileFirstText\"=:firstlifetext ";
|
||||
query += "WHERE \"useruuid\"=:uuid";
|
||||
|
||||
try
|
||||
{
|
||||
@@ -729,12 +733,12 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("profileURL", props.WebUrl);
|
||||
cmd.Parameters.AddWithValue("image", props.ImageId.ToString());
|
||||
cmd.Parameters.AddWithValue("abouttext", props.AboutText);
|
||||
cmd.Parameters.AddWithValue("firstlifeimage", props.FirstLifeImageId.ToString());
|
||||
cmd.Parameters.AddWithValue("firstlifetext", props.FirstLifeText);
|
||||
cmd.Parameters.AddWithValue("uuid", props.UserId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("profileURL", props.WebUrl));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("image", props.ImageId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("abouttext", props.AboutText));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("firstlifeimage", props.FirstLifeImageId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("firstlifetext", props.FirstLifeText));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("uuid", props.UserId));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@@ -742,7 +746,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentPropertiesUpdate exception {0}", e.Message);
|
||||
|
||||
return false;
|
||||
@@ -757,12 +761,12 @@ namespace OpenSim.Data.PGSQL
|
||||
string query = string.Empty;
|
||||
|
||||
query += "UPDATE userprofile SET ";
|
||||
query += "profileWantToMask=:WantMask, ";
|
||||
query += "profileWantToText=:WantText,";
|
||||
query += "profileSkillsMask=:SkillsMask,";
|
||||
query += "profileSkillsText=:SkillsText, ";
|
||||
query += "profileLanguages=:Languages ";
|
||||
query += "WHERE useruuid=:uuid";
|
||||
query += "\"profileWantToMask\"=:WantMask, ";
|
||||
query += "\"profileWantToText\"=:WantText,";
|
||||
query += "\"profileSkillsMask\"=:SkillsMask,";
|
||||
query += "\"profileSkillsText\"=:SkillsText, ";
|
||||
query += "\"profileLanguages\"=:Languages ";
|
||||
query += "WHERE \"useruuid\"=:uuid";
|
||||
|
||||
try
|
||||
{
|
||||
@@ -771,12 +775,12 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("WantMask", up.WantToMask);
|
||||
cmd.Parameters.AddWithValue("WantText", up.WantToText);
|
||||
cmd.Parameters.AddWithValue("SkillsMask", up.SkillsMask);
|
||||
cmd.Parameters.AddWithValue("SkillsText", up.SkillsText);
|
||||
cmd.Parameters.AddWithValue("Languages", up.Language);
|
||||
cmd.Parameters.AddWithValue("uuid", up.UserId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("WantMask", up.WantToMask));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("WantText", up.WantToText));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SkillsMask", up.SkillsMask));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("SkillsText", up.SkillsText));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Languages", up.Language));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("uuid", up.UserId));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
@@ -784,7 +788,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentInterestsUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -798,9 +802,6 @@ namespace OpenSim.Data.PGSQL
|
||||
OSDArray data = new OSDArray();
|
||||
string query = "SELECT \"snapshotuuid\" FROM {0} WHERE \"creatoruuid\" = :Id";
|
||||
|
||||
// Get classified image assets
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(ConnectionString))
|
||||
@@ -809,7 +810,7 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format (query,"\"classifieds\""), dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
@@ -817,7 +818,7 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
|
||||
data.Add(new OSDString((string)reader["snapshotuuid"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -828,7 +829,7 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format (query,"\"userpicks\""), dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
@@ -836,7 +837,7 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
data.Add(new OSDString((string)reader["snapshotuuid"].ToString ()));
|
||||
data.Add(new OSDString((string)reader["snapshotuuid"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -849,7 +850,7 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format (query,"\"userpicks\""), dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", avatarId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
@@ -857,8 +858,8 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
data.Add(new OSDString((string)reader["profileImage"].ToString ()));
|
||||
data.Add(new OSDString((string)reader["profileFirstImage"].ToString ()));
|
||||
data.Add(new OSDString((string)reader["profileImage"]));
|
||||
data.Add(new OSDString((string)reader["profileFirstImage"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -867,7 +868,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarNotes exception {0}", e.Message);
|
||||
}
|
||||
return data;
|
||||
@@ -891,7 +892,7 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", pref.UserId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", pref.UserId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
@@ -900,7 +901,7 @@ namespace OpenSim.Data.PGSQL
|
||||
reader.Read();
|
||||
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
|
||||
bool.TryParse((string)reader["visible"], out pref.Visible);
|
||||
pref.EMail = (string)reader["email"];
|
||||
pref.EMail = (string)reader["email"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -921,7 +922,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Get preferences exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
}
|
||||
@@ -934,7 +935,8 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
query += "UPDATE usersettings SET ";
|
||||
query += "imviaemail=:ImViaEmail, ";
|
||||
query += "visible=:Visible,";
|
||||
query += "visible=:Visible, ";
|
||||
query += "email=:Email ";
|
||||
query += "WHERE useruuid=:uuid";
|
||||
|
||||
try
|
||||
@@ -944,9 +946,10 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("ImViaEmail", pref.IMViaEmail.ToString().ToLower ());
|
||||
cmd.Parameters.AddWithValue("Visible", pref.Visible.ToString().ToLower ());
|
||||
cmd.Parameters.AddWithValue("uuid", pref.UserId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ImViaEmail", pref.IMViaEmail.ToString().ToLower ()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Visible", pref.Visible.ToString().ToLower ()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("EMail", pref.EMail.ToString().ToLower ()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("uuid", pref.UserId.ToString()));
|
||||
|
||||
lock(Lock)
|
||||
{
|
||||
@@ -957,7 +960,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentInterestsUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -982,8 +985,8 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Id", props.UserId.ToString());
|
||||
cmd.Parameters.AddWithValue (":TagId", props.TagId.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Id", props.UserId));
|
||||
cmd.Parameters.Add(m_database.CreateParameter(":TagId", props.TagId));
|
||||
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
@@ -1003,10 +1006,10 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
using (NpgsqlCommand put = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
put.Parameters.AddWithValue("Id", props.UserId.ToString());
|
||||
put.Parameters.AddWithValue("TagId", props.TagId.ToString());
|
||||
put.Parameters.AddWithValue("DataKey", props.DataKey.ToString());
|
||||
put.Parameters.AddWithValue("DataVal", props.DataVal.ToString());
|
||||
put.Parameters.Add(m_database.CreateParameter("Id", props.UserId));
|
||||
put.Parameters.Add(m_database.CreateParameter("TagId", props.TagId));
|
||||
put.Parameters.Add(m_database.CreateParameter("DataKey", props.DataKey.ToString()));
|
||||
put.Parameters.Add(m_database.CreateParameter("DataVal", props.DataVal.ToString()));
|
||||
|
||||
lock(Lock)
|
||||
{
|
||||
@@ -1020,7 +1023,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Requst application data exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -1046,10 +1049,10 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("UserId", props.UserId.ToString());
|
||||
cmd.Parameters.AddWithValue("TagId", props.TagId.ToString ());
|
||||
cmd.Parameters.AddWithValue("DataKey", props.DataKey.ToString ());
|
||||
cmd.Parameters.AddWithValue("DataVal", props.DataKey.ToString ());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("UserId", props.UserId.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("TagId", props.TagId.ToString ()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("DataKey", props.DataKey.ToString ()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("DataVal", props.DataKey.ToString ()));
|
||||
|
||||
lock(Lock)
|
||||
{
|
||||
@@ -1060,7 +1063,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": SetUserData exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace OpenSim.Data.PGSQL
|
||||
private const int DaysBetweenAccessTimeUpdates = 30;
|
||||
|
||||
private bool m_enableCompression = false;
|
||||
private PGSQLManager m_database;
|
||||
private string m_connectionString;
|
||||
private object m_dbLock = new object();
|
||||
|
||||
@@ -92,6 +93,7 @@ namespace OpenSim.Data.PGSQL
|
||||
m_log.ErrorFormat("[PGSQL XASSETDATA]: ***********************************************************");
|
||||
|
||||
m_connectionString = connect;
|
||||
m_database = new PGSQLManager(m_connectionString);
|
||||
|
||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||
{
|
||||
@@ -138,12 +140,12 @@ namespace OpenSim.Data.PGSQL
|
||||
dbcon.Open();
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(
|
||||
@"SELECT ""Name"", ""Description"", ""AccessTime"", ""AssetType"", ""Local"", ""Temporary"", ""AssetFlags"", ""CreatorID"", ""Data""
|
||||
@"SELECT name, description, access_time, ""AssetType"", local, temporary, asset_flags, creatorid, data
|
||||
FROM XAssetsMeta
|
||||
JOIN XAssetsData ON XAssetsMeta.Hash = XAssetsData.Hash WHERE ""ID""=:ID",
|
||||
JOIN XAssetsData ON XAssetsMeta.hash = XAssetsData.Hash WHERE id=:ID",
|
||||
dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("ID", assetID.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ID", assetID));
|
||||
|
||||
try
|
||||
{
|
||||
@@ -151,18 +153,23 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
asset = new AssetBase(assetID, (string)dbReader["Name"], (sbyte)dbReader["AssetType"], dbReader["CreatorID"].ToString());
|
||||
asset.Data = (byte[])dbReader["Data"];
|
||||
asset.Description = (string)dbReader["Description"];
|
||||
asset = new AssetBase(
|
||||
assetID,
|
||||
(string)dbReader["name"],
|
||||
Convert.ToSByte(dbReader["AssetType"]),
|
||||
dbReader["creatorid"].ToString());
|
||||
|
||||
string local = dbReader["Local"].ToString();
|
||||
asset.Data = (byte[])dbReader["data"];
|
||||
asset.Description = (string)dbReader["description"];
|
||||
|
||||
string local = dbReader["local"].ToString();
|
||||
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
|
||||
asset.Local = true;
|
||||
else
|
||||
asset.Local = false;
|
||||
|
||||
asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]);
|
||||
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
|
||||
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
|
||||
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
|
||||
if (m_enableCompression)
|
||||
{
|
||||
@@ -179,7 +186,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]);
|
||||
UpdateAccessTime(asset.Metadata, (int)dbReader["access_time"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,6 +252,9 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
byte[] hash = hasher.ComputeHash(asset.Data);
|
||||
|
||||
UUID asset_id;
|
||||
UUID.TryParse(asset.ID, out asset_id);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
|
||||
// asset.ID, asset.Name, hash, compressedData.Length);
|
||||
@@ -253,31 +263,33 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
using (NpgsqlCommand cmd =
|
||||
new NpgsqlCommand(
|
||||
@"insert INTO XAssetsMeta(""ID"", ""Hash"", ""Name"", ""Description"", ""AssetType"", ""Local"", ""Temporary"", ""CreateTime"", ""AccessTime"", ""AssetFlags"", ""CreatorID"")
|
||||
@"insert INTO XAssetsMeta(id, hash, name, description, ""AssetType"", local, temporary, create_time, access_time, asset_flags, creatorid)
|
||||
Select :ID, :Hash, :Name, :Description, :AssetType, :Local, :Temporary, :CreateTime, :AccessTime, :AssetFlags, :CreatorID
|
||||
where not exists( Select ""ID"" from XAssetsMeta where ""ID"" = :ID ;
|
||||
where not exists( Select id from XAssetsMeta where id = :ID);
|
||||
|
||||
update XAssetsMeta
|
||||
set ""ID"" = :ID, ""Hash"" = :Hash, ""Name"" = :Name, ""Description"" = :Description,
|
||||
""AssetType"" = :AssetType, ""Local"" = :Local, ""Temporary"" = :Temporary, ""CreateTime"" = :CreateTime,
|
||||
""AccessTime"" = :AccessTime, ""AssetFlags"" = :AssetFlags, ""CreatorID"" = :CreatorID
|
||||
where ""ID"" = :ID;
|
||||
set id = :ID, hash = :Hash, name = :Name, description = :Description,
|
||||
""AssetType"" = :AssetType, local = :Local, temporary = :Temporary, create_time = :CreateTime,
|
||||
access_time = :AccessTime, asset_flags = :AssetFlags, creatorid = :CreatorID
|
||||
where id = :ID;
|
||||
",
|
||||
dbcon))
|
||||
{
|
||||
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("ID", asset.ID);
|
||||
cmd.Parameters.AddWithValue("Hash", hash);
|
||||
cmd.Parameters.AddWithValue("Name", assetName);
|
||||
cmd.Parameters.AddWithValue("Description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("AssetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("Local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("Temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("CreateTime", now);
|
||||
cmd.Parameters.AddWithValue("AccessTime", now);
|
||||
cmd.Parameters.AddWithValue("CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("AssetFlags", (int)asset.Flags);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("ID", asset_id));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Hash", hash));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Name", assetName));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Description", assetDescription));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("AssetType", asset.Type));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Local", asset.Local));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Temporary", asset.Temporary));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("CreateTime", now));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("AccessTime", now));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("CreatorID", asset.Metadata.CreatorID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("AssetFlags", (int)asset.Flags));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
@@ -297,11 +309,11 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
using (NpgsqlCommand cmd =
|
||||
new NpgsqlCommand(
|
||||
@"INSERT INTO XAssetsData(""Hash"", ""Data"") VALUES(:Hash, :Data)",
|
||||
@"INSERT INTO XAssetsData(hash, data) VALUES(:Hash, :Data)",
|
||||
dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Hash", hash);
|
||||
cmd.Parameters.AddWithValue("Data", asset.Data);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Hash", hash));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Data", asset.Data));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
@@ -344,15 +356,18 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
dbcon.Open();
|
||||
NpgsqlCommand cmd =
|
||||
new NpgsqlCommand(@"update XAssetsMeta set ""AccessTime""=:AccessTime where ID=:ID", dbcon);
|
||||
new NpgsqlCommand(@"update XAssetsMeta set access_time=:AccessTime where id=:ID", dbcon);
|
||||
|
||||
try
|
||||
{
|
||||
UUID asset_id;
|
||||
UUID.TryParse(assetMetadata.ID, out asset_id);
|
||||
|
||||
using (cmd)
|
||||
{
|
||||
// create unix epoch time
|
||||
cmd.Parameters.AddWithValue("ID", assetMetadata.ID);
|
||||
cmd.Parameters.AddWithValue("AccessTime", (int)Utils.DateTimeToUnixTime(now));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("id", asset_id));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("access_time", (int)Utils.DateTimeToUnixTime(now)));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
@@ -380,9 +395,9 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
bool exists = false;
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT ""Hash"" FROM XAssetsData WHERE ""Hash""=:Hash", dbcon))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT hash FROM XAssetsData WHERE hash=:Hash", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("Hash", hash);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("Hash", hash));
|
||||
|
||||
try
|
||||
{
|
||||
@@ -419,7 +434,7 @@ namespace OpenSim.Data.PGSQL
|
||||
HashSet<UUID> exist = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format(@"SELECT ""ID"" FROM XAssetsMeta WHERE ""ID"" IN ({0})", ids);
|
||||
string sql = string.Format(@"SELECT id FROM XAssetsMeta WHERE id IN ({0})", ids);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
{
|
||||
@@ -459,9 +474,9 @@ namespace OpenSim.Data.PGSQL
|
||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT ""ID"" FROM XAssetsMeta WHERE ""ID""=:ID", dbcon))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(@"SELECT id FROM XAssetsMeta WHERE id=:ID", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("ID", uuid.ToString());
|
||||
cmd.Parameters.Add(m_database.CreateParameter("id", uuid));
|
||||
|
||||
try
|
||||
{
|
||||
@@ -503,11 +518,11 @@ namespace OpenSim.Data.PGSQL
|
||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
NpgsqlCommand cmd = new NpgsqlCommand( @"SELECT ""Name"", ""Description"", ""AccessTime"", ""AssetType"", ""Temporary"", ""ID"", ""AssetFlags"", ""CreatorID""
|
||||
NpgsqlCommand cmd = new NpgsqlCommand( @"SELECT name, description, access_time, ""AssetType"", temporary, id, asset_flags, creatorid
|
||||
FROM XAssetsMeta
|
||||
LIMIT :start, :count", dbcon);
|
||||
cmd.Parameters.AddWithValue("start", start);
|
||||
cmd.Parameters.AddWithValue("count", count);
|
||||
cmd.Parameters.Add(m_database.CreateParameter("start", start));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("count", count));
|
||||
|
||||
try
|
||||
{
|
||||
@@ -516,18 +531,18 @@ namespace OpenSim.Data.PGSQL
|
||||
while (dbReader.Read())
|
||||
{
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["Name"];
|
||||
metadata.Description = (string)dbReader["Description"];
|
||||
metadata.Type = (sbyte)dbReader["AssetType"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["Temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["ID"]);
|
||||
metadata.CreatorID = dbReader["CreatorID"].ToString();
|
||||
metadata.Name = (string)dbReader["name"];
|
||||
metadata.Description = (string)dbReader["description"];
|
||||
metadata.Type = Convert.ToSByte(dbReader["AssetType"]);
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]);
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
|
||||
metadata.CreatorID = dbReader["creatorid"].ToString();
|
||||
|
||||
// We'll ignore this for now - it appears unused!
|
||||
// metadata.SHA1 = dbReader["hash"]);
|
||||
|
||||
UpdateAccessTime(metadata, (int)dbReader["AccessTime"]);
|
||||
UpdateAccessTime(metadata, (int)dbReader["access_time"]);
|
||||
|
||||
retList.Add(metadata);
|
||||
}
|
||||
@@ -553,9 +568,9 @@ namespace OpenSim.Data.PGSQL
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(@"delete from XAssetsMeta where ""ID""=:ID", dbcon))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(@"delete from XAssetsMeta where id=:ID", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("ID", id);
|
||||
cmd.Parameters.Add(m_database.CreateParameter(id, id));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
|
||||
@@ -89,4 +89,58 @@ CREATE TABLE usersettings (
|
||||
"visible" bytea NOT NULL,
|
||||
PRIMARY KEY ("useruuid")
|
||||
);
|
||||
commit;
|
||||
commit;
|
||||
|
||||
:VERSION 4
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Classifieds
|
||||
ALTER TABLE classifieds DROP CONSTRAINT classifiedspk;
|
||||
ALTER TABLE classifieds ALTER COLUMN classifieduuid SET DATA TYPE uuid using classifieduuid::uuid;
|
||||
ALTER TABLE classifieds ALTER COLUMN creatoruuid SET DATA TYPE uuid using creatoruuid::uuid;
|
||||
ALTER TABLE classifieds ALTER COLUMN parceluuid SET DATA TYPE uuid using parceluuid::uuid;
|
||||
ALTER TABLE classifieds ALTER COLUMN snapshotuuid SET DATA TYPE uuid using snapshotuuid::uuid;
|
||||
ALTER TABLE classifieds ADD CONSTRAINT classifiedspk PRIMARY KEY (classifieduuid);
|
||||
|
||||
-- Notes
|
||||
ALTER TABLE usernotes DROP CONSTRAINT usernoteuk;
|
||||
ALTER TABLE usernotes ALTER COLUMN useruuid SET DATA TYPE uuid USING useruuid::uuid;
|
||||
ALTER TABLE usernotes ALTER COLUMN targetuuid SET DATA TYPE uuid USING targetuuid::uuid;
|
||||
ALTER TABLE usernotes ADD CONSTRAINT usernoteuk UNIQUE (useruuid,targetuuid);
|
||||
|
||||
|
||||
-- Userpicks
|
||||
ALTER TABLE userpicks DROP CONSTRAINT userpicks_pkey;
|
||||
ALTER TABLE userpicks ALTER COLUMN pickuuid SET DATA TYPE uuid USING pickuuid::uuid;
|
||||
ALTER TABLE userpicks ALTER COLUMN creatoruuid SET DATA TYPE uuid USING creatoruuid::uuid;
|
||||
ALTER TABLE userpicks ALTER COLUMN parceluuid SET DATA TYPE uuid USING parceluuid::uuid;
|
||||
ALTER TABLE userpicks ALTER COLUMN parceluuid SET DATA TYPE uuid USING parceluuid::uuid;
|
||||
ALTER TABLE userpicks ADD PRIMARY KEY (pickuuid);
|
||||
|
||||
-- Userprofile
|
||||
ALTER TABLE userprofile DROP CONSTRAINT userprofile_pkey;
|
||||
ALTER TABLE userprofile ALTER COLUMN useruuid SET DATA TYPE uuid USING useruuid::uuid;
|
||||
ALTER TABLE userprofile ALTER COLUMN "profilePartner" SET DATA TYPE uuid USING "profilePartner"::uuid;
|
||||
-- Force column conversions
|
||||
ALTER TABLE userprofile ALTER COLUMN "profileAllowPublish" SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
|
||||
ALTER TABLE userprofile ALTER COLUMN "profileMaturePublish" SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
|
||||
ALTER TABLE userprofile ALTER COLUMN "profileImage" SET DATA TYPE uuid USING "profileImage"::uuid;
|
||||
ALTER TABLE userprofile ALTER COLUMN "profileFirstImage" SET DATA TYPE uuid USING "profileFirstImage"::uuid;
|
||||
ALTER TABLE userprofile ADD PRIMARY KEY (useruuid);
|
||||
|
||||
-- Userdata
|
||||
ALTER TABLE userdata DROP CONSTRAINT userdata_pkey;
|
||||
ALTER TABLE userdata ALTER COLUMN "UserId" SET DATA TYPE uuid USING "UserId"::uuid;
|
||||
ALTER TABLE userdata ALTER COLUMN "UserId" SET DATA TYPE uuid USING "UserId"::uuid;
|
||||
ALTER TABLE userdata ADD PRIMARY KEY ("UserId","TagId");
|
||||
|
||||
|
||||
-- Usersettings
|
||||
ALTER TABLE usersettings DROP CONSTRAINT usersettings_pkey;
|
||||
ALTER TABLE usersettings ALTER COLUMN useruuid SET DATA TYPE uuid USING useruuid::uuid;
|
||||
ALTER TABLE usersettings ALTER COLUMN visible SET DATA TYPE boolean USING CASE WHEN false THEN false ELSE true END;
|
||||
ALTER TABLE usersettings ADD COLUMN email varchar(254) NOT NULL;
|
||||
ALTER TABLE usersettings ADD PRIMARY KEY (useruuid);
|
||||
|
||||
COMMIT;
|
||||
@@ -25,3 +25,51 @@ CREATE TABLE XAssetsData (
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
:VERSION 2
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE xassetsmeta ALTER COLUMN "Local" SET DATA TYPE boolean USING CASE WHEN '0' THEN FALSE ELSE TRUE END;
|
||||
ALTER TABLE xassetsmeta ALTER COLUMN "Temporary" SET DATA TYPE boolean USING CASE WHEN '0' THEN FALSE ELSE TRUE END;
|
||||
ALTER TABLE xassetsmeta ALTER COLUMN "Hash" SET DATA TYPE char(66);
|
||||
ALTER TABLE xassetsdata ALTER COLUMN "Hash" SET DATA TYPE char(66);
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 3
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "ID" TO id;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "Hash" TO hash;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "Name" TO name;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "Description" TO description;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "Local" to local;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "Temporary" TO temporary;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "CreateTime" TO create_time;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "AccessTime" TO access_time;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "AssetFlags" TO asset_flags;
|
||||
ALTER TABLE xassetsmeta RENAME COLUMN "CreatorID" TO creatorid;
|
||||
ALTER TABLE xassetsmeta DROP CONSTRAINT xassetsmeta_pkey;
|
||||
ALTER TABLE xassetsmeta ADD PRIMARY KEY (id);
|
||||
|
||||
|
||||
ALTER TABLE xassetsdata RENAME COLUMN "Hash" TO hash;
|
||||
ALTER TABLE xassetsdata RENAME COLUMN "Data" TO data;
|
||||
ALTER TABLE xassetsdata DROP CONSTRAINT xassetsdata_pkey;
|
||||
ALTER TABLE xassetsdata ADD PRIMARY KEY (hash);
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
:VERSION 4
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE xassetsmeta ALTER COLUMN id SET DATA TYPE uuid USING id::uuid;
|
||||
ALTER TABLE xassetsmeta ALTER COLUMN hash SET DATA TYPE bytea USING hash::bytea;
|
||||
ALTER TABLE xassetsdata ALTER COLUMN hash SET DATA TYPE bytea USING hash::bytea;
|
||||
|
||||
COMMIT;
|
||||
@@ -92,3 +92,110 @@ BEGIN;
|
||||
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
|
||||
:VERSION 3
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Not a pretty way to do this, but it did not work as-is
|
||||
-- and nothing was found about converting between existing data
|
||||
-- and the new type.
|
||||
-- Since there should be nothing to preserve ...
|
||||
|
||||
DROP TABLE IF EXISTS os_groups_groups CASCADE;
|
||||
|
||||
CREATE TABLE os_groups_groups (
|
||||
"GroupID" uuid PRIMARY KEY NOT NULL,
|
||||
"Location" varchar(255) NOT NULL DEFAULT '',
|
||||
"Name" varchar(255) NOT NULL DEFAULT '',
|
||||
"Charter" text NOT NULL,
|
||||
"InsigniaID" uuid NOT NULL,
|
||||
"FounderID" uuid NOT NULL,
|
||||
"MembershipFee" integer NOT NULL DEFAULT '0',
|
||||
"OpenEnrollment" varchar(255) NOT NULL DEFAULT '',
|
||||
"ShowInList" integer NOT NULL DEFAULT '0',
|
||||
"AllowPublish" integer NOT NULL DEFAULT '0',
|
||||
"MaturePublish" integer NOT NULL DEFAULT '0',
|
||||
"OwnerRoleID" uuid NOT NULL
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS os_groups_membership;
|
||||
|
||||
CREATE TABLE os_groups_membership (
|
||||
"GroupID"uuid NOT NULL,
|
||||
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
|
||||
"SelectedRoleID" uuid NOT NULL,
|
||||
"Contribution" integer NOT NULL DEFAULT '0',
|
||||
"ListInProfile" integer NOT NULL DEFAULT '1',
|
||||
"AcceptNotices" integer NOT NULL DEFAULT '1',
|
||||
"AccessToken" uuid NOT NULL,
|
||||
constraint os_groupmemberpk PRIMARY KEY ("GroupID", "PrincipalID")
|
||||
);
|
||||
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS os_groups_roles;
|
||||
|
||||
CREATE TABLE os_groups_roles (
|
||||
"GroupID" uuid NOT NULL,
|
||||
"RoleID" uuid NOT NULL,
|
||||
"Name" varchar(255) NOT NULL DEFAULT '',
|
||||
"Description" varchar(255) NOT NULL DEFAULT '',
|
||||
"Title" varchar(255) NOT NULL DEFAULT '',
|
||||
"Powers" varchar(36) NOT NULL DEFAULT '',
|
||||
constraint os_grouprolepk PRIMARY KEY ("GroupID","RoleID")
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS os_groups_rolemembership;
|
||||
|
||||
CREATE TABLE os_groups_rolemembership (
|
||||
"GroupID" uuid NOT NULL,
|
||||
"RoleID" uuid NOT NULL,
|
||||
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
|
||||
constraint os_grouprolememberpk PRIMARY KEY ("GroupID","RoleID","PrincipalID")
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS os_groups_invites;
|
||||
|
||||
CREATE TABLE os_groups_invites (
|
||||
"InviteID" uuid NOT NULL,
|
||||
"GroupID" uuid NOT NULL,
|
||||
"RoleID" uuid NOT NULL,
|
||||
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
|
||||
"TMStamp" timestamp NOT NULL DEFAULT now(),
|
||||
constraint os_groupinvitespk PRIMARY KEY ("InviteID")
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS os_groups_notices;
|
||||
|
||||
CREATE TABLE os_groups_notices (
|
||||
"GroupID" uuid NOT NULL,
|
||||
"NoticeID" uuid NOT NULL,
|
||||
"TMStamp" integer NOT NULL DEFAULT '0',
|
||||
"FromName" varchar(255) NOT NULL DEFAULT '',
|
||||
"Subject" varchar(255) NOT NULL DEFAULT '',
|
||||
"Message" text NOT NULL,
|
||||
"HasAttachment" integer NOT NULL DEFAULT '0',
|
||||
"AttachmentType" integer NOT NULL DEFAULT '0',
|
||||
"AttachmentName" varchar(128) NOT NULL DEFAULT '',
|
||||
"AttachmentItemID" uuid NOT NULL,
|
||||
"AttachmentOwnerID" varchar(255) NOT NULL DEFAULT '',
|
||||
constraint os_groupsnoticespk PRIMARY KEY ("NoticeID")
|
||||
);
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS os_groups_principals;
|
||||
|
||||
CREATE TABLE os_groups_principals (
|
||||
"PrincipalID" VARCHAR(255) NOT NULL DEFAULT '',
|
||||
"ActiveGroupID" uuid NOT NULL,
|
||||
constraint os_groupprincpk PRIMARY KEY ("PrincipalID")
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
@@ -239,7 +239,7 @@ namespace OpenSim.Data.SQLite
|
||||
if (inventoryRow == null)
|
||||
{
|
||||
if (! add)
|
||||
m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existant inventory folder: {0}", folder.ID);
|
||||
m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existent inventory folder: {0}", folder.ID);
|
||||
|
||||
inventoryRow = inventoryFolderTable.NewRow();
|
||||
fillFolderRow(inventoryRow, folder);
|
||||
@@ -298,7 +298,7 @@ namespace OpenSim.Data.SQLite
|
||||
if (inventoryRow == null)
|
||||
{
|
||||
if (!add)
|
||||
m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existant inventory item: {0}", item.ID);
|
||||
m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existent inventory item: {0}", item.ID);
|
||||
|
||||
inventoryRow = inventoryItemTable.NewRow();
|
||||
fillItemRow(inventoryRow, item);
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UserAccount exception {0}", e.Message);
|
||||
}
|
||||
n.Add("classifieduuid", OSD.FromUUID(Id));
|
||||
@@ -217,7 +217,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": ClassifiedesUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -243,7 +243,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": DeleteClassifiedRecord exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -289,7 +289,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetPickInfo exception {0}", e.Message);
|
||||
}
|
||||
return true;
|
||||
@@ -326,7 +326,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarPicks exception {0}", e.Message);
|
||||
}
|
||||
return data;
|
||||
@@ -378,7 +378,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetPickInfo exception {0}", e.Message);
|
||||
}
|
||||
return pick;
|
||||
@@ -446,7 +446,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UpdateAvatarNotes exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -471,7 +471,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": DeleteUserPickRecord exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -507,7 +507,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarNotes exception {0}", e.Message);
|
||||
}
|
||||
return true;
|
||||
@@ -550,7 +550,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": UpdateAvatarNotes exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -577,7 +577,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarProperties exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -696,7 +696,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentPropertiesUpdate exception {0}", e.Message);
|
||||
|
||||
return false;
|
||||
@@ -733,7 +733,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentInterestsUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -747,7 +747,8 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
query += "UPDATE usersettings SET ";
|
||||
query += "imviaemail=:ImViaEmail, ";
|
||||
query += "visible=:Visible ";
|
||||
query += "visible=:Visible, ";
|
||||
query += "email=:EMail ";
|
||||
query += "WHERE useruuid=:uuid";
|
||||
|
||||
try
|
||||
@@ -757,6 +758,7 @@ namespace OpenSim.Data.SQLite
|
||||
cmd.CommandText = query;
|
||||
cmd.Parameters.AddWithValue(":ImViaEmail", pref.IMViaEmail);
|
||||
cmd.Parameters.AddWithValue(":Visible", pref.Visible);
|
||||
cmd.Parameters.AddWithValue(":EMail", pref.EMail);
|
||||
cmd.Parameters.AddWithValue(":uuid", pref.UserId.ToString());
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
@@ -764,7 +766,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": AgentInterestsUpdate exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -796,7 +798,7 @@ namespace OpenSim.Data.SQLite
|
||||
{
|
||||
bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail);
|
||||
bool.TryParse((string)reader["visible"], out pref.Visible);
|
||||
pref.EMail = (string)reader["email"];
|
||||
pref.EMail = (string)reader["email"];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -816,7 +818,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Get preferences exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -871,7 +873,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": Requst application data exception {0}", e.Message);
|
||||
result = e.Message;
|
||||
return false;
|
||||
@@ -904,7 +906,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": SetUserData exception {0}", e.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -968,7 +970,7 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
m_log.ErrorFormat("[PROFILES_DATA]" +
|
||||
": GetAvatarNotes exception {0}", e.Message);
|
||||
}
|
||||
return data;
|
||||
|
||||
@@ -520,6 +520,12 @@ namespace OpenSim.Framework
|
||||
if (!m_attachments.ContainsKey(attach.AttachPoint))
|
||||
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
||||
|
||||
foreach (AvatarAttachment prev in m_attachments[attach.AttachPoint])
|
||||
{
|
||||
if (prev.ItemID == attach.ItemID)
|
||||
return;
|
||||
}
|
||||
|
||||
m_attachments[attach.AttachPoint].Add(attach);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace OpenSim.Framework
|
||||
public int assetThrottle;
|
||||
public int textureThrottle;
|
||||
public int totalThrottle;
|
||||
public int maxThrottle;
|
||||
|
||||
public Dictionary<string, int> SyncRequests = new Dictionary<string,int>();
|
||||
public Dictionary<string, int> AsyncRequests = new Dictionary<string,int>();
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace OpenSim.Framework.Communications
|
||||
/// other threads to execute, while it waits for a response from the web-service. RestClient itself can be
|
||||
/// invoked by the caller in either synchronous mode or asynchronous modes.
|
||||
/// </remarks>
|
||||
public class RestClient
|
||||
public class RestClient : IDisposable
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
@@ -148,6 +148,33 @@ namespace OpenSim.Framework.Communications
|
||||
|
||||
#endregion constructors
|
||||
|
||||
|
||||
#region Dispose
|
||||
|
||||
private bool disposed = false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
_resource.Dispose();
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
#endregion Dispose
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Add a path element to the query, e.g. assets
|
||||
/// </summary>
|
||||
@@ -320,6 +347,10 @@ namespace OpenSim.Framework.Communications
|
||||
if (auth != null)
|
||||
auth.AddAuthorization(_request.Headers);
|
||||
|
||||
int reqnum = WebUtil.RequestNumber++;
|
||||
if (WebUtil.DebugLevel >= 3)
|
||||
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
|
||||
|
||||
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
|
||||
try
|
||||
{
|
||||
@@ -366,6 +397,9 @@ namespace OpenSim.Framework.Communications
|
||||
_resource.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
WebUtil.LogResponseDetail(reqnum, _resource);
|
||||
|
||||
return _resource;
|
||||
}
|
||||
}
|
||||
@@ -382,16 +416,18 @@ namespace OpenSim.Framework.Communications
|
||||
if (auth != null)
|
||||
auth.AddAuthorization(_request.Headers);
|
||||
|
||||
m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength);
|
||||
m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri());
|
||||
src.Seek(0, SeekOrigin.Begin);
|
||||
m_log.Info("[REST]: Seek is ok");
|
||||
|
||||
int reqnum = WebUtil.RequestNumber++;
|
||||
if (WebUtil.DebugLevel >= 3)
|
||||
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src);
|
||||
|
||||
Stream dst = _request.GetRequestStream();
|
||||
m_log.Info("[REST]: GetRequestStream is ok");
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
int length = src.Read(buf, 0, 1024);
|
||||
m_log.Info("[REST]: First Read is ok");
|
||||
while (length > 0)
|
||||
{
|
||||
dst.Write(buf, 0, length);
|
||||
@@ -406,14 +442,29 @@ namespace OpenSim.Framework.Communications
|
||||
{
|
||||
m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
|
||||
RequestMethod, _request.RequestUri, e.Status, e.Message);
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[REST]: Request {0} {1} failed with exception {2} {3}",
|
||||
RequestMethod, _request.RequestUri, e.Message, e.StackTrace);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
{
|
||||
using (Stream responseStream = _response.GetResponseStream())
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(responseStream))
|
||||
{
|
||||
string responseStr = reader.ReadToEnd();
|
||||
WebUtil.LogResponseDetail(reqnum, responseStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_response.Close();
|
||||
|
||||
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
|
||||
|
||||
|
||||
@@ -424,9 +424,9 @@ namespace OpenSim.Framework.Console
|
||||
return new string[] { new List<string>(current.Keys)[0] };
|
||||
}
|
||||
|
||||
public string[] Resolve(string[] cmd)
|
||||
private CommandInfo ResolveCommand(string[] cmd, out string[] result)
|
||||
{
|
||||
string[] result = cmd;
|
||||
result = cmd;
|
||||
int index = -1;
|
||||
|
||||
Dictionary<string, object> current = tree;
|
||||
@@ -458,7 +458,7 @@ namespace OpenSim.Framework.Console
|
||||
}
|
||||
else if (found.Count > 0)
|
||||
{
|
||||
return new string[0];
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -467,21 +467,37 @@ namespace OpenSim.Framework.Console
|
||||
}
|
||||
|
||||
if (current.ContainsKey(String.Empty))
|
||||
return (CommandInfo)current[String.Empty];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool HasCommand(string command)
|
||||
{
|
||||
string[] result;
|
||||
return ResolveCommand(Parser.Parse(command), out result) != null;
|
||||
}
|
||||
|
||||
public string[] Resolve(string[] cmd)
|
||||
{
|
||||
string[] result;
|
||||
CommandInfo ci = ResolveCommand(cmd, out result);
|
||||
|
||||
if (ci == null)
|
||||
return new string[0];
|
||||
|
||||
if (ci.fn.Count == 0)
|
||||
return new string[0];
|
||||
|
||||
foreach (CommandDelegate fn in ci.fn)
|
||||
{
|
||||
CommandInfo ci = (CommandInfo)current[String.Empty];
|
||||
if (ci.fn.Count == 0)
|
||||
if (fn != null)
|
||||
fn(ci.module, result);
|
||||
else
|
||||
return new string[0];
|
||||
foreach (CommandDelegate fn in ci.fn)
|
||||
{
|
||||
if (fn != null)
|
||||
fn(ci.module, result);
|
||||
else
|
||||
return new string[0];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return new string[0];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public XmlElement GetXml(XmlDocument doc)
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace OpenSim.Framework.Console
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a console integer to an int, automatically complaining if a console is given.
|
||||
/// Convert a console input to a bool, automatically complaining if a console is given.
|
||||
/// </summary>
|
||||
/// <param name='console'>Can be null if no console is available.</param>
|
||||
/// <param name='rawConsoleVector'>/param>
|
||||
@@ -176,7 +176,7 @@ namespace OpenSim.Framework.Console
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a console integer to an int, automatically complaining if a console is given.
|
||||
/// Convert a console input to an int, automatically complaining if a console is given.
|
||||
/// </summary>
|
||||
/// <param name='console'>Can be null if no console is available.</param>
|
||||
/// <param name='rawConsoleInt'>/param>
|
||||
@@ -195,6 +195,46 @@ namespace OpenSim.Framework.Console
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a console input to a float, automatically complaining if a console is given.
|
||||
/// </summary>
|
||||
/// <param name='console'>Can be null if no console is available.</param>
|
||||
/// <param name='rawConsoleInput'>/param>
|
||||
/// <param name='i'></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryParseConsoleFloat(ICommandConsole console, string rawConsoleInput, out float i)
|
||||
{
|
||||
if (!float.TryParse(rawConsoleInput, out i))
|
||||
{
|
||||
if (console != null)
|
||||
console.OutputFormat("ERROR: {0} is not a valid float", rawConsoleInput);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a console input to a double, automatically complaining if a console is given.
|
||||
/// </summary>
|
||||
/// <param name='console'>Can be null if no console is available.</param>
|
||||
/// <param name='rawConsoleInput'>/param>
|
||||
/// <param name='i'></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryParseConsoleDouble(ICommandConsole console, string rawConsoleInput, out double i)
|
||||
{
|
||||
if (!double.TryParse(rawConsoleInput, out i))
|
||||
{
|
||||
if (console != null)
|
||||
console.OutputFormat("ERROR: {0} is not a valid double", rawConsoleInput);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a console integer to a natural int, automatically complaining if a console is given.
|
||||
/// </summary>
|
||||
|
||||
@@ -32,6 +32,8 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Framework.Console
|
||||
@@ -41,7 +43,9 @@ namespace OpenSim.Framework.Console
|
||||
/// </summary>
|
||||
public class LocalConsole : CommandConsole
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private string m_historyPath;
|
||||
private bool m_historyEnable;
|
||||
|
||||
// private readonly object m_syncRoot = new object();
|
||||
private const string LOGLEVEL_NONE = "(none)";
|
||||
@@ -79,8 +83,54 @@ namespace OpenSim.Framework.Console
|
||||
return Colors[(Math.Abs(input.ToUpper().GetHashCode()) % Colors.Length)];
|
||||
}
|
||||
|
||||
public LocalConsole(string defaultPrompt) : base(defaultPrompt)
|
||||
public LocalConsole(string defaultPrompt, IConfig startupConfig = null) : base(defaultPrompt)
|
||||
{
|
||||
|
||||
if (startupConfig == null) return;
|
||||
|
||||
m_historyEnable = startupConfig.GetBoolean("ConsoleHistoryFileEnabled", false);
|
||||
if (!m_historyEnable)
|
||||
{
|
||||
m_log.Info("[LOCAL CONSOLE]: Persistent command line history from file is Disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt");
|
||||
int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100);
|
||||
m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile));
|
||||
m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath);
|
||||
|
||||
if (File.Exists(m_historyPath))
|
||||
{
|
||||
using (StreamReader history_file = new StreamReader(m_historyPath))
|
||||
{
|
||||
string line;
|
||||
while ((line = history_file.ReadLine()) != null)
|
||||
{
|
||||
m_history.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_history.Count > m_historySize)
|
||||
{
|
||||
while (m_history.Count > m_historySize)
|
||||
m_history.RemoveAt(0);
|
||||
|
||||
using (StreamWriter history_file = new StreamWriter(m_historyPath))
|
||||
{
|
||||
foreach (string line in m_history)
|
||||
{
|
||||
history_file.WriteLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_log.InfoFormat("[LOCAL CONSOLE]: Read {0} lines of command line history from file {1}", m_history.Count, m_historyPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[LOCAL CONSOLE]: Creating new empty command line history file {0}", m_historyPath);
|
||||
File.Create(m_historyPath).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddToHistory(string text)
|
||||
@@ -89,6 +139,10 @@ namespace OpenSim.Framework.Console
|
||||
m_history.RemoveAt(0);
|
||||
|
||||
m_history.Add(text);
|
||||
if (m_historyEnable)
|
||||
{
|
||||
File.AppendAllText(m_historyPath, text + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -82,6 +82,7 @@ namespace OpenSim.Framework.Console
|
||||
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {}
|
||||
public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {}
|
||||
public string[] FindNextOption(string[] cmd, bool term) { return null; }
|
||||
public bool HasCommand(string cmd) { return false; }
|
||||
public string[] Resolve(string[] cmd) { return null; }
|
||||
public XmlElement GetXml(XmlDocument doc) { return null; }
|
||||
}
|
||||
|
||||
@@ -67,9 +67,16 @@ namespace OpenSim.Framework
|
||||
string help, string longhelp, string descriptivehelp,
|
||||
CommandDelegate fn);
|
||||
|
||||
string[] FindNextOption(string[] cmd, bool term);
|
||||
/// <summary>
|
||||
/// Has the given command already been registered?
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <param name="command">Command.</param>
|
||||
bool HasCommand(string command);
|
||||
|
||||
string[] Resolve(string[] cmd);
|
||||
string[] FindNextOption(string[] command, bool term);
|
||||
|
||||
string[] Resolve(string[] command);
|
||||
|
||||
XmlElement GetXml(XmlDocument doc);
|
||||
}
|
||||
|
||||
@@ -65,13 +65,18 @@ namespace OpenSim.Framework
|
||||
/// </remarks>
|
||||
AvatarAppearance Appearance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set if initial data about the scene (avatars, objects) has been sent to the client.
|
||||
/// </summary>
|
||||
bool SentInitialDataToClient { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Send initial scene data to the client controlling this agent
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This includes scene object data and the appearance data of other avatars.
|
||||
/// </remarks>
|
||||
void SendInitialDataToMe();
|
||||
void SendInitialDataToClient();
|
||||
|
||||
/// <summary>
|
||||
/// Direction in which the scene presence is looking.
|
||||
|
||||
312
OpenSim/Framework/Monitoring/JobEngine.cs
Normal file
312
OpenSim/Framework/Monitoring/JobEngine.cs
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Framework.Monitoring
|
||||
{
|
||||
public class Job
|
||||
{
|
||||
public string Name;
|
||||
public WaitCallback Callback;
|
||||
public object O;
|
||||
|
||||
public Job(string name, WaitCallback callback, object o)
|
||||
{
|
||||
Name = name;
|
||||
Callback = callback;
|
||||
O = o;
|
||||
}
|
||||
}
|
||||
|
||||
public class JobEngine
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public int LogLevel { get; set; }
|
||||
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping.
|
||||
/// </summary>
|
||||
public int RequestProcessTimeoutOnStop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether we need to warn in the log about exceeding the max queue size.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in
|
||||
/// order to avoid spamming the log with lots of warnings.
|
||||
/// </remarks>
|
||||
private bool m_warnOverMaxQueue = true;
|
||||
|
||||
private BlockingCollection<Job> m_requestQueue;
|
||||
|
||||
private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
|
||||
|
||||
private Stat m_requestsWaitingStat;
|
||||
|
||||
private Job m_currentJob;
|
||||
|
||||
/// <summary>
|
||||
/// Used to signal that we are ready to complete stop.
|
||||
/// </summary>
|
||||
private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
|
||||
|
||||
public JobEngine()
|
||||
{
|
||||
RequestProcessTimeoutOnStop = 5000;
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug jobengine",
|
||||
"debug jobengine <start|stop|status>",
|
||||
"Start, stop or get status of the job engine.",
|
||||
"If stopped then all jobs are processed immediately.",
|
||||
HandleControlCommand);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (IsRunning)
|
||||
return;
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
m_finishedProcessingAfterStop.Reset();
|
||||
|
||||
m_requestQueue = new BlockingCollection<Job>(new ConcurrentQueue<Job>(), 5000);
|
||||
|
||||
m_requestsWaitingStat =
|
||||
new Stat(
|
||||
"JobsWaiting",
|
||||
"Number of jobs waiting for processing.",
|
||||
"",
|
||||
"",
|
||||
"server",
|
||||
"jobengine",
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.None,
|
||||
stat => stat.Value = m_requestQueue.Count,
|
||||
StatVerbosity.Debug);
|
||||
|
||||
StatsManager.RegisterStat(m_requestsWaitingStat);
|
||||
|
||||
Watchdog.StartThread(
|
||||
ProcessRequests,
|
||||
"JobEngineThread",
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsRunning)
|
||||
return;
|
||||
|
||||
IsRunning = false;
|
||||
|
||||
int requestsLeft = m_requestQueue.Count;
|
||||
|
||||
if (requestsLeft <= 0)
|
||||
{
|
||||
m_cancelSource.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[JOB ENGINE]: Waiting to write {0} events after stop.", requestsLeft);
|
||||
|
||||
while (requestsLeft > 0)
|
||||
{
|
||||
if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
|
||||
{
|
||||
// After timeout no events have been written
|
||||
if (requestsLeft == m_requestQueue.Count)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[JOB ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests",
|
||||
RequestProcessTimeoutOnStop, requestsLeft);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
requestsLeft = m_requestQueue.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_cancelSource.Dispose();
|
||||
StatsManager.DeregisterStat(m_requestsWaitingStat);
|
||||
m_requestsWaitingStat = null;
|
||||
m_requestQueue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool QueueRequest(string name, WaitCallback req, object o)
|
||||
{
|
||||
if (LogLevel >= 1)
|
||||
m_log.DebugFormat("[JOB ENGINE]: Queued job {0}", name);
|
||||
|
||||
if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
|
||||
// categories, client.AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
m_requestQueue.Add(new Job(name, req, o));
|
||||
|
||||
if (!m_warnOverMaxQueue)
|
||||
m_warnOverMaxQueue = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_warnOverMaxQueue)
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[JOB ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
|
||||
// client.AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
m_log.WarnFormat("[JOB ENGINE]: Request queue at maximum capacity, not recording job");
|
||||
|
||||
m_warnOverMaxQueue = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessRequests()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (IsRunning || m_requestQueue.Count > 0)
|
||||
{
|
||||
m_currentJob = m_requestQueue.Take(m_cancelSource.Token);
|
||||
|
||||
// QueueEmpty callback = req.Client.OnQueueEmpty;
|
||||
//
|
||||
// if (callback != null)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// callback(req.Categories);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e);
|
||||
// }
|
||||
// }
|
||||
|
||||
if (LogLevel >= 1)
|
||||
m_log.DebugFormat("[JOB ENGINE]: Processing job {0}", m_currentJob.Name);
|
||||
|
||||
m_currentJob.Callback.Invoke(m_currentJob.O);
|
||||
|
||||
if (LogLevel >= 1)
|
||||
m_log.DebugFormat("[JOB ENGINE]: Processed job {0}", m_currentJob.Name);
|
||||
|
||||
m_currentJob = null;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
|
||||
m_finishedProcessingAfterStop.Set();
|
||||
}
|
||||
|
||||
private void HandleControlCommand(string module, string[] args)
|
||||
{
|
||||
// if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
// return;
|
||||
|
||||
if (args.Length < 3)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug jobengine <stop|start|status|loglevel>");
|
||||
return;
|
||||
}
|
||||
|
||||
string subCommand = args[2];
|
||||
|
||||
if (subCommand == "stop")
|
||||
{
|
||||
Stop();
|
||||
MainConsole.Instance.OutputFormat("Stopped job engine.");
|
||||
}
|
||||
else if (subCommand == "start")
|
||||
{
|
||||
Start();
|
||||
MainConsole.Instance.OutputFormat("Started job engine.");
|
||||
}
|
||||
else if (subCommand == "status")
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Job engine running: {0}", IsRunning);
|
||||
MainConsole.Instance.OutputFormat("Current job {0}", m_currentJob != null ? m_currentJob.Name : "none");
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Jobs waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
|
||||
MainConsole.Instance.OutputFormat("Log Level: {0}", LogLevel);
|
||||
}
|
||||
|
||||
else if (subCommand == "loglevel")
|
||||
{
|
||||
// int logLevel;
|
||||
int logLevel = int.Parse(args[3]);
|
||||
// if (ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out logLevel))
|
||||
// {
|
||||
LogLevel = logLevel;
|
||||
MainConsole.Instance.OutputFormat("Set log level to {0}", LogLevel);
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Unrecognized job engine subcommand {0}", subCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,9 @@ namespace OpenSim.Framework.Monitoring
|
||||
// IRegionModuleBase.Initialize
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
if (source == null)
|
||||
return;
|
||||
|
||||
IConfig cfg = source.Configs["Monitoring"];
|
||||
|
||||
if (cfg != null)
|
||||
@@ -141,19 +144,19 @@ namespace OpenSim.Framework.Monitoring
|
||||
processorPercentPerfCounter = new PerfCounterControl(tempPC);
|
||||
// A long time bug in mono is that CPU percent is reported as CPU percent idle. Windows reports CPU percent busy.
|
||||
tempStat = new Stat(tempName, tempName, "", "percent", CategoryServer, ContainerProcessor,
|
||||
StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter, Util.IsWindows() ? 1 : -1); },
|
||||
StatType.Pull, (s) => { GetNextValue(s, processorPercentPerfCounter); },
|
||||
StatVerbosity.Info);
|
||||
StatsManager.RegisterStat(tempStat);
|
||||
RegisteredStats.Add(tempName, tempStat);
|
||||
|
||||
MakeStat("TotalProcessorTime", null, "sec", ContainerProcessor,
|
||||
(s) => { s.Value = Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds; });
|
||||
(s) => { s.Value = Math.Round(Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds, 3); });
|
||||
|
||||
MakeStat("UserProcessorTime", null, "sec", ContainerProcessor,
|
||||
(s) => { s.Value = Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; });
|
||||
(s) => { s.Value = Math.Round(Process.GetCurrentProcess().UserProcessorTime.TotalSeconds, 3); });
|
||||
|
||||
MakeStat("PrivilegedProcessorTime", null, "sec", ContainerProcessor,
|
||||
(s) => { s.Value = Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; });
|
||||
(s) => { s.Value = Math.Round(Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds, 3); });
|
||||
|
||||
MakeStat("Threads", null, "threads", ContainerProcessor,
|
||||
(s) => { s.Value = Process.GetCurrentProcess().Threads.Count; });
|
||||
@@ -253,11 +256,8 @@ namespace OpenSim.Framework.Monitoring
|
||||
// "How to get the CPU Usage in C#": http://stackoverflow.com/questions/278071/how-to-get-the-cpu-usage-in-c
|
||||
// "Mono Performance Counters": http://www.mono-project.com/Mono_Performance_Counters
|
||||
private delegate double PerfCounterNextValue();
|
||||
|
||||
private void GetNextValue(Stat stat, PerfCounterControl perfControl)
|
||||
{
|
||||
GetNextValue(stat, perfControl, 1.0);
|
||||
}
|
||||
private void GetNextValue(Stat stat, PerfCounterControl perfControl, double factor)
|
||||
{
|
||||
if (Util.EnvironmentTickCountSubtract(perfControl.lastFetch) > performanceCounterSampleInterval)
|
||||
{
|
||||
@@ -265,16 +265,13 @@ namespace OpenSim.Framework.Monitoring
|
||||
{
|
||||
try
|
||||
{
|
||||
// Kludge for factor to run double duty. If -1, subtract the value from one
|
||||
if (factor == -1)
|
||||
stat.Value = 1 - perfControl.perfCounter.NextValue();
|
||||
else
|
||||
stat.Value = perfControl.perfCounter.NextValue() / factor;
|
||||
stat.Value = Math.Round(perfControl.perfCounter.NextValue(), 3);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("{0} Exception on NextValue fetching {1}: {2}", LogHeader, stat.Name, e);
|
||||
}
|
||||
|
||||
perfControl.lastFetch = Util.EnvironmentTickCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,8 @@ namespace OpenSim.Framework.Monitoring
|
||||
foreach (char c in DisallowedShortNameCharacters)
|
||||
{
|
||||
if (shortName.IndexOf(c) != -1)
|
||||
throw new Exception(string.Format("Stat name {0} cannot contain character {1}", shortName, c));
|
||||
shortName = shortName.Replace(c, '#');
|
||||
// throw new Exception(string.Format("Stat name {0} cannot contain character {1}", shortName, c));
|
||||
}
|
||||
|
||||
ShortName = shortName;
|
||||
|
||||
@@ -70,18 +70,18 @@ namespace OpenSim.Framework.Monitoring
|
||||
{
|
||||
ICommandConsole con = MainConsole.Instance;
|
||||
|
||||
if (cmd.Length != 4)
|
||||
if (cmd.Length != 3)
|
||||
{
|
||||
con.Output("Usage: debug stats record start|stop");
|
||||
con.Output("Usage: stats record start|stop");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd[3] == "start")
|
||||
if (cmd[2] == "start")
|
||||
{
|
||||
Start();
|
||||
con.OutputFormat("Now recording all stats to file every {0}ms", m_statsLogIntervalMs);
|
||||
}
|
||||
else if (cmd[3] == "stop")
|
||||
else if (cmd[2] == "stop")
|
||||
{
|
||||
Stop();
|
||||
con.Output("Stopped recording stats to file.");
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace OpenSim.Framework.Monitoring
|
||||
/// </summary>
|
||||
public Stat Stat { get; set; }
|
||||
|
||||
public ThreadWatchdogInfo(Thread thread, int timeout)
|
||||
public ThreadWatchdogInfo(Thread thread, int timeout, string name)
|
||||
{
|
||||
Thread = thread;
|
||||
Timeout = timeout;
|
||||
@@ -96,8 +96,8 @@ namespace OpenSim.Framework.Monitoring
|
||||
|
||||
Stat
|
||||
= new Stat(
|
||||
thread.Name,
|
||||
string.Format("Last update of thread {0}", thread.Name),
|
||||
name,
|
||||
string.Format("Last update of thread {0}", name),
|
||||
"",
|
||||
"ms",
|
||||
"server",
|
||||
@@ -133,6 +133,8 @@ namespace OpenSim.Framework.Monitoring
|
||||
/// /summary>
|
||||
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
|
||||
|
||||
public static JobEngine JobEngine { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this watchdog active?
|
||||
/// </summary>
|
||||
@@ -173,6 +175,7 @@ namespace OpenSim.Framework.Monitoring
|
||||
|
||||
static Watchdog()
|
||||
{
|
||||
JobEngine = new JobEngine();
|
||||
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
|
||||
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
||||
m_watchdogTimer.AutoReset = false;
|
||||
@@ -187,15 +190,16 @@ namespace OpenSim.Framework.Monitoring
|
||||
/// <param name="priority">Priority to run the thread at</param>
|
||||
/// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
|
||||
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
|
||||
/// <param name="log">If true then creation of thread is logged.</param>
|
||||
/// <returns>The newly created Thread object</returns>
|
||||
public static Thread StartThread(
|
||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
|
||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, bool log = true)
|
||||
{
|
||||
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS, log);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a new thread that is tracked by the watchdog timer
|
||||
/// Start a new thread that is tracked by the watchdog
|
||||
/// </summary>
|
||||
/// <param name="start">The method that will be executed in a new thread</param>
|
||||
/// <param name="name">A name to give to the new thread</param>
|
||||
@@ -208,31 +212,67 @@ namespace OpenSim.Framework.Monitoring
|
||||
/// Normally, this will just return some useful debugging information.
|
||||
/// </param>
|
||||
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
|
||||
/// <param name="log">If true then creation of thread is logged.</param>
|
||||
/// <returns>The newly created Thread object</returns>
|
||||
public static Thread StartThread(
|
||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground,
|
||||
bool alarmIfTimeout, Func<string> alarmMethod, int timeout)
|
||||
bool alarmIfTimeout, Func<string> alarmMethod, int timeout, bool log = true)
|
||||
{
|
||||
Thread thread = new Thread(start);
|
||||
thread.Name = name;
|
||||
thread.Priority = priority;
|
||||
thread.IsBackground = isBackground;
|
||||
|
||||
ThreadWatchdogInfo twi
|
||||
= new ThreadWatchdogInfo(thread, timeout)
|
||||
= new ThreadWatchdogInfo(thread, timeout, name)
|
||||
{ AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
||||
if (log)
|
||||
m_log.DebugFormat(
|
||||
"[WATCHDOG]: Started tracking thread {0}, ID {1}", name, twi.Thread.ManagedThreadId);
|
||||
|
||||
lock (m_threads)
|
||||
m_threads.Add(twi.Thread.ManagedThreadId, twi);
|
||||
|
||||
|
||||
thread.Start();
|
||||
thread.Name = name;
|
||||
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run the callback in a new thread immediately. If the thread exits with an exception log it but do
|
||||
/// not propogate it.
|
||||
/// </summary>
|
||||
/// <param name="callback">Code for the thread to execute.</param>
|
||||
/// <param name="name">Name of the thread</param>
|
||||
/// <param name="obj">Object to pass to the thread.</param>
|
||||
public static void RunInThread(WaitCallback callback, string name, object obj, bool log = false)
|
||||
{
|
||||
if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
callback(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadStart ts = new ThreadStart(delegate()
|
||||
{
|
||||
try
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
callback(obj);
|
||||
Watchdog.RemoveThread(log:false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(string.Format("[WATCHDOG]: Exception in thread {0}.", name), e);
|
||||
}
|
||||
});
|
||||
|
||||
StartThread(ts, name, ThreadPriority.Normal, true, false, log:log);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks the current thread as alive
|
||||
/// </summary>
|
||||
@@ -244,24 +284,26 @@ namespace OpenSim.Framework.Monitoring
|
||||
/// <summary>
|
||||
/// Stops watchdog tracking on the current thread
|
||||
/// </summary>
|
||||
/// <param name="log">If true then normal events in thread removal are not logged.</param>
|
||||
/// <returns>
|
||||
/// True if the thread was removed from the list of tracked
|
||||
/// threads, otherwise false
|
||||
/// </returns>
|
||||
public static bool RemoveThread()
|
||||
public static bool RemoveThread(bool log = true)
|
||||
{
|
||||
return RemoveThread(Thread.CurrentThread.ManagedThreadId);
|
||||
return RemoveThread(Thread.CurrentThread.ManagedThreadId, log);
|
||||
}
|
||||
|
||||
private static bool RemoveThread(int threadID)
|
||||
private static bool RemoveThread(int threadID, bool log = true)
|
||||
{
|
||||
lock (m_threads)
|
||||
{
|
||||
ThreadWatchdogInfo twi;
|
||||
if (m_threads.TryGetValue(threadID, out twi))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
||||
if (log)
|
||||
m_log.DebugFormat(
|
||||
"[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
||||
|
||||
twi.Cleanup();
|
||||
m_threads.Remove(threadID);
|
||||
@@ -411,5 +453,20 @@ namespace OpenSim.Framework.Monitoring
|
||||
|
||||
m_watchdogTimer.Start();
|
||||
}
|
||||
|
||||
public static void RunWhenPossible(string jobType, WaitCallback callback, string name, object obj, bool log = false)
|
||||
{
|
||||
if (Util.FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
callback(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (JobEngine.IsRunning)
|
||||
JobEngine.QueueRequest(name, callback, obj);
|
||||
else
|
||||
RunInThread(callback, name, obj, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,6 @@ namespace OpenSim.Framework
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[REGION INFO]";
|
||||
|
||||
public bool commFailTF = false;
|
||||
public string RegionFile = String.Empty;
|
||||
public bool isSandbox = false;
|
||||
public bool Persistent = true;
|
||||
@@ -128,7 +127,6 @@ namespace OpenSim.Framework
|
||||
private int m_objectCapacity = 0;
|
||||
private int m_maxPrimsPerUser = -1;
|
||||
private int m_linksetCapacity = 0;
|
||||
private int m_agentCapacity = 0;
|
||||
private string m_regionType = String.Empty;
|
||||
private RegionLightShareData m_windlight = new RegionLightShareData();
|
||||
protected uint m_httpPort;
|
||||
@@ -352,10 +350,7 @@ namespace OpenSim.Framework
|
||||
get { return m_linksetCapacity; }
|
||||
}
|
||||
|
||||
public int AgentCapacity
|
||||
{
|
||||
get { return m_agentCapacity; }
|
||||
}
|
||||
public int AgentCapacity { get; set; }
|
||||
|
||||
public byte AccessLevel
|
||||
{
|
||||
@@ -749,7 +744,7 @@ namespace OpenSim.Framework
|
||||
|
||||
#endregion
|
||||
|
||||
m_agentCapacity = config.GetInt("MaxAgents", 100);
|
||||
AgentCapacity = config.GetInt("MaxAgents", 100);
|
||||
allKeys.Remove("MaxAgents");
|
||||
|
||||
// Multi-tenancy
|
||||
@@ -865,8 +860,8 @@ namespace OpenSim.Framework
|
||||
if (m_linksetCapacity > 0)
|
||||
config.Set("LinksetPrims", m_linksetCapacity);
|
||||
|
||||
if (m_agentCapacity > 0)
|
||||
config.Set("MaxAgents", m_agentCapacity);
|
||||
if (AgentCapacity > 0)
|
||||
config.Set("MaxAgents", AgentCapacity);
|
||||
|
||||
if (ScopeID != UUID.Zero)
|
||||
config.Set("ScopeID", ScopeID.ToString());
|
||||
@@ -881,11 +876,6 @@ namespace OpenSim.Framework
|
||||
config.Set("MaptileStaticFile", MaptileStaticFile);
|
||||
}
|
||||
|
||||
public bool ignoreIncomingConfiguration(string configuration_key, object configuration_result)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SaveRegionToFile(string description, string filename)
|
||||
{
|
||||
if (filename.ToLower().EndsWith(".ini"))
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <param name="xtr"></param>
|
||||
/// <returns>true on successful, false if there were any processing failures</returns>
|
||||
public static bool ExecuteReadProcessors<NodeType>(
|
||||
NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlTextReader>> processors, XmlTextReader xtr)
|
||||
NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlReader>> processors, XmlReader xtr)
|
||||
{
|
||||
return ExecuteReadProcessors(
|
||||
nodeToFill,
|
||||
@@ -75,8 +75,8 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <returns>true on successful, false if there were any processing failures</returns>
|
||||
public static bool ExecuteReadProcessors<NodeType>(
|
||||
NodeType nodeToFill,
|
||||
Dictionary<string, Action<NodeType, XmlTextReader>> processors,
|
||||
XmlTextReader xtr,
|
||||
Dictionary<string, Action<NodeType, XmlReader>> processors,
|
||||
XmlReader xtr,
|
||||
Action<NodeType, string, Exception> parseExceptionAction)
|
||||
{
|
||||
bool errors = false;
|
||||
@@ -88,7 +88,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
|
||||
// m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName);
|
||||
|
||||
Action<NodeType, XmlTextReader> p = null;
|
||||
Action<NodeType, XmlReader> p = null;
|
||||
if (processors.TryGetValue(xtr.Name, out p))
|
||||
{
|
||||
// m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName);
|
||||
|
||||
@@ -44,11 +44,11 @@ namespace OpenSim.Framework.Serialization.External
|
||||
{
|
||||
// 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>>();
|
||||
private static Dictionary<string, Action<LandData, XmlReader>> m_ldProcessors
|
||||
= new Dictionary<string, Action<LandData, XmlReader>>();
|
||||
|
||||
private static Dictionary<string, Action<LandAccessEntry, XmlTextReader>> m_laeProcessors
|
||||
= new Dictionary<string, Action<LandAccessEntry, XmlTextReader>>();
|
||||
private static Dictionary<string, Action<LandAccessEntry, XmlReader>> m_laeProcessors
|
||||
= new Dictionary<string, Action<LandAccessEntry, XmlReader>>();
|
||||
|
||||
static LandDataSerializer()
|
||||
{
|
||||
@@ -134,7 +134,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
"AccessList", (lae, xtr) => lae.Flags = (AccessList)Convert.ToUInt32(xtr.ReadElementString("AccessList")));
|
||||
}
|
||||
|
||||
public static void ProcessParcelAccessList(LandData ld, XmlTextReader xtr)
|
||||
public static void ProcessParcelAccessList(LandData ld, XmlReader xtr)
|
||||
{
|
||||
if (!xtr.IsEmptyElement)
|
||||
{
|
||||
|
||||
@@ -46,8 +46,8 @@ namespace OpenSim.Framework.Serialization.External
|
||||
{
|
||||
// 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>>();
|
||||
private static Dictionary<string, Action<InventoryItemBase, XmlReader>> m_InventoryItemXmlProcessors
|
||||
= new Dictionary<string, Action<InventoryItemBase, XmlReader>>();
|
||||
|
||||
#region InventoryItemBase Processor initialization
|
||||
static UserInventoryItemSerializer()
|
||||
@@ -76,103 +76,103 @@ namespace OpenSim.Framework.Serialization.External
|
||||
#endregion
|
||||
|
||||
#region InventoryItemBase Processors
|
||||
private static void ProcessName(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessName(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.Name = reader.ReadElementContentAsString("Name", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessID(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessID(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.ID = Util.ReadUUID(reader, "ID");
|
||||
}
|
||||
|
||||
private static void ProcessInvType(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessInvType(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.InvType = reader.ReadElementContentAsInt("InvType", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessCreatorUUID(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessCreatorUUID(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.CreatorId = reader.ReadElementContentAsString("CreatorUUID", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessCreatorID(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessCreatorID(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
// when it exists, this overrides the previous
|
||||
item.CreatorId = reader.ReadElementContentAsString("CreatorID", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessCreationDate(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessCreationDate(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessOwner(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessOwner(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.Owner = Util.ReadUUID(reader, "Owner");
|
||||
}
|
||||
|
||||
private static void ProcessDescription(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessDescription(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.Description = reader.ReadElementContentAsString("Description", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessAssetType(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessAssetType(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.AssetType = reader.ReadElementContentAsInt("AssetType", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessAssetID(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessAssetID(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.AssetID = Util.ReadUUID(reader, "AssetID");
|
||||
}
|
||||
|
||||
private static void ProcessSaleType(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessSaleType(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.SaleType = (byte)reader.ReadElementContentAsInt("SaleType", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessSalePrice(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessSalePrice(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessBasePermissions(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessBasePermissions(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.BasePermissions = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessCurrentPermissions(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessCurrentPermissions(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.CurrentPermissions = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.EveryOnePermissions = (uint)reader.ReadElementContentAsInt("EveryOnePermissions", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessNextPermissions(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessNextPermissions(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.NextPermissions = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessFlags(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessFlags(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.Flags = (uint)reader.ReadElementContentAsInt("Flags", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessGroupID(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessGroupID(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.GroupID = Util.ReadUUID(reader, "GroupID");
|
||||
}
|
||||
|
||||
private static void ProcessGroupOwned(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessGroupOwned(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.GroupOwned = Util.ReadBoolean(reader);
|
||||
}
|
||||
|
||||
private static void ProcessCreatorData(InventoryItemBase item, XmlTextReader reader)
|
||||
private static void ProcessCreatorData(InventoryItemBase item, XmlReader reader)
|
||||
{
|
||||
item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty);
|
||||
}
|
||||
|
||||
@@ -832,28 +832,40 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
return; // never log these; they're just binary data
|
||||
|
||||
Stream inputStream = Util.Copy(request.InputStream);
|
||||
|
||||
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
|
||||
inputStream = new GZipStream(inputStream, System.IO.Compression.CompressionMode.Decompress);
|
||||
|
||||
using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
|
||||
Stream innerStream = null;
|
||||
try
|
||||
{
|
||||
string output;
|
||||
|
||||
if (DebugLevel == 5)
|
||||
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
|
||||
{
|
||||
char[] chars = new char[WebUtil.MaxRequestDiagLength + 1]; // +1 so we know to add "..." only if needed
|
||||
int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1);
|
||||
output = new string(chars, 0, Math.Min(len, WebUtil.MaxRequestDiagLength));
|
||||
if (len > WebUtil.MaxRequestDiagLength)
|
||||
output += "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
output = reader.ReadToEnd();
|
||||
innerStream = inputStream;
|
||||
inputStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress);
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output));
|
||||
using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
|
||||
{
|
||||
string output;
|
||||
|
||||
if (DebugLevel == 5)
|
||||
{
|
||||
char[] chars = new char[WebUtil.MaxRequestDiagLength + 1]; // +1 so we know to add "..." only if needed
|
||||
int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1);
|
||||
output = new string(chars, 0, Math.Min(len, WebUtil.MaxRequestDiagLength));
|
||||
if (len > WebUtil.MaxRequestDiagLength)
|
||||
output += "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
output = reader.ReadToEnd();
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (innerStream != null)
|
||||
innerStream.Dispose();
|
||||
inputStream.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -981,19 +993,33 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
/// <param name="response"></param>
|
||||
private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
|
||||
{
|
||||
String requestBody;
|
||||
|
||||
Stream requestStream = request.InputStream;
|
||||
Stream innerStream = null;
|
||||
try
|
||||
{
|
||||
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
|
||||
{
|
||||
innerStream = requestStream;
|
||||
requestStream = new GZipStream(innerStream, System.IO.Compression.CompressionMode.Decompress);
|
||||
}
|
||||
|
||||
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
|
||||
requestStream = new GZipStream(requestStream, System.IO.Compression.CompressionMode.Decompress);
|
||||
using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
|
||||
{
|
||||
requestBody = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (innerStream != null)
|
||||
innerStream.Dispose();
|
||||
requestStream.Dispose();
|
||||
}
|
||||
|
||||
Encoding encoding = Encoding.UTF8;
|
||||
StreamReader reader = new StreamReader(requestStream, encoding);
|
||||
|
||||
string requestBody = reader.ReadToEnd();
|
||||
reader.Close();
|
||||
requestStream.Close();
|
||||
//m_log.Debug(requestBody);
|
||||
requestBody = requestBody.Replace("<base64></base64>", "");
|
||||
|
||||
string responseString = String.Empty;
|
||||
XmlRpcRequest xmlRprcRequest = null;
|
||||
|
||||
@@ -1089,18 +1115,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
response.ContentType = "text/xml";
|
||||
using (MemoryStream outs = new MemoryStream())
|
||||
using (XmlTextWriter writer = new XmlTextWriter(outs, Encoding.UTF8))
|
||||
{
|
||||
using (XmlTextWriter writer = new XmlTextWriter(outs, Encoding.UTF8))
|
||||
writer.Formatting = Formatting.None;
|
||||
XmlRpcResponseSerializer.Singleton.Serialize(writer, xmlRpcResponse);
|
||||
writer.Flush();
|
||||
outs.Flush();
|
||||
outs.Position = 0;
|
||||
using (StreamReader sr = new StreamReader(outs))
|
||||
{
|
||||
writer.Formatting = Formatting.None;
|
||||
XmlRpcResponseSerializer.Singleton.Serialize(writer, xmlRpcResponse);
|
||||
writer.Flush();
|
||||
outs.Flush();
|
||||
outs.Position = 0;
|
||||
using (StreamReader sr = new StreamReader(outs))
|
||||
{
|
||||
responseString = sr.ReadToEnd();
|
||||
}
|
||||
responseString = sr.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
@@ -61,6 +62,24 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
Description = description;
|
||||
m_httpMethod = httpMethod;
|
||||
m_path = path;
|
||||
|
||||
// FIXME: A very temporary measure to stop the simulator stats being overwhelmed with user CAPS info.
|
||||
// Needs to be fixed properly in stats display
|
||||
if (!path.StartsWith("/CAPS/"))
|
||||
{
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
"requests",
|
||||
"requests",
|
||||
"Number of requests received by this service endpoint",
|
||||
"requests",
|
||||
"service",
|
||||
string.Format("{0}:{1}", httpMethod, path),
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.AverageChangeOverTime,
|
||||
s => s.Value = RequestsReceived,
|
||||
StatVerbosity.Debug));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual string Path
|
||||
|
||||
@@ -70,9 +70,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
_id = id;
|
||||
|
||||
_engine = new Thread(new ThreadStart(Engine));
|
||||
_engine.Name = EngineID;
|
||||
_engine.IsBackground = true;
|
||||
_engine.Start();
|
||||
_engine.Name = string.Format ("Engine:{0}",EngineID);
|
||||
|
||||
ThreadTracker.Add(_engine);
|
||||
}
|
||||
@@ -91,9 +91,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
public void Start()
|
||||
{
|
||||
_engine = new Thread(new ThreadStart(Engine));
|
||||
_engine.Name = EngineID;
|
||||
_engine.IsBackground = true;
|
||||
_engine.Start();
|
||||
_engine.Name = string.Format ("Engine:{0}",EngineID);
|
||||
|
||||
ThreadTracker.Add(_engine);
|
||||
}
|
||||
|
||||
@@ -150,9 +150,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
public void Start()
|
||||
{
|
||||
_engine = new Thread(new ThreadStart(Engine));
|
||||
_engine.Name = _engineId;
|
||||
_engine.IsBackground = true;
|
||||
_engine.Start();
|
||||
_engine.Name = string.Format ("Engine:{0}",_engineId);
|
||||
|
||||
ThreadTracker.Add(_engine);
|
||||
|
||||
|
||||
@@ -52,23 +52,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
request.Method = verb;
|
||||
request.ContentType = "text/xml";
|
||||
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
using (MemoryStream buffer = new MemoryStream())
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, obj);
|
||||
writer.Flush();
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, obj);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
int length = (int)buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
}
|
||||
|
||||
int length = (int) buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
Stream requestStream = request.GetRequestStream();
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
|
||||
request.BeginGetResponse(AsyncCallback, request);
|
||||
}
|
||||
|
||||
@@ -60,24 +60,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
request.ContentType = "text/xml";
|
||||
request.Timeout = 10000;
|
||||
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
using (MemoryStream buffer = new MemoryStream())
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, obj);
|
||||
writer.Flush();
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, obj);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
int length = (int)buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
}
|
||||
|
||||
int length = (int) buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
Stream requestStream = request.GetRequestStream();
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
requestStream.Close();
|
||||
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
|
||||
request.BeginGetResponse(AsyncCallback, request);
|
||||
}
|
||||
|
||||
@@ -77,26 +77,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
request.ContentType = "text/xml";
|
||||
request.Timeout = 20000;
|
||||
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
using (MemoryStream buffer = new MemoryStream())
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, sobj);
|
||||
writer.Flush();
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, sobj);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
int length = (int)buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
}
|
||||
|
||||
int length = (int)buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
Stream requestStream = request.GetRequestStream();
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
buffer.Close();
|
||||
requestStream.Close();
|
||||
|
||||
TResponse deserial = default(TResponse);
|
||||
using (WebResponse resp = request.GetResponse())
|
||||
{
|
||||
@@ -133,25 +132,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
request.ContentType = "text/xml";
|
||||
request.Timeout = 10000;
|
||||
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
using (MemoryStream buffer = new MemoryStream())
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, sobj);
|
||||
writer.Flush();
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(buffer, settings))
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(type);
|
||||
serializer.Serialize(writer, sobj);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
int length = (int)buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
}
|
||||
buffer.Close();
|
||||
|
||||
int length = (int)buffer.Length;
|
||||
request.ContentLength = length;
|
||||
|
||||
Stream requestStream = request.GetRequestStream();
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
requestStream.Close();
|
||||
// IAsyncResult result = request.BeginGetResponse(AsyncCallback, request);
|
||||
request.BeginGetResponse(AsyncCallback, request);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
using Animation = OpenSim.Framework.Animation;
|
||||
|
||||
namespace OpenSim.Framework.Tests
|
||||
|
||||
@@ -25,55 +25,48 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using System;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// Mock scene for unit tests
|
||||
/// A thread-safe Random since the .NET version is not.
|
||||
/// See http://msdn.microsoft.com/en-us/library/system.random%28v=vs.100%29.aspx
|
||||
/// </summary>
|
||||
public class MockScene : SceneBase
|
||||
public class ThreadSafeRandom : Random
|
||||
{
|
||||
public int ObjectNameCallsReceived
|
||||
{
|
||||
get { return m_objectNameCallsReceived; }
|
||||
}
|
||||
protected int m_objectNameCallsReceived;
|
||||
|
||||
public MockScene() : base(new RegionInfo(1000, 1000, null, null))
|
||||
{
|
||||
m_regStatus = RegionStatus.Up;
|
||||
}
|
||||
|
||||
public override void Update(int frames) {}
|
||||
public override void LoadWorldMap() {}
|
||||
|
||||
public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
|
||||
{
|
||||
client.OnObjectName += RecordObjectNameCall;
|
||||
public ThreadSafeRandom() : base() {}
|
||||
|
||||
// FIXME
|
||||
return null;
|
||||
public ThreadSafeRandom(int seed): base (seed) {}
|
||||
|
||||
public override int Next()
|
||||
{
|
||||
lock (this)
|
||||
return base.Next();
|
||||
}
|
||||
|
||||
public override bool CloseAgent(UUID agentID, bool force) { return true; }
|
||||
|
||||
public override bool CheckClient(UUID clientId, IPEndPoint endPoint) { return true; }
|
||||
|
||||
public override void OtherRegionUp(GridRegion otherRegion) { }
|
||||
|
||||
public override bool TryGetScenePresence(UUID uuid, out ScenePresence sp) { sp = null; return false; }
|
||||
|
||||
/// <summary>
|
||||
/// Doesn't really matter what the call is - we're using this to test that a packet has actually been received
|
||||
/// </summary>
|
||||
protected void RecordObjectNameCall(IClientAPI remoteClient, uint localID, string message)
|
||||
public override int Next(int maxValue)
|
||||
{
|
||||
m_objectNameCallsReceived++;
|
||||
lock (this)
|
||||
return base.Next(maxValue);
|
||||
}
|
||||
|
||||
public override int Next(int minValue, int maxValue)
|
||||
{
|
||||
lock (this)
|
||||
return base.Next(minValue, maxValue);
|
||||
}
|
||||
|
||||
public override void NextBytes(byte[] buffer)
|
||||
{
|
||||
lock (this)
|
||||
base.NextBytes(buffer);
|
||||
}
|
||||
|
||||
public override double NextDouble()
|
||||
{
|
||||
lock (this)
|
||||
return base.NextDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@ namespace OpenSim.Framework
|
||||
public string User = string.Empty;
|
||||
public string SimName = string.Empty;
|
||||
public string GlobalPos = "<0,0,0>";
|
||||
public string Gatekeeper = string.Empty;
|
||||
public int SortOrder = 0;
|
||||
public bool Enabled = false;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
private static uint nextXferID = 5000;
|
||||
private static Random randomClass = new Random();
|
||||
private static Random randomClass = new ThreadSafeRandom();
|
||||
|
||||
// Get a list of invalid file characters (OS dependent)
|
||||
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
|
||||
@@ -509,6 +509,19 @@ namespace OpenSim.Framework
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static byte[] DocToBytes(XmlDocument doc)
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
using (XmlTextWriter xw = new XmlTextWriter(ms, null))
|
||||
{
|
||||
xw.Formatting = Formatting.Indented;
|
||||
doc.WriteTo(xw);
|
||||
xw.Flush();
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the platform Windows?
|
||||
/// </summary>
|
||||
@@ -1307,46 +1320,6 @@ namespace OpenSim.Framework
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string Compress(string text)
|
||||
{
|
||||
byte[] buffer = Util.UTF8.GetBytes(text);
|
||||
MemoryStream memory = new MemoryStream();
|
||||
using (GZipStream compressor = new GZipStream(memory, CompressionMode.Compress, true))
|
||||
{
|
||||
compressor.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
memory.Position = 0;
|
||||
|
||||
byte[] compressed = new byte[memory.Length];
|
||||
memory.Read(compressed, 0, compressed.Length);
|
||||
|
||||
byte[] compressedBuffer = new byte[compressed.Length + 4];
|
||||
Buffer.BlockCopy(compressed, 0, compressedBuffer, 4, compressed.Length);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, compressedBuffer, 0, 4);
|
||||
return Convert.ToBase64String(compressedBuffer);
|
||||
}
|
||||
|
||||
public static string Decompress(string compressedText)
|
||||
{
|
||||
byte[] compressedBuffer = Convert.FromBase64String(compressedText);
|
||||
using (MemoryStream memory = new MemoryStream())
|
||||
{
|
||||
int msgLength = BitConverter.ToInt32(compressedBuffer, 0);
|
||||
memory.Write(compressedBuffer, 4, compressedBuffer.Length - 4);
|
||||
|
||||
byte[] buffer = new byte[msgLength];
|
||||
|
||||
memory.Position = 0;
|
||||
using (GZipStream decompressor = new GZipStream(memory, CompressionMode.Decompress))
|
||||
{
|
||||
decompressor.Read(buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
return Util.UTF8.GetString(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy data from one stream to another, leaving the read position of both streams at the beginning.
|
||||
/// </summary>
|
||||
@@ -2027,7 +2000,7 @@ namespace OpenSim.Framework
|
||||
{
|
||||
ThreadFuncNum = threadFuncNum;
|
||||
this.context = context;
|
||||
LogThread = true;
|
||||
LogThread = false;
|
||||
Thread = null;
|
||||
Running = false;
|
||||
Aborted = false;
|
||||
@@ -2208,6 +2181,12 @@ namespace OpenSim.Framework
|
||||
(LogThreadPool >= 2) ? full : partial);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Since we didn't log "Queue threadfunc", don't log "Run threadfunc" or "End threadfunc" either.
|
||||
// Those log lines aren't useful when we don't know which function is running in the thread.
|
||||
threadInfo.LogThread = false;
|
||||
}
|
||||
|
||||
switch (FireAndForgetMethod)
|
||||
{
|
||||
@@ -2420,36 +2399,6 @@ namespace OpenSim.Framework
|
||||
|
||||
#endregion FireAndForget Threading Pattern
|
||||
|
||||
/// <summary>
|
||||
/// Run the callback on a different thread, outside the thread pool. This is used for tasks
|
||||
/// that may take a long time.
|
||||
/// </summary>
|
||||
public static void RunThreadNoTimeout(WaitCallback callback, string name, object obj)
|
||||
{
|
||||
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
callback(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
Thread t = new Thread(delegate()
|
||||
{
|
||||
try
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
callback(obj);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("Exception in thread " + name, e);
|
||||
}
|
||||
});
|
||||
|
||||
t.Name = name;
|
||||
t.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
||||
/// and negative every 24.9 days. This trims down TickCount so it doesn't wrap
|
||||
@@ -2626,7 +2575,7 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
#region Xml Serialization Utilities
|
||||
public static bool ReadBoolean(XmlTextReader reader)
|
||||
public static bool ReadBoolean(XmlReader reader)
|
||||
{
|
||||
// AuroraSim uses "int" for some fields that are boolean in OpenSim, e.g. "PassCollisions". Don't fail because of this.
|
||||
reader.ReadStartElement();
|
||||
@@ -2637,7 +2586,7 @@ namespace OpenSim.Framework
|
||||
return result;
|
||||
}
|
||||
|
||||
public static UUID ReadUUID(XmlTextReader reader, string name)
|
||||
public static UUID ReadUUID(XmlReader reader, string name)
|
||||
{
|
||||
UUID id;
|
||||
string idStr;
|
||||
@@ -2656,7 +2605,7 @@ namespace OpenSim.Framework
|
||||
return id;
|
||||
}
|
||||
|
||||
public static Vector3 ReadVector(XmlTextReader reader, string name)
|
||||
public static Vector3 ReadVector(XmlReader reader, string name)
|
||||
{
|
||||
Vector3 vec;
|
||||
|
||||
@@ -2669,7 +2618,7 @@ namespace OpenSim.Framework
|
||||
return vec;
|
||||
}
|
||||
|
||||
public static Quaternion ReadQuaternion(XmlTextReader reader, string name)
|
||||
public static Quaternion ReadQuaternion(XmlReader reader, string name)
|
||||
{
|
||||
Quaternion quat = new Quaternion();
|
||||
|
||||
@@ -2698,7 +2647,7 @@ namespace OpenSim.Framework
|
||||
return quat;
|
||||
}
|
||||
|
||||
public static T ReadEnum<T>(XmlTextReader reader, string name)
|
||||
public static T ReadEnum<T>(XmlReader reader, string name)
|
||||
{
|
||||
string value = reader.ReadElementContentAsString(name, String.Empty);
|
||||
// !!!!! to deal with flags without commas
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace OpenSim.Framework
|
||||
/// <summary>
|
||||
/// Request number for diagnostic purposes.
|
||||
/// </summary>
|
||||
public static int RequestNumber { get; internal set; }
|
||||
public static int RequestNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Control where OSD requests should be serialized per endpoint.
|
||||
@@ -176,7 +176,8 @@ namespace OpenSim.Framework
|
||||
|
||||
public static void LogOutgoingDetail(string context, Stream outputStream)
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(Util.Copy(outputStream), Encoding.UTF8))
|
||||
using (Stream stream = Util.Copy(outputStream))
|
||||
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
|
||||
{
|
||||
string output;
|
||||
|
||||
@@ -262,12 +263,12 @@ namespace OpenSim.Framework
|
||||
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
using (GZipStream comp = new GZipStream(ms, CompressionMode.Compress))
|
||||
using (GZipStream comp = new GZipStream(ms, CompressionMode.Compress, true))
|
||||
{
|
||||
comp.Write(buffer, 0, buffer.Length);
|
||||
// We need to close the gzip stream before we write it anywhere
|
||||
// because apparently something important related to gzip compression
|
||||
// gets written on the strteam upon Dispose()
|
||||
// gets written on the stream upon Dispose()
|
||||
}
|
||||
byte[] buf = ms.ToArray();
|
||||
request.ContentLength = buf.Length; //Count bytes to send
|
||||
|
||||
@@ -213,6 +213,8 @@ namespace OpenSim
|
||||
// Make sure command line options take precedence
|
||||
m_config.Source.Merge(argvSource);
|
||||
|
||||
m_config.Source.ReplaceKeyValues();
|
||||
|
||||
ReadConfigSettings();
|
||||
|
||||
return m_config;
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace OpenSim
|
||||
Util.FireAndForgetMethod = asyncCallMethod;
|
||||
|
||||
stpMinThreads = startupConfig.GetInt("MinPoolThreads", 15);
|
||||
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
|
||||
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 300);
|
||||
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace OpenSim
|
||||
((RemoteConsole)m_console).ReadConfig(Config);
|
||||
break;
|
||||
default:
|
||||
m_console = new LocalConsole("Region");
|
||||
m_console = new LocalConsole("Region", Config.Configs["Startup"]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -268,23 +268,24 @@ namespace OpenSim
|
||||
|
||||
m_console.Commands.AddCommand("Archiving", false, "load oar",
|
||||
"load oar [--merge] [--skip-assets]"
|
||||
+ " [--default-user \"User Name\"]"
|
||||
+ " [--force-terrain] [--force-parcels]"
|
||||
+ " [--no-objects]"
|
||||
+ " [--rotation degrees] [--rotation-center \"<x,y,z>\"]"
|
||||
+ " [--displacement \"<x,y,z>\"]"
|
||||
+ " [--default-user \"User Name\"]"
|
||||
+ " [--displacement \"<x,y,z>\"]"
|
||||
+ " [<OAR path>]",
|
||||
"Load a region's data from an OAR archive.",
|
||||
"--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading)." + Environment.NewLine
|
||||
+ "--skip-assets will load the OAR but ignore the assets it contains." + Environment.NewLine
|
||||
+ "--displacement will add this value to the position of every object loaded" + Environment.NewLine
|
||||
+ "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge)" + Environment.NewLine
|
||||
+ "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge)" + Environment.NewLine
|
||||
+ "--rotation specified rotation to be applied to the oar. Specified in degrees." + Environment.NewLine
|
||||
+ "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>" + Environment.NewLine
|
||||
+ "--no-objects suppresses the addition of any objects (good for loading only the terrain)" + Environment.NewLine
|
||||
+ "The path can be either a filesystem location or a URI."
|
||||
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
|
||||
"--merge will merge the OAR with the existing scene (suppresses terrain and parcel info loading).\n"
|
||||
+ "--default-user will use this user for any objects with an owner whose UUID is not found in the grid.\n"
|
||||
+ "--displacement will add this value to the position of every object loaded.\n"
|
||||
+ "--force-terrain forces the loading of terrain from the oar (undoes suppression done by --merge).\n"
|
||||
+ "--force-parcels forces the loading of parcels from the oar (undoes suppression done by --merge).\n"
|
||||
+ "--no-objects suppresses the addition of any objects (good for loading only the terrain).\n"
|
||||
+ "--rotation specified rotation to be applied to the oar. Specified in degrees.\n"
|
||||
+ "--rotation-center Location (relative to original OAR) to apply rotation. Default is <128,128,0>.\n"
|
||||
+ "--skip-assets will load the OAR but ignore the assets it contains.\n\n"
|
||||
+ "The path can be either a filesystem location or a URI.\n"
|
||||
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
|
||||
LoadOar);
|
||||
|
||||
m_console.Commands.AddCommand("Archiving", false, "save oar",
|
||||
@@ -921,7 +922,7 @@ namespace OpenSim
|
||||
|
||||
foreach (IRegionModuleBase module in scene.RegionModules.Values)
|
||||
{
|
||||
if (module.GetType().GetInterface("ISharedRegionModule") != null)
|
||||
if (module.GetType().GetInterface("ISharedRegionModule") == null)
|
||||
nonSharedModules.Add(module);
|
||||
else
|
||||
sharedModules.Add(module);
|
||||
|
||||
@@ -730,8 +730,6 @@ namespace OpenSim
|
||||
clientServer = clientNetworkServers;
|
||||
scene.LoadWorldMap();
|
||||
|
||||
Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
|
||||
scene.PhysicsScene = GetPhysicsScene(scene.RegionInfo.RegionName, regionExtent);
|
||||
scene.PhysicsScene.RequestAssetMethod = scene.PhysicsRequestAsset;
|
||||
scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
|
||||
scene.PhysicsScene.SetWaterLevel((float) regionInfo.RegionSettings.WaterHeight);
|
||||
@@ -747,10 +745,13 @@ namespace OpenSim
|
||||
protected override Scene CreateScene(RegionInfo regionInfo, ISimulationDataService simDataService,
|
||||
IEstateDataService estateDataService, AgentCircuitManager circuitManager)
|
||||
{
|
||||
Vector3 regionExtent = new Vector3(regionInfo.RegionSizeX, regionInfo.RegionSizeY, regionInfo.RegionSizeZ);
|
||||
PhysicsScene physicsScene = GetPhysicsScene(regionInfo.RegionName, regionExtent);
|
||||
|
||||
SceneCommunicationService sceneGridService = new SceneCommunicationService();
|
||||
|
||||
return new Scene(
|
||||
regionInfo, circuitManager, sceneGridService,
|
||||
regionInfo, circuitManager, physicsScene, sceneGridService,
|
||||
simDataService, estateDataService,
|
||||
Config, m_version);
|
||||
}
|
||||
|
||||
@@ -268,8 +268,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
public string SeedCapRequest(string request, string path, string param,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
|
||||
// m_log.DebugFormat(
|
||||
// "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
|
||||
|
||||
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
||||
{
|
||||
@@ -546,7 +546,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
if (texture_list.Count > 0)
|
||||
{
|
||||
ScenePresence avatar = null;
|
||||
IClientAPI client = null;
|
||||
m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
|
||||
|
||||
if (avatar != null)
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
"debug eq [0|1|2]",
|
||||
"Turn on event queue debugging\n"
|
||||
+ " <= 0 - turns off all event queue logging\n"
|
||||
+ " >= 1 - turns on outgoing event logging\n"
|
||||
+ " >= 1 - turns on event queue setup and outgoing event logging\n"
|
||||
+ " >= 2 - turns on poll notification",
|
||||
HandleDebugEq);
|
||||
|
||||
@@ -188,9 +188,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
if (!queues.ContainsKey(agentId))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
|
||||
agentId, m_scene.RegionInfo.RegionName);
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat(
|
||||
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
|
||||
agentId, m_scene.RegionInfo.RegionName);
|
||||
|
||||
queues[agentId] = new Queue<OSD>();
|
||||
}
|
||||
|
||||
@@ -302,9 +304,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
// Register an event queue for the client
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
|
||||
agentID, caps, m_scene.RegionInfo.RegionName);
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat(
|
||||
"[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
|
||||
agentID, caps, m_scene.RegionInfo.RegionName);
|
||||
|
||||
// Let's instantiate a Queue for this agent right now
|
||||
TryGetQueue(agentID);
|
||||
@@ -720,8 +723,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
m_log.DebugFormat("{0} EnableSimulator. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
|
||||
LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY);
|
||||
|
||||
OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
|
||||
Enqueue(item, avatarID);
|
||||
@@ -730,8 +734,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
|
||||
ulong regionHandle, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
|
||||
LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY);
|
||||
|
||||
OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
@@ -741,8 +747,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
uint locationID, uint flags, string capsURL,
|
||||
UUID avatarID, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, avatarID={2}, regionSize=<{3},{4}>",
|
||||
LogHeader, regionHandle, avatarID, regionSizeX, regionSizeY);
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
|
||||
LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
|
||||
|
||||
OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
|
||||
locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
|
||||
@@ -753,8 +760,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
IPEndPoint newRegionExternalEndPoint,
|
||||
string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
|
||||
{
|
||||
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
|
||||
LogHeader, handle, avatarID, regionSizeX, regionSizeY);
|
||||
|
||||
OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
|
||||
capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
|
||||
@@ -819,4 +827,4 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,6 @@ using OpenSim.Region.CoreModules.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.OptionalModules.World.NPC;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
@@ -37,7 +38,7 @@ using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
// using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
@@ -56,8 +57,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulatorFeaturesModule")]
|
||||
public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
|
||||
|
||||
@@ -69,18 +70,31 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
private OSDMap m_features = new OSDMap();
|
||||
|
||||
private string m_SearchURL = string.Empty;
|
||||
private string m_DestinationGuideURL = string.Empty;
|
||||
private bool m_ExportSupported = false;
|
||||
private string m_GridName = string.Empty;
|
||||
private string m_GridURL = string.Empty;
|
||||
|
||||
#region ISharedRegionModule Members
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig config = source.Configs["SimulatorFeatures"];
|
||||
if (config != null)
|
||||
{
|
||||
m_SearchURL = config.GetString("SearchServerURI", string.Empty);
|
||||
|
||||
if (config != null)
|
||||
{
|
||||
// These are normaly set in their respective modules
|
||||
m_SearchURL = config.GetString("SearchServerURI", m_SearchURL);
|
||||
m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL);
|
||||
if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config
|
||||
m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL);
|
||||
m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported);
|
||||
m_GridURL = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
|
||||
new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty);
|
||||
m_GridName = config.GetString("GridName", string.Empty);
|
||||
if (m_GridName == string.Empty)
|
||||
m_GridName = Util.GetConfigVarFromSections<string>(source, "gridname",
|
||||
new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty);
|
||||
}
|
||||
|
||||
AddDefaultFeatures();
|
||||
@@ -101,6 +115,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
GetGridExtraFeatures(s);
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
@@ -126,6 +141,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
/// </remarks>
|
||||
private void AddDefaultFeatures()
|
||||
{
|
||||
|
||||
lock (m_features)
|
||||
{
|
||||
m_features["MeshRezEnabled"] = true;
|
||||
@@ -141,15 +157,27 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
// Extra information for viewers that want to use it
|
||||
// TODO: Take these out of here into their respective modules, like map-server-url
|
||||
OSDMap extrasMap = new OSDMap();
|
||||
OSDMap extrasMap;
|
||||
if(m_features.ContainsKey("OpenSimExtras"))
|
||||
{
|
||||
extrasMap = (OSDMap)m_features["OpenSimExtras"];
|
||||
}
|
||||
else
|
||||
extrasMap = new OSDMap();
|
||||
|
||||
if (m_SearchURL != string.Empty)
|
||||
extrasMap["search-server-url"] = m_SearchURL;
|
||||
if (!string.IsNullOrEmpty(m_DestinationGuideURL))
|
||||
extrasMap["destination-guide-url"] = m_DestinationGuideURL;
|
||||
if (m_ExportSupported)
|
||||
extrasMap["ExportSupported"] = true;
|
||||
if (m_GridURL != string.Empty)
|
||||
extrasMap["GridURL"] = m_GridURL;
|
||||
if (m_GridName != string.Empty)
|
||||
extrasMap["GridName"] = m_GridName;
|
||||
|
||||
if (extrasMap.Count > 0)
|
||||
m_features["OpenSimExtras"] = extrasMap;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,11 +227,16 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
|
||||
m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
|
||||
|
||||
OSDMap copy = DeepCopy();
|
||||
|
||||
// Let's add the agentID to the destination guide, if it is expecting that.
|
||||
if (copy.ContainsKey("OpenSimExtras") && ((OSDMap)(copy["OpenSimExtras"])).ContainsKey("destination-guide-url"))
|
||||
((OSDMap)copy["OpenSimExtras"])["destination-guide-url"] = Replace(((OSDMap)copy["OpenSimExtras"])["destination-guide-url"], "[USERID]", agentID.ToString());
|
||||
|
||||
SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest;
|
||||
|
||||
if (handlerOnSimulatorFeaturesRequest != null)
|
||||
handlerOnSimulatorFeaturesRequest(agentID, ref copy);
|
||||
|
||||
@@ -217,5 +250,46 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the grid extra features.
|
||||
/// </summary>
|
||||
/// <param name='featuresURI'>
|
||||
/// The URI Robust uses to handle the get_extra_features request
|
||||
/// </param>
|
||||
private void GetGridExtraFeatures(Scene scene)
|
||||
{
|
||||
Dictionary<string, object> extraFeatures = scene.GridService.GetExtraFeatures();
|
||||
if (extraFeatures.ContainsKey("Result") && extraFeatures["Result"] != null && extraFeatures["Result"].ToString() == "Failure")
|
||||
{
|
||||
m_log.WarnFormat("[SIMULATOR FEATURES MODULE]: Unable to retrieve grid-wide features");
|
||||
return;
|
||||
}
|
||||
|
||||
lock (m_features)
|
||||
{
|
||||
OSDMap extrasMap = new OSDMap();
|
||||
|
||||
foreach(string key in extraFeatures.Keys)
|
||||
{
|
||||
extrasMap[key] = (string)extraFeatures[key];
|
||||
|
||||
if (key == "ExportSupported")
|
||||
{
|
||||
bool.TryParse(extraFeatures[key].ToString(), out m_ExportSupported);
|
||||
}
|
||||
}
|
||||
m_features["OpenSimExtras"] = extrasMap;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private string Replace(string url, string substring, string replacement)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(url) && url.Contains(substring))
|
||||
return url.Replace(substring, replacement);
|
||||
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ using OpenSim.Region.CoreModules.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
|
||||
|
||||
@@ -4201,6 +4201,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLCLIENTVIEW]: Sent {0} updates in ProcessEntityUpdates() for {1} {2} in {3}",
|
||||
// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
|
||||
//
|
||||
#endregion Packet Sending
|
||||
}
|
||||
|
||||
@@ -11848,7 +11852,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <returns></returns>
|
||||
protected bool HandleAgentTextureCached(IClientAPI simclient, Packet packet)
|
||||
{
|
||||
//m_log.Debug("texture cached: " + packet.ToString());
|
||||
AgentCachedTexturePacket cachedtex = (AgentCachedTexturePacket)packet;
|
||||
AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse);
|
||||
|
||||
@@ -11864,24 +11867,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
cachedresp.WearableData =
|
||||
new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
|
||||
|
||||
//IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
|
||||
// var item = fac.GetBakedTextureFaces(AgentId);
|
||||
//WearableCacheItem[] items = fac.GetCachedItems(AgentId);
|
||||
|
||||
IAssetService cache = m_scene.AssetService;
|
||||
IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
|
||||
//bakedTextureModule = null;
|
||||
int maxWearablesLoop = cachedtex.WearableData.Length;
|
||||
if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
|
||||
maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
|
||||
|
||||
// Find the cached baked textures for this user, if they're available
|
||||
|
||||
IAssetService cache = m_scene.AssetService;
|
||||
IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
|
||||
|
||||
WearableCacheItem[] cacheItems = null;
|
||||
|
||||
if (bakedTextureModule != null && cache != null)
|
||||
{
|
||||
// We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
|
||||
|
||||
WearableCacheItem[] cacheItems = null;
|
||||
ScenePresence p = m_scene.GetScenePresence(AgentId);
|
||||
if (p.Appearance != null)
|
||||
{
|
||||
if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
|
||||
{
|
||||
try
|
||||
@@ -11890,22 +11891,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
p.Appearance.WearableCacheItems = cacheItems;
|
||||
p.Appearance.WearableCacheItemsDirty = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
|
||||
*
|
||||
catch (System.Net.Sockets.SocketException)
|
||||
{
|
||||
cacheItems = null;
|
||||
}
|
||||
catch (WebException)
|
||||
{
|
||||
cacheItems = null;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
cacheItems = null;
|
||||
} */
|
||||
catch (Exception)
|
||||
{
|
||||
cacheItems = null;
|
||||
@@ -11916,87 +11901,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
cacheItems = p.Appearance.WearableCacheItems;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cache != null && cacheItems != null)
|
||||
if (cacheItems != null)
|
||||
{
|
||||
// We need to make sure the asset stored in the bake is available on this server also by its assetid before we map it to a Cacheid.
|
||||
// Copy the baked textures to the sim's assets cache (local only).
|
||||
foreach (WearableCacheItem item in cacheItems)
|
||||
{
|
||||
foreach (WearableCacheItem item in cacheItems)
|
||||
if (cache.GetCached(item.TextureID.ToString()) == null)
|
||||
{
|
||||
|
||||
if (cache.GetCached(item.TextureID.ToString()) == null)
|
||||
{
|
||||
item.TextureAsset.Temporary = true;
|
||||
cache.Store(item.TextureAsset);
|
||||
}
|
||||
|
||||
|
||||
item.TextureAsset.Temporary = true;
|
||||
item.TextureAsset.Local = true;
|
||||
cache.Store(item.TextureAsset);
|
||||
}
|
||||
}
|
||||
if (cacheItems != null)
|
||||
|
||||
// Return the cached textures
|
||||
for (int i = 0; i < maxWearablesLoop; i++)
|
||||
{
|
||||
WearableCacheItem item =
|
||||
WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex, cacheItems);
|
||||
|
||||
for (int i = 0; i < maxWearablesLoop; i++)
|
||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||
cachedresp.WearableData[i].HostName = new byte[0];
|
||||
if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
|
||||
{
|
||||
WearableCacheItem item =
|
||||
WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
|
||||
|
||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||
cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
|
||||
cachedresp.WearableData[i].HostName = new byte[0];
|
||||
if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
|
||||
{
|
||||
|
||||
cachedresp.WearableData[i].TextureID = item.TextureID;
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||
}
|
||||
cachedresp.WearableData[i].TextureID = item.TextureID;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < maxWearablesLoop; i++)
|
||||
else
|
||||
{
|
||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||
cachedresp.WearableData[i].HostName = new byte[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cache == null)
|
||||
// Cached textures not available
|
||||
for (int i = 0; i < maxWearablesLoop; i++)
|
||||
{
|
||||
for (int i = 0; i < maxWearablesLoop; i++)
|
||||
{
|
||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||
cachedresp.WearableData[i].HostName = new byte[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < maxWearablesLoop; i++)
|
||||
{
|
||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||
|
||||
|
||||
|
||||
if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
|
||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||
else
|
||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||
// UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||
cachedresp.WearableData[i].HostName = new byte[0];
|
||||
}
|
||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||
cachedresp.WearableData[i].HostName = new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
cachedresp.Header.Zerocoded = true;
|
||||
OutPacket(cachedresp, ThrottleOutPacketType.Task);
|
||||
|
||||
@@ -12389,6 +12341,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// provide your own method.</param>
|
||||
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
|
||||
{
|
||||
if (m_outPacketsToDrop != null)
|
||||
if (m_outPacketsToDrop.Contains(packet.Type.ToString()))
|
||||
return;
|
||||
|
||||
if (DebugPacketLevel > 0)
|
||||
{
|
||||
bool logPacket = true;
|
||||
@@ -12447,6 +12403,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <param name="Pack">OpenMetaverse.packet</param>
|
||||
public void ProcessInPacket(Packet packet)
|
||||
{
|
||||
if (m_inPacketsToDrop != null)
|
||||
if (m_inPacketsToDrop.Contains(packet.Type.ToString()))
|
||||
return;
|
||||
|
||||
if (DebugPacketLevel > 0)
|
||||
{
|
||||
bool logPacket = true;
|
||||
@@ -13171,5 +13131,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
eq.Enqueue(BuildEvent("BulkUpdateInventory",
|
||||
llsd), AgentId);
|
||||
}
|
||||
|
||||
private HashSet<string> m_outPacketsToDrop;
|
||||
|
||||
public bool AddOutPacketToDropSet(string packetName)
|
||||
{
|
||||
if (m_outPacketsToDrop == null)
|
||||
m_outPacketsToDrop = new HashSet<string>();
|
||||
|
||||
return m_outPacketsToDrop.Add(packetName);
|
||||
}
|
||||
|
||||
public bool RemoveOutPacketFromDropSet(string packetName)
|
||||
{
|
||||
if (m_outPacketsToDrop == null)
|
||||
return false;
|
||||
|
||||
return m_outPacketsToDrop.Remove(packetName);
|
||||
}
|
||||
|
||||
public HashSet<string> GetOutPacketDropSet()
|
||||
{
|
||||
return new HashSet<string>(m_outPacketsToDrop);
|
||||
}
|
||||
|
||||
private HashSet<string> m_inPacketsToDrop;
|
||||
|
||||
public bool AddInPacketToDropSet(string packetName)
|
||||
{
|
||||
if (m_inPacketsToDrop == null)
|
||||
m_inPacketsToDrop = new HashSet<string>();
|
||||
|
||||
return m_inPacketsToDrop.Add(packetName);
|
||||
}
|
||||
|
||||
public bool RemoveInPacketFromDropSet(string packetName)
|
||||
{
|
||||
if (m_inPacketsToDrop == null)
|
||||
return false;
|
||||
|
||||
return m_inPacketsToDrop.Remove(packetName);
|
||||
}
|
||||
|
||||
public HashSet<string> GetInPacketDropSet()
|
||||
{
|
||||
return new HashSet<string>(m_inPacketsToDrop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// or removed, this number must also change</summary>
|
||||
const int THROTTLE_CATEGORY_COUNT = 8;
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether information is logged about each outbound packet immediately before it is sent. For debug purposes.
|
||||
/// </summary>
|
||||
/// <remarks>Any level above 0 will turn on logging.</remarks>
|
||||
public int DebugDataOutLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether information is logged about each outbound packet immediately before it is sent. For debug purposes.
|
||||
/// </summary>
|
||||
/// <remarks>Any level above 0 will turn on logging.</remarks>
|
||||
public int ThrottleDebugLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_throttleDebugLevel;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
m_throttleDebugLevel = value;
|
||||
m_throttleClient.DebugLevel = m_throttleDebugLevel;
|
||||
m_throttleCategory.DebugLevel = m_throttleDebugLevel;
|
||||
foreach (TokenBucket tb in m_throttleCategories)
|
||||
tb.DebugLevel = m_throttleDebugLevel;
|
||||
}
|
||||
}
|
||||
private int m_throttleDebugLevel;
|
||||
|
||||
/// <summary>Fired when updated networking stats are produced for this client</summary>
|
||||
public event PacketStats OnPacketStats;
|
||||
/// <summary>Fired when the queue for a packet category is empty. This event can be
|
||||
@@ -201,9 +229,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_maxRTO = maxRTO;
|
||||
|
||||
// Create a token bucket throttle for this client that has the scene token bucket as a parent
|
||||
m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
|
||||
// Create a token bucket throttle for the total categary with the client bucket as a throttle
|
||||
m_throttleCategory = new TokenBucket(m_throttleClient, 0);
|
||||
m_throttleClient
|
||||
= new AdaptiveTokenBucket(
|
||||
string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name),
|
||||
parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
|
||||
|
||||
// Create a token bucket throttle for the total category with the client bucket as a throttle
|
||||
m_throttleCategory
|
||||
= new TokenBucket(
|
||||
string.Format("total throttle for {0} in {1}", AgentID, server.Scene.Name),
|
||||
m_throttleClient, 0);
|
||||
|
||||
// Create an array of token buckets for this clients different throttle categories
|
||||
m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
|
||||
|
||||
@@ -215,8 +251,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
// Initialize the packet outboxes, where packets sit while they are waiting for tokens
|
||||
m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
|
||||
|
||||
// Initialize the token buckets that control the throttling for each category
|
||||
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
|
||||
m_throttleCategories[i]
|
||||
= new TokenBucket(
|
||||
string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name),
|
||||
m_throttleCategory, rates.GetRate(type));
|
||||
}
|
||||
|
||||
// Default the retransmission timeout to one second
|
||||
@@ -262,6 +302,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate;
|
||||
m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate;
|
||||
m_info.totalThrottle = (int)m_throttleCategory.DripRate;
|
||||
m_info.maxThrottle = (int)m_throttleClient.MaxDripRate;
|
||||
|
||||
return m_info;
|
||||
}
|
||||
@@ -278,6 +319,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the total number of pakcets queued for this client.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetTotalPacketsQueuedCount()
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
for (int i = 0; i <= (int)ThrottleOutPacketType.Asset; i++)
|
||||
total += m_packetOutboxes[i].Count;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the number of packets queued for the given throttle type.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <param name="throttleType"></param>
|
||||
public int GetPacketsQueuedCount(ThrottleOutPacketType throttleType)
|
||||
{
|
||||
if ((int)throttleType > 0)
|
||||
return m_packetOutboxes[(int)throttleType].Count;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return statistics information about client packet queues.
|
||||
/// </summary>
|
||||
@@ -347,6 +415,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4;
|
||||
int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
|
||||
|
||||
if (ThrottleDebugLevel > 0)
|
||||
{
|
||||
long total = resend + land + wind + cloud + task + texture + asset;
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}",
|
||||
AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total);
|
||||
}
|
||||
|
||||
// Make sure none of the throttles are set below our packet MTU,
|
||||
// otherwise a throttle could become permanently clogged
|
||||
resend = Math.Max(resend, LLUDPServer.MTU);
|
||||
@@ -364,8 +440,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
texture = (int)((1 - m_cannibalrate) * texture);
|
||||
|
||||
//int total = resend + land + wind + cloud + task + texture + asset;
|
||||
//m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}",
|
||||
// AgentID, resend, land, wind, cloud, task, texture, asset, total);
|
||||
|
||||
if (ThrottleDebugLevel > 0)
|
||||
{
|
||||
long total = resend + land + wind + cloud + task + texture + asset;
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPCLIENT]: {0} is setting throttles in {1} to Resend={2}, Land={3}, Wind={4}, Cloud={5}, Task={6}, Texture={7}, Asset={8}, TOTAL = {9}",
|
||||
AgentID, m_udpServer.Scene.Name, resend, land, wind, cloud, task, texture, asset, total);
|
||||
}
|
||||
|
||||
// Update the token buckets with new throttle values
|
||||
TokenBucket bucket;
|
||||
@@ -649,8 +731,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
if (HasUpdates(m_categories))
|
||||
{
|
||||
// Asynchronously run the callback
|
||||
Util.FireAndForget(FireQueueEmpty, categories);
|
||||
if (!m_udpServer.OqrEngine.IsRunning)
|
||||
{
|
||||
// Asynchronously run the callback
|
||||
Util.FireAndForget(FireQueueEmpty, categories);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_udpServer.OqrEngine.QueueRequest(this, categories);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -669,8 +758,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <param name="o">Throttle categories to fire the callback for,
|
||||
/// stored as an object to match the WaitCallback delegate
|
||||
/// signature</param>
|
||||
private void FireQueueEmpty(object o)
|
||||
public void FireQueueEmpty(object o)
|
||||
{
|
||||
// m_log.DebugFormat("[LLUDPCLIENT]: FireQueueEmpty for {0} in {1}", AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
// int start = Environment.TickCount & Int32.MaxValue;
|
||||
// const int MIN_CALLBACK_MS = 30;
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using NDesk.Options;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenSim.Framework;
|
||||
@@ -222,6 +221,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// </summary>
|
||||
public int DefaultClientPacketDebugLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If set then all inbound agent updates are discarded. For debugging purposes.
|
||||
/// discard agent update.
|
||||
/// </summary>
|
||||
public bool DiscardInboundAgentUpdates { get; set; }
|
||||
|
||||
/// <summary>The measured resolution of Environment.TickCount</summary>
|
||||
public readonly float TickCountResolution;
|
||||
|
||||
@@ -238,19 +243,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <summary>Incoming packets that are awaiting handling</summary>
|
||||
private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
|
||||
|
||||
/// <summary></summary>
|
||||
//private UDPClientCollection m_clients = new UDPClientCollection();
|
||||
/// <summary>Bandwidth throttle for this UDP server</summary>
|
||||
protected TokenBucket m_throttle;
|
||||
public TokenBucket Throttle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum total drip rate allowed to all clients.
|
||||
/// </summary>
|
||||
public long MaxTotalDripRate { get { return Throttle.RequestedDripRate; } }
|
||||
|
||||
/// <summary>Bandwidth throttle rates for this UDP server</summary>
|
||||
/// <summary>Per client throttle rates enforced by this server</summary>
|
||||
/// <remarks>
|
||||
/// If the total rate is non-zero, then this is the maximum total throttle setting that any client can ever have.
|
||||
/// The other rates (resend, asset, etc.) are the defaults for a new client and can be changed (and usually
|
||||
/// do get changed immediately). They do not need to sum to the total.
|
||||
/// </remarks>
|
||||
public ThrottleRates ThrottleRates { get; private set; }
|
||||
|
||||
/// <summary>Manages authentication for agent circuits</summary>
|
||||
private AgentCircuitManager m_circuitManager;
|
||||
|
||||
/// <summary>Reference to the scene this UDP server is attached to</summary>
|
||||
protected Scene m_scene;
|
||||
public Scene Scene { get; private set; }
|
||||
|
||||
/// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
|
||||
private Location m_location;
|
||||
@@ -355,6 +368,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// </summary>
|
||||
private IClientAPI m_currentIncomingClient;
|
||||
|
||||
/// <summary>
|
||||
/// Experimental facility to run queue empty processing within a controlled number of threads rather than
|
||||
/// requiring massive numbers of short-lived threads from the threadpool when there are a high number of
|
||||
/// connections.
|
||||
/// </summary>
|
||||
public OutgoingQueueRefillEngine OqrEngine { get; private set; }
|
||||
|
||||
public LLUDPServer(
|
||||
IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
|
||||
IConfigSource configSource, AgentCircuitManager circuitManager)
|
||||
@@ -427,22 +447,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
#endregion BinaryStats
|
||||
|
||||
m_throttle = new TokenBucket(null, sceneThrottleBps);
|
||||
// FIXME: Can't add info here because don't know scene yet.
|
||||
// m_throttle
|
||||
// = new TokenBucket(
|
||||
// string.Format("server throttle bucket for {0}", Scene.Name), null, sceneThrottleBps);
|
||||
|
||||
Throttle = new TokenBucket("server throttle bucket", null, sceneThrottleBps);
|
||||
|
||||
ThrottleRates = new ThrottleRates(configSource);
|
||||
|
||||
if (usePools)
|
||||
EnablePools();
|
||||
|
||||
OqrEngine = new OutgoingQueueRefillEngine(this);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
StartInbound();
|
||||
StartOutbound();
|
||||
OqrEngine.Start();
|
||||
|
||||
m_elapsedMSSinceLastStatReport = Environment.TickCount;
|
||||
}
|
||||
|
||||
private void StartInbound()
|
||||
public void StartInbound()
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
|
||||
@@ -453,7 +482,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// This thread will process the packets received that are placed on the packetInbox
|
||||
Watchdog.StartThread(
|
||||
IncomingPacketHandler,
|
||||
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||
string.Format("Incoming Packets ({0})", Scene.Name),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
@@ -461,7 +490,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
private new void StartOutbound()
|
||||
public override void StartOutbound()
|
||||
{
|
||||
m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
|
||||
|
||||
@@ -469,7 +498,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
Watchdog.StartThread(
|
||||
OutgoingPacketHandler,
|
||||
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||
string.Format("Outgoing Packets ({0})", Scene.Name),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
@@ -479,12 +508,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
|
||||
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name);
|
||||
base.StopOutbound();
|
||||
base.StopInbound();
|
||||
OqrEngine.Stop();
|
||||
}
|
||||
|
||||
protected override bool EnablePools()
|
||||
public override bool EnablePools()
|
||||
{
|
||||
if (!UsePools)
|
||||
{
|
||||
@@ -498,7 +528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override bool DisablePools()
|
||||
public override bool DisablePools()
|
||||
{
|
||||
if (UsePools)
|
||||
{
|
||||
@@ -518,7 +548,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// This is a seperate method so that it can be called once we have an m_scene to distinguish different scene
|
||||
/// stats.
|
||||
/// </summary>
|
||||
private void EnablePoolStats()
|
||||
protected internal void EnablePoolStats()
|
||||
{
|
||||
m_poolCountStat
|
||||
= new Stat(
|
||||
@@ -527,7 +557,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"The number of objects currently stored within the UDPPacketBuffer pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = Pool.Count,
|
||||
StatVerbosity.Debug);
|
||||
@@ -541,7 +571,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"The number of objects currently stored within the incoming packet pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = m_incomingPacketPool.Count,
|
||||
StatVerbosity.Debug);
|
||||
@@ -552,7 +582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <summary>
|
||||
/// Disables pool stats.
|
||||
/// </summary>
|
||||
private void DisablePoolStats()
|
||||
protected internal void DisablePoolStats()
|
||||
{
|
||||
StatsManager.DeregisterStat(m_poolCountStat);
|
||||
m_poolCountStat = null;
|
||||
@@ -585,7 +615,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public void AddScene(IScene scene)
|
||||
{
|
||||
if (m_scene != null)
|
||||
if (Scene != null)
|
||||
{
|
||||
m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene");
|
||||
return;
|
||||
@@ -597,8 +627,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return;
|
||||
}
|
||||
|
||||
m_scene = (Scene)scene;
|
||||
m_location = new Location(m_scene.RegionInfo.RegionHandle);
|
||||
Scene = (Scene)scene;
|
||||
m_location = new Location(Scene.RegionInfo.RegionHandle);
|
||||
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
@@ -621,7 +651,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"Packets reused",
|
||||
"Number of packets reused out of all requests to the packet pool",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat =>
|
||||
{ PercentageStat pstat = (PercentageStat)stat;
|
||||
@@ -635,7 +665,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"Packet data blocks reused",
|
||||
"Number of data blocks reused out of all requests to the packet pool",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat =>
|
||||
{ PercentageStat pstat = (PercentageStat)stat;
|
||||
@@ -650,7 +680,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"The number of objects currently stored within the packet pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = PacketPool.Instance.PacketsPooled,
|
||||
StatVerbosity.Debug));
|
||||
@@ -662,240 +692,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
"The number of objects currently stored within the packet data block pool",
|
||||
"",
|
||||
"clientstack",
|
||||
m_scene.Name,
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
stat => stat.Value = PacketPool.Instance.BlocksPooled,
|
||||
StatVerbosity.Debug));
|
||||
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
"OutgoingPacketsQueuedCount",
|
||||
"Packets queued for outgoing send",
|
||||
"Number of queued outgoing packets across all connections",
|
||||
"",
|
||||
"clientstack",
|
||||
Scene.Name,
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.AverageChangeOverTime,
|
||||
stat => stat.Value = GetTotalQueuedOutgoingPackets(),
|
||||
StatVerbosity.Info));
|
||||
|
||||
// We delay enabling pool stats to AddScene() instead of Initialize() so that we can distinguish pool stats by
|
||||
// scene name
|
||||
if (UsePools)
|
||||
EnablePoolStats();
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug", false, "debug lludp packet",
|
||||
"debug lludp packet [--default] <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Turn on packet debugging",
|
||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||
+ "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
|
||||
+ "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
|
||||
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
|
||||
+ "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
|
||||
+ "If level <= 0 then no packets are logged.\n"
|
||||
+ "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
|
||||
+ "In this case, you cannot also specify an avatar name.\n"
|
||||
+ "If an avatar name is given then only packets from that avatar are logged.",
|
||||
HandlePacketCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp start",
|
||||
"debug lludp start <in|out|all>",
|
||||
"Control LLUDP packet processing.",
|
||||
"No effect if packet processing has already started.\n"
|
||||
+ "in - start inbound processing.\n"
|
||||
+ "out - start outbound processing.\n"
|
||||
+ "all - start in and outbound processing.\n",
|
||||
HandleStartCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp stop",
|
||||
"debug lludp stop <in|out|all>",
|
||||
"Stop LLUDP packet processing.",
|
||||
"No effect if packet processing has already stopped.\n"
|
||||
+ "in - stop inbound processing.\n"
|
||||
+ "out - stop outbound processing.\n"
|
||||
+ "all - stop in and outbound processing.\n",
|
||||
HandleStopCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp pool",
|
||||
"debug lludp pool <on|off>",
|
||||
"Turn object pooling within the lludp component on or off.",
|
||||
HandlePoolCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp status",
|
||||
"debug lludp status",
|
||||
"Return status of LLUDP packet processing.",
|
||||
HandleStatusCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp toggle agentupdate",
|
||||
"debug lludp toggle agentupdate",
|
||||
"Toggle whether agentupdate packets are processed or simply discarded.",
|
||||
HandleAgentUpdateCommand);
|
||||
}
|
||||
|
||||
private void HandlePacketCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
bool setAsDefaultLevel = false;
|
||||
OptionSet optionSet = new OptionSet().Add("default", o => setAsDefaultLevel = o != null);
|
||||
List<string> filteredArgs = optionSet.Parse(args);
|
||||
|
||||
string name = null;
|
||||
|
||||
if (filteredArgs.Count == 6)
|
||||
{
|
||||
if (!setAsDefaultLevel)
|
||||
{
|
||||
name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default logging level");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredArgs.Count > 3)
|
||||
{
|
||||
int newDebug;
|
||||
if (int.TryParse(filteredArgs[3], out newDebug))
|
||||
{
|
||||
if (setAsDefaultLevel)
|
||||
{
|
||||
DefaultClientPacketDebugLevel = newDebug;
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Debug packet debug for new clients set to {0} in {1}", DefaultClientPacketDebugLevel, m_scene.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (name == null || sp.Name == name)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name);
|
||||
|
||||
sp.ControllingClient.DebugPacketLevel = newDebug;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp packet [--default] 0..255 [<first-name> <last-name>]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStartCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
|
||||
return;
|
||||
}
|
||||
|
||||
string subCommand = args[3];
|
||||
|
||||
if (subCommand == "in" || subCommand == "all")
|
||||
StartInbound();
|
||||
|
||||
if (subCommand == "out" || subCommand == "all")
|
||||
StartOutbound();
|
||||
}
|
||||
|
||||
private void HandleStopCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
|
||||
return;
|
||||
}
|
||||
|
||||
string subCommand = args[3];
|
||||
|
||||
if (subCommand == "in" || subCommand == "all")
|
||||
StopInbound();
|
||||
|
||||
if (subCommand == "out" || subCommand == "all")
|
||||
StopOutbound();
|
||||
}
|
||||
|
||||
private void HandlePoolCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
||||
return;
|
||||
}
|
||||
|
||||
string enabled = args[3];
|
||||
|
||||
if (enabled == "on")
|
||||
{
|
||||
if (EnablePools())
|
||||
{
|
||||
EnablePoolStats();
|
||||
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
|
||||
}
|
||||
}
|
||||
else if (enabled == "off")
|
||||
{
|
||||
if (DisablePools())
|
||||
{
|
||||
DisablePoolStats();
|
||||
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
||||
}
|
||||
}
|
||||
|
||||
bool m_discardAgentUpdates;
|
||||
|
||||
private void HandleAgentUpdateCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
m_discardAgentUpdates = !m_discardAgentUpdates;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Discard AgentUpdates now {0} for {1}", m_discardAgentUpdates, m_scene.Name);
|
||||
}
|
||||
|
||||
private void HandleStatusCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
|
||||
return;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
|
||||
|
||||
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug level for new clients is {0}", DefaultClientPacketDebugLevel);
|
||||
LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
|
||||
commands.Register();
|
||||
}
|
||||
|
||||
public bool HandlesRegion(Location x)
|
||||
@@ -903,6 +724,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return x == m_location;
|
||||
}
|
||||
|
||||
public int GetTotalQueuedOutgoingPackets()
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
foreach (ScenePresence sp in Scene.GetScenePresences())
|
||||
{
|
||||
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
|
||||
total += udpClient.GetTotalPacketsQueuedCount();
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
// public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
|
||||
// {
|
||||
// // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
|
||||
@@ -973,7 +807,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
for (int i = 0; i < packetCount; i++)
|
||||
{
|
||||
byte[] data = datas[i];
|
||||
|
||||
if (!SendPacketData(udpClient, data, packet.Type, category, method))
|
||||
packetQueued = true;
|
||||
}
|
||||
@@ -981,7 +814,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
else
|
||||
{
|
||||
byte[] data = packet.ToBytes();
|
||||
packetQueued = SendPacketData(udpClient, data, packet.Type, category, method);
|
||||
if (!SendPacketData(udpClient, data, packet.Type, category, method))
|
||||
packetQueued = true;
|
||||
}
|
||||
|
||||
PacketPool.Instance.ReturnPacket(packet);
|
||||
@@ -1059,14 +893,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
#region Queue or Send
|
||||
|
||||
OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
|
||||
|
||||
// If we were not provided a method for handling unacked, use the UDPServer default method
|
||||
outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
|
||||
if ((outgoingPacket.Buffer.Data[0] & Helpers.MSG_RELIABLE) != 0)
|
||||
outgoingPacket.UnackedMethod = ((method == null) ? delegate(OutgoingPacket oPacket) { ResendUnacked(oPacket); } : method);
|
||||
|
||||
// If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will
|
||||
// continue to display the deleted object until relog. Therefore, we need to always queue a kill object
|
||||
// packet so that it isn't sent before a queued update packet.
|
||||
bool requestQueue = type == PacketType.KillObject;
|
||||
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue))
|
||||
bool forceQueue = (type == PacketType.KillObject);
|
||||
|
||||
if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue))
|
||||
{
|
||||
SendPacketFinal(outgoingPacket);
|
||||
return true;
|
||||
@@ -1270,6 +1107,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// is 100% correct
|
||||
PacketsSentCount++;
|
||||
|
||||
if (udpClient.DebugDataOutLevel > 0)
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Sending packet #{0} (rel: {1}, res: {2}) to {3} from {4}",
|
||||
outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name);
|
||||
|
||||
// Put the UDP payload on the wire
|
||||
AsyncBeginSend(buffer);
|
||||
|
||||
@@ -1399,7 +1241,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
// Determine which agent this packet came from
|
||||
IClientAPI client;
|
||||
if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
|
||||
if (!Scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
|
||||
{
|
||||
//m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
|
||||
|
||||
@@ -1514,7 +1356,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
if (packet.Type == PacketType.AgentUpdate)
|
||||
{
|
||||
if (m_discardAgentUpdates)
|
||||
if (DiscardInboundAgentUpdates)
|
||||
return;
|
||||
|
||||
((LLClientView)client).TotalAgentUpdates++;
|
||||
@@ -1694,7 +1536,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
|
||||
uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint);
|
||||
uccp.CircuitCode.Code, Scene.RegionInfo.RegionName, endPoint);
|
||||
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||
@@ -1716,11 +1558,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// We only want to send initial data to new clients, not ones which are being converted from child to root.
|
||||
if (client != null)
|
||||
{
|
||||
AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
|
||||
AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
|
||||
bool tp = (aCircuit.teleportFlags > 0);
|
||||
// Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
|
||||
if (!tp)
|
||||
client.SceneAgent.SendInitialDataToMe();
|
||||
if (!tp && !client.SceneAgent.SentInitialDataToClient)
|
||||
client.SceneAgent.SendInitialDataToClient();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1728,7 +1570,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[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, endPoint);
|
||||
uccp.CircuitCode.ID, Scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
@@ -1760,7 +1602,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, m_scene.Name);
|
||||
"[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, Scene.Name);
|
||||
|
||||
// Determine which agent this packet came from
|
||||
// We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
|
||||
@@ -1771,7 +1613,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
int count = 40;
|
||||
while (count-- > 0)
|
||||
{
|
||||
if (m_scene.TryGetClient(endPoint, out client))
|
||||
if (Scene.TryGetClient(endPoint, out client))
|
||||
{
|
||||
if (!client.IsActive)
|
||||
{
|
||||
@@ -1780,7 +1622,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// not yet been established).
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.",
|
||||
endPoint, client.Name, m_scene.Name);
|
||||
endPoint, client.Name, Scene.Name);
|
||||
}
|
||||
else if (client.SceneAgent == null)
|
||||
{
|
||||
@@ -1792,7 +1634,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// the client manager
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.",
|
||||
endPoint, client.Name, m_scene.Name);
|
||||
endPoint, client.Name, Scene.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1803,7 +1645,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
|
||||
endPoint, m_scene.Name);
|
||||
endPoint, Scene.Name);
|
||||
}
|
||||
|
||||
Thread.Sleep(200);
|
||||
@@ -1813,7 +1655,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
|
||||
endPoint, m_scene.Name);
|
||||
endPoint, Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1825,7 +1667,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// purposes.
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.",
|
||||
endPoint, client.Name, m_scene.Name);
|
||||
endPoint, client.Name, Scene.Name);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1920,11 +1762,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// consistently, this lock could probably be removed.
|
||||
lock (this)
|
||||
{
|
||||
if (!m_scene.TryGetClient(agentID, out client))
|
||||
if (!Scene.TryGetClient(agentID, out client))
|
||||
{
|
||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, Throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||
|
||||
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client.OnLogout += LogoutHandler;
|
||||
client.DebugPacketLevel = DefaultClientPacketDebugLevel;
|
||||
|
||||
@@ -1954,17 +1796,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.",
|
||||
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, m_scene.Name);
|
||||
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, Scene.Name);
|
||||
|
||||
if (!client.SceneAgent.IsChildAgent)
|
||||
client.Kick("Simulator logged you out due to connection timeout.");
|
||||
}
|
||||
|
||||
m_scene.CloseAgent(client.AgentId, true);
|
||||
Scene.CloseAgent(client.AgentId, true);
|
||||
}
|
||||
|
||||
private void IncomingPacketHandler()
|
||||
{
|
||||
Thread.CurrentThread.Priority = ThreadPriority.Highest;
|
||||
|
||||
// Set this culture for the thread that incoming packets are received
|
||||
// on to en-US to avoid number parsing issues
|
||||
Culture.SetCurrentCulture();
|
||||
@@ -2010,6 +1854,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private void OutgoingPacketHandler()
|
||||
{
|
||||
Thread.CurrentThread.Priority = ThreadPriority.Highest;
|
||||
|
||||
// Set this culture for the thread that outgoing packets are sent
|
||||
// on to en-US to avoid number parsing issues
|
||||
Culture.SetCurrentCulture();
|
||||
@@ -2072,7 +1918,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
// Handle outgoing packets, resends, acknowledgements, and pings for each
|
||||
// client. m_packetSent will be set to true if a packet is sent
|
||||
m_scene.ForEachClient(clientPacketHandler);
|
||||
Scene.ForEachClient(clientPacketHandler);
|
||||
|
||||
m_currentOutgoingClient = null;
|
||||
|
||||
@@ -2239,7 +2085,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
watch1.Reset();
|
||||
|
||||
// reuse this -- it's every ~100ms
|
||||
if (m_scene.EmergencyMonitoring && nticks % 100 == 0)
|
||||
if (Scene.EmergencyMonitoring && nticks % 100 == 0)
|
||||
{
|
||||
m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (TickCountRes: {5} sent: {6} notsent: {7})",
|
||||
avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
|
||||
@@ -2288,7 +2134,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
|
||||
packet.Type, client.Name, m_scene.RegionInfo.RegionName);
|
||||
packet.Type, client.Name, Scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
IncomingPacketsProcessed++;
|
||||
@@ -2301,8 +2147,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (!client.IsLoggingOut)
|
||||
{
|
||||
client.IsLoggingOut = true;
|
||||
m_scene.CloseAgent(client.AgentId, false);
|
||||
Scene.CloseAgent(client.AgentId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
694
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
Normal file
694
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServerCommands.cs
Normal file
@@ -0,0 +1,694 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NDesk.Options;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
public class LLUDPServerCommands
|
||||
{
|
||||
private ICommandConsole m_console;
|
||||
private LLUDPServer m_udpServer;
|
||||
|
||||
public LLUDPServerCommands(ICommandConsole console, LLUDPServer udpServer)
|
||||
{
|
||||
m_console = console;
|
||||
m_udpServer = udpServer;
|
||||
}
|
||||
|
||||
public void Register()
|
||||
{
|
||||
m_console.Commands.AddCommand(
|
||||
"Comms", false, "show server throttles",
|
||||
"show server throttles",
|
||||
"Show information about server throttles",
|
||||
HandleShowServerThrottlesCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug", false, "debug lludp packet",
|
||||
"debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.",
|
||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||
+ "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
|
||||
+ "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
|
||||
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
|
||||
+ "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
|
||||
+ "If level <= 0 then no packets are logged.\n"
|
||||
+ "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
|
||||
+ "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n"
|
||||
+ "In these cases, you cannot also specify an avatar name.\n"
|
||||
+ "If an avatar name is given then only packets from that avatar are logged.",
|
||||
HandlePacketCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug", false, "debug lludp data out",
|
||||
"debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"",
|
||||
"Turn on debugging for final outgoing data to the given user's client.",
|
||||
"This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n"
|
||||
+ "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n"
|
||||
+ "If level <= 0 then no information about outgoing UDP data for this avatar is logged.",
|
||||
HandleDataCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug", false, "debug lludp drop",
|
||||
"debug lludp drop <in|out> <add|remove> <packet-name>",
|
||||
"Drop all in or outbound packets that match the given name",
|
||||
"For test purposes.",
|
||||
HandleDropCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp start",
|
||||
"debug lludp start <in|out|all>",
|
||||
"Control LLUDP packet processing.",
|
||||
"No effect if packet processing has already started.\n"
|
||||
+ "in - start inbound processing.\n"
|
||||
+ "out - start outbound processing.\n"
|
||||
+ "all - start in and outbound processing.\n",
|
||||
HandleStartCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp stop",
|
||||
"debug lludp stop <in|out|all>",
|
||||
"Stop LLUDP packet processing.",
|
||||
"No effect if packet processing has already stopped.\n"
|
||||
+ "in - stop inbound processing.\n"
|
||||
+ "out - stop outbound processing.\n"
|
||||
+ "all - stop in and outbound processing.\n",
|
||||
HandleStopCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp pool",
|
||||
"debug lludp pool <on|off>",
|
||||
"Turn object pooling within the lludp component on or off.",
|
||||
HandlePoolCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp status",
|
||||
"debug lludp status",
|
||||
"Return status of LLUDP packet processing.",
|
||||
HandleStatusCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp throttles log",
|
||||
"debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Change debug logging level for throttles.",
|
||||
"If level >= 0 then throttle debug logging is performed.\n"
|
||||
+ "If level <= 0 then no throttle debug logging is performed.",
|
||||
HandleThrottleCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp throttles get",
|
||||
"debug lludp throttles get [<avatar-first-name> <avatar-last-name>]",
|
||||
"Return debug settings for throttles.",
|
||||
HandleThrottleGetCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp throttles set",
|
||||
"debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Set a throttle parameter for the given client.",
|
||||
"Avaiable parameters are:\n"
|
||||
+ "adaptive - true/false, control adaptive throttle setting\n"
|
||||
+ "throttle-max - kbps, control maximum throttle setting for current and future clients\n",
|
||||
HandleThrottleSetCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp set",
|
||||
"debug lludp set <param> <value>",
|
||||
"Set a parameter for the server.",
|
||||
"Only current setting is 'scene-throttle-max' which sets the current max cumulative kbps provided for this scene to clients",
|
||||
HandleSetCommand);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp toggle agentupdate",
|
||||
"debug lludp toggle agentupdate",
|
||||
"Toggle whether agentupdate packets are processed or simply discarded.",
|
||||
HandleAgentUpdateCommand);
|
||||
}
|
||||
|
||||
private void HandleShowServerThrottlesCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
m_console.OutputFormat("Throttles for {0}", m_udpServer.Scene.Name);
|
||||
ConsoleDisplayList cdl = new ConsoleDisplayList();
|
||||
cdl.AddRow("Adaptive throttles", m_udpServer.ThrottleRates.AdaptiveThrottlesEnabled);
|
||||
|
||||
long maxSceneDripRate = m_udpServer.MaxTotalDripRate;
|
||||
cdl.AddRow(
|
||||
"Max scene throttle",
|
||||
maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset");
|
||||
|
||||
int maxClientDripRate = m_udpServer.ThrottleRates.Total;
|
||||
cdl.AddRow(
|
||||
"Max new client throttle",
|
||||
maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset");
|
||||
|
||||
m_console.Output(cdl.ToString());
|
||||
|
||||
m_console.OutputFormat("{0}\n", GetServerThrottlesReport(m_udpServer));
|
||||
}
|
||||
|
||||
private string GetServerThrottlesReport(LLUDPServer udpServer)
|
||||
{
|
||||
StringBuilder report = new StringBuilder();
|
||||
|
||||
report.AppendFormat(
|
||||
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
|
||||
"Total",
|
||||
"Resend",
|
||||
"Land",
|
||||
"Wind",
|
||||
"Cloud",
|
||||
"Task",
|
||||
"Texture",
|
||||
"Asset");
|
||||
|
||||
report.AppendFormat(
|
||||
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
|
||||
"kb/s",
|
||||
"kb/s",
|
||||
"kb/s",
|
||||
"kb/s",
|
||||
"kb/s",
|
||||
"kb/s",
|
||||
"kb/s",
|
||||
"kb/s");
|
||||
|
||||
ThrottleRates throttleRates = udpServer.ThrottleRates;
|
||||
report.AppendFormat(
|
||||
"{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
|
||||
(throttleRates.Total * 8) / 1000,
|
||||
(throttleRates.Resend * 8) / 1000,
|
||||
(throttleRates.Land * 8) / 1000,
|
||||
(throttleRates.Wind * 8) / 1000,
|
||||
(throttleRates.Cloud * 8) / 1000,
|
||||
(throttleRates.Task * 8) / 1000,
|
||||
(throttleRates.Texture * 8) / 1000,
|
||||
(throttleRates.Asset * 8) / 1000);
|
||||
|
||||
return report.ToString();
|
||||
}
|
||||
|
||||
protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
|
||||
{
|
||||
return string.Format(
|
||||
"{0,-" + maxLength + "}{1,-" + columnPadding + "}",
|
||||
entry.Length > maxLength ? entry.Substring(0, maxLength) : entry,
|
||||
"");
|
||||
}
|
||||
|
||||
private void HandleDataCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 7)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>");
|
||||
return;
|
||||
}
|
||||
|
||||
int level;
|
||||
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
|
||||
return;
|
||||
|
||||
string firstName = args[5];
|
||||
string lastName = args[6];
|
||||
|
||||
m_udpServer.Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (sp.Firstname == firstName && sp.Lastname == lastName)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Data debug for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
|
||||
|
||||
((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleThrottleCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
bool all = args.Length == 5;
|
||||
bool one = args.Length == 7;
|
||||
|
||||
if (!all && !one)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Usage: debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]");
|
||||
return;
|
||||
}
|
||||
|
||||
int level;
|
||||
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out level))
|
||||
return;
|
||||
|
||||
string firstName = null;
|
||||
string lastName = null;
|
||||
|
||||
if (one)
|
||||
{
|
||||
firstName = args[5];
|
||||
lastName = args[6];
|
||||
}
|
||||
|
||||
m_udpServer.Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Throttle log level for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
|
||||
|
||||
((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleThrottleSetCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
bool all = args.Length == 6;
|
||||
bool one = args.Length == 8;
|
||||
|
||||
if (!all && !one)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Usage: debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]");
|
||||
return;
|
||||
}
|
||||
|
||||
string param = args[4];
|
||||
string rawValue = args[5];
|
||||
|
||||
string firstName = null;
|
||||
string lastName = null;
|
||||
|
||||
if (one)
|
||||
{
|
||||
firstName = args[6];
|
||||
lastName = args[7];
|
||||
}
|
||||
|
||||
if (param == "adaptive")
|
||||
{
|
||||
bool newValue;
|
||||
if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out newValue))
|
||||
return;
|
||||
|
||||
m_udpServer.Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Setting param {0} to {1} for {2} ({3}) in {4}",
|
||||
param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
|
||||
|
||||
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
|
||||
udpClient.FlowThrottle.Enabled = newValue;
|
||||
// udpClient.FlowThrottle.MaxDripRate = 0;
|
||||
// udpClient.FlowThrottle.AdjustedDripRate = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (param == "throttle-max")
|
||||
{
|
||||
int newValue;
|
||||
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
|
||||
return;
|
||||
|
||||
int newThrottleMaxKbps = newValue * 1000 / 8;
|
||||
m_udpServer.ThrottleRates.Total = newThrottleMaxKbps;
|
||||
|
||||
m_udpServer.Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Setting param {0} to {1} for {2} ({3}) in {4}",
|
||||
param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
|
||||
|
||||
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
|
||||
udpClient.FlowThrottle.RequestedDripRate = newThrottleMaxKbps;
|
||||
udpClient.FlowThrottle.MaxDripRate = newThrottleMaxKbps;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleThrottleGetCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
bool all = args.Length == 4;
|
||||
bool one = args.Length == 6;
|
||||
|
||||
if (!all && !one)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Usage: debug lludp throttles get [<avatar-first-name> <avatar-last-name>]");
|
||||
return;
|
||||
}
|
||||
|
||||
string firstName = null;
|
||||
string lastName = null;
|
||||
|
||||
if (one)
|
||||
{
|
||||
firstName = args[4];
|
||||
lastName = args[5];
|
||||
}
|
||||
|
||||
m_udpServer.Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
|
||||
{
|
||||
m_console.OutputFormat(
|
||||
"Status for {0} ({1}) in {2}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
|
||||
|
||||
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
|
||||
|
||||
ConsoleDisplayList cdl = new ConsoleDisplayList();
|
||||
cdl.AddRow("Adaptive throttle", udpClient.FlowThrottle.Enabled);
|
||||
cdl.AddRow("Max throttle", string.Format("{0} kbps", udpClient.FlowThrottle.RequestedDripRate * 8 / 1000));
|
||||
|
||||
m_console.Output(cdl.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleSetCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 5)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Usage: debug lludp set <param> <value>");
|
||||
return;
|
||||
}
|
||||
|
||||
string param = args[3];
|
||||
string rawValue = args[4];
|
||||
|
||||
int newValue;
|
||||
|
||||
if (param == "scene-throttle-max")
|
||||
{
|
||||
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
|
||||
return;
|
||||
|
||||
m_udpServer.Throttle.RequestedDripRate = newValue * 1000 / 8;
|
||||
}
|
||||
|
||||
m_console.OutputFormat("{0} set to {1} in {2}", param, rawValue, m_udpServer.Scene.Name);
|
||||
}
|
||||
|
||||
private void HandlePacketCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
bool setAsDefaultLevel = false;
|
||||
bool setAll = false;
|
||||
OptionSet optionSet = new OptionSet()
|
||||
.Add("default", o => setAsDefaultLevel = (o != null))
|
||||
.Add("all", o => setAll = (o != null));
|
||||
List<string> filteredArgs = optionSet.Parse(args);
|
||||
|
||||
string name = null;
|
||||
|
||||
if (filteredArgs.Count == 6)
|
||||
{
|
||||
if (!(setAsDefaultLevel || setAll))
|
||||
{
|
||||
name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default/all logging level");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (filteredArgs.Count > 3)
|
||||
{
|
||||
int newDebug;
|
||||
if (int.TryParse(filteredArgs[3], out newDebug))
|
||||
{
|
||||
if (setAsDefaultLevel || setAll)
|
||||
{
|
||||
m_udpServer.DefaultClientPacketDebugLevel = newDebug;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} clients set to {1} in {2}",
|
||||
(setAll ? "all" : "future"), m_udpServer.DefaultClientPacketDebugLevel, m_udpServer.Scene.Name);
|
||||
|
||||
if (setAll)
|
||||
{
|
||||
m_udpServer.Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
|
||||
|
||||
sp.ControllingClient.DebugPacketLevel = newDebug;
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_udpServer.Scene.ForEachScenePresence(sp =>
|
||||
{
|
||||
if (name == null || sp.Name == name)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug for {0} ({1}) set to {2} in {3}",
|
||||
sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
|
||||
|
||||
sp.ControllingClient.DebugPacketLevel = newDebug;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDropCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 6)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
|
||||
return;
|
||||
}
|
||||
|
||||
string direction = args[3];
|
||||
string subCommand = args[4];
|
||||
string packetName = args[5];
|
||||
|
||||
if (subCommand == "add")
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Adding packet {0} to {1} drop list for all connections in {2}",
|
||||
direction, packetName, m_udpServer.Scene.Name);
|
||||
|
||||
m_udpServer.Scene.ForEachScenePresence(
|
||||
sp =>
|
||||
{
|
||||
LLClientView llcv = (LLClientView)sp.ControllingClient;
|
||||
|
||||
if (direction == "in")
|
||||
llcv.AddInPacketToDropSet(packetName);
|
||||
else if (direction == "out")
|
||||
llcv.AddOutPacketToDropSet(packetName);
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (subCommand == "remove")
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Removing packet {0} from {1} drop list for all connections in {2}",
|
||||
direction, packetName, m_udpServer.Scene.Name);
|
||||
|
||||
m_udpServer.Scene.ForEachScenePresence(
|
||||
sp =>
|
||||
{
|
||||
LLClientView llcv = (LLClientView)sp.ControllingClient;
|
||||
|
||||
if (direction == "in")
|
||||
llcv.RemoveInPacketFromDropSet(packetName);
|
||||
else if (direction == "out")
|
||||
llcv.RemoveOutPacketFromDropSet(packetName);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStartCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
|
||||
return;
|
||||
}
|
||||
|
||||
string subCommand = args[3];
|
||||
|
||||
if (subCommand == "in" || subCommand == "all")
|
||||
m_udpServer.StartInbound();
|
||||
|
||||
if (subCommand == "out" || subCommand == "all")
|
||||
m_udpServer.StartOutbound();
|
||||
}
|
||||
|
||||
private void HandleStopCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
|
||||
return;
|
||||
}
|
||||
|
||||
string subCommand = args[3];
|
||||
|
||||
if (subCommand == "in" || subCommand == "all")
|
||||
m_udpServer.StopInbound();
|
||||
|
||||
if (subCommand == "out" || subCommand == "all")
|
||||
m_udpServer.StopOutbound();
|
||||
}
|
||||
|
||||
private void HandlePoolCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
||||
return;
|
||||
}
|
||||
|
||||
string enabled = args[3];
|
||||
|
||||
if (enabled == "on")
|
||||
{
|
||||
if (m_udpServer.EnablePools())
|
||||
{
|
||||
m_udpServer.EnablePoolStats();
|
||||
MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_udpServer.Scene.Name);
|
||||
}
|
||||
}
|
||||
else if (enabled == "off")
|
||||
{
|
||||
if (m_udpServer.DisablePools())
|
||||
{
|
||||
m_udpServer.DisablePoolStats();
|
||||
MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_udpServer.Scene.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp pool <on|off>");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAgentUpdateCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
m_udpServer.DiscardInboundAgentUpdates = !m_udpServer.DiscardInboundAgentUpdates;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Discard AgentUpdates now {0} for {1}", m_udpServer.DiscardInboundAgentUpdates, m_udpServer.Scene.Name);
|
||||
}
|
||||
|
||||
private void HandleStatusCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"IN LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningInbound ? "enabled" : "disabled");
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
|
||||
|
||||
MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_udpServer.Scene.Name, m_udpServer.UsePools ? "on" : "off");
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +135,7 @@ namespace OpenMetaverse
|
||||
/// manner (not throwing an exception when the remote side resets the
|
||||
/// connection). This call is ignored on Mono where the flag is not
|
||||
/// necessary</remarks>
|
||||
public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
|
||||
public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling)
|
||||
{
|
||||
m_asyncPacketHandling = asyncPacketHandling;
|
||||
|
||||
@@ -185,14 +185,14 @@ namespace OpenMetaverse
|
||||
/// <summary>
|
||||
/// Start outbound UDP packet handling.
|
||||
/// </summary>
|
||||
public void StartOutbound()
|
||||
public virtual void StartOutbound()
|
||||
{
|
||||
m_log.DebugFormat("[UDPBASE]: Starting outbound UDP loop");
|
||||
|
||||
IsRunningOutbound = true;
|
||||
}
|
||||
|
||||
public void StopInbound()
|
||||
public virtual void StopInbound()
|
||||
{
|
||||
if (IsRunningInbound)
|
||||
{
|
||||
@@ -203,14 +203,14 @@ namespace OpenMetaverse
|
||||
}
|
||||
}
|
||||
|
||||
public void StopOutbound()
|
||||
public virtual void StopOutbound()
|
||||
{
|
||||
m_log.DebugFormat("[UDPBASE]: Stopping outbound UDP loop");
|
||||
|
||||
IsRunningOutbound = false;
|
||||
}
|
||||
|
||||
protected virtual bool EnablePools()
|
||||
public virtual bool EnablePools()
|
||||
{
|
||||
if (!UsePools)
|
||||
{
|
||||
@@ -224,7 +224,7 @@ namespace OpenMetaverse
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool DisablePools()
|
||||
public virtual bool DisablePools()
|
||||
{
|
||||
if (UsePools)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
public struct RefillRequest
|
||||
{
|
||||
public LLUDPClient Client;
|
||||
public ThrottleOutPacketTypeFlags Categories;
|
||||
|
||||
public RefillRequest(LLUDPClient client, ThrottleOutPacketTypeFlags categories)
|
||||
{
|
||||
Client = client;
|
||||
Categories = categories;
|
||||
}
|
||||
}
|
||||
|
||||
public class OutgoingQueueRefillEngine
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The timeout in milliseconds to wait for at least one event to be written when the recorder is stopping.
|
||||
/// </summary>
|
||||
public int RequestProcessTimeoutOnStop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether we need to warn in the log about exceeding the max queue size.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is flipped to false once queue max has been exceeded and back to true when it falls below max, in
|
||||
/// order to avoid spamming the log with lots of warnings.
|
||||
/// </remarks>
|
||||
private bool m_warnOverMaxQueue = true;
|
||||
|
||||
private BlockingCollection<RefillRequest> m_requestQueue;
|
||||
|
||||
private CancellationTokenSource m_cancelSource = new CancellationTokenSource();
|
||||
|
||||
private LLUDPServer m_udpServer;
|
||||
|
||||
private Stat m_oqreRequestsWaitingStat;
|
||||
|
||||
/// <summary>
|
||||
/// Used to signal that we are ready to complete stop.
|
||||
/// </summary>
|
||||
private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false);
|
||||
|
||||
public OutgoingQueueRefillEngine(LLUDPServer server)
|
||||
{
|
||||
RequestProcessTimeoutOnStop = 5000;
|
||||
m_udpServer = server;
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug",
|
||||
false,
|
||||
"debug lludp oqre",
|
||||
"debug lludp oqre <start|stop|status>",
|
||||
"Start, stop or get status of OutgoingQueueRefillEngine.",
|
||||
"If stopped then refill requests are processed directly via the threadpool.",
|
||||
HandleOqreCommand);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (IsRunning)
|
||||
return;
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
m_finishedProcessingAfterStop.Reset();
|
||||
|
||||
m_requestQueue = new BlockingCollection<RefillRequest>(new ConcurrentQueue<RefillRequest>(), 5000);
|
||||
|
||||
m_oqreRequestsWaitingStat =
|
||||
new Stat(
|
||||
"OQRERequestsWaiting",
|
||||
"Number of outgong queue refill requests waiting for processing.",
|
||||
"",
|
||||
"",
|
||||
"clientstack",
|
||||
m_udpServer.Scene.Name,
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.None,
|
||||
stat => stat.Value = m_requestQueue.Count,
|
||||
StatVerbosity.Debug);
|
||||
|
||||
StatsManager.RegisterStat(m_oqreRequestsWaitingStat);
|
||||
|
||||
Watchdog.StartThread(
|
||||
ProcessRequests,
|
||||
String.Format("OutgoingQueueRefillEngineThread ({0})", m_udpServer.Scene.Name),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsRunning)
|
||||
return;
|
||||
|
||||
IsRunning = false;
|
||||
|
||||
int requestsLeft = m_requestQueue.Count;
|
||||
|
||||
if (requestsLeft <= 0)
|
||||
{
|
||||
m_cancelSource.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[OUTGOING QUEUE REFILL ENGINE]: Waiting to write {0} events after stop.", requestsLeft);
|
||||
|
||||
while (requestsLeft > 0)
|
||||
{
|
||||
if (!m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
|
||||
{
|
||||
// After timeout no events have been written
|
||||
if (requestsLeft == m_requestQueue.Count)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[OUTGOING QUEUE REFILL ENGINE]: No requests processed after {0} ms wait. Discarding remaining {1} requests",
|
||||
RequestProcessTimeoutOnStop, requestsLeft);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
requestsLeft = m_requestQueue.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_cancelSource.Dispose();
|
||||
StatsManager.DeregisterStat(m_oqreRequestsWaitingStat);
|
||||
m_oqreRequestsWaitingStat = null;
|
||||
m_requestQueue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool QueueRequest(LLUDPClient client, ThrottleOutPacketTypeFlags categories)
|
||||
{
|
||||
if (m_requestQueue.Count < m_requestQueue.BoundedCapacity)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[OUTGOING QUEUE REFILL ENGINE]: Adding request for categories {0} for {1} in {2}",
|
||||
// categories, client.AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
m_requestQueue.Add(new RefillRequest(client, categories));
|
||||
|
||||
if (!m_warnOverMaxQueue)
|
||||
m_warnOverMaxQueue = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_warnOverMaxQueue)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[OUTGOING QUEUE REFILL ENGINE]: Request queue at maximum capacity, not recording request from {0} in {1}",
|
||||
client.AgentID, m_udpServer.Scene.Name);
|
||||
|
||||
m_warnOverMaxQueue = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessRequests()
|
||||
{
|
||||
Thread.CurrentThread.Priority = ThreadPriority.Highest;
|
||||
|
||||
try
|
||||
{
|
||||
while (IsRunning || m_requestQueue.Count > 0)
|
||||
{
|
||||
RefillRequest req = m_requestQueue.Take(m_cancelSource.Token);
|
||||
|
||||
// QueueEmpty callback = req.Client.OnQueueEmpty;
|
||||
//
|
||||
// if (callback != null)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// callback(req.Categories);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// m_log.Error("[OUTGOING QUEUE REFILL ENGINE]: ProcessRequests(" + req.Categories + ") threw an exception: " + e.Message, e);
|
||||
// }
|
||||
// }
|
||||
|
||||
req.Client.FireQueueEmpty(req.Categories);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
|
||||
m_finishedProcessingAfterStop.Set();
|
||||
}
|
||||
|
||||
private void HandleOqreCommand(string module, string[] args)
|
||||
{
|
||||
if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
|
||||
return;
|
||||
|
||||
if (args.Length != 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug lludp oqre <stop|start|status>");
|
||||
return;
|
||||
}
|
||||
|
||||
string subCommand = args[3];
|
||||
|
||||
if (subCommand == "stop")
|
||||
{
|
||||
Stop();
|
||||
MainConsole.Instance.OutputFormat("Stopped OQRE for {0}", m_udpServer.Scene.Name);
|
||||
}
|
||||
else if (subCommand == "start")
|
||||
{
|
||||
Start();
|
||||
MainConsole.Instance.OutputFormat("Started OQRE for {0}", m_udpServer.Scene.Name);
|
||||
}
|
||||
else if (subCommand == "status")
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("OQRE in {0}", m_udpServer.Scene.Name);
|
||||
MainConsole.Instance.OutputFormat("Running: {0}", IsRunning);
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Requests waiting: {0}", IsRunning ? m_requestQueue.Count.ToString() : "n/a");
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Unrecognized OQRE subcommand {0}", subCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,6 @@ using OpenSim.Framework;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
{
|
||||
@@ -47,7 +46,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
public class BasicCircuitTests : OpenSimTestCase
|
||||
{
|
||||
private Scene m_scene;
|
||||
private TestLLUDPServer m_udpServer;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
@@ -73,72 +71,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
StatsManager.SimExtraStats = new SimExtraStatsCollector();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build an object name packet for test purposes
|
||||
/// </summary>
|
||||
/// <param name="objectLocalId"></param>
|
||||
/// <param name="objectName"></param>
|
||||
private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
||||
{
|
||||
ObjectNamePacket onp = new ObjectNamePacket();
|
||||
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
|
||||
odb.LocalID = objectLocalId;
|
||||
odb.Name = Utils.StringToBytes(objectName);
|
||||
onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb };
|
||||
onp.Header.Zerocoded = false;
|
||||
|
||||
return onp;
|
||||
}
|
||||
|
||||
private void AddUdpServer()
|
||||
{
|
||||
AddUdpServer(new IniConfigSource());
|
||||
}
|
||||
|
||||
private void AddUdpServer(IniConfigSource configSource)
|
||||
{
|
||||
uint port = 0;
|
||||
AgentCircuitManager acm = m_scene.AuthenticateHandler;
|
||||
|
||||
m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
|
||||
m_udpServer.AddScene(m_scene);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by tests that aren't testing this stage.
|
||||
/// </summary>
|
||||
private ScenePresence AddClient()
|
||||
{
|
||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||
uint myCircuitCode = 123456;
|
||||
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||
|
||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
|
||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
= new UseCircuitCodePacket.CircuitCodeBlock();
|
||||
uccpCcBlock.Code = myCircuitCode;
|
||||
uccpCcBlock.ID = myAgentUuid;
|
||||
uccpCcBlock.SessionID = mySessionUuid;
|
||||
uccp.CircuitCode = uccpCcBlock;
|
||||
|
||||
byte[] uccpBytes = uccp.ToBytes();
|
||||
UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
|
||||
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||
|
||||
AgentCircuitData acd = new AgentCircuitData();
|
||||
acd.AgentID = myAgentUuid;
|
||||
acd.SessionID = mySessionUuid;
|
||||
|
||||
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||
|
||||
m_udpServer.PacketReceived(upb);
|
||||
|
||||
return m_scene.GetScenePresence(myAgentUuid);
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Build an object name packet for test purposes
|
||||
// /// </summary>
|
||||
// /// <param name="objectLocalId"></param>
|
||||
// /// <param name="objectName"></param>
|
||||
// private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
||||
// {
|
||||
// ObjectNamePacket onp = new ObjectNamePacket();
|
||||
// ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
|
||||
// odb.LocalID = objectLocalId;
|
||||
// odb.Name = Utils.StringToBytes(objectName);
|
||||
// onp.ObjectData = new ObjectNamePacket.ObjectDataBlock[] { odb };
|
||||
// onp.Header.Zerocoded = false;
|
||||
//
|
||||
// return onp;
|
||||
// }
|
||||
//
|
||||
/// <summary>
|
||||
/// Test adding a client to the stack
|
||||
/// </summary>
|
||||
@@ -148,7 +97,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
AddUdpServer();
|
||||
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene);
|
||||
|
||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||
@@ -169,7 +118,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||
|
||||
m_udpServer.PacketReceived(upb);
|
||||
udpServer.PacketReceived(upb);
|
||||
|
||||
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
||||
Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);
|
||||
@@ -180,15 +129,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
|
||||
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||
|
||||
m_udpServer.PacketReceived(upb);
|
||||
udpServer.PacketReceived(upb);
|
||||
|
||||
// Should succeed now
|
||||
ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
|
||||
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
||||
|
||||
Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||
Assert.That(udpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||
|
||||
Packet packet = m_udpServer.PacketsSent[0];
|
||||
Packet packet = udpServer.PacketsSent[0];
|
||||
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
||||
|
||||
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
||||
@@ -200,15 +149,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
public void TestLogoutClientDueToAck()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
TestHelpers.EnableLogging();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
IniConfigSource ics = new IniConfigSource();
|
||||
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
||||
config.Set("AckTimeout", -1);
|
||||
AddUdpServer(ics);
|
||||
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(m_scene, ics);
|
||||
|
||||
ScenePresence sp = AddClient();
|
||||
m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
|
||||
ScenePresence sp
|
||||
= ClientStackHelpers.AddChildClient(
|
||||
m_scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
|
||||
|
||||
udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
|
||||
|
||||
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
|
||||
Assert.That(spAfterAckTimeout, Is.Null);
|
||||
@@ -233,7 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
// testLLUDPServer.RemoveClientCircuit(myCircuitCode);
|
||||
// Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
|
||||
//
|
||||
// // Check that removing a non-existant circuit doesn't have any bad effects
|
||||
// // Check that removing a non-existent circuit doesn't have any bad effects
|
||||
// testLLUDPServer.RemoveClientCircuit(101);
|
||||
// Assert.IsFalse(testLLUDPServer.HasCircuit(101));
|
||||
// }
|
||||
|
||||
@@ -39,7 +39,6 @@ using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Agent.TextureSender;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
{
|
||||
|
||||
@@ -30,7 +30,6 @@ using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
|
||||
257
OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs
Normal file
257
OpenSim/Region/ClientStack/Linden/UDP/Tests/ThrottleTests.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ThrottleTests : OpenSimTestCase
|
||||
{
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
|
||||
// tests really shouldn't).
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClientThrottleSetNoLimit()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
|
||||
|
||||
ScenePresence sp
|
||||
= ClientStackHelpers.AddChildClient(
|
||||
scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
|
||||
|
||||
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
|
||||
// udpClient.ThrottleDebugLevel = 1;
|
||||
|
||||
int resendBytes = 1000;
|
||||
int landBytes = 2000;
|
||||
int windBytes = 3000;
|
||||
int cloudBytes = 4000;
|
||||
int taskBytes = 5000;
|
||||
int textureBytes = 6000;
|
||||
int assetBytes = 7000;
|
||||
|
||||
SetThrottles(
|
||||
udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
|
||||
|
||||
ClientInfo ci = udpClient.GetClientInfo();
|
||||
|
||||
// We expect this to be lower because of the minimum bound set by MTU
|
||||
float totalBytes = LLUDPServer.MTU + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes;
|
||||
Assert.AreEqual(LLUDPServer.MTU, ci.resendThrottle);
|
||||
Assert.AreEqual(landBytes, ci.landThrottle);
|
||||
Assert.AreEqual(windBytes, ci.windThrottle);
|
||||
Assert.AreEqual(cloudBytes, ci.cloudThrottle);
|
||||
Assert.AreEqual(taskBytes, ci.taskThrottle);
|
||||
Assert.AreEqual(textureBytes, ci.textureThrottle);
|
||||
Assert.AreEqual(assetBytes, ci.assetThrottle);
|
||||
Assert.AreEqual(totalBytes, ci.totalThrottle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test throttle setttings where max client throttle has been limited server side.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSingleClientThrottleRegionLimited()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
int resendBytes = 6000;
|
||||
int landBytes = 8000;
|
||||
int windBytes = 10000;
|
||||
int cloudBytes = 12000;
|
||||
int taskBytes = 14000;
|
||||
int textureBytes = 16000;
|
||||
int assetBytes = 18000;
|
||||
int totalBytes
|
||||
= (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2);
|
||||
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
|
||||
udpServer.Throttle.RequestedDripRate = totalBytes;
|
||||
|
||||
ScenePresence sp1
|
||||
= ClientStackHelpers.AddChildClient(
|
||||
scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
|
||||
|
||||
LLUDPClient udpClient1 = ((LLClientView)sp1.ControllingClient).UDPClient;
|
||||
|
||||
SetThrottles(
|
||||
udpClient1, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
|
||||
|
||||
{
|
||||
ClientInfo ci = udpClient1.GetClientInfo();
|
||||
|
||||
// Console.WriteLine(
|
||||
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
|
||||
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
|
||||
|
||||
Assert.AreEqual(resendBytes / 2, ci.resendThrottle);
|
||||
Assert.AreEqual(landBytes / 2, ci.landThrottle);
|
||||
Assert.AreEqual(windBytes / 2, ci.windThrottle);
|
||||
Assert.AreEqual(cloudBytes / 2, ci.cloudThrottle);
|
||||
Assert.AreEqual(taskBytes / 2, ci.taskThrottle);
|
||||
Assert.AreEqual(textureBytes / 2, ci.textureThrottle);
|
||||
Assert.AreEqual(assetBytes / 2, ci.assetThrottle);
|
||||
Assert.AreEqual(totalBytes, ci.totalThrottle);
|
||||
}
|
||||
|
||||
// Now add another client
|
||||
ScenePresence sp2
|
||||
= ClientStackHelpers.AddChildClient(
|
||||
scene, udpServer, TestHelpers.ParseTail(0x10), TestHelpers.ParseTail(0x20), 123457);
|
||||
|
||||
LLUDPClient udpClient2 = ((LLClientView)sp2.ControllingClient).UDPClient;
|
||||
// udpClient.ThrottleDebugLevel = 1;
|
||||
|
||||
SetThrottles(
|
||||
udpClient2, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
|
||||
|
||||
{
|
||||
ClientInfo ci = udpClient1.GetClientInfo();
|
||||
|
||||
// Console.WriteLine(
|
||||
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
|
||||
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
|
||||
|
||||
Assert.AreEqual(resendBytes / 4, ci.resendThrottle);
|
||||
Assert.AreEqual(landBytes / 4, ci.landThrottle);
|
||||
Assert.AreEqual(windBytes / 4, ci.windThrottle);
|
||||
Assert.AreEqual(cloudBytes / 4, ci.cloudThrottle);
|
||||
Assert.AreEqual(taskBytes / 4, ci.taskThrottle);
|
||||
Assert.AreEqual(textureBytes / 4, ci.textureThrottle);
|
||||
Assert.AreEqual(assetBytes / 4, ci.assetThrottle);
|
||||
Assert.AreEqual(totalBytes / 2, ci.totalThrottle);
|
||||
}
|
||||
|
||||
{
|
||||
ClientInfo ci = udpClient2.GetClientInfo();
|
||||
|
||||
// Console.WriteLine(
|
||||
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
|
||||
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
|
||||
|
||||
Assert.AreEqual(resendBytes / 4, ci.resendThrottle);
|
||||
Assert.AreEqual(landBytes / 4, ci.landThrottle);
|
||||
Assert.AreEqual(windBytes / 4, ci.windThrottle);
|
||||
Assert.AreEqual(cloudBytes / 4, ci.cloudThrottle);
|
||||
Assert.AreEqual(taskBytes / 4, ci.taskThrottle);
|
||||
Assert.AreEqual(textureBytes / 4, ci.textureThrottle);
|
||||
Assert.AreEqual(assetBytes / 4, ci.assetThrottle);
|
||||
Assert.AreEqual(totalBytes / 2, ci.totalThrottle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test throttle setttings where max client throttle has been limited server side.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestClientThrottlePerClientLimited()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
int resendBytes = 4000;
|
||||
int landBytes = 6000;
|
||||
int windBytes = 8000;
|
||||
int cloudBytes = 10000;
|
||||
int taskBytes = 12000;
|
||||
int textureBytes = 14000;
|
||||
int assetBytes = 16000;
|
||||
int totalBytes
|
||||
= (int)((resendBytes + landBytes + windBytes + cloudBytes + taskBytes + textureBytes + assetBytes) / 2);
|
||||
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
TestLLUDPServer udpServer = ClientStackHelpers.AddUdpServer(scene);
|
||||
udpServer.ThrottleRates.Total = totalBytes;
|
||||
|
||||
ScenePresence sp
|
||||
= ClientStackHelpers.AddChildClient(
|
||||
scene, udpServer, TestHelpers.ParseTail(0x1), TestHelpers.ParseTail(0x2), 123456);
|
||||
|
||||
LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
|
||||
// udpClient.ThrottleDebugLevel = 1;
|
||||
|
||||
SetThrottles(
|
||||
udpClient, resendBytes, landBytes, windBytes, cloudBytes, taskBytes, textureBytes, assetBytes);
|
||||
|
||||
ClientInfo ci = udpClient.GetClientInfo();
|
||||
|
||||
// Console.WriteLine(
|
||||
// "Resend={0}, Land={1}, Wind={2}, Cloud={3}, Task={4}, Texture={5}, Asset={6}, TOTAL = {7}",
|
||||
// ci.resendThrottle, ci.landThrottle, ci.windThrottle, ci.cloudThrottle, ci.taskThrottle, ci.textureThrottle, ci.assetThrottle, ci.totalThrottle);
|
||||
|
||||
Assert.AreEqual(resendBytes / 2, ci.resendThrottle);
|
||||
Assert.AreEqual(landBytes / 2, ci.landThrottle);
|
||||
Assert.AreEqual(windBytes / 2, ci.windThrottle);
|
||||
Assert.AreEqual(cloudBytes / 2, ci.cloudThrottle);
|
||||
Assert.AreEqual(taskBytes / 2, ci.taskThrottle);
|
||||
Assert.AreEqual(textureBytes / 2, ci.textureThrottle);
|
||||
Assert.AreEqual(assetBytes / 2, ci.assetThrottle);
|
||||
Assert.AreEqual(totalBytes, ci.totalThrottle);
|
||||
}
|
||||
|
||||
private void SetThrottles(
|
||||
LLUDPClient udpClient, int resendBytes, int landBytes, int windBytes, int cloudBytes, int taskBytes, int textureBytes, int assetBytes)
|
||||
{
|
||||
byte[] throttles = new byte[28];
|
||||
|
||||
Array.Copy(BitConverter.GetBytes((float)resendBytes * 8), 0, throttles, 0, 4);
|
||||
Array.Copy(BitConverter.GetBytes((float)landBytes * 8), 0, throttles, 4, 4);
|
||||
Array.Copy(BitConverter.GetBytes((float)windBytes * 8), 0, throttles, 8, 4);
|
||||
Array.Copy(BitConverter.GetBytes((float)cloudBytes * 8), 0, throttles, 12, 4);
|
||||
Array.Copy(BitConverter.GetBytes((float)taskBytes * 8), 0, throttles, 16, 4);
|
||||
Array.Copy(BitConverter.GetBytes((float)textureBytes * 8), 0, throttles, 20, 4);
|
||||
Array.Copy(BitConverter.GetBytes((float)assetBytes * 8), 0, throttles, 24, 4);
|
||||
|
||||
udpClient.SetThrottles(throttles);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
@@ -42,9 +42,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
public class TokenBucket
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static Int32 m_counter = 0;
|
||||
|
||||
// private Int32 m_identifier;
|
||||
|
||||
public string Identifier { get; private set; }
|
||||
|
||||
public int DebugLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of ticks (ms) per quantum, drip rate and max burst
|
||||
@@ -165,16 +166,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
/// <param name="identifier">Identifier for this token bucket</param>
|
||||
/// <param name="parent">Parent bucket if this is a child bucket, or
|
||||
/// null if this is a root bucket</param>
|
||||
/// <param name="maxBurst">Maximum size of the bucket in bytes, or
|
||||
/// zero if this bucket has no maximum capacity</param>
|
||||
/// <param name="dripRate">Rate that the bucket fills, in bytes per
|
||||
/// second. If zero, the bucket always remains full</param>
|
||||
public TokenBucket(TokenBucket parent, Int64 dripRate)
|
||||
public TokenBucket(string identifier, TokenBucket parent, Int64 dripRate)
|
||||
{
|
||||
// m_identifier = m_counter++;
|
||||
m_counter++;
|
||||
Identifier = identifier;
|
||||
|
||||
Parent = parent;
|
||||
RequestedDripRate = dripRate;
|
||||
@@ -301,7 +300,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// with no drip rate...
|
||||
if (DripRate == 0)
|
||||
{
|
||||
m_log.WarnFormat("[TOKENBUCKET] something odd is happening and drip rate is 0");
|
||||
m_log.WarnFormat("[TOKENBUCKET] something odd is happening and drip rate is 0 for {0}", Identifier);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -321,7 +320,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public class AdaptiveTokenBucket : TokenBucket
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// The minimum rate for flow control. Minimum drip rate is one
|
||||
@@ -335,13 +334,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// greater than this.
|
||||
// </summary>
|
||||
protected Int64 m_maxDripRate = 0;
|
||||
protected Int64 MaxDripRate
|
||||
public Int64 MaxDripRate
|
||||
{
|
||||
get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); }
|
||||
set { m_maxDripRate = (value == 0 ? 0 : Math.Max(value,m_minimumFlow)); }
|
||||
}
|
||||
|
||||
private bool m_enabled = false;
|
||||
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
// <summary>
|
||||
//
|
||||
@@ -360,13 +359,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// <summary>
|
||||
//
|
||||
// </summary>
|
||||
public AdaptiveTokenBucket(TokenBucket parent, Int64 maxDripRate, bool enabled) : base(parent,maxDripRate)
|
||||
public AdaptiveTokenBucket(string identifier, TokenBucket parent, Int64 maxDripRate, bool enabled)
|
||||
: base(identifier, parent, maxDripRate)
|
||||
{
|
||||
m_enabled = enabled;
|
||||
Enabled = enabled;
|
||||
|
||||
if (m_enabled)
|
||||
if (Enabled)
|
||||
{
|
||||
// m_log.DebugFormat("[TOKENBUCKET] Adaptive throttle enabled");
|
||||
// m_log.DebugFormat("[TOKENBUCKET]: Adaptive throttle enabled");
|
||||
MaxDripRate = maxDripRate;
|
||||
AdjustedDripRate = m_minimumFlow;
|
||||
}
|
||||
@@ -377,9 +377,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// </summary>
|
||||
public void ExpirePackets(Int32 count)
|
||||
{
|
||||
// m_log.WarnFormat("[ADAPTIVEBUCKET] drop {0} by {1} expired packets",AdjustedDripRate,count);
|
||||
if (m_enabled)
|
||||
if (Enabled)
|
||||
{
|
||||
if (DebugLevel > 0)
|
||||
m_log.WarnFormat(
|
||||
"[ADAPTIVEBUCKET] drop {0} by {1} expired packets for {2}",
|
||||
AdjustedDripRate, count, Identifier);
|
||||
|
||||
AdjustedDripRate = (Int64) (AdjustedDripRate / Math.Pow(2,count));
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
@@ -387,7 +393,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// </summary>
|
||||
public void AcknowledgePackets(Int32 count)
|
||||
{
|
||||
if (m_enabled)
|
||||
if (Enabled)
|
||||
AdjustedDripRate = AdjustedDripRate + count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +231,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
{
|
||||
try
|
||||
{
|
||||
List<int> layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(new MemoryStream(j2kData));
|
||||
List<int> layerStarts;
|
||||
using (MemoryStream ms = new MemoryStream(j2kData))
|
||||
{
|
||||
layerStarts = CSJ2K.J2kImage.GetLayerBoundaries(ms);
|
||||
}
|
||||
|
||||
if (layerStarts != null && layerStarts.Count > 0)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,7 @@ using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
@@ -963,7 +964,8 @@ namespace OpenSim.Region.CoreModules.Asset
|
||||
case "assets":
|
||||
con.Output("Ensuring assets are cached for all scenes.");
|
||||
|
||||
Util.RunThreadNoTimeout(delegate {
|
||||
Watchdog.RunInThread(delegate
|
||||
{
|
||||
int assetReferenceTotal = TouchAllSceneAssets(true);
|
||||
con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal);
|
||||
}, "TouchAllSceneAssets", null);
|
||||
|
||||
@@ -39,7 +39,6 @@ using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Asset.Tests
|
||||
{
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
{
|
||||
DebugLevel = debugLevel;
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Set event queue debug level to {0} in {1}", DebugLevel, m_scene.Name);
|
||||
"Set attachments debug level to {0} in {1}", DebugLevel, m_scene.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +387,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
if (!Enabled)
|
||||
return false;
|
||||
|
||||
return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append);
|
||||
group.DetachFromBackup();
|
||||
|
||||
bool success = AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory, false, append);
|
||||
|
||||
if (!success)
|
||||
group.AttachToBackup();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -815,8 +822,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
"[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
|
||||
so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
|
||||
|
||||
so.DetachFromBackup();
|
||||
|
||||
// Remove from database and parcel prim count
|
||||
m_scene.DeleteFromStorage(so.UUID);
|
||||
m_scene.EventManager.TriggerParcelPrimCountTainted();
|
||||
|
||||
@@ -53,7 +53,6 @@ using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.XEngine;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
{
|
||||
@@ -199,6 +198,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
string attName = "att";
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
|
||||
Assert.That(so.Backup, Is.True);
|
||||
|
||||
m_numberOfAttachEventsFired = 0;
|
||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, true, false);
|
||||
@@ -213,6 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
Assert.That(attSo.Backup, Is.False);
|
||||
|
||||
// Check item status
|
||||
Assert.That(
|
||||
@@ -385,7 +386,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
public void TestRezAttachmentFromInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
Scene scene = CreateTestScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
|
||||
@@ -407,6 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
Assert.IsFalse(attSo.Backup);
|
||||
|
||||
// Check appearance status
|
||||
Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
|
||||
@@ -601,7 +603,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null);
|
||||
|
||||
// Check object in scene
|
||||
Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
|
||||
SceneObjectGroup soInScene = scene.GetSceneObjectGroup("att");
|
||||
Assert.That(soInScene, Is.Not.Null);
|
||||
Assert.IsTrue(soInScene.Backup);
|
||||
|
||||
// Check events
|
||||
Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
|
||||
@@ -755,6 +759,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
Assert.IsFalse(attSo.Backup);
|
||||
|
||||
// Check appearance status
|
||||
List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
|
||||
@@ -884,6 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
|
||||
Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
|
||||
Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
|
||||
Assert.IsFalse(actualSceneBAtt.Backup);
|
||||
|
||||
Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
|
||||
@@ -994,6 +1000,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
|
||||
Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
|
||||
Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
|
||||
Assert.IsFalse(actualSceneBAtt.Backup);
|
||||
|
||||
Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
private void SendAppearance(ScenePresence sp)
|
||||
{
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
sp.SendAppearanceToAllOtherClients();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
|
||||
@@ -34,7 +34,6 @@ using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Asset;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
|
||||
|
||||
sr.ReadEndElement();
|
||||
}
|
||||
m_log.DebugFormat("[XBakes]: Ended reading");
|
||||
m_log.DebugFormat("[XBakes]: read {0} textures for user {1}", ret.Count, id);
|
||||
sr.Close();
|
||||
s.Close();
|
||||
|
||||
@@ -186,6 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
|
||||
delegate
|
||||
{
|
||||
rc.Request(reqStream, m_Auth);
|
||||
m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", data.Length, agentId);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
@@ -289,18 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
rootElement.AppendChild(result);
|
||||
|
||||
return DocToBytes(doc);
|
||||
}
|
||||
|
||||
private byte[] DocToBytes(XmlDocument doc)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||
xw.Formatting = Formatting.Indented;
|
||||
doc.WriteTo(xw);
|
||||
xw.Flush();
|
||||
|
||||
return ms.ToArray();
|
||||
return Util.DocToBytes(doc);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -35,7 +35,6 @@ using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Avatar.Friends;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
{
|
||||
|
||||
@@ -61,6 +61,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
private UserAccount m_userInfo;
|
||||
private string m_invPath;
|
||||
|
||||
/// <value>
|
||||
/// ID of this request
|
||||
/// </value>
|
||||
protected UUID m_id;
|
||||
|
||||
/// <summary>
|
||||
/// Do we want to merge this load with existing inventory?
|
||||
@@ -71,6 +76,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
protected IAssetService m_AssetService;
|
||||
protected IUserAccountService m_UserAccountService;
|
||||
|
||||
private InventoryArchiverModule m_module;
|
||||
|
||||
/// <value>
|
||||
/// The stream from which the inventory archive will be loaded.
|
||||
/// </value>
|
||||
@@ -114,11 +121,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids
|
||||
/// after OSP resolution (since OSP creators are only stored in the item
|
||||
/// </summary>
|
||||
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
|
||||
protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>();
|
||||
|
||||
public InventoryArchiveReadRequest(
|
||||
IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
|
||||
: this(UUID.Zero, null,
|
||||
inv,
|
||||
assets,
|
||||
uacc,
|
||||
userInfo,
|
||||
invPath,
|
||||
loadPath,
|
||||
merge)
|
||||
{
|
||||
}
|
||||
|
||||
public InventoryArchiveReadRequest(
|
||||
UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge)
|
||||
: this(
|
||||
id,
|
||||
module,
|
||||
inv,
|
||||
assets,
|
||||
uacc,
|
||||
@@ -130,8 +152,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
public InventoryArchiveReadRequest(
|
||||
IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
|
||||
UUID id, InventoryArchiverModule module, IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge)
|
||||
{
|
||||
m_id = id;
|
||||
m_InventoryService = inv;
|
||||
m_AssetService = assets;
|
||||
m_UserAccountService = uacc;
|
||||
@@ -139,6 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_userInfo = userInfo;
|
||||
m_invPath = invPath;
|
||||
m_loadStream = loadStream;
|
||||
m_module = module;
|
||||
|
||||
// FIXME: Do not perform this check since older versions of OpenSim do save the control file after other things
|
||||
// (I thought they weren't). We will need to bump the version number and perform this check on all
|
||||
@@ -161,6 +185,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
try
|
||||
{
|
||||
Exception reportedException = null;
|
||||
|
||||
string filePath = "ERROR";
|
||||
|
||||
List<InventoryFolderBase> folderCandidates
|
||||
@@ -197,14 +223,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
archive.Close();
|
||||
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
|
||||
m_successfulAssetRestores, m_failedAssetRestores);
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", m_successfulItemRestores);
|
||||
|
||||
//Alicia: When this is called by LibraryModule or Tests, m_module will be null as event is not required
|
||||
if(m_module != null)
|
||||
m_module.TriggerInventoryArchiveLoaded(m_id, true, m_userInfo, m_invPath, m_loadStream, reportedException, m_successfulItemRestores);
|
||||
|
||||
return m_loadedNodes;
|
||||
}
|
||||
catch(Exception Ex)
|
||||
{
|
||||
// Trigger saved event with failed result and exception data
|
||||
if (m_module != null)
|
||||
m_module.TriggerInventoryArchiveLoaded(m_id, false, m_userInfo, m_invPath, m_loadStream, Ex, 0);
|
||||
|
||||
return m_loadedNodes;
|
||||
}
|
||||
finally
|
||||
{
|
||||
m_loadStream.Close();
|
||||
|
||||
@@ -34,6 +34,7 @@ using System.Xml;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Framework.Serialization;
|
||||
using OpenSim.Framework.Serialization.External;
|
||||
using OpenSim.Region.CoreModules.World.Archiver;
|
||||
@@ -42,6 +43,7 @@ using OpenSim.Services.Interfaces;
|
||||
using Ionic.Zlib;
|
||||
using GZipStream = Ionic.Zlib.GZipStream;
|
||||
using CompressionMode = Ionic.Zlib.CompressionMode;
|
||||
using PermissionMask = OpenSim.Framework.PermissionMask;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
@@ -54,6 +56,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// </summary>
|
||||
public bool SaveAssets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines which items will be included in the archive, according to their permissions.
|
||||
/// Default is null, meaning no permission checks.
|
||||
/// </summary>
|
||||
public string FilterContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Counter for inventory items saved to archive for passing to compltion event
|
||||
/// </summary>
|
||||
public int CountItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Counter for inventory items skipped due to permission filter option for passing to compltion event
|
||||
/// </summary>
|
||||
public int CountFiltered { get; set; }
|
||||
|
||||
/// <value>
|
||||
/// Used to select all inventory nodes in a folder but not the folder itself
|
||||
/// </value>
|
||||
@@ -73,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// <value>
|
||||
/// ID of this request
|
||||
/// </value>
|
||||
protected Guid m_id;
|
||||
protected UUID m_id;
|
||||
|
||||
/// <value>
|
||||
/// Used to collect the uuids of the assets that we need to save into the archive
|
||||
@@ -94,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public InventoryArchiveWriteRequest(
|
||||
Guid id, InventoryArchiverModule module, Scene scene,
|
||||
UUID id, InventoryArchiverModule module, Scene scene,
|
||||
UserAccount userInfo, string invPath, string savePath)
|
||||
: this(
|
||||
id,
|
||||
@@ -110,7 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public InventoryArchiveWriteRequest(
|
||||
Guid id, InventoryArchiverModule module, Scene scene,
|
||||
UUID id, InventoryArchiverModule module, Scene scene,
|
||||
UserAccount userInfo, string invPath, Stream saveStream)
|
||||
{
|
||||
m_id = id;
|
||||
@@ -122,6 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_assetGatherer = new UuidGatherer(m_scene.AssetService);
|
||||
|
||||
SaveAssets = true;
|
||||
FilterContent = null;
|
||||
}
|
||||
|
||||
protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
|
||||
@@ -150,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
m_module.TriggerInventoryArchiveSaved(
|
||||
m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException);
|
||||
m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException, CountItems, CountFiltered);
|
||||
}
|
||||
|
||||
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||
@@ -166,10 +185,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
"[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}",
|
||||
inventoryItem.Name, inventoryItem.ID, path);
|
||||
}
|
||||
|
||||
CountFiltered++;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check For Permissions Filter Flags
|
||||
if (!CanUserArchiveObject(m_userInfo.PrincipalID, inventoryItem))
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[INVENTORY ARCHIVER]: Insufficient permissions, skipping inventory item {0} {1} at {2}",
|
||||
inventoryItem.Name, inventoryItem.ID, path);
|
||||
|
||||
// Count Items Excluded
|
||||
CountFiltered++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.ContainsKey("verbose"))
|
||||
m_log.InfoFormat(
|
||||
"[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})",
|
||||
@@ -185,6 +220,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
|
||||
|
||||
// Count inventory items (different to asset count)
|
||||
CountItems++;
|
||||
|
||||
// Don't chase down link asset items as they actually point to their target item IDs rather than an asset
|
||||
if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
|
||||
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (sbyte)inventoryItem.AssetType, m_assetUuids);
|
||||
@@ -242,6 +280,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether the user has permission to export an inventory item to an IAR.
|
||||
/// </summary>
|
||||
/// <param name="UserID">The user</param>
|
||||
/// <param name="InvItem">The inventory item</param>
|
||||
/// <returns>Whether the user is allowed to export the object to an IAR</returns>
|
||||
private bool CanUserArchiveObject(UUID UserID, InventoryItemBase InvItem)
|
||||
{
|
||||
if (FilterContent == null)
|
||||
return true;// Default To Allow Export
|
||||
|
||||
bool permitted = true;
|
||||
|
||||
bool canCopy = (InvItem.CurrentPermissions & (uint)PermissionMask.Copy) != 0;
|
||||
bool canTransfer = (InvItem.CurrentPermissions & (uint)PermissionMask.Transfer) != 0;
|
||||
bool canMod = (InvItem.CurrentPermissions & (uint)PermissionMask.Modify) != 0;
|
||||
|
||||
if (FilterContent.Contains("C") && !canCopy)
|
||||
permitted = false;
|
||||
|
||||
if (FilterContent.Contains("T") && !canTransfer)
|
||||
permitted = false;
|
||||
|
||||
if (FilterContent.Contains("M") && !canMod)
|
||||
permitted = false;
|
||||
|
||||
return permitted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute the inventory write request
|
||||
/// </summary>
|
||||
@@ -250,6 +317,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
if (options.ContainsKey("noassets") && (bool)options["noassets"])
|
||||
SaveAssets = false;
|
||||
|
||||
// Set Permission filter if flag is set
|
||||
if (options.ContainsKey("checkPermissions"))
|
||||
{
|
||||
Object temp;
|
||||
if (options.TryGetValue("checkPermissions", out temp))
|
||||
FilterContent = temp.ToString().ToUpper();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
InventoryFolderBase inventoryFolder = null;
|
||||
@@ -309,7 +384,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
// We couldn't find the path indicated
|
||||
string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
|
||||
Exception e = new InventoryArchiverException(errorMessage);
|
||||
m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e);
|
||||
m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e, 0, 0);
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -356,7 +431,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
|
||||
options, ReceivedAllAssets);
|
||||
|
||||
Util.RunThreadNoTimeout(o => ar.Execute(), "AssetsRequest", null);
|
||||
Watchdog.RunInThread(o => ar.Execute(), string.Format("AssetsRequest ({0})", m_scene.Name), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
// public bool DisablePresenceChecks { get; set; }
|
||||
|
||||
public event InventoryArchiveSaved OnInventoryArchiveSaved;
|
||||
public event InventoryArchiveLoaded OnInventoryArchiveLoaded;
|
||||
|
||||
/// <summary>
|
||||
/// The file to load and save inventory if no filename has been specified
|
||||
@@ -64,9 +65,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
protected const string DEFAULT_INV_BACKUP_FILENAME = "user-inventory.iar";
|
||||
|
||||
/// <value>
|
||||
/// Pending save completions initiated from the console
|
||||
/// Pending save and load completions initiated from the console
|
||||
/// </value>
|
||||
protected List<Guid> m_pendingConsoleSaves = new List<Guid>();
|
||||
protected List<UUID> m_pendingConsoleTasks = new List<UUID>();
|
||||
|
||||
/// <value>
|
||||
/// All scenes that this module knows about
|
||||
@@ -111,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
scene.RegisterModuleInterface<IInventoryArchiverModule>(this);
|
||||
OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
|
||||
OnInventoryArchiveLoaded += LoadInvConsoleCommandCompleted;
|
||||
|
||||
scene.AddCommand(
|
||||
"Archiving", this, "load iar",
|
||||
@@ -139,7 +141,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
+ "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine
|
||||
+ "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine
|
||||
+ "-v|--verbose extra debug messages.\n"
|
||||
+ "--noassets stops assets being saved to the IAR.",
|
||||
+ "--noassets stops assets being saved to the IAR."
|
||||
+ "--perm=<permissions> stops items with insufficient permissions from being saved to the IAR.\n"
|
||||
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer, \"M\" = Modify.\n",
|
||||
HandleSaveInvConsoleCommand);
|
||||
|
||||
m_aScene = scene;
|
||||
@@ -175,22 +179,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// Trigger the inventory archive saved event.
|
||||
/// </summary>
|
||||
protected internal void TriggerInventoryArchiveSaved(
|
||||
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
|
||||
Exception reportedException)
|
||||
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
|
||||
Exception reportedException, int SaveCount, int FilterCount)
|
||||
{
|
||||
InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved;
|
||||
if (handlerInventoryArchiveSaved != null)
|
||||
handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException);
|
||||
handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException, SaveCount , FilterCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trigger the inventory archive loaded event.
|
||||
/// </summary>
|
||||
protected internal void TriggerInventoryArchiveLoaded(
|
||||
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
|
||||
Exception reportedException, int LoadCount)
|
||||
{
|
||||
InventoryArchiveLoaded handlerInventoryArchiveLoaded = OnInventoryArchiveLoaded;
|
||||
if (handlerInventoryArchiveLoaded != null)
|
||||
handlerInventoryArchiveLoaded(id, succeeded, userInfo, invPath, loadStream, reportedException, LoadCount);
|
||||
}
|
||||
|
||||
public bool ArchiveInventory(
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
|
||||
UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream)
|
||||
{
|
||||
return ArchiveInventory(id, firstName, lastName, invPath, pass, saveStream, new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
public bool ArchiveInventory(
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
|
||||
UUID id, string firstName, string lastName, string invPath, string pass, Stream saveStream,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
if (m_scenes.Count > 0)
|
||||
@@ -230,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
public bool ArchiveInventory(
|
||||
Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
|
||||
UUID id, string firstName, string lastName, string invPath, string pass, string savePath,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
// if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath))
|
||||
@@ -272,13 +288,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DearchiveInventory(string firstName, string lastName, string invPath, string pass, Stream loadStream)
|
||||
public bool DearchiveInventory(UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream)
|
||||
{
|
||||
return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
|
||||
return DearchiveInventory(id, firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>());
|
||||
}
|
||||
|
||||
public bool DearchiveInventory(
|
||||
string firstName, string lastName, string invPath, string pass, Stream loadStream,
|
||||
UUID id, string firstName, string lastName, string invPath, string pass, Stream loadStream,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
if (m_scenes.Count > 0)
|
||||
@@ -294,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
try
|
||||
{
|
||||
request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
|
||||
request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
@@ -326,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
public bool DearchiveInventory(
|
||||
string firstName, string lastName, string invPath, string pass, string loadPath,
|
||||
UUID id, string firstName, string lastName, string invPath, string pass, string loadPath,
|
||||
Dictionary<string, object> options)
|
||||
{
|
||||
if (m_scenes.Count > 0)
|
||||
@@ -342,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
try
|
||||
{
|
||||
request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
|
||||
request = new InventoryArchiveReadRequest(id, this, m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge);
|
||||
}
|
||||
catch (EntryPointNotFoundException e)
|
||||
{
|
||||
@@ -378,6 +394,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
try
|
||||
{
|
||||
UUID id = UUID.Random();
|
||||
|
||||
Dictionary<string, object> options = new Dictionary<string, object>();
|
||||
OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
|
||||
|
||||
@@ -400,10 +418,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
"[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}",
|
||||
loadPath, invPath, firstName, lastName);
|
||||
|
||||
if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options))
|
||||
m_log.InfoFormat(
|
||||
"[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}",
|
||||
loadPath, firstName, lastName);
|
||||
lock (m_pendingConsoleTasks)
|
||||
m_pendingConsoleTasks.Add(id);
|
||||
|
||||
DearchiveInventory(id, firstName, lastName, invPath, pass, loadPath, options);
|
||||
}
|
||||
catch (InventoryArchiverException e)
|
||||
{
|
||||
@@ -417,7 +435,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// <param name="cmdparams"></param>
|
||||
protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams)
|
||||
{
|
||||
Guid id = Guid.NewGuid();
|
||||
UUID id = UUID.Random();
|
||||
|
||||
Dictionary<string, object> options = new Dictionary<string, object>();
|
||||
|
||||
@@ -439,6 +457,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
options["excludefolders"] = new List<String>();
|
||||
((List<String>)options["excludefolders"]).Add(v);
|
||||
});
|
||||
ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
|
||||
|
||||
List<string> mainParams = ops.Parse(cmdparams);
|
||||
|
||||
@@ -464,8 +483,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
|
||||
savePath, invPath, firstName, lastName);
|
||||
|
||||
lock (m_pendingConsoleSaves)
|
||||
m_pendingConsoleSaves.Add(id);
|
||||
lock (m_pendingConsoleTasks)
|
||||
m_pendingConsoleTasks.Add(id);
|
||||
|
||||
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
|
||||
}
|
||||
@@ -476,20 +495,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
|
||||
private void SaveInvConsoleCommandCompleted(
|
||||
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
|
||||
Exception reportedException)
|
||||
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
|
||||
Exception reportedException, int SaveCount, int FilterCount)
|
||||
{
|
||||
lock (m_pendingConsoleSaves)
|
||||
lock (m_pendingConsoleTasks)
|
||||
{
|
||||
if (m_pendingConsoleSaves.Contains(id))
|
||||
m_pendingConsoleSaves.Remove(id);
|
||||
if (m_pendingConsoleTasks.Contains(id))
|
||||
m_pendingConsoleTasks.Remove(id);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (succeeded)
|
||||
{
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName);
|
||||
// Report success and include item count and filter count (Skipped items due to --perm or --exclude switches)
|
||||
if(FilterCount == 0)
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}", SaveCount, userInfo.FirstName, userInfo.LastName);
|
||||
else
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive with {0} items for {1} {2}. Skipped {3} items due to exclude and/or perm switches", SaveCount, userInfo.FirstName, userInfo.LastName, FilterCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -499,6 +522,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadInvConsoleCommandCompleted(
|
||||
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream loadStream,
|
||||
Exception reportedException, int LoadCount)
|
||||
{
|
||||
lock (m_pendingConsoleTasks)
|
||||
{
|
||||
if (m_pendingConsoleTasks.Contains(id))
|
||||
m_pendingConsoleTasks.Remove(id);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (succeeded)
|
||||
{
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Loaded {0} items from archive {1} for {2} {3}", LoadCount, invPath, userInfo.FirstName, userInfo.LastName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[INVENTORY ARCHIVER]: Archive load for {0} {1} failed - {2}",
|
||||
userInfo.FirstName, userInfo.LastName, reportedException.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get user information for the given name.
|
||||
/// </summary>
|
||||
|
||||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
{
|
||||
@@ -69,8 +68,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
|
||||
|
||||
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
|
||||
|
||||
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
|
||||
InventoryItemBase foundItem1
|
||||
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
|
||||
|
||||
@@ -79,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// Now try loading to a root child folder
|
||||
UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA", false);
|
||||
MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray());
|
||||
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
|
||||
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream);
|
||||
|
||||
InventoryItemBase foundItem2
|
||||
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name);
|
||||
@@ -88,7 +87,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// Now try loading to a more deeply nested folder
|
||||
UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC", false);
|
||||
archiveReadStream = new MemoryStream(archiveReadStream.ToArray());
|
||||
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
|
||||
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream);
|
||||
|
||||
InventoryItemBase foundItem3
|
||||
= InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name);
|
||||
@@ -110,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
|
||||
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
|
||||
archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
|
||||
|
||||
InventoryItemBase foundItem1
|
||||
= InventoryArchiveUtils.FindItemByPath(
|
||||
@@ -180,13 +179,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
mre.Reset();
|
||||
archiverModule.ArchiveInventory(
|
||||
Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
|
||||
UUID.Random(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
|
||||
mre.WaitOne(60000, false);
|
||||
|
||||
// LOAD ITEM
|
||||
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
|
||||
|
||||
archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
|
||||
|
||||
archiverModule.DearchiveInventory(UUID.Random(), userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
|
||||
|
||||
InventoryItemBase foundItem1
|
||||
= InventoryArchiveUtils.FindItemByPath(
|
||||
@@ -229,7 +228,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
{
|
||||
// Test replication of path1
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
foldersCreated, nodesLoaded);
|
||||
@@ -246,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
{
|
||||
// Test replication of path2
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
foldersCreated, nodesLoaded);
|
||||
@@ -292,7 +291,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
||||
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
|
||||
@@ -343,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName });
|
||||
|
||||
new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
|
||||
new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true)
|
||||
.ReplicateArchivePathToUserInventory(
|
||||
itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID),
|
||||
new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>());
|
||||
|
||||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
{
|
||||
@@ -72,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
|
||||
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
|
||||
m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
|
||||
|
||||
InventoryItemBase coaItem
|
||||
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName);
|
||||
@@ -106,8 +105,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
|
||||
|
||||
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
|
||||
|
||||
m_archiverModule.DearchiveInventory(UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream);
|
||||
InventoryItemBase foundItem1
|
||||
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name);
|
||||
|
||||
@@ -171,7 +170,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
|
||||
m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
|
||||
m_archiverModule.DearchiveInventory(UUID.Random(), m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream);
|
||||
|
||||
InventoryItemBase foundItem1
|
||||
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
|
||||
|
||||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
{
|
||||
@@ -85,8 +84,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
|
||||
Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
|
||||
|
||||
InventoryArchiveReadRequest iarr
|
||||
= new InventoryArchiveReadRequest(null, null, null, null, null, (Stream)null, false);
|
||||
InventoryArchiveReadRequest iarr
|
||||
= new InventoryArchiveReadRequest(UUID.Random(), null, null, null, null, null, null, (Stream)null, false);
|
||||
iarr.LoadControlFile(filePath, data);
|
||||
|
||||
Assert.That(iarr.ControlFileLoaded, Is.True);
|
||||
@@ -110,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
mre.Reset();
|
||||
m_archiverModule.ArchiveInventory(
|
||||
Guid.NewGuid(), userFirstName, userLastName, "/", userPassword, archiveWriteStream);
|
||||
UUID.Random(), userFirstName, userLastName, "/", userPassword, archiveWriteStream);
|
||||
mre.WaitOne(60000, false);
|
||||
|
||||
// Test created iar
|
||||
@@ -179,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
mre.Reset();
|
||||
m_archiverModule.ArchiveInventory(
|
||||
Guid.NewGuid(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream);
|
||||
UUID.Random(), userFirstName, userLastName, "f1", userPassword, archiveWriteStream);
|
||||
mre.WaitOne(60000, false);
|
||||
|
||||
// Test created iar
|
||||
@@ -267,7 +266,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
mre.Reset();
|
||||
m_archiverModule.ArchiveInventory(
|
||||
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
|
||||
UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream);
|
||||
mre.WaitOne(60000, false);
|
||||
|
||||
byte[] archive = archiveWriteStream.ToArray();
|
||||
@@ -364,7 +363,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
// When we're not saving assets, archiving is being done synchronously.
|
||||
m_archiverModule.ArchiveInventory(
|
||||
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
|
||||
UUID.Random(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
|
||||
|
||||
byte[] archive = archiveWriteStream.ToArray();
|
||||
MemoryStream archiveReadStream = new MemoryStream(archive);
|
||||
|
||||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
{
|
||||
@@ -163,14 +162,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
scene.AddInventoryItem(coaItem);
|
||||
|
||||
archiverModule.ArchiveInventory(
|
||||
Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream);
|
||||
UUID.Random(), m_uaLL1.FirstName, m_uaLL1.LastName, "/*", "hampshire", archiveWriteStream);
|
||||
|
||||
m_iarStreamBytes = archiveWriteStream.ToArray();
|
||||
}
|
||||
|
||||
protected void SaveCompleted(
|
||||
Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
|
||||
Exception reportedException)
|
||||
UUID id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream,
|
||||
Exception reportedException, int SaveCount, int FilterCount)
|
||||
{
|
||||
mre.Set();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests
|
||||
{
|
||||
|
||||
@@ -48,6 +48,8 @@ using Mono.Addins;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.UserProfilesService;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using Microsoft.CSharp;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
{
|
||||
@@ -78,7 +80,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
/// <value>
|
||||
/// The configuration
|
||||
/// </value>
|
||||
public IConfigSource Config {
|
||||
public IConfigSource Config
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
@@ -89,7 +92,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
/// <value>
|
||||
/// The profile server URI.
|
||||
/// </value>
|
||||
public string ProfileServerUri {
|
||||
public string ProfileServerUri
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
@@ -111,11 +115,17 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
/// <value>
|
||||
/// <c>true</c> if enabled; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool Enabled {
|
||||
public bool Enabled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string MyGatekeeper
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
|
||||
#region IRegionModuleBase implementation
|
||||
/// <summary>
|
||||
@@ -152,6 +162,9 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
m_log.Debug("[PROFILES]: Full Profiles Enabled");
|
||||
ReplaceableInterface = null;
|
||||
Enabled = true;
|
||||
|
||||
MyGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
|
||||
new string[] { "Startup", "Hypergrid", "UserProfiles" }, String.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -599,30 +612,64 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
return;
|
||||
|
||||
UUID targetID;
|
||||
UUID.TryParse(args[0], out targetID);
|
||||
UUID.TryParse (args [0], out targetID);
|
||||
string serverURI = string.Empty;
|
||||
GetUserProfileServerURI(targetID, out serverURI);
|
||||
GetUserProfileServerURI (targetID, out serverURI);
|
||||
|
||||
string theirGatekeeperURI;
|
||||
GetUserGatekeeperURI (targetID, out theirGatekeeperURI);
|
||||
|
||||
IClientAPI remoteClient = (IClientAPI)sender;
|
||||
|
||||
UserProfilePick pick = new UserProfilePick();
|
||||
UUID.TryParse(args[0], out pick.CreatorId);
|
||||
UUID.TryParse(args[1], out pick.PickId);
|
||||
UserProfilePick pick = new UserProfilePick ();
|
||||
UUID.TryParse (args [0], out pick.CreatorId);
|
||||
UUID.TryParse (args [1], out pick.PickId);
|
||||
|
||||
|
||||
object Pick = (object)pick;
|
||||
if(!rpc.JsonRpcRequest(ref Pick, "pickinforequest", serverURI, UUID.Random().ToString()))
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage(
|
||||
if (!rpc.JsonRpcRequest (ref Pick, "pickinforequest", serverURI, UUID.Random ().ToString ())) {
|
||||
remoteClient.SendAgentAlertMessage (
|
||||
"Error selecting pick", false);
|
||||
return;
|
||||
}
|
||||
pick = (UserProfilePick) Pick;
|
||||
|
||||
Vector3 globalPos;
|
||||
Vector3.TryParse(pick.GlobalPos,out globalPos);
|
||||
pick = (UserProfilePick)Pick;
|
||||
|
||||
Vector3 globalPos = new Vector3(Vector3.Zero);
|
||||
|
||||
// Smoke and mirrors
|
||||
if (pick.Gatekeeper == MyGatekeeper)
|
||||
{
|
||||
Vector3.TryParse(pick.GlobalPos,out globalPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setup the illusion
|
||||
string region = string.Format("{0} {1}",pick.Gatekeeper,pick.SimName);
|
||||
GridRegion target = Scene.GridService.GetRegionByName(Scene.RegionInfo.ScopeID, region);
|
||||
|
||||
if(target == null)
|
||||
{
|
||||
// This is a dead or unreachable region
|
||||
}
|
||||
else
|
||||
{
|
||||
// Work our slight of hand
|
||||
int x = target.RegionLocX;
|
||||
int y = target.RegionLocY;
|
||||
|
||||
dynamic synthX = globalPos.X - (globalPos.X/Constants.RegionSize) * Constants.RegionSize;
|
||||
synthX += x;
|
||||
globalPos.X = synthX;
|
||||
|
||||
dynamic synthY = globalPos.Y - (globalPos.Y/Constants.RegionSize) * Constants.RegionSize;
|
||||
synthY += y;
|
||||
globalPos.Y = synthY;
|
||||
}
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString());
|
||||
|
||||
// Pull the rabbit out of the hat
|
||||
remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name,
|
||||
pick.Desc,pick.SnapshotId,pick.User,pick.OriginalName,pick.SimName,
|
||||
globalPos,pick.SortOrder,pick.Enabled);
|
||||
@@ -659,7 +706,8 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
/// Enabled.
|
||||
/// </param>
|
||||
public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled)
|
||||
{
|
||||
{
|
||||
//TODO: See how this works with NPC, May need to test
|
||||
m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString());
|
||||
|
||||
UserProfilePick pick = new UserProfilePick();
|
||||
@@ -699,6 +747,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
avaPos.X, avaPos.Y, p.Scene.Name);
|
||||
}
|
||||
|
||||
|
||||
pick.PickId = pickID;
|
||||
pick.CreatorId = creatorID;
|
||||
pick.TopPick = topPick;
|
||||
@@ -708,6 +757,7 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
pick.SnapshotId = snapshotID;
|
||||
pick.User = landOwnerName;
|
||||
pick.SimName = remoteClient.Scene.RegionInfo.RegionName;
|
||||
pick.Gatekeeper = MyGatekeeper;
|
||||
pick.GlobalPos = posGlobal.ToString();
|
||||
pick.SortOrder = sortOrder;
|
||||
pick.Enabled = enabled;
|
||||
@@ -1259,6 +1309,37 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user gatekeeper server URI.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The user gatekeeper server URI.
|
||||
/// </returns>
|
||||
/// <param name='userID'>
|
||||
/// If set to <c>true</c> user URI.
|
||||
/// </param>
|
||||
/// <param name='serverURI'>
|
||||
/// If set to <c>true</c> server URI.
|
||||
/// </param>
|
||||
bool GetUserGatekeeperURI(UUID userID, out string serverURI)
|
||||
{
|
||||
bool local;
|
||||
local = UserManagementModule.IsLocalGridUser(userID);
|
||||
|
||||
if (!local)
|
||||
{
|
||||
serverURI = UserManagementModule.GetUserServerURL(userID, "GatekeeperURI");
|
||||
// Is Foreign
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serverURI = MyGatekeeper;
|
||||
// Is local
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user profile server UR.
|
||||
/// </summary>
|
||||
|
||||
@@ -1529,7 +1529,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
else
|
||||
{
|
||||
// The destination region just doesn't exist
|
||||
failureReason = "Cannot cross into non-existant region";
|
||||
failureReason = "Cannot cross into non-existent region";
|
||||
}
|
||||
|
||||
if (neighbourRegion == null)
|
||||
@@ -1786,8 +1786,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
|
||||
|
||||
// now we have a child agent in this region. Request all interesting data about other (root) agents
|
||||
agent.SendOtherAgentsAvatarDataToMe();
|
||||
agent.SendOtherAgentsAppearanceToMe();
|
||||
agent.SendOtherAgentsAvatarDataToClient();
|
||||
agent.SendOtherAgentsAppearanceToClient();
|
||||
|
||||
// Backwards compatibility. Best effort
|
||||
if (version == "Unknown" || version == string.Empty)
|
||||
|
||||
@@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
logout = success; // flag for later logout from this grid; this is an HG TP
|
||||
|
||||
if (success)
|
||||
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
|
||||
Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
|
||||
|
||||
return success;
|
||||
}
|
||||
@@ -516,13 +516,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
// Local region?
|
||||
if (info != null)
|
||||
{
|
||||
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
|
||||
Scene.RequestTeleportLocation(
|
||||
remoteClient, info.RegionHandle, lm.Position,
|
||||
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Foreign region
|
||||
Scene scene = (Scene)(remoteClient.Scene);
|
||||
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
|
||||
GridRegion gatekeeper = new GridRegion();
|
||||
gatekeeper.ServerURI = lm.Gatekeeper;
|
||||
@@ -533,15 +533,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
if (finalDestination != null)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
|
||||
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
|
||||
ScenePresence sp = Scene.GetScenePresence(remoteClient.AgentId);
|
||||
|
||||
if (transferMod != null && sp != null)
|
||||
if (sp != null)
|
||||
{
|
||||
if (message != null)
|
||||
sp.ControllingClient.SendAgentAlertMessage(message, true);
|
||||
|
||||
transferMod.DoTeleport(
|
||||
// Validate assorted conditions
|
||||
string reason = string.Empty;
|
||||
if (!ValidateGenericConditions(sp, gatekeeper, finalDestination, 0, out reason))
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed(reason);
|
||||
return;
|
||||
}
|
||||
|
||||
DoTeleport(
|
||||
sp, gatekeeper, finalDestination, lm.Position, Vector3.UnitX,
|
||||
(uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
|
||||
}
|
||||
@@ -625,4 +632,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
return region;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -798,7 +798,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
|
||||
bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
|
||||
{
|
||||
AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
|
||||
AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
|
||||
|
||||
if (rezAsset == null)
|
||||
{
|
||||
@@ -829,7 +829,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
|
||||
Vector3 pos;
|
||||
|
||||
bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);
|
||||
bool single
|
||||
= m_Scene.GetObjectsToRez(
|
||||
rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);
|
||||
|
||||
if (single)
|
||||
{
|
||||
@@ -910,7 +912,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
// one full update during the attachment
|
||||
// process causes some clients to fail to display the
|
||||
// attachment properly.
|
||||
m_Scene.AddNewSceneObject(group, true, false);
|
||||
m_Scene.AddNewSceneObject(group, !attachment, false);
|
||||
|
||||
// if attachment we set it's asset id so object updates
|
||||
// can reflect that, if not, we set it's position in world.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user