Merge branch 'master' into 0.9.0-post-fixes

0.9.0-post-fixes
Diva Canto 2017-01-08 10:11:45 -08:00
commit 7642233109
1007 changed files with 44353 additions and 48124 deletions

2
.gitignore vendored
View File

@ -31,6 +31,7 @@
*/*/*/*/*/bin */*/*/*/*/bin
*/*/*/*/*/*/bin */*/*/*/*/*/bin
*/*/*/*/*/*/*/bin */*/*/*/*/*/*/bin
.vs/
addon-modules/ addon-modules/
bin/Debug/*.dll bin/Debug/*.dll
bin/*.dll.mdb bin/*.dll.mdb
@ -93,7 +94,6 @@ TAGS
Makefile.local Makefile.local
bin/.version bin/.version
compile.bat compile.bat
addon-modules
OpenSim/Data/Tests/test-results/ OpenSim/Data/Tests/test-results/
OpenSim/Framework/Serialization/Tests/test-results/ OpenSim/Framework/Serialization/Tests/test-results/
OpenSim/Framework/Servers/Tests/test-results/ OpenSim/Framework/Servers/Tests/test-results/

View File

@ -89,6 +89,7 @@ what it is today.
* dmiles (Daxtron Labs) * dmiles (Daxtron Labs)
* Dong Jun Lan (IBM) * Dong Jun Lan (IBM)
* DoranZemlja * DoranZemlja
* Drake Arconis
* dr0b3rts * dr0b3rts
* dslake * dslake
* eeyore * eeyore
@ -107,6 +108,7 @@ what it is today.
* Flyte Xevious * Flyte Xevious
* Freaky Tech * Freaky Tech
* Garmin Kawaguichi * Garmin Kawaguichi
* Geir Noklebye
* Glenn Martin (MOSES) * Glenn Martin (MOSES)
* Gryc Ueusp * Gryc Ueusp
* H-H-H (ginge264) * H-H-H (ginge264)
@ -115,6 +117,7 @@ what it is today.
* Imaze Rhiano * Imaze Rhiano
* Intimidated * Intimidated
* Jak Daniels * Jak Daniels
* Jeff Kelly
* Jeremy Bongio (IBM) * Jeremy Bongio (IBM)
* jhurliman * jhurliman
* John R Sohn (XenReborn) * John R Sohn (XenReborn)
@ -136,6 +139,7 @@ what it is today.
* Magnuz Binder * Magnuz Binder
* maimedleech * maimedleech
* Mana Janus * Mana Janus
* Mandarinka Tasty
* MarcelEdward * MarcelEdward
* Matt Lehmann * Matt Lehmann
* Mic Bowman * Mic Bowman
@ -158,6 +162,7 @@ what it is today.
* openlifegrid.com * openlifegrid.com
* otakup0pe * otakup0pe
* Pixel Tomsen * Pixel Tomsen
* Quill Littlefeather
* ralphos * ralphos
* RemedyTomm * RemedyTomm
* Revolution * Revolution
@ -183,6 +188,7 @@ what it is today.
* TBG Renfold * TBG Renfold
* tglion * tglion
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud) * tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
* TomDataWorks
* TomTheDragon (muckwaddle) * TomTheDragon (muckwaddle)
* tyre * tyre
* Vegaslon <vegaslon@gmail.com> * Vegaslon <vegaslon@gmail.com>

File diff suppressed because it is too large Load Diff

View File

@ -523,7 +523,7 @@ namespace OpenSim.Groups
UUID ejecteeID = new UUID(im.toAgentID); UUID ejecteeID = new UUID(im.toAgentID);
im.imSessionID = UUID.Zero.Guid; im.imSessionID = UUID.Zero.Guid;
im.dialog = (byte)InstantMessageDialog.MessageFromAgent; im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
OutgoingInstantMessage(im, ejecteeID); OutgoingInstantMessage(im, ejecteeID);
@ -756,7 +756,7 @@ namespace OpenSim.Groups
if (avatar != null) if (avatar != null)
{ {
if (avatar.UserLevel < m_levelGroupCreate) if (avatar.GodController.UserLevel < m_levelGroupCreate)
{ {
remoteClient.SendCreateGroupReply(UUID.Zero, false, String.Format("Insufficient permissions to create a group. Requires level {0}", m_levelGroupCreate)); remoteClient.SendCreateGroupReply(UUID.Zero, false, String.Format("Insufficient permissions to create a group. Requires level {0}", m_levelGroupCreate));
return UUID.Zero; return UUID.Zero;
@ -781,8 +781,8 @@ namespace OpenSim.Groups
if (groupID != UUID.Zero) if (groupID != UUID.Zero)
{ {
if (money != null) if (money != null && money.GroupCreationCharge > 0)
money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate); money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate, name);
remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully"); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully");
@ -979,10 +979,28 @@ namespace OpenSim.Groups
{ {
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
GroupRecord groupRecord = GetGroupRecord(groupID);
IMoneyModule money = remoteClient.Scene.RequestModuleInterface<IMoneyModule>();
// Should check to see if there's an outstanding invitation
if (money != null && groupRecord.MembershipFee > 0)
{
// Does the agent have the funds to cover the group join fee?
if (!money.AmountCovered(remoteClient.AgentId, groupRecord.MembershipFee))
{
remoteClient.SendAlertMessage("Insufficient funds to join the group.");
remoteClient.SendJoinGroupReply(groupID, false);
return;
}
}
string reason = string.Empty; string reason = string.Empty;
// Should check to see if OpenEnrollment, or if there's an outstanding invitation
if (m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID, UUID.Zero, string.Empty, out reason)) if (m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID, UUID.Zero, string.Empty, out reason))
{ {
if (money != null && groupRecord.MembershipFee > 0)
money.ApplyCharge(remoteClient.AgentId, groupRecord.MembershipFee, MoneyTransactionType.GroupJoin, groupRecord.GroupName);
remoteClient.SendJoinGroupReply(groupID, true); remoteClient.SendJoinGroupReply(groupID, true);

View File

@ -286,7 +286,7 @@ namespace OpenSim.Groups
string requestingAgentID = request["RequestingAgentID"].ToString(); string requestingAgentID = request["RequestingAgentID"].ToString();
if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID)) if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
NullResult(result, string.Format("Insufficient permissions.", agentID)); NullResult(result, string.Format("Insufficient permissions. {0}", agentID));
else else
result["RESULT"] = "true"; result["RESULT"] = "true";
} }

View File

@ -307,20 +307,20 @@ namespace OpenSim.Groups
m.Contribution = Int32.Parse(d.Data["Contribution"]); m.Contribution = Int32.Parse(d.Data["Contribution"]);
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false; m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
GridUserData gud = m_GridUserService.Get(d.PrincipalID); GridUserData gud = m_GridUserService.Get(d.PrincipalID);
if (gud != null) if (gud != null)
{ {
if (bool.Parse(gud.Data["Online"])) if (bool.Parse(gud.Data["Online"]))
{ {
m.OnlineStatus = @"Online"; m.OnlineStatus = @"Online";
} }
else else
{ {
int unixtime = int.Parse(gud.Data["Login"]); int unixtime = int.Parse(gud.Data["Login"]);
// The viewer is very picky about how these strings are formed. Eg. it will crash on malformed dates! // The viewer is very picky about how these strings are formed. Eg. it will crash on malformed dates!
m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy"); m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy");
} }
} }
// Is this person an owner of the group? // Is this person an owner of the group?
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false; m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
@ -496,7 +496,7 @@ namespace OpenSim.Groups
if (!unlimited && limited) if (!unlimited && limited)
{ {
// check whether person's has this role // check whether person's has this role
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID); RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
if (rolemembership == null) if (rolemembership == null)
{ {
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID); m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
@ -516,13 +516,26 @@ namespace OpenSim.Groups
return false; return false;
// check permissions // check permissions
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID); bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
if (!unlimited) if (!limited && !unlimited)
{ {
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID); m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
return false; return false;
} }
// AssignMemberLimited means that the person can assign another person to the same roles that she has in the group
if (!unlimited && limited)
{
// check whether person's has this role
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
if (rolemembership == null)
{
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
return false;
}
}
RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID); RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
if (rolemember == null) if (rolemember == null)
@ -812,7 +825,7 @@ namespace OpenSim.Groups
if (RoleID != UUID.Zero) if (RoleID != UUID.Zero)
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID); _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
// Make thit this active group // Make this the active group
PrincipalData pdata = new PrincipalData(); PrincipalData pdata = new PrincipalData();
pdata.PrincipalID = AgentID; pdata.PrincipalID = AgentID;
pdata.ActiveGroupID = GroupID; pdata.ActiveGroupID = GroupID;

View File

@ -35,67 +35,67 @@ using OpenSim.Services.Base;
namespace OpenSim.Groups namespace OpenSim.Groups
{ {
public class GroupsServiceBase : ServiceBase public class GroupsServiceBase : ServiceBase
{ {
protected IGroupsData m_Database = null; protected IGroupsData m_Database = null;
protected IGridUserData m_GridUserService = null; protected IGridUserData m_GridUserService = null;
public GroupsServiceBase(IConfigSource config, string cName) public GroupsServiceBase(IConfigSource config, string cName)
: base(config) : base(config)
{ {
string dllName = String.Empty; string dllName = String.Empty;
string connString = String.Empty; string connString = String.Empty;
string realm = "os_groups"; string realm = "os_groups";
string usersRealm = "GridUser"; string usersRealm = "GridUser";
string configName = (cName == string.Empty) ? "Groups" : cName; string configName = (cName == string.Empty) ? "Groups" : cName;
// //
// Try reading the [DatabaseService] section, if it exists // Try reading the [DatabaseService] section, if it exists
// //
IConfig dbConfig = config.Configs["DatabaseService"]; IConfig dbConfig = config.Configs["DatabaseService"];
if (dbConfig != null) if (dbConfig != null)
{ {
if (dllName == String.Empty) if (dllName == String.Empty)
dllName = dbConfig.GetString("StorageProvider", String.Empty); dllName = dbConfig.GetString("StorageProvider", String.Empty);
if (connString == String.Empty) if (connString == String.Empty)
connString = dbConfig.GetString("ConnectionString", String.Empty); connString = dbConfig.GetString("ConnectionString", String.Empty);
} }
// //
// [Groups] section overrides [DatabaseService], if it exists // [Groups] section overrides [DatabaseService], if it exists
// //
IConfig groupsConfig = config.Configs[configName]; IConfig groupsConfig = config.Configs[configName];
if (groupsConfig != null) if (groupsConfig != null)
{ {
dllName = groupsConfig.GetString("StorageProvider", dllName); dllName = groupsConfig.GetString("StorageProvider", dllName);
connString = groupsConfig.GetString("ConnectionString", connString); connString = groupsConfig.GetString("ConnectionString", connString);
realm = groupsConfig.GetString("Realm", realm); realm = groupsConfig.GetString("Realm", realm);
} }
// //
// We tried, but this doesn't exist. We can't proceed. // We tried, but this doesn't exist. We can't proceed.
// //
if (dllName.Equals(String.Empty)) if (dllName.Equals(String.Empty))
throw new Exception("No StorageProvider configured"); throw new Exception("No StorageProvider configured");
m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm }); m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm });
if (m_Database == null) if (m_Database == null)
throw new Exception("Could not find a storage interface in the given module " + dllName); throw new Exception("Could not find a storage interface in the given module " + dllName);
// //
// [GridUserService] section overrides [DatabaseService], if it exists // [GridUserService] section overrides [DatabaseService], if it exists
// //
IConfig usersConfig = config.Configs["GridUserService"]; IConfig usersConfig = config.Configs["GridUserService"];
if (usersConfig != null) if (usersConfig != null)
{ {
dllName = usersConfig.GetString("StorageProvider", dllName); dllName = usersConfig.GetString("StorageProvider", dllName);
connString = usersConfig.GetString("ConnectionString", connString); connString = usersConfig.GetString("ConnectionString", connString);
usersRealm = usersConfig.GetString("Realm", usersRealm); usersRealm = usersConfig.GetString("Realm", usersRealm);
} }
m_GridUserService = LoadPlugin<IGridUserData>(dllName, new Object[] { connString, usersRealm }); m_GridUserService = LoadPlugin<IGridUserData>(dllName, new Object[] { connString, usersRealm });
if (m_GridUserService == null) if (m_GridUserService == null)
throw new Exception("Could not find a storage inferface for the given users module " + dllName); throw new Exception("Could not find a storage inferface for the given users module " + dllName);
} }
} }
} }

View File

@ -3053,11 +3053,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController
{ {
if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
{ {
uint perms = item.CurrentPermissions; if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms); item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
item.CurrentPermissions = perms; if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
} }
item.CurrentPermissions &= item.NextPermissions; item.CurrentPermissions &= item.NextPermissions;
item.BasePermissions &= item.NextPermissions; item.BasePermissions &= item.NextPermissions;
item.EveryOnePermissions &= item.NextPermissions; item.EveryOnePermissions &= item.NextPermissions;

View File

@ -136,11 +136,16 @@ namespace OpenSim.Framework.Capabilities
} }
m_agentID = agent; m_agentID = agent;
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL); m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort);
m_regionName = regionName; m_regionName = regionName;
m_capsActive.Reset(); m_capsActive.Reset();
} }
~Caps()
{
m_capsActive.Dispose();
}
/// <summary> /// <summary>
/// Register a handler. This allows modules to register handlers. /// Register a handler. This allows modules to register handlers.
/// </summary> /// </summary>

View File

@ -53,31 +53,15 @@ namespace OpenSim.Framework.Capabilities
/// <param name="httpListener">base HTTP server</param> /// <param name="httpListener">base HTTP server</param>
/// <param name="httpListenerHostname">host name of the HTTP server</param> /// <param name="httpListenerHostname">host name of the HTTP server</param>
/// <param name="httpListenerPort">HTTP port</param> /// <param name="httpListenerPort">HTTP port</param>
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort) public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
: this(httpListener,httpListenerHostname,httpListenerPort, false) {
{
}
/// <summary></summary>
/// CapsHandlers is a cap handler container but also takes
/// care of adding and removing cap handlers to and from the
/// supplied BaseHttpServer.
/// </summary>
/// <param name="httpListener">base HTTP server</param>
/// <param name="httpListenerHostname">host name of the HTTP
/// server</param>
/// <param name="httpListenerPort">HTTP port</param>
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort, bool https)
{
m_httpListener = httpListener; m_httpListener = httpListener;
m_httpListenerHostName = httpListenerHostname; m_httpListenerHostName = httpListenerHostname;
m_httpListenerPort = httpListenerPort; m_httpListenerPort = httpListenerPort;
m_useSSL = https; if (httpListener != null && httpListener.UseSSL)
if (httpListener != null && m_useSSL) m_useSSL = true;
{ else
m_httpListenerHostName = httpListener.SSLCommonName; m_useSSL = false;
m_httpListenerPort = httpListener.SSLPort;
}
} }
/// <summary> /// <summary>

View File

@ -80,6 +80,7 @@ namespace OpenSim.Capabilities.Handlers
{ {
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
return null;
} }
UUID textureID; UUID textureID;
@ -150,6 +151,7 @@ namespace OpenSim.Capabilities.Handlers
return true; return true;
} }
WriteTextureData(httpRequest, httpResponse, texture, format); WriteTextureData(httpRequest, httpResponse, texture, format);
return true;
} }
else else
{ {

View File

@ -204,7 +204,7 @@ namespace OpenSim.Data.MySQL
foreach (RegionData r in dbret) foreach (RegionData r in dbret)
{ {
if (r.posX + r.sizeX > startX && r.posX <= endX if (r.posX + r.sizeX > startX && r.posX <= endX
&& r.posY + r.sizeX > startY && r.posY <= endY) && r.posY + r.sizeY > startY && r.posY <= endY)
ret.Add(r); ret.Add(r);
} }
return ret; return ret;

View File

@ -167,7 +167,7 @@ namespace OpenSim.Data.MySQL
"SitTargetOrientY, SitTargetOrientZ, " + "SitTargetOrientY, SitTargetOrientZ, " +
"RegionUUID, CreatorID, " + "RegionUUID, CreatorID, " +
"OwnerID, GroupID, " + "OwnerID, GroupID, " +
"LastOwnerID, SceneGroupID, " + "LastOwnerID, RezzerID, SceneGroupID, " +
"PayPrice, PayButton1, " + "PayPrice, PayButton1, " +
"PayButton2, PayButton3, " + "PayButton2, PayButton3, " +
"PayButton4, LoopedSound, " + "PayButton4, LoopedSound, " +
@ -207,7 +207,7 @@ namespace OpenSim.Data.MySQL
"?SitTargetOrientW, ?SitTargetOrientX, " + "?SitTargetOrientW, ?SitTargetOrientX, " +
"?SitTargetOrientY, ?SitTargetOrientZ, " + "?SitTargetOrientY, ?SitTargetOrientZ, " +
"?RegionUUID, ?CreatorID, ?OwnerID, " + "?RegionUUID, ?CreatorID, ?OwnerID, " +
"?GroupID, ?LastOwnerID, ?SceneGroupID, " + "?GroupID, ?LastOwnerID, ?RezzerID, ?SceneGroupID, " +
"?PayPrice, ?PayButton1, ?PayButton2, " + "?PayPrice, ?PayButton1, ?PayButton2, " +
"?PayButton3, ?PayButton4, ?LoopedSound, " + "?PayButton3, ?PayButton4, ?LoopedSound, " +
"?LoopedSoundGain, ?TextureAnimation, " + "?LoopedSoundGain, ?TextureAnimation, " +
@ -1279,6 +1279,10 @@ namespace OpenSim.Data.MySQL
prim.OwnerID = DBGuid.FromDB(row["OwnerID"]); prim.OwnerID = DBGuid.FromDB(row["OwnerID"]);
prim.GroupID = DBGuid.FromDB(row["GroupID"]); prim.GroupID = DBGuid.FromDB(row["GroupID"]);
prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]); prim.LastOwnerID = DBGuid.FromDB(row["LastOwnerID"]);
if (row["RezzerID"] != DBNull.Value)
prim.RezzerID = DBGuid.FromDB(row["RezzerID"]);
else
prim.RezzerID = UUID.Zero;
// explicit conversion of integers is required, which sort // explicit conversion of integers is required, which sort
// of sucks. No idea if there is a shortcut here or not. // of sucks. No idea if there is a shortcut here or not.
@ -1682,6 +1686,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString()); cmd.Parameters.AddWithValue("OwnerID", prim.OwnerID.ToString());
cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString()); cmd.Parameters.AddWithValue("GroupID", prim.GroupID.ToString());
cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString()); cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString());
cmd.Parameters.AddWithValue("RezzerID", prim.RezzerID.ToString());
cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask); cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask);
cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask); cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask);
cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask); cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask);

View File

@ -193,7 +193,9 @@ namespace OpenSim.Data.MySQL
{ {
using (MySqlCommand cmd = new MySqlCommand()) using (MySqlCommand cmd = new MySqlCommand())
{ {
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1", m_Realm); // cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1", m_Realm);
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags & 1");
cmd.Parameters.AddWithValue("?uuid", principalID.ToString()); cmd.Parameters.AddWithValue("?uuid", principalID.ToString());
cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture);
@ -212,7 +214,10 @@ namespace OpenSim.Data.MySQL
{ {
cmd.Connection = dbcon; cmd.Connection = dbcon;
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); // cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm);
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID");
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue("?AssetID", assetID.ToString()); cmd.Parameters.AddWithValue("?AssetID", assetID.ToString());

View File

@ -11,6 +11,6 @@ CREATE TABLE IF NOT EXISTS `im_offline` (
PRIMARY KEY (`ID`), PRIMARY KEY (`ID`),
KEY `PrincipalID` (`PrincipalID`), KEY `PrincipalID` (`PrincipalID`),
KEY `FromID` (`FromID`) KEY `FromID` (`FromID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
COMMIT; COMMIT;

View File

@ -97,7 +97,7 @@ CREATE TABLE IF NOT EXISTS `prims` (
PRIMARY KEY (`UUID`), PRIMARY KEY (`UUID`),
KEY `prims_regionuuid` (`RegionUUID`), KEY `prims_regionuuid` (`RegionUUID`),
KEY `prims_scenegroupid` (`SceneGroupID`) KEY `prims_scenegroupid` (`SceneGroupID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `primshapes` ( CREATE TABLE IF NOT EXISTS `primshapes` (
`Shape` int(11) DEFAULT NULL, `Shape` int(11) DEFAULT NULL,
@ -130,7 +130,7 @@ CREATE TABLE IF NOT EXISTS `primshapes` (
`Media` text, `Media` text,
`LastAttachPoint` int(4) NOT NULL DEFAULT '0', `LastAttachPoint` int(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`UUID`) PRIMARY KEY (`UUID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `primitems` ( CREATE TABLE IF NOT EXISTS `primitems` (
`invType` int(11) DEFAULT NULL, `invType` int(11) DEFAULT NULL,
@ -154,13 +154,13 @@ CREATE TABLE IF NOT EXISTS `primitems` (
`lastOwnerID` char(36) DEFAULT NULL, `lastOwnerID` char(36) DEFAULT NULL,
PRIMARY KEY (`itemID`), PRIMARY KEY (`itemID`),
KEY `primitems_primid` (`primID`) KEY `primitems_primid` (`primID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `terrain` ( CREATE TABLE IF NOT EXISTS `terrain` (
`RegionUUID` varchar(255) DEFAULT NULL, `RegionUUID` varchar(255) DEFAULT NULL,
`Revision` int(11) DEFAULT NULL, `Revision` int(11) DEFAULT NULL,
`Heightfield` longblob `Heightfield` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `land` ( CREATE TABLE IF NOT EXISTS `land` (
`UUID` varchar(255) NOT NULL, `UUID` varchar(255) NOT NULL,
@ -204,21 +204,21 @@ CREATE TABLE IF NOT EXISTS `land` (
`ObscureMusic` tinyint(1) NOT NULL DEFAULT '0', `ObscureMusic` tinyint(1) NOT NULL DEFAULT '0',
`ObscureMedia` tinyint(1) NOT NULL DEFAULT '0', `ObscureMedia` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`UUID`) PRIMARY KEY (`UUID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `landaccesslist` ( CREATE TABLE IF NOT EXISTS `landaccesslist` (
`LandUUID` varchar(255) DEFAULT NULL, `LandUUID` varchar(255) DEFAULT NULL,
`AccessUUID` varchar(255) DEFAULT NULL, `AccessUUID` varchar(255) DEFAULT NULL,
`Flags` int(11) DEFAULT NULL, `Flags` int(11) DEFAULT NULL,
`Expires` int(11) NOT NULL DEFAULT '0' `Expires` int(11) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `regionban` ( CREATE TABLE IF NOT EXISTS `regionban` (
`regionUUID` varchar(36) NOT NULL, `regionUUID` varchar(36) NOT NULL,
`bannedUUID` varchar(36) NOT NULL, `bannedUUID` varchar(36) NOT NULL,
`bannedIp` varchar(16) NOT NULL, `bannedIp` varchar(16) NOT NULL,
`bannedIpHostMask` varchar(16) NOT NULL `bannedIpHostMask` varchar(16) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `regionsettings` ( CREATE TABLE IF NOT EXISTS `regionsettings` (
`regionUUID` char(36) NOT NULL, `regionUUID` char(36) NOT NULL,
@ -265,7 +265,7 @@ CREATE TABLE IF NOT EXISTS `regionsettings` (
`parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
`covenant_datetime` int(10) unsigned NOT NULL DEFAULT '0', `covenant_datetime` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`regionUUID`) PRIMARY KEY (`regionUUID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `regionwindlight` ( CREATE TABLE IF NOT EXISTS `regionwindlight` (
`region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000', `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
@ -390,3 +390,74 @@ CREATE TABLE IF NOT EXISTS `bakedterrain` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
COMMIT; COMMIT;
:VERSION 55 #----- Increase float precision for windlight needed by scripts
BEGIN;
ALTER TABLE `regionwindlight`
MODIFY `water_fog_density_exponent` float(9,7) unsigned NOT NULL DEFAULT '4.0',
MODIFY `underwater_fog_modifier` float(9,8) unsigned NOT NULL DEFAULT '0.25',
MODIFY `reflection_wavelet_scale_1` float(9,7) unsigned NOT NULL DEFAULT '2.0',
MODIFY `reflection_wavelet_scale_2` float(9,7) unsigned NOT NULL DEFAULT '2.0',
MODIFY `reflection_wavelet_scale_3` float(9,7) unsigned NOT NULL DEFAULT '2.0',
MODIFY `fresnel_scale` float(9,8) unsigned NOT NULL DEFAULT '0.40',
MODIFY `fresnel_offset` float(9,8) unsigned NOT NULL DEFAULT '0.50',
MODIFY `refract_scale_above` float(9,8) unsigned NOT NULL DEFAULT '0.03',
MODIFY `refract_scale_below` float(9,8) unsigned NOT NULL DEFAULT '0.20',
MODIFY `blur_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.040',
MODIFY `big_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.05',
MODIFY `big_wave_direction_y` float(9,8) NOT NULL DEFAULT '-0.42',
MODIFY `little_wave_direction_x` float(9,8) NOT NULL DEFAULT '1.11',
MODIFY `little_wave_direction_y` float(9,8) NOT NULL DEFAULT '-1.16',
MODIFY `horizon_r` float(9,8) unsigned NOT NULL DEFAULT '0.25',
MODIFY `horizon_g` float(9,8) unsigned NOT NULL DEFAULT '0.25',
MODIFY `horizon_b` float(9,8) unsigned NOT NULL DEFAULT '0.32',
MODIFY `horizon_i` float(9,8) unsigned NOT NULL DEFAULT '0.32',
MODIFY `haze_horizon` float(9,8) unsigned NOT NULL DEFAULT '0.19',
MODIFY `blue_density_r` float(9,8) unsigned NOT NULL DEFAULT '0.12',
MODIFY `blue_density_g` float(9,8) unsigned NOT NULL DEFAULT '0.22',
MODIFY `blue_density_b` float(9,8) unsigned NOT NULL DEFAULT '0.38',
MODIFY `blue_density_i` float(9,8) unsigned NOT NULL DEFAULT '0.38',
MODIFY `haze_density` float(9,8) unsigned NOT NULL DEFAULT '0.70',
MODIFY `density_multiplier` float(9,8) unsigned NOT NULL DEFAULT '0.18',
MODIFY `distance_multiplier` float(9,6) unsigned NOT NULL DEFAULT '0.8',
MODIFY `sun_moon_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.24',
MODIFY `sun_moon_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.26',
MODIFY `sun_moon_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.30',
MODIFY `sun_moon_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.30',
MODIFY `sun_moon_position` float(9,8) unsigned NOT NULL DEFAULT '0.317',
MODIFY `ambient_r` float(9,8) unsigned NOT NULL DEFAULT '0.35',
MODIFY `ambient_g` float(9,8) unsigned NOT NULL DEFAULT '0.35',
MODIFY `ambient_b` float(9,8) unsigned NOT NULL DEFAULT '0.35',
MODIFY `ambient_i` float(9,8) unsigned NOT NULL DEFAULT '0.35',
MODIFY `east_angle` float(9,8) unsigned NOT NULL DEFAULT '0.00',
MODIFY `sun_glow_focus` float(9,8) unsigned NOT NULL DEFAULT '0.10',
MODIFY `sun_glow_size` float(9,8) unsigned NOT NULL DEFAULT '1.75',
MODIFY `scene_gamma` float(9,7) unsigned NOT NULL DEFAULT '1.00',
MODIFY `star_brightness` float(9,8) unsigned NOT NULL DEFAULT '0.00',
MODIFY `cloud_color_r` float(9,8) unsigned NOT NULL DEFAULT '0.41',
MODIFY `cloud_color_g` float(9,8) unsigned NOT NULL DEFAULT '0.41',
MODIFY `cloud_color_b` float(9,8) unsigned NOT NULL DEFAULT '0.41',
MODIFY `cloud_color_i` float(9,8) unsigned NOT NULL DEFAULT '0.41',
MODIFY `cloud_x` float(9,8) unsigned NOT NULL DEFAULT '1.00',
MODIFY `cloud_y` float(9,8) unsigned NOT NULL DEFAULT '0.53',
MODIFY `cloud_density` float(9,8) unsigned NOT NULL DEFAULT '1.00',
MODIFY `cloud_coverage` float(9,8) unsigned NOT NULL DEFAULT '0.27',
MODIFY `cloud_scale` float(9,8) unsigned NOT NULL DEFAULT '0.42',
MODIFY `cloud_detail_x` float(9,8) unsigned NOT NULL DEFAULT '1.00',
MODIFY `cloud_detail_y` float(9,8) unsigned NOT NULL DEFAULT '0.53',
MODIFY `cloud_detail_density` float(9,8) unsigned NOT NULL DEFAULT '0.12',
MODIFY `cloud_scroll_x` float(9,7) NOT NULL DEFAULT '0.20',
MODIFY `cloud_scroll_y` float(9,7) NOT NULL DEFAULT '0.01';
COMMIT;
:VERSION 56 #----- Add RezzerID field in table prims
BEGIN;
ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL;
COMMIT;

View File

@ -27,7 +27,7 @@ CREATE TABLE IF NOT EXISTS `usernotes` (
`targetuuid` varchar(36) NOT NULL, `targetuuid` varchar(36) NOT NULL,
`notes` text NOT NULL, `notes` text NOT NULL,
UNIQUE KEY `useruuid` (`useruuid`,`targetuuid`) UNIQUE KEY `useruuid` (`useruuid`,`targetuuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `userpicks` ( CREATE TABLE IF NOT EXISTS `userpicks` (
@ -46,7 +46,7 @@ CREATE TABLE IF NOT EXISTS `userpicks` (
`enabled` enum('true','false') NOT NULL, `enabled` enum('true','false') NOT NULL,
`gatekeeper` varchar(255), `gatekeeper` varchar(255),
PRIMARY KEY (`pickuuid`) PRIMARY KEY (`pickuuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `userprofile` ( CREATE TABLE IF NOT EXISTS `userprofile` (
@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS `userprofile` (
`profileFirstImage` varchar(36) NOT NULL, `profileFirstImage` varchar(36) NOT NULL,
`profileFirstText` text NOT NULL, `profileFirstText` text NOT NULL,
PRIMARY KEY (`useruuid`) PRIMARY KEY (`useruuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `userdata` ( CREATE TABLE IF NOT EXISTS `userdata` (
`UserId` char(36) NOT NULL, `UserId` char(36) NOT NULL,
@ -73,7 +73,7 @@ CREATE TABLE IF NOT EXISTS `userdata` (
`DataKey` varchar(255), `DataKey` varchar(255),
`DataVal` varchar(255), `DataVal` varchar(255),
PRIMARY KEY (`UserId`,`TagId`) PRIMARY KEY (`UserId`,`TagId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `usersettings` ( CREATE TABLE IF NOT EXISTS `usersettings` (
`useruuid` varchar(36) NOT NULL, `useruuid` varchar(36) NOT NULL,
@ -81,6 +81,6 @@ CREATE TABLE IF NOT EXISTS `usersettings` (
`visible` enum('true','false') NOT NULL, `visible` enum('true','false') NOT NULL,
`email` varchar(254) NOT NULL, `email` varchar(254) NOT NULL,
PRIMARY KEY (`useruuid`) PRIMARY KEY (`useruuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
commit; commit;

View File

@ -18,7 +18,7 @@ CREATE TABLE `os_groups_groups` (
PRIMARY KEY (`GroupID`), PRIMARY KEY (`GroupID`),
UNIQUE KEY `Name` (`Name`), UNIQUE KEY `Name` (`Name`),
FULLTEXT KEY `Name_2` (`Name`) FULLTEXT KEY `Name_2` (`Name`)
) ENGINE=MyISAM; ) ENGINE=InnoDB;
CREATE TABLE `os_groups_membership` ( CREATE TABLE `os_groups_membership` (
@ -31,7 +31,7 @@ CREATE TABLE `os_groups_membership` (
`AccessToken` char(36) NOT NULL default '', `AccessToken` char(36) NOT NULL default '',
PRIMARY KEY (`GroupID`,`PrincipalID`), PRIMARY KEY (`GroupID`,`PrincipalID`),
KEY `PrincipalID` (`PrincipalID`) KEY `PrincipalID` (`PrincipalID`)
) ENGINE=MyISAM; ) ENGINE=InnoDB;
CREATE TABLE `os_groups_roles` ( CREATE TABLE `os_groups_roles` (
@ -43,7 +43,7 @@ CREATE TABLE `os_groups_roles` (
`Powers` bigint(20) unsigned NOT NULL default '0', `Powers` bigint(20) unsigned NOT NULL default '0',
PRIMARY KEY (`GroupID`,`RoleID`), PRIMARY KEY (`GroupID`,`RoleID`),
KEY `GroupID` (`GroupID`) KEY `GroupID` (`GroupID`)
) ENGINE=MyISAM; ) ENGINE=InnoDB;
CREATE TABLE `os_groups_rolemembership` ( CREATE TABLE `os_groups_rolemembership` (
@ -52,7 +52,7 @@ CREATE TABLE `os_groups_rolemembership` (
`PrincipalID` VARCHAR(255) NOT NULL default '', `PrincipalID` VARCHAR(255) NOT NULL default '',
PRIMARY KEY (`GroupID`,`RoleID`,`PrincipalID`), PRIMARY KEY (`GroupID`,`RoleID`,`PrincipalID`),
KEY `PrincipalID` (`PrincipalID`) KEY `PrincipalID` (`PrincipalID`)
) ENGINE=MyISAM; ) ENGINE=InnoDB;
CREATE TABLE `os_groups_invites` ( CREATE TABLE `os_groups_invites` (
@ -63,7 +63,7 @@ CREATE TABLE `os_groups_invites` (
`TMStamp` timestamp NOT NULL, `TMStamp` timestamp NOT NULL,
PRIMARY KEY (`InviteID`), PRIMARY KEY (`InviteID`),
UNIQUE KEY `PrincipalGroup` (`GroupID`,`PrincipalID`) UNIQUE KEY `PrincipalGroup` (`GroupID`,`PrincipalID`)
) ENGINE=MyISAM; ) ENGINE=InnoDB;
CREATE TABLE `os_groups_notices` ( CREATE TABLE `os_groups_notices` (
@ -81,13 +81,13 @@ CREATE TABLE `os_groups_notices` (
PRIMARY KEY (`NoticeID`), PRIMARY KEY (`NoticeID`),
KEY `GroupID` (`GroupID`), KEY `GroupID` (`GroupID`),
KEY `TMStamp` (`TMStamp`) KEY `TMStamp` (`TMStamp`)
) ENGINE=MyISAM; ) ENGINE=InnoDB;
CREATE TABLE `os_groups_principals` ( CREATE TABLE `os_groups_principals` (
`PrincipalID` VARCHAR(255) NOT NULL default '', `PrincipalID` VARCHAR(255) NOT NULL default '',
`ActiveGroupID` char(36) NOT NULL default '', `ActiveGroupID` char(36) NOT NULL default '',
PRIMARY KEY (`PrincipalID`) PRIMARY KEY (`PrincipalID`)
) ENGINE=MyISAM; ) ENGINE=InnoDB;
COMMIT; COMMIT;

View File

@ -211,7 +211,7 @@ namespace OpenSim.Data.PGSQL
foreach (RegionData r in dbret) foreach (RegionData r in dbret)
{ {
if (r.posX + r.sizeX > startX && r.posX <= endX if (r.posX + r.sizeX > startX && r.posX <= endX
&& r.posY + r.sizeX > startY && r.posY <= endY) && r.posY + r.sizeY > startY && r.posY <= endY)
ret.Add(r); ret.Add(r);
} }
return ret; return ret;

View File

@ -174,7 +174,9 @@ namespace OpenSim.Data.PGSQL
{ {
using (NpgsqlCommand cmd = new NpgsqlCommand()) using (NpgsqlCommand cmd = new NpgsqlCommand())
{ {
cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1", m_Realm); // cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1", m_Realm);
cmd.CommandText = String.Format(@"select * from inventoryitems where ""avatarID"" = :uuid and ""assetType"" = :type and ""flags"" = 1");
UUID princID = UUID.Zero; UUID princID = UUID.Zero;
UUID.TryParse(principalID, out princID); UUID.TryParse(principalID, out princID);
@ -194,11 +196,18 @@ namespace OpenSim.Data.PGSQL
{ {
using (NpgsqlCommand cmd = new NpgsqlCommand()) using (NpgsqlCommand cmd = new NpgsqlCommand())
{ {
/*
cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions"" cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions""
from inventoryitems from inventoryitems
where ""avatarID"" = :PrincipalID where ""avatarID"" = :PrincipalID
and ""assetID"" = :AssetID and ""assetID"" = :AssetID
group by ""assetID"" ", m_Realm); group by ""assetID"" ", m_Realm);
*/
cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions""
from inventoryitems
where ""avatarID""::uuid = :PrincipalID
and ""assetID"" = :AssetID
group by ""assetID"" ");
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID)); cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID));
cmd.Parameters.Add(m_database.CreateParameter("AssetID", assetID)); cmd.Parameters.Add(m_database.CreateParameter("AssetID", assetID));

View File

@ -363,3 +363,11 @@ CREATE TABLE IF NOT EXISTS bakedterrain(
Heightfield blob); Heightfield blob);
COMMIT; COMMIT;
:VERSION 35 #----- Add RezzerID field in table prims
BEGIN;
ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL;
COMMIT;

View File

@ -1216,6 +1216,7 @@ namespace OpenSim.Data.SQLite
createCol(prims, "OwnerID", typeof(String)); createCol(prims, "OwnerID", typeof(String));
createCol(prims, "GroupID", typeof(String)); createCol(prims, "GroupID", typeof(String));
createCol(prims, "LastOwnerID", typeof(String)); createCol(prims, "LastOwnerID", typeof(String));
createCol(prims, "RezzerID", typeof(String));
createCol(prims, "OwnerMask", typeof(Int32)); createCol(prims, "OwnerMask", typeof(Int32));
createCol(prims, "NextOwnerMask", typeof(Int32)); createCol(prims, "NextOwnerMask", typeof(Int32));
createCol(prims, "GroupMask", typeof(Int32)); createCol(prims, "GroupMask", typeof(Int32));
@ -1679,6 +1680,7 @@ namespace OpenSim.Data.SQLite
prim.OwnerID = new UUID((String)row["OwnerID"]); prim.OwnerID = new UUID((String)row["OwnerID"]);
prim.GroupID = new UUID((String)row["GroupID"]); prim.GroupID = new UUID((String)row["GroupID"]);
prim.LastOwnerID = new UUID((String)row["LastOwnerID"]); prim.LastOwnerID = new UUID((String)row["LastOwnerID"]);
prim.RezzerID = row["RezzerID"] == DBNull.Value ? UUID.Zero : new UUID((String)row["RezzerID"]);
prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]);
prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]);
prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); prim.GroupMask = Convert.ToUInt32(row["GroupMask"]);
@ -2125,6 +2127,7 @@ namespace OpenSim.Data.SQLite
row["OwnerID"] = prim.OwnerID.ToString(); row["OwnerID"] = prim.OwnerID.ToString();
row["GroupID"] = prim.GroupID.ToString(); row["GroupID"] = prim.GroupID.ToString();
row["LastOwnerID"] = prim.LastOwnerID.ToString(); row["LastOwnerID"] = prim.LastOwnerID.ToString();
row["RezzerID"] = prim.RezzerID.ToString();
row["OwnerMask"] = prim.OwnerMask; row["OwnerMask"] = prim.OwnerMask;
row["NextOwnerMask"] = prim.NextOwnerMask; row["NextOwnerMask"] = prim.NextOwnerMask;
row["GroupMask"] = prim.GroupMask; row["GroupMask"] = prim.GroupMask;

View File

@ -81,6 +81,8 @@ namespace OpenSim.Framework
public Vector3 ClientAgentPosition; public Vector3 ClientAgentPosition;
public bool UseClientAgentPosition; public bool UseClientAgentPosition;
public bool NeedsCameraCollision;
public uint lastpacketSequence;
public AgentUpdateArgs() public AgentUpdateArgs()
{ {

View File

@ -155,7 +155,7 @@ namespace OpenSim.Framework
} }
} }
public virtual byte[] Data public byte[] Data
{ {
get { return m_data; } get { return m_data; }
set { m_data = value; } set { m_data = value; }

View File

@ -531,14 +531,14 @@ namespace OpenSim.Framework
{ {
lock (m_attachments) lock (m_attachments)
{ {
List<AvatarAttachment> alist = new List<AvatarAttachment>(); List<AvatarAttachment> alist = new List<AvatarAttachment>();
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments) foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
{ {
foreach (AvatarAttachment attach in kvp.Value) foreach (AvatarAttachment attach in kvp.Value)
alist.Add(new AvatarAttachment(attach)); alist.Add(new AvatarAttachment(attach));
} }
return alist; return alist;
} }
} }
internal void AppendAttachment(AvatarAttachment attach) internal void AppendAttachment(AvatarAttachment attach)

View File

@ -89,14 +89,14 @@ namespace OpenSim.Framework
public CacheItemBase(string index) public CacheItemBase(string index)
{ {
uuid = index; uuid = index;
entered = DateTime.Now; entered = DateTime.UtcNow;
lastUsed = entered; lastUsed = entered;
} }
public CacheItemBase(string index, DateTime ttl) public CacheItemBase(string index, DateTime ttl)
{ {
uuid = index; uuid = index;
entered = DateTime.Now; entered = DateTime.UtcNow;
lastUsed = entered; lastUsed = entered;
expires = ttl; expires = ttl;
} }
@ -215,6 +215,8 @@ namespace OpenSim.Framework
private CacheFlags m_Flags = 0; private CacheFlags m_Flags = 0;
private int m_Size = 1024; private int m_Size = 1024;
private TimeSpan m_DefaultTTL = new TimeSpan(0); private TimeSpan m_DefaultTTL = new TimeSpan(0);
private DateTime m_nextExpire;
private TimeSpan m_expiresTime = new TimeSpan(0,0,30);
public ExpireDelegate OnExpire; public ExpireDelegate OnExpire;
// Comparison interfaces // Comparison interfaces
@ -233,6 +235,21 @@ namespace OpenSim.Framework
return(a.lastUsed.CompareTo(b.lastUsed)); return(a.lastUsed.CompareTo(b.lastUsed));
} }
} }
// same as above, reverse order
private class SortLRUrev : IComparer<CacheItemBase>
{
public int Compare(CacheItemBase a, CacheItemBase b)
{
if (a == null && b == null)
return 0;
if (a == null)
return -1;
if (b == null)
return 1;
return(b.lastUsed.CompareTo(a.lastUsed));
}
}
// Convenience constructors // Convenience constructors
// //
@ -241,6 +258,8 @@ namespace OpenSim.Framework
m_Strategy = CacheStrategy.Balanced; m_Strategy = CacheStrategy.Balanced;
m_Medium = CacheMedium.Memory; m_Medium = CacheMedium.Memory;
m_Flags = 0; m_Flags = 0;
m_nextExpire = DateTime.UtcNow + m_expiresTime;
m_Strategy = CacheStrategy.Aggressive;
} }
public Cache(CacheMedium medium) : public Cache(CacheMedium medium) :
@ -295,19 +314,23 @@ namespace OpenSim.Framework
{ {
lock (m_Index) lock (m_Index)
{ {
if (Count <= Size) int target = newSize;
return; if(m_Strategy == CacheStrategy.Aggressive)
target = (int)(newSize * 0.9);
m_Index.Sort(new SortLRU()); if(Count > target)
m_Index.Reverse(); {
m_Index.Sort(new SortLRUrev());
m_Index.RemoveRange(newSize, Count - newSize); m_Index.RemoveRange(newSize, Count - target);
m_Lookup.Clear();
foreach (CacheItemBase item in m_Index)
m_Lookup[item.uuid] = item;
}
m_Size = newSize; m_Size = newSize;
m_Lookup.Clear();
foreach (CacheItemBase item in m_Index)
m_Lookup[item.uuid] = item;
} }
} }
@ -335,7 +358,7 @@ namespace OpenSim.Framework
} }
item.hits++; item.hits++;
item.lastUsed = DateTime.Now; item.lastUsed = DateTime.UtcNow;
Expire(true); Expire(true);
} }
@ -361,30 +384,26 @@ namespace OpenSim.Framework
// //
public virtual Object Get(string index, FetchDelegate fetch) public virtual Object Get(string index, FetchDelegate fetch)
{ {
Object item = Get(index); CacheItemBase item = GetItem(index);
if (item != null) if (item != null)
return item; return item.Retrieve();
Object data = fetch(index); Object data = fetch(index);
if (data == null)
{ if (data == null && (m_Flags & CacheFlags.CacheMissing) == 0)
if ((m_Flags & CacheFlags.CacheMissing) != 0)
{
lock (m_Index)
{
CacheItemBase missing = new CacheItemBase(index);
if (!m_Index.Contains(missing))
{
m_Index.Add(missing);
m_Lookup[index] = missing;
}
}
}
return null; return null;
lock (m_Index)
{
CacheItemBase missing = new CacheItemBase(index);
if (!m_Index.Contains(missing))
{
m_Index.Add(missing);
m_Lookup[index] = missing;
}
} }
Store(index, data); Store(index, data);
return data; return data;
} }
@ -442,9 +461,9 @@ namespace OpenSim.Framework
item = GetItem(index); item = GetItem(index);
item.hits++; item.hits++;
item.lastUsed = DateTime.Now; item.lastUsed = DateTime.UtcNow;
if (m_DefaultTTL.Ticks != 0) if (m_DefaultTTL.Ticks != 0)
item.expires = DateTime.Now + m_DefaultTTL; item.expires = DateTime.UtcNow + m_DefaultTTL;
item.Store(data); item.Store(data);
} }
@ -455,7 +474,7 @@ namespace OpenSim.Framework
parameters); parameters);
if (m_DefaultTTL.Ticks != 0) if (m_DefaultTTL.Ticks != 0)
item.expires = DateTime.Now + m_DefaultTTL; item.expires = DateTime.UtcNow + m_DefaultTTL;
m_Index.Add(item); m_Index.Add(item);
m_Lookup[index] = item; m_Lookup[index] = item;
@ -476,10 +495,14 @@ namespace OpenSim.Framework
if (getting && (m_Strategy == CacheStrategy.Aggressive)) if (getting && (m_Strategy == CacheStrategy.Aggressive))
return; return;
DateTime now = DateTime.UtcNow;
if(now < m_nextExpire)
return;
m_nextExpire = now + m_expiresTime;
if (m_DefaultTTL.Ticks != 0) if (m_DefaultTTL.Ticks != 0)
{ {
DateTime now= DateTime.Now;
foreach (CacheItemBase item in new List<CacheItemBase>(m_Index)) foreach (CacheItemBase item in new List<CacheItemBase>(m_Index))
{ {
if (item.expires.Ticks == 0 || if (item.expires.Ticks == 0 ||
@ -494,16 +517,14 @@ namespace OpenSim.Framework
switch (m_Strategy) switch (m_Strategy)
{ {
case CacheStrategy.Aggressive: case CacheStrategy.Aggressive:
if (Count < Size)
return;
m_Index.Sort(new SortLRU());
m_Index.Reverse();
int target = (int)((float)Size * 0.9); int target = (int)((float)Size * 0.9);
if (target == Count) // Cover ridiculous cache sizes if (Count < target) // Cover ridiculous cache sizes
return; return;
target = (int)((float)Size * 0.8);
m_Index.Sort(new SortLRUrev());
ExpireDelegate doExpire = OnExpire; ExpireDelegate doExpire = OnExpire;
if (doExpire != null) if (doExpire != null)

View File

@ -89,6 +89,8 @@ namespace OpenSim.Framework
public Vector3 AtAxis; public Vector3 AtAxis;
public Vector3 LeftAxis; public Vector3 LeftAxis;
public Vector3 UpAxis; public Vector3 UpAxis;
//public int GodLevel;
public OSD GodData = null;
public bool ChangedGrid; public bool ChangedGrid;
// This probably shouldn't be here // This probably shouldn't be here
@ -116,6 +118,16 @@ namespace OpenSim.Framework
args["far"] = OSD.FromReal(Far); args["far"] = OSD.FromReal(Far);
args["changed_grid"] = OSD.FromBoolean(ChangedGrid); args["changed_grid"] = OSD.FromBoolean(ChangedGrid);
//args["god_level"] = OSD.FromString(GodLevel.ToString());
if(GodData != null)
{
args["god_data"] = GodData;
OSDMap g = (OSDMap)GodData;
// Set legacy value
// TODO: remove after 0.9 is superseded
if (g.ContainsKey("ViewerUiIsGod"))
args["god_level"] = g["ViewerUiIsGod"].AsBoolean() ? 200 : 0;
}
if ((Throttles != null) && (Throttles.Length > 0)) if ((Throttles != null) && (Throttles.Length > 0))
args["throttles"] = OSD.FromBinary(Throttles); args["throttles"] = OSD.FromBinary(Throttles);
@ -174,6 +186,11 @@ namespace OpenSim.Framework
if (args["changed_grid"] != null) if (args["changed_grid"] != null)
ChangedGrid = args["changed_grid"].AsBoolean(); ChangedGrid = args["changed_grid"].AsBoolean();
//if (args["god_level"] != null)
// Int32.TryParse(args["god_level"].AsString(), out GodLevel);
if (args.ContainsKey("god_data") && args["god_data"] != null)
GodData = args["god_data"];
if (args["far"] != null) if (args["far"] != null)
Far = (float)(args["far"].AsReal()); Far = (float)(args["far"].AsReal());
@ -348,7 +365,8 @@ namespace OpenSim.Framework
public Quaternion BodyRotation; public Quaternion BodyRotation;
public uint ControlFlags; public uint ControlFlags;
public float EnergyLevel; public float EnergyLevel;
public Byte GodLevel; public OSD GodData = null;
//public Byte GodLevel;
public bool AlwaysRun; public bool AlwaysRun;
public UUID PreyAgent; public UUID PreyAgent;
public Byte AgentAccess; public Byte AgentAccess;
@ -422,7 +440,14 @@ namespace OpenSim.Framework
args["control_flags"] = OSD.FromString(ControlFlags.ToString()); args["control_flags"] = OSD.FromString(ControlFlags.ToString());
args["energy_level"] = OSD.FromReal(EnergyLevel); args["energy_level"] = OSD.FromReal(EnergyLevel);
args["god_level"] = OSD.FromString(GodLevel.ToString()); //args["god_level"] = OSD.FromString(GodLevel.ToString());
if(GodData != null)
{
args["god_data"] = GodData;
OSDMap g = (OSDMap)GodData;
if (g.ContainsKey("ViewerUiIsGod"))
args["god_level"] = g["ViewerUiIsGod"].AsBoolean() ? 200 : 0;;
}
args["always_run"] = OSD.FromBoolean(AlwaysRun); args["always_run"] = OSD.FromBoolean(AlwaysRun);
args["prey_agent"] = OSD.FromUUID(PreyAgent); args["prey_agent"] = OSD.FromUUID(PreyAgent);
args["agent_access"] = OSD.FromString(AgentAccess.ToString()); args["agent_access"] = OSD.FromString(AgentAccess.ToString());
@ -600,8 +625,11 @@ namespace OpenSim.Framework
if (args["energy_level"] != null) if (args["energy_level"] != null)
EnergyLevel = (float)(args["energy_level"].AsReal()); EnergyLevel = (float)(args["energy_level"].AsReal());
if (args["god_level"] != null) //if (args["god_level"] != null)
Byte.TryParse(args["god_level"].AsString(), out GodLevel); // Byte.TryParse(args["god_level"].AsString(), out GodLevel);
if (args.ContainsKey("god_data") && args["god_data"] != null)
GodData = args["god_data"];
if (args["always_run"] != null) if (args["always_run"] != null)
AlwaysRun = args["always_run"].AsBoolean(); AlwaysRun = args["always_run"].AsBoolean();

View File

@ -34,6 +34,7 @@ using System.Reflection;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Timers;
using OpenMetaverse; using OpenMetaverse;
using Nini.Config; using Nini.Config;
using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers.HttpServer;
@ -41,51 +42,147 @@ using log4net;
namespace OpenSim.Framework.Console namespace OpenSim.Framework.Console
{ {
public class ConsoleConnection
{
public int last;
public long lastLineSeen;
public bool newConnection = true;
}
// A console that uses REST interfaces // A console that uses REST interfaces
// //
public class RemoteConsole : CommandConsole public class RemoteConsole : CommandConsole
{ {
private IHttpServer m_Server = null; // Connection specific data, indexed by a session ID
private IConfigSource m_Config = null; // we create when a client connects.
protected class ConsoleConnection
{
// Last activity from the client
public int last;
private List<string> m_Scrollback = new List<string>(); // Last line of scrollback posted to this client
private ManualResetEvent m_DataEvent = new ManualResetEvent(false); public long lastLineSeen;
private List<string> m_InputData = new List<string>();
private long m_LineNumber = 0; // True if this is a new connection, e.g. has never
private Dictionary<UUID, ConsoleConnection> m_Connections = // displayed a prompt to the user.
public bool newConnection = true;
}
// A line in the scrollback buffer.
protected class ScrollbackEntry
{
// The line number of this entry
public long lineNumber;
// The text to send to the client
public string text;
// The level this should be logged as. Omitted for
// prompts and input echo.
public string level;
// True if the text above is a prompt, e.g. the
// client should turn on the cursor / accept input
public bool isPrompt;
// True if the requested input is a command. A
// client may offer help or validate input if
// this is set. If false, input should be sent
// as typed.
public bool isCommand;
// True if this text represents a line of text that
// was input in response to a prompt. A client should
// turn off the cursor and refrain from sending commands
// until a new prompt is received.
public bool isInput;
}
// Data that is relevant to all connections
// The scrollback buffer
protected List<ScrollbackEntry> m_Scrollback = new List<ScrollbackEntry>();
// Monotonously incrementing line number. This may eventually
// wrap. No provision is made for that case because 64 bits
// is a long, long time.
protected long m_lineNumber = 0;
// These two variables allow us to send the correct
// information about the prompt status to the client,
// irrespective of what may have run off the top of the
// scrollback buffer;
protected bool m_expectingInput = false;
protected bool m_expectingCommand = true;
protected string m_lastPromptUsed;
// This is the list of things received from clients.
// Note: Race conditions can happen. If a client sends
// something while nothing is expected, it will be
// intepreted as input to the next prompt. For
// commands this is largely correct. For other prompts,
// YMMV.
// TODO: Find a better way to fix this
protected List<string> m_InputData = new List<string>();
// Event to allow ReadLine to wait synchronously even though
// everthing else is asynchronous here.
protected ManualResetEvent m_DataEvent = new ManualResetEvent(false);
// The list of sessions we maintain. Unlike other console types,
// multiple users on the same console are explicitly allowed.
protected Dictionary<UUID, ConsoleConnection> m_Connections =
new Dictionary<UUID, ConsoleConnection>(); new Dictionary<UUID, ConsoleConnection>();
private string m_UserName = String.Empty;
private string m_Password = String.Empty; // Timer to control expiration of sessions that have been
private string m_AllowedOrigin = String.Empty; // disconnected.
protected System.Timers.Timer m_expireTimer = new System.Timers.Timer(5000);
// The less interesting stuff that makes the actual server
// work.
protected IHttpServer m_Server = null;
protected IConfigSource m_Config = null;
protected string m_UserName = String.Empty;
protected string m_Password = String.Empty;
protected string m_AllowedOrigin = String.Empty;
public RemoteConsole(string defaultPrompt) : base(defaultPrompt) public RemoteConsole(string defaultPrompt) : base(defaultPrompt)
{ {
// There is something wrong with this architecture.
// A prompt is sent on every single input, so why have this?
// TODO: Investigate and fix.
m_lastPromptUsed = defaultPrompt;
// Start expiration of sesssions.
m_expireTimer.Elapsed += DoExpire;
m_expireTimer.Start();
} }
public void ReadConfig(IConfigSource config) public void ReadConfig(IConfigSource config)
{ {
m_Config = config; m_Config = config;
// We're pulling this from the 'Network' section for legacy
// compatibility. However, this is so essentially insecure
// that TLS and client certs should be used instead of
// a username / password.
IConfig netConfig = m_Config.Configs["Network"]; IConfig netConfig = m_Config.Configs["Network"];
if (netConfig == null) if (netConfig == null)
return; return;
// Get the username and password.
m_UserName = netConfig.GetString("ConsoleUser", String.Empty); m_UserName = netConfig.GetString("ConsoleUser", String.Empty);
m_Password = netConfig.GetString("ConsolePass", String.Empty); m_Password = netConfig.GetString("ConsolePass", String.Empty);
// Woefully underdocumented, this is what makes javascript
// console clients work. Set to "*" for anywhere or (better)
// to specific addresses.
m_AllowedOrigin = netConfig.GetString("ConsoleAllowedOrigin", String.Empty); m_AllowedOrigin = netConfig.GetString("ConsoleAllowedOrigin", String.Empty);
} }
public void SetServer(IHttpServer server) public void SetServer(IHttpServer server)
{ {
// This is called by the framework to give us the server
// instance (means: port) to work with.
m_Server = server; m_Server = server;
// Add our handlers
m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession); m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession);
m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession); m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession);
m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand); m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand);
@ -93,38 +190,84 @@ namespace OpenSim.Framework.Console
public override void Output(string text, string level) public override void Output(string text, string level)
{ {
Output(text, level, false, false, false);
}
protected void Output(string text, string level, bool isPrompt, bool isCommand, bool isInput)
{
// Increment the line number. It was 0 and they start at 1
// so we need to pre-increment.
m_lineNumber++;
// Create and populate the new entry.
ScrollbackEntry newEntry = new ScrollbackEntry();
newEntry.lineNumber = m_lineNumber;
newEntry.text = text;
newEntry.level = level;
newEntry.isPrompt = isPrompt;
newEntry.isCommand = isCommand;
newEntry.isInput = isInput;
// Add a line to the scrollback. In some cases, that may not
// actually be a line of text.
lock (m_Scrollback) lock (m_Scrollback)
{ {
// Prune the scrollback to the length se send as connect
// burst to give the user some context.
while (m_Scrollback.Count >= 1000) while (m_Scrollback.Count >= 1000)
m_Scrollback.RemoveAt(0); m_Scrollback.RemoveAt(0);
m_LineNumber++;
m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text); m_Scrollback.Add(newEntry);
} }
// Let the rest of the system know we have output something.
FireOnOutput(text.Trim()); FireOnOutput(text.Trim());
// Also display it for debugging.
System.Console.WriteLine(text.Trim()); System.Console.WriteLine(text.Trim());
} }
public override void Output(string text) public override void Output(string text)
{ {
Output(text, "normal"); // Output plain (non-logging style) text.
Output(text, String.Empty, false, false, false);
} }
public override string ReadLine(string p, bool isCommand, bool e) public override string ReadLine(string p, bool isCommand, bool e)
{ {
// Output the prompt an prepare to wait. This
// is called on a dedicated console thread and
// needs to be synchronous. Old architecture but
// not worth upgrading.
if (isCommand) if (isCommand)
Output("+++"+p); {
m_expectingInput = true;
m_expectingCommand = true;
Output(p, String.Empty, true, true, false);
m_lastPromptUsed = p;
}
else else
Output("-++"+p); {
m_expectingInput = true;
Output(p, String.Empty, true, false, false);
}
// Here is where we wait for the user to input something.
m_DataEvent.WaitOne(); m_DataEvent.WaitOne();
string cmdinput; string cmdinput;
// Check for empty input. Read input if not empty.
lock (m_InputData) lock (m_InputData)
{ {
if (m_InputData.Count == 0) if (m_InputData.Count == 0)
{ {
m_DataEvent.Reset(); m_DataEvent.Reset();
m_expectingInput = false;
m_expectingCommand = false;
return ""; return "";
} }
@ -135,8 +278,19 @@ namespace OpenSim.Framework.Console
} }
m_expectingInput = false;
m_expectingCommand = false;
// Echo to all the other users what we have done. This
// will also go to ourselves.
Output (cmdinput, String.Empty, false, false, true);
// If this is a command, we need to resolve and execute it.
if (isCommand) if (isCommand)
{ {
// This call will actually execute the command and create
// any output associated with it. The core just gets an
// empty string so it will call again immediately.
string[] cmd = Commands.Resolve(Parser.Parse(cmdinput)); string[] cmd = Commands.Resolve(Parser.Parse(cmdinput));
if (cmd.Length != 0) if (cmd.Length != 0)
@ -151,18 +305,23 @@ namespace OpenSim.Framework.Console
return String.Empty; return String.Empty;
} }
} }
// Return the raw input string if not a command.
return cmdinput; return cmdinput;
} }
private Hashtable CheckOrigin(Hashtable result) // Very simplistic static access control header.
protected Hashtable CheckOrigin(Hashtable result)
{ {
if (!string.IsNullOrEmpty(m_AllowedOrigin)) if (!string.IsNullOrEmpty(m_AllowedOrigin))
result["access_control_allow_origin"] = m_AllowedOrigin; result["access_control_allow_origin"] = m_AllowedOrigin;
return result; return result;
} }
/* TODO: Figure out how PollServiceHTTPHandler can access the request headers /* TODO: Figure out how PollServiceHTTPHandler can access the request headers
* in order to use m_AllowedOrigin as a regular expression * in order to use m_AllowedOrigin as a regular expression
private Hashtable CheckOrigin(Hashtable headers, Hashtable result) protected Hashtable CheckOrigin(Hashtable headers, Hashtable result)
{ {
if (!string.IsNullOrEmpty(m_AllowedOrigin)) if (!string.IsNullOrEmpty(m_AllowedOrigin))
{ {
@ -177,18 +336,23 @@ namespace OpenSim.Framework.Console
} }
*/ */
private void DoExpire() protected void DoExpire(Object sender, ElapsedEventArgs e)
{ {
// Iterate the list of console connections and find those we
// haven't heard from for longer then the longpoll interval.
// Remove them.
List<UUID> expired = new List<UUID>(); List<UUID> expired = new List<UUID>();
lock (m_Connections) lock (m_Connections)
{ {
// Mark the expired ones
foreach (KeyValuePair<UUID, ConsoleConnection> kvp in m_Connections) foreach (KeyValuePair<UUID, ConsoleConnection> kvp in m_Connections)
{ {
if (System.Environment.TickCount - kvp.Value.last > 500000) if (System.Environment.TickCount - kvp.Value.last > 500000)
expired.Add(kvp.Key); expired.Add(kvp.Key);
} }
// Delete them
foreach (UUID id in expired) foreach (UUID id in expired)
{ {
m_Connections.Remove(id); m_Connections.Remove(id);
@ -197,10 +361,10 @@ namespace OpenSim.Framework.Console
} }
} }
private Hashtable HandleHttpStartSession(Hashtable request) // Start a new session.
protected Hashtable HandleHttpStartSession(Hashtable request)
{ {
DoExpire(); // The login is in the form of a http form post
Hashtable post = DecodePostString(request["body"].ToString()); Hashtable post = DecodePostString(request["body"].ToString());
Hashtable reply = new Hashtable(); Hashtable reply = new Hashtable();
@ -208,6 +372,7 @@ namespace OpenSim.Framework.Console
reply["int_response_code"] = 401; reply["int_response_code"] = 401;
reply["content_type"] = "text/plain"; reply["content_type"] = "text/plain";
// Check user name and password
if (m_UserName == String.Empty) if (m_UserName == String.Empty)
return reply; return reply;
@ -220,22 +385,28 @@ namespace OpenSim.Framework.Console
return reply; return reply;
} }
// Set up the new console connection record
ConsoleConnection c = new ConsoleConnection(); ConsoleConnection c = new ConsoleConnection();
c.last = System.Environment.TickCount; c.last = System.Environment.TickCount;
c.lastLineSeen = 0; c.lastLineSeen = 0;
// Assign session ID
UUID sessionID = UUID.Random(); UUID sessionID = UUID.Random();
// Add connection to list.
lock (m_Connections) lock (m_Connections)
{ {
m_Connections[sessionID] = c; m_Connections[sessionID] = c;
} }
// This call is a CAP. The URL is the authentication.
string uri = "/ReadResponses/" + sessionID.ToString() + "/"; string uri = "/ReadResponses/" + sessionID.ToString() + "/";
m_Server.AddPollServiceHTTPHandler( m_Server.AddPollServiceHTTPHandler(
uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout
// Our reply is an XML document.
// TODO: Change this to Linq.Xml
XmlDocument xmldoc = new XmlDocument(); XmlDocument xmldoc = new XmlDocument();
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
"", ""); "", "");
@ -252,12 +423,13 @@ namespace OpenSim.Framework.Console
rootElement.AppendChild(id); rootElement.AppendChild(id);
XmlElement prompt = xmldoc.CreateElement("", "Prompt", ""); XmlElement prompt = xmldoc.CreateElement("", "Prompt", "");
prompt.AppendChild(xmldoc.CreateTextNode(DefaultPrompt)); prompt.AppendChild(xmldoc.CreateTextNode(m_lastPromptUsed));
rootElement.AppendChild(prompt); rootElement.AppendChild(prompt);
rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc)); rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc));
// Set up the response and check origin
reply["str_response_string"] = xmldoc.InnerXml; reply["str_response_string"] = xmldoc.InnerXml;
reply["int_response_code"] = 200; reply["int_response_code"] = 200;
reply["content_type"] = "text/xml"; reply["content_type"] = "text/xml";
@ -266,10 +438,9 @@ namespace OpenSim.Framework.Console
return reply; return reply;
} }
private Hashtable HandleHttpCloseSession(Hashtable request) // Client closes session. Clean up.
protected Hashtable HandleHttpCloseSession(Hashtable request)
{ {
DoExpire();
Hashtable post = DecodePostString(request["body"].ToString()); Hashtable post = DecodePostString(request["body"].ToString());
Hashtable reply = new Hashtable(); Hashtable reply = new Hashtable();
@ -316,10 +487,9 @@ namespace OpenSim.Framework.Console
return reply; return reply;
} }
private Hashtable HandleHttpSessionCommand(Hashtable request) // Command received from the client.
protected Hashtable HandleHttpSessionCommand(Hashtable request)
{ {
DoExpire();
Hashtable post = DecodePostString(request["body"].ToString()); Hashtable post = DecodePostString(request["body"].ToString());
Hashtable reply = new Hashtable(); Hashtable reply = new Hashtable();
@ -327,6 +497,7 @@ namespace OpenSim.Framework.Console
reply["int_response_code"] = 404; reply["int_response_code"] = 404;
reply["content_type"] = "text/plain"; reply["content_type"] = "text/plain";
// Check the ID
if (post["ID"] == null) if (post["ID"] == null)
return reply; return reply;
@ -334,21 +505,25 @@ namespace OpenSim.Framework.Console
if (!UUID.TryParse(post["ID"].ToString(), out id)) if (!UUID.TryParse(post["ID"].ToString(), out id))
return reply; return reply;
// Find the connection for that ID.
lock (m_Connections) lock (m_Connections)
{ {
if (!m_Connections.ContainsKey(id)) if (!m_Connections.ContainsKey(id))
return reply; return reply;
} }
// Empty post. Just error out.
if (post["COMMAND"] == null) if (post["COMMAND"] == null)
return reply; return reply;
// Place the input data in the buffer.
lock (m_InputData) lock (m_InputData)
{ {
m_DataEvent.Set(); m_DataEvent.Set();
m_InputData.Add(post["COMMAND"].ToString()); m_InputData.Add(post["COMMAND"].ToString());
} }
// Create the XML reply document.
XmlDocument xmldoc = new XmlDocument(); XmlDocument xmldoc = new XmlDocument();
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
"", ""); "", "");
@ -372,7 +547,8 @@ namespace OpenSim.Framework.Console
return reply; return reply;
} }
private Hashtable DecodePostString(string data) // Decode a HTTP form post to a Hashtable
protected Hashtable DecodePostString(string data)
{ {
Hashtable result = new Hashtable(); Hashtable result = new Hashtable();
@ -396,6 +572,7 @@ namespace OpenSim.Framework.Console
return result; return result;
} }
// Close the CAP receiver for the responses for a given client.
public void CloseConnection(UUID id) public void CloseConnection(UUID id)
{ {
try try
@ -409,7 +586,9 @@ namespace OpenSim.Framework.Console
} }
} }
private bool HasEvents(UUID RequestID, UUID sessionID) // Check if there is anything to send. Return true if this client has
// lines pending.
protected bool HasEvents(UUID RequestID, UUID sessionID)
{ {
ConsoleConnection c = null; ConsoleConnection c = null;
@ -420,13 +599,15 @@ namespace OpenSim.Framework.Console
c = m_Connections[sessionID]; c = m_Connections[sessionID];
} }
c.last = System.Environment.TickCount; c.last = System.Environment.TickCount;
if (c.lastLineSeen < m_LineNumber) if (c.lastLineSeen < m_lineNumber)
return true; return true;
return false; return false;
} }
private Hashtable GetEvents(UUID RequestID, UUID sessionID) // Send all pending output to the client.
protected Hashtable GetEvents(UUID RequestID, UUID sessionID)
{ {
// Find the connection that goes with this client.
ConsoleConnection c = null; ConsoleConnection c = null;
lock (m_Connections) lock (m_Connections)
@ -435,12 +616,15 @@ namespace OpenSim.Framework.Console
return NoEvents(RequestID, UUID.Zero); return NoEvents(RequestID, UUID.Zero);
c = m_Connections[sessionID]; c = m_Connections[sessionID];
} }
// If we have nothing to send, send the no events response.
c.last = System.Environment.TickCount; c.last = System.Environment.TickCount;
if (c.lastLineSeen >= m_LineNumber) if (c.lastLineSeen >= m_lineNumber)
return NoEvents(RequestID, UUID.Zero); return NoEvents(RequestID, UUID.Zero);
Hashtable result = new Hashtable(); Hashtable result = new Hashtable();
// Create the response document.
XmlDocument xmldoc = new XmlDocument(); XmlDocument xmldoc = new XmlDocument();
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
"", ""); "", "");
@ -449,30 +633,53 @@ namespace OpenSim.Framework.Console
XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession", XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession",
""); "");
if (c.newConnection) //if (c.newConnection)
{ //{
c.newConnection = false; // c.newConnection = false;
Output("+++" + DefaultPrompt); // Output("+++" + DefaultPrompt);
} //}
lock (m_Scrollback) lock (m_Scrollback)
{ {
long startLine = m_LineNumber - m_Scrollback.Count; long startLine = m_lineNumber - m_Scrollback.Count;
long sendStart = startLine; long sendStart = startLine;
if (sendStart < c.lastLineSeen) if (sendStart < c.lastLineSeen)
sendStart = c.lastLineSeen; sendStart = c.lastLineSeen;
for (long i = sendStart ; i < m_LineNumber ; i++) for (long i = sendStart ; i < m_lineNumber ; i++)
{ {
ScrollbackEntry e = m_Scrollback[(int)(i - startLine)];
XmlElement res = xmldoc.CreateElement("", "Line", ""); XmlElement res = xmldoc.CreateElement("", "Line", "");
long line = i + 1; res.SetAttribute("Number", e.lineNumber.ToString());
res.SetAttribute("Number", line.ToString()); res.SetAttribute("Level", e.level);
res.AppendChild(xmldoc.CreateTextNode(m_Scrollback[(int)(i - startLine)])); // Don't include these for the scrollback, we'll send the
// real state later.
if (!c.newConnection)
{
res.SetAttribute("Prompt", e.isPrompt ? "true" : "false");
res.SetAttribute("Command", e.isCommand ? "true" : "false");
res.SetAttribute("Input", e.isInput ? "true" : "false");
}
else if (i == m_lineNumber - 1) // Last line for a new connection
{
res.SetAttribute("Prompt", m_expectingInput ? "true" : "false");
res.SetAttribute("Command", m_expectingCommand ? "true" : "false");
res.SetAttribute("Input", (!m_expectingInput) ? "true" : "false");
}
else
{
res.SetAttribute("Input", e.isInput ? "true" : "false");
}
res.AppendChild(xmldoc.CreateTextNode(e.text));
rootElement.AppendChild(res); rootElement.AppendChild(res);
} }
} }
c.lastLineSeen = m_LineNumber;
c.lastLineSeen = m_lineNumber;
c.newConnection = false;
xmldoc.AppendChild(rootElement); xmldoc.AppendChild(rootElement);
@ -486,7 +693,9 @@ namespace OpenSim.Framework.Console
return result; return result;
} }
private Hashtable NoEvents(UUID RequestID, UUID id) // This is really just a no-op. It generates what is sent
// to the client if the poll times out without any events.
protected Hashtable NoEvents(UUID RequestID, UUID id)
{ {
Hashtable result = new Hashtable(); Hashtable result = new Hashtable();

View File

@ -55,6 +55,11 @@ namespace OpenSim.Framework
Dictionary2 = new Dictionary<TKey2, TValue>(capacity); Dictionary2 = new Dictionary<TKey2, TValue>(capacity);
} }
~DoubleDictionaryThreadAbortSafe()
{
rwLock.Dispose();
}
public void Add(TKey1 key1, TKey2 key2, TValue value) public void Add(TKey1 key1, TKey2 key2, TValue value)
{ {
bool gotLock = false; bool gotLock = false;

View File

@ -29,7 +29,7 @@ using OpenSim.Framework;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
public interface IImprovedAssetCache public interface IAssetCache
{ {
/// <summary> /// <summary>
/// Cache the specified asset. /// Cache the specified asset.
@ -38,6 +38,12 @@ namespace OpenSim.Framework
void Cache(AssetBase asset); void Cache(AssetBase asset);
/// <summary> /// <summary>
/// Cache that the specified asset wasn't found.
/// </summary>
/// <param name='id'></param>
/// <summary>
void CacheNegative(string id);
/// Get an asset by its id. /// Get an asset by its id.
/// </summary> /// </summary>
/// <param name='id'></param> /// <param name='id'></param>

View File

@ -227,10 +227,10 @@ namespace OpenSim.Framework
byte RayEndIsIntersection); byte RayEndIsIntersection);
public delegate void RequestGodlikePowers( public delegate void RequestGodlikePowers(
UUID AgentID, UUID SessionID, UUID token, bool GodLike, IClientAPI remote_client); UUID AgentID, UUID SessionID, UUID token, bool GodLike);
public delegate void GodKickUser( public delegate void GodKickUser(
UUID GodAgentID, UUID GodSessionID, UUID AgentID, uint kickflags, byte[] reason); UUID GodAgentID, UUID AgentID, uint kickflags, byte[] reason);
public delegate void CreateInventoryFolder( public delegate void CreateInventoryFolder(
IClientAPI remoteClient, UUID folderID, ushort folderType, string folderName, UUID parentID); IClientAPI remoteClient, UUID folderID, ushort folderType, string folderName, UUID parentID);
@ -1293,7 +1293,7 @@ namespace OpenSim.Framework
void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks); void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks);
void SendViewerTime(int phase); void SendViewerTime(int phase);
void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout, void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] membershipType, string flAbout,
uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID); uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID);
void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question); void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question);

View File

@ -56,7 +56,7 @@ namespace OpenSim.Framework
bool IsChildAgent { get; } bool IsChildAgent { get; }
bool IsInTransit { get; } bool IsInTransit { get; }
bool isNPC { get;} bool IsNPC { get;}
bool Invulnerable { get; set; } bool Invulnerable { get; set; }
/// <summary> /// <summary>

View File

@ -93,7 +93,10 @@ namespace OpenSim.Framework
if (oldHead == oldTail) if (oldHead == oldTail)
{ {
if (oldHeadNext == null) if (oldHeadNext == null)
{
count = 0;
return false; return false;
}
CAS(ref tail, oldTail, oldHeadNext); CAS(ref tail, oldTail, oldHeadNext);
} }
@ -118,8 +121,7 @@ namespace OpenSim.Framework
{ {
// ugly // ugly
T item; T item;
while(count > 0) while(Dequeue(out item));
Dequeue(out item);
Init(); Init();
} }

View File

@ -136,7 +136,8 @@ namespace OpenSim.Framework.Monitoring
if(m_jobQueue.Count <= 0) if(m_jobQueue.Count <= 0)
m_cancelSource.Cancel(); m_cancelSource.Cancel();
m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop); if(m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop))
m_finishedProcessingAfterStop.Close();
} }
finally finally
{ {

View File

@ -64,24 +64,5 @@ namespace OpenSim.Framework
str = "."; str = ".";
return str; return str;
} }
/// <summary>
/// Applies an object's folded permissions to its regular permissions.
/// </summary>
/// <param name="foldedPerms">The folded permissions. Only the lowest 7 bits are examined.</param>
/// <param name="mainPerms">The permissions variable to modify.</param>
public static void ApplyFoldedPermissions(uint foldedPerms, ref uint mainPerms)
{
// if ((foldedPerms & 7) == 0)
// return; // assume that if the folded permissions are 0 then this means that they weren't actually recorded
if ((foldedPerms & ((uint)PermissionMask.Copy >> 13)) == 0)
mainPerms &= ~(uint)PermissionMask.Copy;
if ((foldedPerms & ((uint)PermissionMask.Transfer >> 13)) == 0)
mainPerms &= ~(uint)PermissionMask.Transfer;
if ((foldedPerms & ((uint)PermissionMask.Modify >> 13)) == 0)
mainPerms &= ~(uint)PermissionMask.Modify;
}
} }
} }

View File

@ -44,17 +44,17 @@ namespace OpenSim.Framework
/// <summary> /// <summary>
/// Manager for registries and plugins /// Manager for registries and plugins
/// </summary> /// </summary>
public class PluginManager : SetupService public class PluginManager : SetupService
{ {
public AddinRegistry PluginRegistry; public AddinRegistry PluginRegistry;
public PluginManager(AddinRegistry registry): base (registry) public PluginManager(AddinRegistry registry): base (registry)
{ {
PluginRegistry = registry; PluginRegistry = registry;
} }
/// <summary> /// <summary>
/// Installs the plugin. /// Installs the plugin.
/// </summary> /// </summary>
/// <returns> /// <returns>
@ -159,11 +159,11 @@ namespace OpenSim.Framework
{ {
Dictionary<string, object> res = new Dictionary<string, object>(); Dictionary<string, object> res = new Dictionary<string, object>();
Addin[] addins = GetSortedAddinList("RobustPlugin"); Addin[] addins = GetSortedAddinList("RobustPlugin");
if(addins.Count() < 1) if(addins.Count() < 1)
{ {
MainConsole.Instance.Output("Error!"); MainConsole.Instance.Output("Error!");
} }
int count = 0; int count = 0;
foreach (Addin addin in addins) foreach (Addin addin in addins)
{ {
@ -537,15 +537,15 @@ namespace OpenSim.Framework
ArrayList xlist = new ArrayList(); ArrayList xlist = new ArrayList();
ArrayList list = new ArrayList(); ArrayList list = new ArrayList();
try try
{ {
list.AddRange(PluginRegistry.GetAddins()); list.AddRange(PluginRegistry.GetAddins());
} }
catch (Exception) catch (Exception)
{ {
Addin[] x = xlist.ToArray(typeof(Addin)) as Addin[]; Addin[] x = xlist.ToArray(typeof(Addin)) as Addin[];
return x; return x;
} }
foreach (Addin addin in list) foreach (Addin addin in list)
{ {
@ -559,5 +559,5 @@ namespace OpenSim.Framework
return addins; return addins;
} }
#endregion Util #endregion Util
} }
} }

View File

@ -138,8 +138,6 @@ namespace OpenSim.Framework
protected uint m_httpPort; protected uint m_httpPort;
protected string m_serverURI; protected string m_serverURI;
protected string m_regionName = String.Empty; protected string m_regionName = String.Empty;
protected bool Allow_Alternate_Ports;
public bool m_allow_alternate_ports;
protected string m_externalHostName; protected string m_externalHostName;
protected IPEndPoint m_internalEndPoint; protected IPEndPoint m_internalEndPoint;
protected uint m_remotingPort; protected uint m_remotingPort;
@ -147,6 +145,7 @@ namespace OpenSim.Framework
public string RemotingAddress; public string RemotingAddress;
public UUID ScopeID = UUID.Zero; public UUID ScopeID = UUID.Zero;
private UUID m_maptileStaticUUID = UUID.Zero; private UUID m_maptileStaticUUID = UUID.Zero;
private bool m_resolveAddress = false;
public uint WorldLocX = 0; public uint WorldLocX = 0;
public uint WorldLocY = 0; public uint WorldLocY = 0;
@ -176,6 +175,9 @@ namespace OpenSim.Framework
/// </remarks> /// </remarks>
public uint RegionSizeZ = Constants.RegionHeight; public uint RegionSizeZ = Constants.RegionHeight;
// If entering avatar has no specific coords, this is where they land
public Vector3 DefaultLandingPoint = new Vector3(128, 128, 30);
private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>(); private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>();
// Apparently, we're applying the same estatesettings regardless of whether it's local or remote. // Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
@ -541,7 +543,7 @@ namespace OpenSim.Framework
private void ReadNiniConfig(IConfigSource source, string name) private void ReadNiniConfig(IConfigSource source, string name)
{ {
// bool creatingNew = false; bool creatingNew = false;
if (source.Configs.Count == 0) if (source.Configs.Count == 0)
{ {
@ -565,7 +567,7 @@ namespace OpenSim.Framework
source.AddConfig(name); source.AddConfig(name);
// creatingNew = true; creatingNew = true;
} }
if (name == String.Empty) if (name == String.Empty)
@ -669,18 +671,19 @@ namespace OpenSim.Framework
} }
m_internalEndPoint = new IPEndPoint(address, port); m_internalEndPoint = new IPEndPoint(address, port);
// AllowAlternatePorts // ResolveAddress
// //
allKeys.Remove("AllowAlternatePorts"); allKeys.Remove("ResolveAddress");
if (config.Contains("AllowAlternatePorts")) if (config.Contains("ResolveAddress"))
{ {
m_allow_alternate_ports = config.GetBoolean("AllowAlternatePorts", true); m_resolveAddress = config.GetBoolean("ResolveAddress", false);
} }
else else
{ {
m_allow_alternate_ports = Convert.ToBoolean(MainConsole.Instance.CmdPrompt("Allow alternate ports", "False")); if (creatingNew)
m_resolveAddress = Convert.ToBoolean(MainConsole.Instance.CmdPrompt("Resolve hostname to IP on start (for running inside Docker)", "False"));
config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString()); config.Set("ResolveAddress", m_resolveAddress.ToString());
} }
// ExternalHostName // ExternalHostName
@ -703,15 +706,36 @@ namespace OpenSim.Framework
"[REGIONINFO]: Resolving SYSTEMIP to {0} for external hostname of region {1}", "[REGIONINFO]: Resolving SYSTEMIP to {0} for external hostname of region {1}",
m_externalHostName, name); m_externalHostName, name);
} }
else else if (!m_resolveAddress)
{ {
m_externalHostName = externalName; m_externalHostName = externalName;
} }
else
{
IPAddress[] addrs = Dns.GetHostAddresses(externalName);
if (addrs.Length != 1) // If it is ambiguous or not resolveable, use it literally
m_externalHostName = externalName;
else
m_externalHostName = addrs[0].ToString();
}
// RegionType // RegionType
m_regionType = config.GetString("RegionType", String.Empty); m_regionType = config.GetString("RegionType", String.Empty);
allKeys.Remove("RegionType"); allKeys.Remove("RegionType");
// Get Default Landing Location (Defaults to 128,128)
string temp_location = config.GetString("DefaultLanding", "<128, 128, 30>");
Vector3 temp_vector;
if (Vector3.TryParse(temp_location, out temp_vector))
DefaultLandingPoint = temp_vector;
else
m_log.ErrorFormat("[RegionInfo]: Unable to parse DefaultLanding for '{0}'. The value given was '{1}'", RegionName, temp_location);
allKeys.Remove("DefaultLanding");
DoDefaultLandingSanityChecks();
#region Prim and map stuff #region Prim and map stuff
m_nonphysPrimMin = config.GetFloat("NonPhysicalPrimMin", 0); m_nonphysPrimMin = config.GetFloat("NonPhysicalPrimMin", 0);
@ -764,6 +788,48 @@ namespace OpenSim.Framework
} }
} }
// Make sure DefaultLanding is within region borders with a buffer zone 5 meters from borders
private void DoDefaultLandingSanityChecks()
{
// Sanity Check Default Landing
float buffer_zone = 5f;
bool ValuesCapped = false;
// Minimum Positions
if (DefaultLandingPoint.X < buffer_zone)
{
DefaultLandingPoint.X = buffer_zone;
ValuesCapped = true;
}
if (DefaultLandingPoint.Y < buffer_zone)
{
DefaultLandingPoint.Y = buffer_zone;
ValuesCapped = true;
}
// Maximum Positions
if (DefaultLandingPoint.X > RegionSizeX - buffer_zone)
{
DefaultLandingPoint.X = RegionSizeX - buffer_zone;
ValuesCapped = true;
}
if (DefaultLandingPoint.Y > RegionSizeY - buffer_zone)
{
DefaultLandingPoint.Y = RegionSizeY - buffer_zone;
ValuesCapped = true;
}
// Height
if (DefaultLandingPoint.Z < 0f)
DefaultLandingPoint.Z = 0f;
if (ValuesCapped == true)
m_log.WarnFormat("[RegionInfo]: The default landing location for {0} has been capped to {1}", RegionName, DefaultLandingPoint);
}
// Make sure user specified region sizes are sane. // Make sure user specified region sizes are sane.
// Must be multiples of legacy region size (256). // Must be multiples of legacy region size (256).
private void DoRegionSizeSanityChecks() private void DoRegionSizeSanityChecks()
@ -843,8 +909,6 @@ namespace OpenSim.Framework
config.Set("InternalAddress", m_internalEndPoint.Address.ToString()); config.Set("InternalAddress", m_internalEndPoint.Address.ToString());
config.Set("InternalPort", m_internalEndPoint.Port); config.Set("InternalPort", m_internalEndPoint.Port);
config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString());
config.Set("ExternalHostName", m_externalHostName); config.Set("ExternalHostName", m_externalHostName);
if (m_nonphysPrimMin > 0) if (m_nonphysPrimMin > 0)
@ -937,10 +1001,6 @@ namespace OpenSim.Framework
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Internal IP Port for incoming UDP client connections", "Internal IP Port for incoming UDP client connections",
m_internalEndPoint.Port.ToString(), true); m_internalEndPoint.Port.ToString(), true);
configMember.addConfigurationOption("allow_alternate_ports",
ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Allow sim to find alternate UDP ports when ports are in use?",
m_allow_alternate_ports.ToString(), true);
configMember.addConfigurationOption("external_host_name", configMember.addConfigurationOption("external_host_name",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"External Host Name", m_externalHostName, true); "External Host Name", m_externalHostName, true);
@ -1010,9 +1070,6 @@ namespace OpenSim.Framework
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Internal IP Port for incoming UDP client connections", "Internal IP Port for incoming UDP client connections",
ConfigSettings.DefaultRegionHttpPort.ToString(), false); ConfigSettings.DefaultRegionHttpPort.ToString(), false);
configMember.addConfigurationOption("allow_alternate_ports", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
"Allow sim to find alternate UDP ports when ports are in use?",
"false", true);
configMember.addConfigurationOption("external_host_name", configMember.addConfigurationOption("external_host_name",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"External Host Name", "127.0.0.1", false); "External Host Name", "127.0.0.1", false);
@ -1083,9 +1140,6 @@ namespace OpenSim.Framework
case "internal_ip_port": case "internal_ip_port":
m_internalEndPoint.Port = (int) configuration_result; m_internalEndPoint.Port = (int) configuration_result;
break; break;
case "allow_alternate_ports":
m_allow_alternate_ports = (bool) configuration_result;
break;
case "external_host_name": case "external_host_name":
if ((string) configuration_result != "SYSTEMIP") if ((string) configuration_result != "SYSTEMIP")
{ {
@ -1162,7 +1216,6 @@ namespace OpenSim.Framework
if ((RemotingAddress != null) && !RemotingAddress.Equals("")) if ((RemotingAddress != null) && !RemotingAddress.Equals(""))
args["remoting_address"] = OSD.FromString(RemotingAddress); args["remoting_address"] = OSD.FromString(RemotingAddress);
args["remoting_port"] = OSD.FromString(RemotingPort.ToString()); args["remoting_port"] = OSD.FromString(RemotingPort.ToString());
args["allow_alt_ports"] = OSD.FromBoolean(m_allow_alternate_ports);
if ((proxyUrl != null) && !proxyUrl.Equals("")) if ((proxyUrl != null) && !proxyUrl.Equals(""))
args["proxy_url"] = OSD.FromString(proxyUrl); args["proxy_url"] = OSD.FromString(proxyUrl);
if (RegionType != String.Empty) if (RegionType != String.Empty)
@ -1217,8 +1270,6 @@ namespace OpenSim.Framework
RemotingAddress = args["remoting_address"].AsString(); RemotingAddress = args["remoting_address"].AsString();
if (args["remoting_port"] != null) if (args["remoting_port"] != null)
UInt32.TryParse(args["remoting_port"].AsString(), out m_remotingPort); UInt32.TryParse(args["remoting_port"].AsString(), out m_remotingPort);
if (args["allow_alt_ports"] != null)
m_allow_alternate_ports = args["allow_alt_ports"].AsBoolean();
if (args["proxy_url"] != null) if (args["proxy_url"] != null)
proxyUrl = args["proxy_url"].AsString(); proxyUrl = args["proxy_url"].AsString();
if (args["region_type"] != null) if (args["region_type"] != null)
@ -1256,7 +1307,8 @@ namespace OpenSim.Framework
kvp["http_port"] = HttpPort.ToString(); kvp["http_port"] = HttpPort.ToString();
kvp["internal_ip_address"] = InternalEndPoint.Address.ToString(); kvp["internal_ip_address"] = InternalEndPoint.Address.ToString();
kvp["internal_port"] = InternalEndPoint.Port.ToString(); kvp["internal_port"] = InternalEndPoint.Port.ToString();
kvp["alternate_ports"] = m_allow_alternate_ports.ToString(); // TODO: Remove in next major version
kvp["alternate_ports"] = "False";
kvp["server_uri"] = ServerURI; kvp["server_uri"] = ServerURI;
return kvp; return kvp;

View File

@ -430,11 +430,11 @@ namespace OpenSim.Framework
using (Stream dst = _request.GetRequestStream()) using (Stream dst = _request.GetRequestStream())
{ {
m_log.Info("[REST]: GetRequestStream is ok"); m_log.Debug("[REST]: GetRequestStream is ok");
byte[] buf = new byte[1024]; byte[] buf = new byte[1024];
int length = src.Read(buf, 0, 1024); int length = src.Read(buf, 0, 1024);
m_log.Info("[REST]: First Read is ok"); m_log.Debug("[REST]: First Read is ok");
while (length > 0) while (length > 0)
{ {
dst.Write(buf, 0, length); dst.Write(buf, 0, length);

View File

@ -77,6 +77,9 @@ namespace OpenSim.Framework.Servers.HttpServer
if (parameters == null) if (parameters == null)
throw new ArgumentNullException("parameters"); throw new ArgumentNullException("parameters");
if(string.IsNullOrWhiteSpace(uri))
return false;
OSDMap request = new OSDMap(); OSDMap request = new OSDMap();
request.Add("jsonrpc", OSD.FromString("2.0")); request.Add("jsonrpc", OSD.FromString("2.0"));
request.Add("id", OSD.FromString(jsonId)); request.Add("id", OSD.FromString(jsonId));

View File

@ -64,6 +64,13 @@ namespace OpenSim.Framework
/// </value> /// </value>
private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim(); private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
~TaskInventoryDictionary()
{
m_itemLock.Dispose();
m_itemLock = null;
}
/// <summary> /// <summary>
/// Are we readlocked by the calling thread? /// Are we readlocked by the calling thread?
/// </summary> /// </summary>

View File

@ -59,6 +59,7 @@ namespace OpenSim.Framework
private int _invType = 0; private int _invType = 0;
private UUID _itemID = UUID.Zero; private UUID _itemID = UUID.Zero;
private UUID _lastOwnerID = UUID.Zero; private UUID _lastOwnerID = UUID.Zero;
private UUID _rezzerID = UUID.Zero;
private string _name = String.Empty; private string _name = String.Empty;
private uint _nextOwnerMask = FULL_MASK_PERMISSIONS_GENERAL; private uint _nextOwnerMask = FULL_MASK_PERMISSIONS_GENERAL;
private UUID _ownerID = UUID.Zero; private UUID _ownerID = UUID.Zero;
@ -254,6 +255,16 @@ namespace OpenSim.Framework
} }
} }
public UUID RezzerID
{
get {
return _rezzerID;
}
set {
_rezzerID = value;
}
}
public string Name { public string Name {
get { get {
return _name; return _name;

View File

@ -27,6 +27,8 @@
using System; using System;
using OpenMetaverse; using OpenMetaverse;
using System.Collections.Generic;
namespace OpenSim.Framework namespace OpenSim.Framework
{ {
@ -122,5 +124,18 @@ namespace OpenSim.Framework
public string UserId = UUID.Zero.ToString(); public string UserId = UUID.Zero.ToString();
public string DataVal = string.Empty; public string DataVal = string.Empty;
} }
public class UserProfileCacheEntry
{
public Dictionary<UUID, string> picksList;
public Dictionary<UUID, UserProfilePick> picks;
public Dictionary<UUID, string> classifiedsLists;
public Dictionary<UUID, UserClassifiedAdd> classifieds;
public UserProfileProperties props;
public string born;
public byte[] membershipType;
public uint flags;
public HashSet<IClientAPI> ClientsWaitingProps;
}
} }

View File

@ -414,6 +414,140 @@ namespace OpenSim.Framework
return regionCoord << 8; return regionCoord << 8;
} }
public static bool checkServiceURI(string uristr, out string serviceURI)
{
serviceURI = string.Empty;
try
{
Uri uri = new Uri(uristr);
serviceURI = uri.AbsoluteUri;
if(uri.Port == 80)
serviceURI = serviceURI.Trim(new char[] { '/', ' ' }) +":80/";
else if(uri.Port == 443)
serviceURI = serviceURI.Trim(new char[] { '/', ' ' }) +":443/";
return true;
}
catch
{
serviceURI = string.Empty;
}
return false;
}
public static bool buildHGRegionURI(string inputName, out string serverURI, out string regionName)
{
serverURI = string.Empty;
regionName = string.Empty;
inputName = inputName.Trim();
if (!inputName.StartsWith("http") && !inputName.StartsWith("https"))
{
// Formats: grid.example.com:8002:region name
// grid.example.com:region name
// grid.example.com:8002
// grid.example.com
string host;
uint port = 80;
string[] parts = inputName.Split(new char[] { ':' });
int indx;
if(parts.Length == 0)
return false;
if (parts.Length == 1)
{
indx = inputName.IndexOf('/');
if (indx < 0)
serverURI = "http://"+ inputName + "/";
else
{
serverURI = "http://"+ inputName.Substring(0,indx + 1);
if(indx + 2 < inputName.Length)
regionName = inputName.Substring(indx + 1);
}
}
else
{
host = parts[0];
if (parts.Length >= 2)
{
indx = parts[1].IndexOf('/');
if(indx < 0)
{
// If it's a number then assume it's a port. Otherwise, it's a region name.
if (!UInt32.TryParse(parts[1], out port))
{
port = 80;
regionName = parts[1];
}
}
else
{
string portstr = parts[1].Substring(0, indx);
if(indx + 2 < parts[1].Length)
regionName = parts[1].Substring(indx + 1);
if (!UInt32.TryParse(portstr, out port))
port = 80;
}
}
// always take the last one
if (parts.Length >= 3)
{
regionName = parts[2];
}
serverURI = "http://"+ host +":"+ port.ToString() + "/";
}
}
else
{
// Formats: http://grid.example.com region name
// http://grid.example.com "region name"
// http://grid.example.com
string[] parts = inputName.Split(new char[] { ' ' });
if (parts.Length == 0)
return false;
serverURI = parts[0];
int indx = serverURI.LastIndexOf('/');
if(indx > 10)
{
if(indx + 2 < inputName.Length)
regionName = inputName.Substring(indx + 1);
serverURI = inputName.Substring(0, indx + 1);
}
else if (parts.Length >= 2)
{
regionName = inputName.Substring(serverURI.Length);
}
}
// use better code for sanity check
Uri uri;
try
{
uri = new Uri(serverURI);
}
catch
{
return false;
}
if(!string.IsNullOrEmpty(regionName))
regionName = regionName.Trim(new char[] { '"', ' ' });
serverURI = uri.AbsoluteUri;
if(uri.Port == 80)
serverURI = serverURI.Trim(new char[] { '/', ' ' }) +":80/";
else if(uri.Port == 443)
serverURI = serverURI.Trim(new char[] { '/', ' ' }) +":443/";
return true;
}
public static T Clamp<T>(T x, T min, T max) public static T Clamp<T>(T x, T min, T max)
where T : IComparable<T> where T : IComparable<T>
{ {
@ -1591,12 +1725,16 @@ namespace OpenSim.Framework
return new UUID(bytes, 0); return new UUID(bytes, 0);
} }
public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y) public static bool ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y)
{ {
byte[] bytes = parcelID.GetBytes(); byte[] bytes = parcelID.GetBytes();
regionHandle = Utils.BytesToUInt64(bytes); regionHandle = Utils.BytesToUInt64(bytes);
x = Utils.BytesToUInt(bytes, 8) & 0xffff; x = Utils.BytesToUInt(bytes, 8) & 0xffff;
y = Utils.BytesToUInt(bytes, 12) & 0xffff; y = Utils.BytesToUInt(bytes, 12) & 0xffff;
// validation may fail, just reducing the odds of using a real UUID as encoded parcel
return ( bytes[0] == 0 && bytes[4] == 0 && // handler x,y multiples of 256
bytes[9] < 64 && bytes[13] < 64 && // positions < 16km
bytes[14] == 0 && bytes[15] == 0);
} }
public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y, out uint z) public static void ParseFakeParcelID(UUID parcelID, out ulong regionHandle, out uint x, out uint y, out uint z)
@ -1685,6 +1823,8 @@ namespace OpenSim.Framework
// hide the password in the connection string // hide the password in the connection string
passPosition = connectionString.IndexOf("password", StringComparison.OrdinalIgnoreCase); passPosition = connectionString.IndexOf("password", StringComparison.OrdinalIgnoreCase);
if (passPosition == -1)
return connectionString;
passPosition = connectionString.IndexOf("=", passPosition); passPosition = connectionString.IndexOf("=", passPosition);
if (passPosition < connectionString.Length) if (passPosition < connectionString.Length)
passPosition += 1; passPosition += 1;

View File

@ -29,8 +29,8 @@ namespace OpenSim
{ {
public class VersionInfo public class VersionInfo
{ {
public const string VersionNumber = "0.9.0.0"; public const string VersionNumber = "0.9.1.0";
public const string AssemblyVersionNumber = "0.9.0.*"; public const string AssemblyVersionNumber = "0.9.1.*";
private const Flavour VERSION_FLAVOUR = Flavour.RC1; private const Flavour VERSION_FLAVOUR = Flavour.RC1;

View File

@ -50,7 +50,7 @@ namespace OpenSim.Framework
return retitems; return retitems;
} }
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache) public static WearableCacheItem[] FromOSD(OSD pInput, IAssetCache dataCache)
{ {
List<WearableCacheItem> ret = new List<WearableCacheItem>(); List<WearableCacheItem> ret = new List<WearableCacheItem>();
if (pInput.Type == OSDType.Array) if (pInput.Type == OSDType.Array)
@ -100,7 +100,7 @@ namespace OpenSim.Framework
} }
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache) public static OSD ToOSD(WearableCacheItem[] pcacheItems, IAssetCache dataCache)
{ {
OSDArray arr = new OSDArray(); OSDArray arr = new OSDArray();
foreach (WearableCacheItem item in pcacheItems) foreach (WearableCacheItem item in pcacheItems)

View File

@ -1019,7 +1019,8 @@ namespace OpenSim.Framework
/// ///
/// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting /// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception> /// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs, IServiceAuth auth) public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs = -1,
IServiceAuth auth = null, bool keepalive = true)
{ {
int reqnum = WebUtil.RequestNumber++; int reqnum = WebUtil.RequestNumber++;
@ -1034,6 +1035,8 @@ namespace OpenSim.Framework
request.Method = verb; request.Method = verb;
if (timeoutsecs > 0) if (timeoutsecs > 0)
request.Timeout = timeoutsecs * 1000; request.Timeout = timeoutsecs * 1000;
if(!keepalive && request is HttpWebRequest)
((HttpWebRequest)request).KeepAlive = false;
if (auth != null) if (auth != null)
auth.AddAuthorization(request.Headers); auth.AddAuthorization(request.Headers);
@ -1062,11 +1065,10 @@ namespace OpenSim.Framework
if (WebUtil.DebugLevel >= 5) if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data)); WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
Stream requestStream = null;
try try
{ {
requestStream = request.GetRequestStream(); using(Stream requestStream = request.GetRequestStream())
requestStream.Write(data, 0, length); requestStream.Write(data,0,length);
} }
catch (Exception e) catch (Exception e)
{ {
@ -1076,9 +1078,6 @@ namespace OpenSim.Framework
} }
finally finally
{ {
if (requestStream != null)
requestStream.Dispose();
// capture how much time was spent writing // capture how much time was spent writing
tickdata = Util.EnvironmentTickCountSubtract(tickstart); tickdata = Util.EnvironmentTickCountSubtract(tickstart);
} }
@ -1129,16 +1128,6 @@ namespace OpenSim.Framework
return respstring; return respstring;
} }
public static string MakeRequest(string verb, string requestUrl, string obj, int timeoutsecs)
{
return MakeRequest(verb, requestUrl, obj, timeoutsecs, null);
}
public static string MakeRequest(string verb, string requestUrl, string obj)
{
return MakeRequest(verb, requestUrl, obj, -1);
}
public static string MakeRequest(string verb, string requestUrl, string obj, IServiceAuth auth) public static string MakeRequest(string verb, string requestUrl, string obj, IServiceAuth auth)
{ {
return MakeRequest(verb, requestUrl, obj, -1, auth); return MakeRequest(verb, requestUrl, obj, -1, auth);

View File

@ -104,16 +104,16 @@ namespace OpenSim
"[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset"); "[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
// Verify the Threadpool allocates or uses enough worker and IO completion threads // Verify the Threadpool allocates or uses enough worker and IO completion threads
// .NET 2.0, workerthreads default to 50 * numcores // .NET 2.0, workerthreads default to 50 * numcores
// .NET 3.0, workerthreads defaults to 250 * numcores // .NET 3.0, workerthreads defaults to 250 * numcores
// .NET 4.0, workerthreads are dynamic based on bitness and OS resources // .NET 4.0, workerthreads are dynamic based on bitness and OS resources
// Max IO Completion threads are 1000 on all 3 CLRs // Max IO Completion threads are 1000 on all 3 CLRs
// //
// Mono 2.10.9 to at least Mono 3.1, workerthreads default to 100 * numcores, iocp threads to 4 * numcores // Mono 2.10.9 to at least Mono 3.1, workerthreads default to 100 * numcores, iocp threads to 4 * numcores
int workerThreadsMin = 500; int workerThreadsMin = 500;
int workerThreadsMax = 1000; // may need further adjustment to match other CLR int workerThreadsMax = 1000; // may need further adjustment to match other CLR
int iocpThreadsMin = 1000; int iocpThreadsMin = 1000;
int iocpThreadsMax = 2000; // may need further adjustment to match other CLR int iocpThreadsMax = 2000; // may need further adjustment to match other CLR
{ {
int currentMinWorkerThreads, currentMinIocpThreads; int currentMinWorkerThreads, currentMinIocpThreads;
@ -138,30 +138,30 @@ namespace OpenSim
m_log.InfoFormat("[OPENSIM MAIN]: Limiting max worker threads to {0}",workerThreads); m_log.InfoFormat("[OPENSIM MAIN]: Limiting max worker threads to {0}",workerThreads);
} }
// Increase the number of IOCP threads available. // Increase the number of IOCP threads available.
// Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17) // Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17)
if (iocpThreads < iocpThreadsMin) if (iocpThreads < iocpThreadsMin)
{ {
iocpThreads = iocpThreadsMin; iocpThreads = iocpThreadsMin;
m_log.InfoFormat("[OPENSIM MAIN]: Bumping up max IOCP threads to {0}",iocpThreads); m_log.InfoFormat("[OPENSIM MAIN]: Bumping up max IOCP threads to {0}",iocpThreads);
} }
// Make sure we don't overallocate IOCP threads and thrash system resources // Make sure we don't overallocate IOCP threads and thrash system resources
if ( iocpThreads > iocpThreadsMax ) if ( iocpThreads > iocpThreadsMax )
{ {
iocpThreads = iocpThreadsMax; iocpThreads = iocpThreadsMax;
m_log.InfoFormat("[OPENSIM MAIN]: Limiting max IOCP completion threads to {0}",iocpThreads); m_log.InfoFormat("[OPENSIM MAIN]: Limiting max IOCP completion threads to {0}",iocpThreads);
} }
// set the resulting worker and IO completion thread counts back to ThreadPool // set the resulting worker and IO completion thread counts back to ThreadPool
if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) ) if ( System.Threading.ThreadPool.SetMaxThreads(workerThreads, iocpThreads) )
{ {
m_log.InfoFormat( m_log.InfoFormat(
"[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IOCP threads", "[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IOCP threads",
workerThreads, iocpThreads); workerThreads, iocpThreads);
} }
else else
{ {
m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect."); m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect.");
} }
// Check if the system is compatible with OpenSimulator. // Check if the system is compatible with OpenSimulator.
// Ensures that the minimum system requirements are met // Ensures that the minimum system requirements are met

View File

@ -348,13 +348,10 @@ namespace OpenSim
config.Set("meshing", "Meshmerizer"); config.Set("meshing", "Meshmerizer");
config.Set("physical_prim", true); config.Set("physical_prim", true);
config.Set("serverside_object_permissions", true); config.Set("serverside_object_permissions", true);
config.Set("storage_prim_inventories", true);
config.Set("startup_console_commands_file", String.Empty); config.Set("startup_console_commands_file", String.Empty);
config.Set("shutdown_console_commands_file", String.Empty); config.Set("shutdown_console_commands_file", String.Empty);
config.Set("DefaultScriptEngine", "XEngine"); config.Set("DefaultScriptEngine", "XEngine");
config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll"); config.Set("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
// life doesn't really work without this
config.Set("EventQueue", true);
} }
{ {

View File

@ -26,6 +26,7 @@
*/ */
using System; using System;
using System.Threading;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -74,7 +75,7 @@ namespace OpenSim
private string m_timedScript = "disabled"; private string m_timedScript = "disabled";
private int m_timeInterval = 1200; private int m_timeInterval = 1200;
private Timer m_scriptTimer; private System.Timers.Timer m_scriptTimer;
public OpenSim(IConfigSource configSource) : base(configSource) public OpenSim(IConfigSource configSource) : base(configSource)
{ {
@ -125,6 +126,21 @@ namespace OpenSim
m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
} }
private static Mono.Unix.UnixSignal[] signals;
private Thread signal_thread = new Thread (delegate ()
{
while (true)
{
// Wait for a signal to be delivered
int index = Mono.Unix.UnixSignal.WaitAny (signals, -1);
//Mono.Unix.Native.Signum signal = signals [index].Signum;
MainConsole.Instance.RunCommand("shutdown");
}
});
/// <summary> /// <summary>
/// Performs initialisation of the scene, such as loading configuration from disk. /// Performs initialisation of the scene, such as loading configuration from disk.
/// </summary> /// </summary>
@ -134,6 +150,24 @@ namespace OpenSim
m_log.Info("========================= STARTING OPENSIM ========================="); m_log.Info("========================= STARTING OPENSIM =========================");
m_log.Info("===================================================================="); m_log.Info("====================================================================");
if(!Util.IsWindows())
{
try
{
// linux mac os specifics
signals = new Mono.Unix.UnixSignal[]
{
new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM)
};
signal_thread.Start();
}
catch (Exception e)
{
m_log.Info("Could not set up UNIX signal handlers. SIGTERM will not");
m_log.InfoFormat("shut down gracefully: {0}", e.Message);
m_log.Debug("Exception was: ", e);
}
}
//m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString());
// http://msdn.microsoft.com/en-us/library/bb384202.aspx // http://msdn.microsoft.com/en-us/library/bb384202.aspx
//GCSettings.LatencyMode = GCLatencyMode.Batch; //GCSettings.LatencyMode = GCLatencyMode.Batch;
@ -172,6 +206,7 @@ namespace OpenSim
MainServer.Instance.AddStreamHandler(new OpenSim.XSimStatusHandler(this)); MainServer.Instance.AddStreamHandler(new OpenSim.XSimStatusHandler(this));
if (userStatsURI != String.Empty) if (userStatsURI != String.Empty)
MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this)); MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this));
MainServer.Instance.AddStreamHandler(new OpenSim.SimRobotsHandler());
if (managedStatsURI != String.Empty) if (managedStatsURI != String.Empty)
{ {
@ -217,7 +252,7 @@ namespace OpenSim
// Start timer script (run a script every xx seconds) // Start timer script (run a script every xx seconds)
if (m_timedScript != "disabled") if (m_timedScript != "disabled")
{ {
m_scriptTimer = new Timer(); m_scriptTimer = new System.Timers.Timer();
m_scriptTimer.Enabled = true; m_scriptTimer.Enabled = true;
m_scriptTimer.Interval = m_timeInterval*1000; m_scriptTimer.Interval = m_timeInterval*1000;
m_scriptTimer.Elapsed += RunAutoTimerScript; m_scriptTimer.Elapsed += RunAutoTimerScript;
@ -242,22 +277,22 @@ namespace OpenSim
ChangeSelectedRegion); ChangeSelectedRegion);
m_console.Commands.AddCommand("Archiving", false, "save xml", m_console.Commands.AddCommand("Archiving", false, "save xml",
"save xml", "save xml [<file name>]",
"Save a region's data in XML format", "Save a region's data in XML format",
SaveXml); SaveXml);
m_console.Commands.AddCommand("Archiving", false, "save xml2", m_console.Commands.AddCommand("Archiving", false, "save xml2",
"save xml2", "save xml2 [<file name>]",
"Save a region's data in XML2 format", "Save a region's data in XML2 format",
SaveXml2); SaveXml2);
m_console.Commands.AddCommand("Archiving", false, "load xml", m_console.Commands.AddCommand("Archiving", false, "load xml",
"load xml [-newIDs [<x> <y> <z>]]", "load xml [<file name> [-newUID [<x> <y> <z>]]]",
"Load a region's data from XML format", "Load a region's data from XML format",
LoadXml); LoadXml);
m_console.Commands.AddCommand("Archiving", false, "load xml2", m_console.Commands.AddCommand("Archiving", false, "load xml2",
"load xml2", "load xml2 [<file name>]",
"Load a region's data from XML2 format", "Load a region's data from XML2 format",
LoadXml2); LoadXml2);
@ -741,7 +776,7 @@ namespace OpenSim
CreateRegion(regInfo, true, out scene); CreateRegion(regInfo, true, out scene);
if (changed) if (changed)
m_estateDataService.StoreEstateSettings(regInfo.EstateSettings); m_estateDataService.StoreEstateSettings(regInfo.EstateSettings);
scene.Start(); scene.Start();
} }
@ -1068,7 +1103,7 @@ namespace OpenSim
/// <param name="cmdparams"></param> /// <param name="cmdparams"></param>
protected void SavePrimsXml2(string module, string[] cmdparams) protected void SavePrimsXml2(string module, string[] cmdparams)
{ {
if (cmdparams.Length > 5) if (cmdparams.Length > 4)
{ {
SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]); SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
} }
@ -1087,7 +1122,7 @@ namespace OpenSim
{ {
MainConsole.Instance.Output("PLEASE NOTE, save-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use save-xml2, please file a mantis detailing the reason."); MainConsole.Instance.Output("PLEASE NOTE, save-xml is DEPRECATED and may be REMOVED soon. If you are using this and there is some reason you can't use save-xml2, please file a mantis detailing the reason.");
if (cmdparams.Length > 0) if (cmdparams.Length > 2)
{ {
SceneManager.SaveCurrentSceneToXml(cmdparams[2]); SceneManager.SaveCurrentSceneToXml(cmdparams[2]);
} }

View File

@ -876,6 +876,26 @@ namespace OpenSim
} }
} }
/// <summary>
/// handler to supply serving http://domainname:port/robots.txt
/// </summary>
public class SimRobotsHandler : BaseStreamHandler
{
public SimRobotsHandler() : base("GET", "/robots.txt", "SimRobots.txt", "Simulator Robots.txt") {}
protected override byte[] ProcessRequest(string path, Stream request,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
string robots = "# go away\nUser-agent: *\nDisallow: /\n";
return Util.UTF8.GetBytes(robots);
}
public override string ContentType
{
get { return "text/plain"; }
}
}
#endregion #endregion
/// <summary> /// <summary>
@ -1083,10 +1103,10 @@ namespace OpenSim
MainConsole.Instance.Output("Joining the estate failed. Please try again."); MainConsole.Instance.Output("Joining the estate failed. Please try again.");
} }
} }
} }
return true; // need to update the database return true; // need to update the database
} }
} }
public class OpenSimConfigSource public class OpenSimConfigSource

View File

@ -29,9 +29,11 @@ using System;
using System.Timers; using System.Timers;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Web;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.StructuredData; using OpenMetaverse.StructuredData;
@ -125,6 +127,8 @@ namespace OpenSim.Region.ClientStack.Linden
private bool m_AllowCapHomeLocation = true; private bool m_AllowCapHomeLocation = true;
private bool m_AllowCapGroupMemberData = true; private bool m_AllowCapGroupMemberData = true;
private IUserManagement m_UserManager;
private enum FileAgentInventoryState : int private enum FileAgentInventoryState : int
{ {
@ -196,6 +200,9 @@ namespace OpenSim.Region.ClientStack.Linden
m_assetService = m_Scene.AssetService; m_assetService = m_Scene.AssetService;
m_regionName = m_Scene.RegionInfo.RegionName; m_regionName = m_Scene.RegionInfo.RegionName;
m_UserManager = m_Scene.RequestModuleInterface<IUserManagement>();
if (m_UserManager == null)
m_log.Error("[CAPS]: GetDisplayNames disabled because user management component not found");
RegisterHandlers(); RegisterHandlers();
@ -229,6 +236,7 @@ namespace OpenSim.Region.ClientStack.Linden
RegisterRegionServiceHandlers(); RegisterRegionServiceHandlers();
RegisterInventoryServiceHandlers(); RegisterInventoryServiceHandlers();
RegisterOtherHandlers();
} }
public void RegisterRegionServiceHandlers() public void RegisterRegionServiceHandlers()
@ -314,6 +322,22 @@ namespace OpenSim.Region.ClientStack.Linden
} }
} }
public void RegisterOtherHandlers()
{
try
{
if (m_UserManager != null)
{
IRequestHandler GetDisplayNamesHandler = new RestStreamHandler(
"GET", GetNewCapPath(), GetDisplayNames, "GetDisplayNames", null);
m_HostCapsObj.RegisterHandler("GetDisplayNames", GetDisplayNamesHandler);
}
}
catch (Exception e)
{
m_log.Error("[CAPS]: " + e.ToString());
}
}
/// <summary> /// <summary>
/// Construct a client response detailing all the capabilities this server can provide. /// Construct a client response detailing all the capabilities this server can provide.
/// </summary> /// </summary>
@ -513,7 +537,7 @@ namespace OpenSim.Region.ClientStack.Linden
// check user level // check user level
if (avatar != null) if (avatar != null)
{ {
if (avatar.UserLevel < m_levelUpload) if (avatar.GodController.UserLevel < m_levelUpload)
{ {
LLSDAssetUploadError resperror = new LLSDAssetUploadError(); LLSDAssetUploadError resperror = new LLSDAssetUploadError();
resperror.message = "Insufficient permissions to upload"; resperror.message = "Insufficient permissions to upload";
@ -970,7 +994,6 @@ namespace OpenSim.Region.ClientStack.Linden
pbs.TextureEntry = textureEntry.GetBytes(); pbs.TextureEntry = textureEntry.GetBytes();
bool hasmesh = false;
if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ... if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
{ {
int meshindx = inner_instance_list["mesh"].AsInteger(); int meshindx = inner_instance_list["mesh"].AsInteger();
@ -980,10 +1003,34 @@ namespace OpenSim.Region.ClientStack.Linden
pbs.SculptType = (byte)SculptType.Mesh; pbs.SculptType = (byte)SculptType.Mesh;
pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
// data will be requested from asset on rez (i hope) // data will be requested from asset on rez (i hope)
hasmesh = true;
} }
} }
// faces number to pbs shape
switch(face_list.Count)
{
case 1:
case 2:
pbs.ProfileCurve = (byte)ProfileCurve.Circle;
pbs.PathCurve = (byte)PathCurve.Circle;
break;
case 3:
case 4:
pbs.ProfileCurve = (byte)ProfileCurve.Circle;
pbs.PathCurve = (byte)PathCurve.Line;
break;
case 5:
pbs.ProfileCurve = (byte)ProfileCurve.EqualTriangle;
pbs.PathCurve = (byte)PathCurve.Line;
break;
default:
pbs.ProfileCurve = (byte)ProfileCurve.Square;
pbs.PathCurve = (byte)PathCurve.Line;
break;
}
Vector3 position = inner_instance_list["position"].AsVector3(); Vector3 position = inner_instance_list["position"].AsVector3();
Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
@ -994,23 +1041,6 @@ namespace OpenSim.Region.ClientStack.Linden
// int material = inner_instance_list["material"].AsInteger(); // int material = inner_instance_list["material"].AsInteger();
byte material = (byte)Material.Wood; byte material = (byte)Material.Wood;
// no longer used - begin ------------------------
// int mesh = inner_instance_list["mesh"].AsInteger();
// OSDMap permissions = (OSDMap)inner_instance_list["permissions"];
// int base_mask = permissions["base_mask"].AsInteger();
// int everyone_mask = permissions["everyone_mask"].AsInteger();
// UUID creator_id = permissions["creator_id"].AsUUID();
// UUID group_id = permissions["group_id"].AsUUID();
// int group_mask = permissions["group_mask"].AsInteger();
// bool is_owner_group = permissions["is_owner_group"].AsBoolean();
// UUID last_owner_id = permissions["last_owner_id"].AsUUID();
// int next_owner_mask = permissions["next_owner_mask"].AsInteger();
// UUID owner_id = permissions["owner_id"].AsUUID();
// int owner_mask = permissions["owner_mask"].AsInteger();
// no longer used - end ------------------------
SceneObjectPart prim SceneObjectPart prim
= new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero); = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
@ -1022,6 +1052,7 @@ namespace OpenSim.Region.ClientStack.Linden
prim.OwnerID = owner_id; prim.OwnerID = owner_id;
prim.GroupID = UUID.Zero; prim.GroupID = UUID.Zero;
prim.LastOwnerID = creatorID; prim.LastOwnerID = creatorID;
prim.RezzerID = creatorID;
prim.CreationDate = Util.UnixTimeSinceEpoch(); prim.CreationDate = Util.UnixTimeSinceEpoch();
if (grp == null) if (grp == null)
@ -1069,6 +1100,7 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
grp = new SceneObjectGroup(prim); grp = new SceneObjectGroup(prim);
grp.LastOwnerID = creatorID; grp.LastOwnerID = creatorID;
grp.RezzerID = creatorID;
} }
else else
grp.AddPart(prim); grp.AddPart(prim);
@ -1649,7 +1681,7 @@ namespace OpenSim.Region.ClientStack.Linden
if(fail) if(fail)
{ {
if(client != null) if(client != null)
client.SendAlertMessage(message, "HomePositionSet"); client.SendAlertMessage(message);
response = OSDParser.SerializeLLSDXmlString(resp); response = OSDParser.SerializeLLSDXmlString(resp);
return response; return response;
} }
@ -1794,6 +1826,72 @@ namespace OpenSim.Region.ClientStack.Linden
response = OSDParser.SerializeLLSDXmlString(resp); response = OSDParser.SerializeLLSDXmlString(resp);
return response; return response;
} }
public string GetDisplayNames(string request, string path,
string param, IOSHttpRequest httpRequest,
IOSHttpResponse httpResponse)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.Gone;
httpResponse.ContentType = "text/plain";
ScenePresence sp = m_Scene.GetScenePresence(m_AgentID);
if(sp == null || sp.IsDeleted)
return "";
if(sp.IsInTransit)
{
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.ServiceUnavailable;
httpResponse.AddHeader("Retry-After","30");
return "";
}
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
string[] ids = query.GetValues("ids");
Dictionary<UUID,string> names = m_UserManager.GetUsersNames(ids);
OSDMap osdReply = new OSDMap();
OSDArray agents = new OSDArray();
osdReply["agents"] = agents;
foreach (KeyValuePair<UUID,string> kvp in names)
{
if (string.IsNullOrEmpty(kvp.Value))
continue;
if(kvp.Key == UUID.Zero)
continue;
string[] parts = kvp.Value.Split(new char[] {' '});
OSDMap osdname = new OSDMap();
if(parts[0] == "Unknown")
{
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2));
}
else
{
osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8));
osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1));
}
osdname["display_name"] = OSD.FromString(kvp.Value);
osdname["legacy_first_name"] = parts[0];
osdname["legacy_last_name"] = parts[1];
osdname["username"] = OSD.FromString(kvp.Value);
osdname["id"] = OSD.FromUUID(kvp.Key);
osdname["is_display_name_default"] = OSD.FromBoolean(true);
agents.Add(osdname);
}
// Full content request
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
//httpResponse.ContentLength = ??;
httpResponse.ContentType = "application/llsd+xml";
string reply = OSDParser.SerializeLLSDXmlString(osdReply);
return reply;
}
} }
public class AssetUploader public class AssetUploader

View File

@ -71,7 +71,6 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
IConfigSource config = new IniConfigSource(); IConfigSource config = new IniConfigSource();
config.AddConfig("Startup"); config.AddConfig("Startup");
config.Configs["Startup"].Set("EventQueue", "true");
CapabilitiesModule capsModule = new CapabilitiesModule(); CapabilitiesModule capsModule = new CapabilitiesModule();
m_eqgMod = new EventQueueGetModule(); m_eqgMod = new EventQueueGetModule();

View File

@ -1,144 +0,0 @@
/*
* 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;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.Reflection;
using System.IO;
using System.Web;
using log4net;
using Nini.Config;
using Mono.Addins;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenMetaverse.Imaging;
using OpenSim.Framework;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Caps = OpenSim.Framework.Capabilities.Caps;
using OpenSim.Capabilities.Handlers;
namespace OpenSim.Region.ClientStack.Linden
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetDisplayNamesModule")]
public class GetDisplayNamesModule : INonSharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Scene m_scene;
protected IUserManagement m_UserManager;
protected bool m_Enabled = false;
protected string m_URL;
#region ISharedRegionModule Members
public virtual void Initialise(IConfigSource source)
{
IConfig config = source.Configs["ClientStack.LindenCaps"];
if (config == null)
return;
m_URL = config.GetString("Cap_GetDisplayNames", string.Empty);
if (m_URL != string.Empty)
m_Enabled = true;
}
public virtual void AddRegion(Scene s)
{
if (!m_Enabled)
return;
m_scene = s;
}
public virtual void RemoveRegion(Scene s)
{
if (!m_Enabled)
return;
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
m_scene = null;
}
public virtual void RegionLoaded(Scene s)
{
if (!m_Enabled)
return;
m_UserManager = m_scene.RequestModuleInterface<IUserManagement>();
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
}
public virtual void PostInitialise()
{
}
public virtual void Close() { }
public virtual string Name { get { return "GetDisplayNamesModule"; } }
public virtual Type ReplaceableInterface
{
get { return null; }
}
#endregion
public virtual void RegisterCaps(UUID agentID, Caps caps)
{
UUID capID = UUID.Random();
if (m_URL == "localhost")
{
m_log.DebugFormat("[GET_DISPLAY_NAMES]: /CAPS/agents/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler(
"GetDisplayNames",
new GetDisplayNamesHandler("/CAPS/agents" + capID + "/", m_UserManager, "GetDisplayNames", agentID.ToString()));
}
else
{
// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
if (handler != null)
handler.RegisterExternalUserCapsHandler(agentID,caps,"GetDisplayNames", m_URL);
else
caps.RegisterHandler("GetDisplayNames", m_URL);
}
}
}
}

View File

@ -186,7 +186,13 @@ namespace OpenSim.Region.ClientStack.Linden
m_log.DebugFormat("[GetMeshModule] Closing"); m_log.DebugFormat("[GetMeshModule] Closing");
foreach (Thread t in m_workerThreads) foreach (Thread t in m_workerThreads)
Watchdog.AbortThread(t.ManagedThreadId); Watchdog.AbortThread(t.ManagedThreadId);
m_queue.Clear(); // This will fail on region shutdown. Its harmless.
// Prevent red ink.
try
{
m_queue.Clear();
}
catch {}
} }
} }

View File

@ -133,7 +133,7 @@ namespace OpenSim.Region.ClientStack.Linden
// data["username"] = sp.Firstname + "." + sp.Lastname; // data["username"] = sp.Firstname + "." + sp.Lastname;
// data["display_name_next_update"] = new OSDDate(DateTime.Now); // data["display_name_next_update"] = new OSDDate(DateTime.Now);
// data["legacy_first_name"] = sp.Firstname; // data["legacy_first_name"] = sp.Firstname;
data["mesh_upload_status"] = "valid"; data["mesh_upload_status"] = "valid";
// data["display_name"] = sp.Firstname + " " + sp.Lastname; // data["display_name"] = sp.Firstname + " " + sp.Lastname;
// data["legacy_last_name"] = sp.Lastname; // data["legacy_last_name"] = sp.Lastname;
// data["id"] = m_agentID; // data["id"] = m_agentID;

View File

@ -284,6 +284,7 @@ namespace OpenSim.Region.ClientStack.Linden
prim.OwnerID = AgentId; prim.OwnerID = AgentId;
prim.GroupID = obj.GroupID; prim.GroupID = obj.GroupID;
prim.LastOwnerID = prim.OwnerID; prim.LastOwnerID = prim.OwnerID;
prim.RezzerID = AgentId;
prim.CreationDate = Util.UnixTimeSinceEpoch(); prim.CreationDate = Util.UnixTimeSinceEpoch();
prim.Name = obj.Name; prim.Name = obj.Name;
prim.Description = ""; prim.Description = "";

View File

@ -346,12 +346,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool m_VelocityInterpolate = false; private bool m_VelocityInterpolate = false;
private const uint MaxTransferBytesPerPacket = 600; private const uint MaxTransferBytesPerPacket = 600;
/// <value>
/// List used in construction of data blocks for an object update packet. This is to stop us having to
/// continually recreate it.
/// </value>
protected List<ObjectUpdatePacket.ObjectDataBlock> m_fullUpdateDataBlocksBuilder;
/// <value> /// <value>
/// Maintain a record of all the objects killed. This allows us to stop an update being sent from the /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the
/// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
@ -511,7 +505,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = scene; m_scene = scene;
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
m_entityProps = new PriorityQueue(m_scene.Entities.Count); m_entityProps = new PriorityQueue(m_scene.Entities.Count);
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
m_killRecord = new List<uint>(); m_killRecord = new List<uint>();
// m_attachmentsSent = new HashSet<uint>(); // m_attachmentsSent = new HashSet<uint>();
@ -594,13 +587,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(disable, ThrottleOutPacketType.Unknown); OutPacket(disable, ThrottleOutPacketType.Unknown);
} }
// Shutdown the image manager
ImageManager.Close();
// Fire the callback for this connection closing // Fire the callback for this connection closing
if (OnConnectionClosed != null) if (OnConnectionClosed != null)
OnConnectionClosed(this); OnConnectionClosed(this);
// Flush all of the packets out of the UDP server for this client // Flush all of the packets out of the UDP server for this client
if (m_udpServer != null) if (m_udpServer != null)
m_udpServer.Flush(m_udpClient); m_udpServer.Flush(m_udpClient);
@ -614,12 +606,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//m_scene.CloseAllAgents(CircuitCode); //m_scene.CloseAllAgents(CircuitCode);
// Disable UDP handling for this client // Disable UDP handling for this client
m_udpClient.OnQueueEmpty -= HandleQueueEmpty;
m_udpClient.HasUpdates -= HandleHasUpdates;
m_udpClient.OnPacketStats -= PopulateStats;
m_udpClient.Shutdown(); m_udpClient.Shutdown();
// Shutdown the image manager
ImageManager.Close();
ImageManager = null;
//m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); m_entityUpdates = new PriorityQueue(1);
//GC.Collect(); m_entityProps = new PriorityQueue(1);
//m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); m_killRecord.Clear();
GroupsInView.Clear();
if(m_scene.GetNumberOfClients() == 0)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
} }
public void Kick(string message) public void Kick(string message)
@ -2702,7 +2708,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(packet, ThrottleOutPacketType.Task); OutPacket(packet, ThrottleOutPacketType.Task);
} }
public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] membershipType,
string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL,
UUID partnerID) UUID partnerID)
{ {
@ -2714,7 +2720,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else else
avatarReply.PropertiesData.AboutText = Utils.EmptyBytes; avatarReply.PropertiesData.AboutText = Utils.EmptyBytes;
avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn); avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn);
avatarReply.PropertiesData.CharterMember = charterMember; avatarReply.PropertiesData.CharterMember = membershipType;
if (flAbout != null) if (flAbout != null)
avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout); avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout);
else else
@ -2856,6 +2862,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendSelectedPartsProprieties(List<ISceneEntity> parts) public void SendSelectedPartsProprieties(List<ISceneEntity> parts)
{ {
/* not in use
// udp part // udp part
ObjectPropertiesPacket packet = ObjectPropertiesPacket packet =
(ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
@ -2893,6 +2900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
llsdBody.Add("ObjectData", array); llsdBody.Add("ObjectData", array);
eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId); eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId);
*/
} }
@ -2920,7 +2928,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString()); m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
} }
part.UpdatePhysRequired = false;
} }
} }
@ -2991,7 +2998,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return; return;
} }
int WearableOut = 0;
bool isWearable = false; bool isWearable = false;
isWearable = ((AssetType) req.AssetInf.Type == isWearable = ((AssetType) req.AssetInf.Type ==
@ -3121,10 +3127,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
reply.Data.ActualArea = land.Area; reply.Data.ActualArea = land.Area;
reply.Data.BillableArea = land.Area; // TODO: what is this? reply.Data.BillableArea = land.Area; // TODO: what is this?
// Bit 0: Mature, bit 7: on sale, other bits: no idea reply.Data.Flags = (byte)Util.ConvertAccessLevelToMaturity((byte)info.AccessLevel);
reply.Data.Flags = (byte)( if((land.Flags & (uint)ParcelFlags.ForSale) != 0)
(info.AccessLevel > 13 ? (1 << 0) : 0) + reply.Data.Flags |= (byte)((1 << 7));
((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0));
Vector3 pos = land.UserLocation; Vector3 pos = land.UserLocation;
if (pos.Equals(Vector3.Zero)) if (pos.Equals(Vector3.Zero))
@ -4094,19 +4099,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ResendPrimUpdate(update); ResendPrimUpdate(update);
} }
private List<ObjectUpdatePacket.ObjectDataBlock> objectUpdateBlocks = new List<ObjectUpdatePacket.ObjectDataBlock>();
private List<ObjectUpdateCompressedPacket.ObjectDataBlock> compressedUpdateBlocks = new List<ObjectUpdateCompressedPacket.ObjectDataBlock>();
private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseAgentUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
private void ProcessEntityUpdates(int maxUpdatesBytes) private void ProcessEntityUpdates(int maxUpdatesBytes)
{ {
OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
// Check to see if this is a flush // Check to see if this is a flush
if (maxUpdatesBytes <= 0) if (maxUpdatesBytes <= 0)
{ {
@ -4327,7 +4331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
else else
ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId); ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId);
objectUpdateBlocks.Value.Add(ablock); objectUpdateBlocks.Add(ablock);
objectUpdates.Value.Add(update); objectUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length; maxUpdatesBytes -= ablock.Length;
@ -4336,7 +4340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
ObjectUpdateCompressedPacket.ObjectDataBlock ablock = ObjectUpdateCompressedPacket.ObjectDataBlock ablock =
CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags); CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags);
compressedUpdateBlocks.Value.Add(ablock); compressedUpdateBlocks.Add(ablock);
compressedUpdates.Value.Add(update); compressedUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length; maxUpdatesBytes -= ablock.Length;
} }
@ -4347,14 +4351,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
// ALL presence updates go into a special list // ALL presence updates go into a special list
ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
terseAgentUpdateBlocks.Value.Add(ablock); terseAgentUpdateBlocks.Add(ablock);
terseAgentUpdates.Value.Add(update); terseAgentUpdates.Value.Add(update);
} }
else else
{ {
// Everything else goes here // Everything else goes here
ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
terseUpdateBlocks.Value.Add(ablock); terseUpdateBlocks.Add(ablock);
terseUpdates.Value.Add(update); terseUpdates.Value.Add(update);
} }
maxUpdatesBytes -= ablock.Length; maxUpdatesBytes -= ablock.Length;
@ -4365,74 +4369,72 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Packet Sending #region Packet Sending
// const float TIME_DILATION = 1.0f;
ushort timeDilation; ushort timeDilation;
// if(updatesThisCall > 0)
// timeDilation = Utils.FloatToUInt16(avgTimeDilation/updatesThisCall, 0.0f, 1.0f); if(!IsActive)
// else return;
// timeDilation = ushort.MaxValue; // 1.0;
timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
if (terseAgentUpdateBlocks.IsValueCreated) if (terseAgentUpdateBlocks.Count > 0)
{ {
List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
ImprovedTerseObjectUpdatePacket packet ImprovedTerseObjectUpdatePacket packet
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation; packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseAgentUpdateBlocks.Count];
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < terseAgentUpdateBlocks.Count; i++)
packet.ObjectData[i] = blocks[i]; packet.ObjectData[i] = terseAgentUpdateBlocks[i];
terseAgentUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
} }
if (objectUpdateBlocks.IsValueCreated) if (objectUpdateBlocks.Count > 0)
{ {
List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation; packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[objectUpdateBlocks.Count];
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < objectUpdateBlocks.Count; i++)
packet.ObjectData[i] = blocks[i]; packet.ObjectData[i] = objectUpdateBlocks[i];
objectUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
} }
if (compressedUpdateBlocks.IsValueCreated) if (compressedUpdateBlocks.Count > 0)
{ {
List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation; packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[compressedUpdateBlocks.Count];
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < compressedUpdateBlocks.Count; i++)
packet.ObjectData[i] = blocks[i]; packet.ObjectData[i] = compressedUpdateBlocks[i];
compressedUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); }); OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
} }
if (terseUpdateBlocks.IsValueCreated) if (terseUpdateBlocks.Count > 0)
{ {
List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
ImprovedTerseObjectUpdatePacket packet ImprovedTerseObjectUpdatePacket packet
= (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
PacketType.ImprovedTerseObjectUpdate); PacketType.ImprovedTerseObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation; packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseUpdateBlocks.Count];
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < terseUpdateBlocks.Count; i++)
packet.ObjectData[i] = blocks[i]; packet.ObjectData[i] = terseUpdateBlocks[i];
terseUpdateBlocks.Clear();
OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
} }
@ -4633,28 +4635,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories)
{ {
// if (!m_udpServer.IsRunningOutbound) if(m_scene == null)
// return; return;
if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
{ {
// if (!m_udpServer.IsRunningOutbound)
// return;
/*
if (m_maxUpdates == 0 || m_LastQueueFill == 0)
{
m_maxUpdates = m_udpServer.PrimUpdatesPerCallback;
}
else
{
if (Util.EnvironmentTickCountSubtract(m_LastQueueFill) < 200)
m_maxUpdates += 5;
else
m_maxUpdates = m_maxUpdates >> 1;
}
m_maxUpdates = Util.Clamp<Int32>(m_maxUpdates,10,500);
m_LastQueueFill = Util.EnvironmentTickCount();
*/
int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30); int maxUpdateBytes = m_udpClient.GetCatBytesCanSend(ThrottleOutPacketType.Task, 30);
if (m_entityUpdates.Count > 0) if (m_entityUpdates.Count > 0)
@ -4670,23 +4655,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories) internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
{ {
bool hasUpdates = false;
if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
{ {
if (m_entityUpdates.Count > 0) if (m_entityUpdates.Count > 0)
hasUpdates = true; return true;
else if (m_entityProps.Count > 0) if (m_entityProps.Count > 0)
hasUpdates = true; return true;
} }
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
{ {
if (ImageManager.HasUpdates()) if (ImageManager.HasUpdates())
hasUpdates = true; return true;
} }
return hasUpdates; return false;
} }
public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
@ -4849,19 +4832,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
} }
List<ObjectPropertiesFamilyPacket.ObjectDataBlock> objectFamilyBlocks = new
List<ObjectPropertiesFamilyPacket.ObjectDataBlock>();
List<ObjectPropertiesPacket.ObjectDataBlock> objectPropertiesBlocks =
new List<ObjectPropertiesPacket.ObjectDataBlock>();
List<SceneObjectPart> needPhysics = new List<SceneObjectPart>();
private void ProcessEntityPropertyRequests(int maxUpdateBytes) private void ProcessEntityPropertyRequests(int maxUpdateBytes)
{ {
OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks = // OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>(); // new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks = // OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>(); // new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
EntityUpdate iupdate; EntityUpdate iupdate;
Int32 timeinqueue; // this is just debugging code & can be dropped later Int32 timeinqueue; // this is just debugging code & can be dropped later
@ -4879,8 +4863,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
SceneObjectPart sop = (SceneObjectPart)update.Entity; SceneObjectPart sop = (SceneObjectPart)update.Entity;
ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
objectFamilyBlocks.Value.Add(objPropDB); objectFamilyBlocks.Add(objPropDB);
familyUpdates.Value.Add(update); // familyUpdates.Value.Add(update);
maxUpdateBytes -= objPropDB.Length; maxUpdateBytes -= objPropDB.Length;
} }
} }
@ -4890,24 +4874,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (update.Entity is SceneObjectPart) if (update.Entity is SceneObjectPart)
{ {
SceneObjectPart sop = (SceneObjectPart)update.Entity; SceneObjectPart sop = (SceneObjectPart)update.Entity;
needPhysics.Add(sop);
ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
objectPropertiesBlocks.Value.Add(objPropDB); objectPropertiesBlocks.Add(objPropDB);
propertyUpdates.Value.Add(update); // propertyUpdates.Value.Add(update);
maxUpdateBytes -= objPropDB.Length; maxUpdateBytes -= objPropDB.Length;
} }
} }
} }
if (objectPropertiesBlocks.IsValueCreated) if (objectPropertiesBlocks.Count > 0)
{ {
List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
List<ObjectPropertyUpdate> updates = propertyUpdates.Value;
ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[objectPropertiesBlocks.Count];
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < objectPropertiesBlocks.Count; i++)
packet.ObjectData[i] = blocks[i]; packet.ObjectData[i] = objectPropertiesBlocks[i];
objectPropertiesBlocks.Clear();
packet.Header.Zerocoded = true; packet.Header.Zerocoded = true;
// Pass in the delegate so that if this packet needs to be resent, we send the current properties // Pass in the delegate so that if this packet needs to be resent, we send the current properties
@ -4916,7 +4900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//OutPacket(packet, ThrottleOutPacketType.Task, true, //OutPacket(packet, ThrottleOutPacketType.Task, true,
// delegate(OutgoingPacket oPacket) // delegate(OutgoingPacket oPacket)
// { // {
// ResendPropertyUpdates(updates, oPacket); // ResendPropertyUpdates(propertyUpdates.Value, oPacket);
// }); // });
OutPacket(packet, ThrottleOutPacketType.Task, true); OutPacket(packet, ThrottleOutPacketType.Task, true);
@ -4927,23 +4911,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Int32 fpcnt = 0; // Int32 fpcnt = 0;
// Int32 fbcnt = 0; // Int32 fbcnt = 0;
if (objectFamilyBlocks.IsValueCreated) if (objectFamilyBlocks.Count > 0)
{ {
List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
// one packet per object block... uggh... // one packet per object block... uggh...
for (int i = 0; i < blocks.Count; i++) for (int i = 0; i < objectFamilyBlocks.Count; i++)
{ {
ObjectPropertiesFamilyPacket packet = ObjectPropertiesFamilyPacket packet =
(ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
packet.ObjectData = blocks[i]; packet.ObjectData = objectFamilyBlocks[i];
packet.Header.Zerocoded = true; packet.Header.Zerocoded = true;
// Pass in the delegate so that if this packet needs to be resent, we send the current properties // Pass in the delegate so that if this packet needs to be resent, we send the current properties
// of the object rather than the properties when the packet was created // of the object rather than the properties when the packet was created
List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); // List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
updates.Add(familyUpdates.Value[i]); // updates.Add(familyUpdates.Value[i]);
// HACK : Remove intelligent resending until it's fixed in core // HACK : Remove intelligent resending until it's fixed in core
//OutPacket(packet, ThrottleOutPacketType.Task, true, //OutPacket(packet, ThrottleOutPacketType.Task, true,
// delegate(OutgoingPacket oPacket) // delegate(OutgoingPacket oPacket)
@ -4955,7 +4937,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// fpcnt++; // fpcnt++;
// fbcnt++; // fbcnt++;
} }
objectFamilyBlocks.Clear();
}
if(needPhysics.Count > 0)
{
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
if(eq != null)
{
OSDArray array = new OSDArray();
foreach(SceneObjectPart sop in needPhysics)
{
OSDMap physinfo = new OSDMap(6);
physinfo["LocalID"] = sop.LocalId;
physinfo["Density"] = sop.Density;
physinfo["Friction"] = sop.Friction;
physinfo["GravityMultiplier"] = sop.GravityModifier;
physinfo["Restitution"] = sop.Restitution;
physinfo["PhysicsShapeType"] = (int)sop.PhysicsShapeType;
array.Add(physinfo);
}
OSDMap llsdBody = new OSDMap(1);
llsdBody.Add("ObjectData", array);
eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId);
}
needPhysics.Clear();
} }
// m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt); // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt);
@ -6245,9 +6253,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return false; return false;
} }
uint seq = packet.Header.Sequence;
TotalAgentUpdates++; TotalAgentUpdates++;
// dont let ignored updates pollute this throttles // dont let ignored updates pollute this throttles
if(SceneAgent == null || SceneAgent.IsChildAgent || SceneAgent.IsInTransit) if(SceneAgent == null || SceneAgent.IsChildAgent ||
SceneAgent.IsInTransit || seq <= m_thisAgentUpdateArgs.lastpacketSequence )
{ {
// throttle reset is done at MoveAgentIntoRegion() // throttle reset is done at MoveAgentIntoRegion()
// called by scenepresence on completemovement // called by scenepresence on completemovement
@ -6255,6 +6266,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
m_thisAgentUpdateArgs.lastpacketSequence = seq;
bool movement = CheckAgentMovementUpdateSignificance(x); bool movement = CheckAgentMovementUpdateSignificance(x);
bool camera = CheckAgentCameraUpdateSignificance(x); bool camera = CheckAgentCameraUpdateSignificance(x);
@ -6268,6 +6281,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation; m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
m_thisAgentUpdateArgs.State = x.State; m_thisAgentUpdateArgs.State = x.State;
m_thisAgentUpdateArgs.NeedsCameraCollision = !camera;
UpdateAgent handlerAgentUpdate = OnAgentUpdate; UpdateAgent handlerAgentUpdate = OnAgentUpdate;
UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
@ -6287,6 +6302,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis; m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis; m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
m_thisAgentUpdateArgs.NeedsCameraCollision = true;
UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate; UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate;
if (handlerAgentCameraUpdate != null) if (handlerAgentCameraUpdate != null)
@ -8547,7 +8564,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// surrounding scene // surrounding scene
if ((ImageType)block.Type == ImageType.Baked) if ((ImageType)block.Type == ImageType.Baked)
args.Priority *= 2.0f; args.Priority *= 2.0f;
int wearableout = 0;
ImageManager.EnqueueReq(args); ImageManager.EnqueueReq(args);
} }
@ -9597,61 +9613,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Parcel related packets #region Parcel related packets
// acumulate several HandleRegionHandleRequest consecutive overlaping requests
// to be done with minimal resources as possible
// variables temporary here while in test
Queue<UUID> RegionHandleRequests = new Queue<UUID>();
bool RegionHandleRequestsInService = false;
private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack)
{ {
UUID currentUUID;
RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
if (handlerRegionHandleRequest == null) if (handlerRegionHandleRequest != null)
return true;
RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
lock (RegionHandleRequests)
{ {
if (RegionHandleRequestsInService) RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
{ handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID);
// we are already busy doing a previus request
// so enqueue it
RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID);
return true;
}
// else do it
currentUUID = rhrPack.RequestBlock.RegionID;
RegionHandleRequestsInService = true;
} }
while (true) return true;
{
handlerRegionHandleRequest(this, currentUUID);
lock (RegionHandleRequests)
{
// exit condition, nothing to do or closed
// current code seems to assume we may loose the handler at anytime,
// so keep checking it
handlerRegionHandleRequest = OnRegionHandleRequest;
if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null)
{
RegionHandleRequests.Clear();
RegionHandleRequestsInService = false;
return true;
}
currentUUID = RegionHandleRequests.Dequeue();
}
}
return true; // actually unreached
} }
private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@ -10483,6 +10455,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandleRequestGodlikePowers(IClientAPI sender, Packet Pack) private bool HandleRequestGodlikePowers(IClientAPI sender, Packet Pack)
{ {
RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack; RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack;
if (rglpPack.AgentData.SessionID != SessionId ||
rglpPack.AgentData.AgentID != AgentId)
return true;
RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock; RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock;
UUID token = rblock.Token; UUID token = rblock.Token;
@ -10492,7 +10469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (handlerReqGodlikePowers != null) if (handlerReqGodlikePowers != null)
{ {
handlerReqGodlikePowers(ablock.AgentID, ablock.SessionID, token, rblock.Godlike, this); handlerReqGodlikePowers(ablock.AgentID, ablock.SessionID, token, rblock.Godlike);
} }
return true; return true;
@ -10503,6 +10480,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
GodUpdateRegionInfoPacket GodUpdateRegionInfo = GodUpdateRegionInfoPacket GodUpdateRegionInfo =
(GodUpdateRegionInfoPacket)Packet; (GodUpdateRegionInfoPacket)Packet;
if (GodUpdateRegionInfo.AgentData.SessionID != SessionId ||
GodUpdateRegionInfo.AgentData.AgentID != AgentId)
return true;
GodUpdateRegionInfoUpdate handlerGodUpdateRegionInfo = OnGodUpdateRegionInfoUpdate; GodUpdateRegionInfoUpdate handlerGodUpdateRegionInfo = OnGodUpdateRegionInfoUpdate;
if (handlerGodUpdateRegionInfo != null) if (handlerGodUpdateRegionInfo != null)
{ {
@ -10536,6 +10517,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
GodlikeMessagePacket GodlikeMessage = GodlikeMessagePacket GodlikeMessage =
(GodlikeMessagePacket)Packet; (GodlikeMessagePacket)Packet;
if (GodlikeMessage.AgentData.SessionID != SessionId ||
GodlikeMessage.AgentData.AgentID != AgentId)
return true;
GodlikeMessage handlerGodlikeMessage = onGodlikeMessage; GodlikeMessage handlerGodlikeMessage = onGodlikeMessage;
if (handlerGodlikeMessage != null) if (handlerGodlikeMessage != null)
{ {
@ -10552,6 +10537,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
StateSavePacket SaveStateMessage = StateSavePacket SaveStateMessage =
(StateSavePacket)Packet; (StateSavePacket)Packet;
if (SaveStateMessage.AgentData.SessionID != SessionId ||
SaveStateMessage.AgentData.AgentID != AgentId)
return true;
SaveStateHandler handlerSaveStatePacket = OnSaveState; SaveStateHandler handlerSaveStatePacket = OnSaveState;
if (handlerSaveStatePacket != null) if (handlerSaveStatePacket != null)
{ {
@ -10565,30 +10555,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
GodKickUserPacket gkupack = (GodKickUserPacket)Pack; GodKickUserPacket gkupack = (GodKickUserPacket)Pack;
if (gkupack.UserInfo.GodSessionID == SessionId && AgentId == gkupack.UserInfo.GodID) if (gkupack.UserInfo.GodSessionID != SessionId ||
gkupack.UserInfo.GodID != AgentId)
return true;
GodKickUser handlerGodKickUser = OnGodKickUser;
if (handlerGodKickUser != null)
{ {
GodKickUser handlerGodKickUser = OnGodKickUser; handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason);
if (handlerGodKickUser != null)
{
handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID,
gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason);
}
} }
else
{
SendAgentAlertMessage("Kick request denied", false);
}
//KickUserPacket kupack = new KickUserPacket();
//KickUserPacket.UserInfoBlock kupackib = kupack.UserInfo;
//kupack.UserInfo.AgentID = gkupack.UserInfo.AgentID;
//kupack.UserInfo.SessionID = gkupack.UserInfo.GodSessionID;
//kupack.TargetBlock.TargetIP = (uint)0;
//kupack.TargetBlock.TargetPort = (ushort)0;
//kupack.UserInfo.Reason = gkupack.UserInfo.Reason;
//OutPacket(kupack, ThrottleOutPacketType.Task);
return true; return true;
} }
#endregion GodPackets #endregion GodPackets
@ -11479,7 +11455,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ScenePresence p; ScenePresence p;
if (scene.TryGetScenePresence(sender.AgentId, out p)) if (scene.TryGetScenePresence(sender.AgentId, out p))
{ {
if (p.GodLevel >= 200) if (p.IsViewerUIGod)
{ {
groupProfileReply.GroupData.OpenEnrollment = true; groupProfileReply.GroupData.OpenEnrollment = true;
groupProfileReply.GroupData.MembershipFee = 0; groupProfileReply.GroupData.MembershipFee = 0;
@ -12928,9 +12904,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// provide your own method.</param> /// provide your own method.</param>
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
{ {
/* this is causing packet loss for some reason
if(!m_udpClient.IsConnected)
{
PacketPool.Instance.ReturnPacket(packet);
return;
}
*/
if (m_outPacketsToDrop != null) if (m_outPacketsToDrop != null)
{
if (m_outPacketsToDrop.Contains(packet.Type.ToString())) if (m_outPacketsToDrop.Contains(packet.Type.ToString()))
{
PacketPool.Instance.ReturnPacket(packet);
return; return;
}
}
if (DebugPacketLevel > 0) if (DebugPacketLevel > 0)
{ {

View File

@ -120,13 +120,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Circuit code that this client is connected on</summary> /// <summary>Circuit code that this client is connected on</summary>
public readonly uint CircuitCode; public readonly uint CircuitCode;
/// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary> /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary>
public readonly IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200); public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200);
/// <summary>Packets we have sent that need to be ACKed by the client</summary> /// <summary>Packets we have sent that need to be ACKed by the client</summary>
public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); public UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
/// <summary>ACKs that are queued up, waiting to be sent to the client</summary> /// <summary>ACKs that are queued up, waiting to be sent to the client</summary>
public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>(); public DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
/// <summary>Current packet sequence number</summary> /// <summary>Current packet sequence number</summary>
public int CurrentSequence; public int CurrentSequence;
@ -161,15 +161,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Total byte count of unacked packets sent to this client</summary> /// <summary>Total byte count of unacked packets sent to this client</summary>
public int UnackedBytes; public int UnackedBytes;
private int m_packetsUnAckReported;
/// <summary>Total number of received packets that we have reported to the OnPacketStats event(s)</summary> /// <summary>Total number of received packets that we have reported to the OnPacketStats event(s)</summary>
private int m_packetsReceivedReported; private int m_packetsReceivedReported;
/// <summary>Total number of sent packets that we have reported to the OnPacketStats event(s)</summary> /// <summary>Total number of sent packets that we have reported to the OnPacketStats event(s)</summary>
private int m_packetsSentReported; private int m_packetsSentReported;
/// <summary>Holds the Environment.TickCount value of when the next OnQueueEmpty can be fired</summary> /// <summary>Holds the Environment.TickCount value of when the next OnQueueEmpty can be fired</summary>
private int m_nextOnQueueEmpty = 1; private double m_nextOnQueueEmpty = 0;
/// <summary>Throttle bucket for this agent's connection</summary> /// <summary>Throttle bucket for this agent's connection</summary>
private readonly AdaptiveTokenBucket m_throttleClient; private AdaptiveTokenBucket m_throttleClient;
public AdaptiveTokenBucket FlowThrottle public AdaptiveTokenBucket FlowThrottle
{ {
get { return m_throttleClient; } get { return m_throttleClient; }
@ -178,10 +179,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Throttle buckets for each packet category</summary> /// <summary>Throttle buckets for each packet category</summary>
private readonly TokenBucket[] m_throttleCategories; private readonly TokenBucket[] m_throttleCategories;
/// <summary>Outgoing queues for throttled packets</summary> /// <summary>Outgoing queues for throttled packets</summary>
private readonly DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; private DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
/// <summary>A container that can hold one packet for each outbox, used to store /// <summary>A container that can hold one packet for each outbox, used to store
/// dequeued packets that are being held for throttling</summary> /// dequeued packets that are being held for throttling</summary>
private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; private OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
/// <summary>A reference to the LLUDPServer that is managing this client</summary> /// <summary>A reference to the LLUDPServer that is managing this client</summary>
private readonly LLUDPServer m_udpServer; private readonly LLUDPServer m_udpServer;
@ -292,9 +293,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// pull the throttle out of the scene throttle // pull the throttle out of the scene throttle
m_throttleClient.Parent.UnregisterRequest(m_throttleClient); m_throttleClient.Parent.UnregisterRequest(m_throttleClient);
OnPacketStats = null; PendingAcks.Clear();
OnQueueEmpty = null; NeedAcks.Clear();
} }
/// <summary> /// <summary>
/// Gets information about this client connection /// Gets information about this client connection
@ -389,11 +390,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
int newPacketsReceived = PacketsReceived - m_packetsReceivedReported; int newPacketsReceived = PacketsReceived - m_packetsReceivedReported;
int newPacketsSent = PacketsSent - m_packetsSentReported; int newPacketsSent = PacketsSent - m_packetsSentReported;
int newPacketUnAck = UnackedBytes - m_packetsUnAckReported;
callback(newPacketsReceived, newPacketsSent, UnackedBytes); callback(newPacketsReceived, newPacketsSent, UnackedBytes);
m_packetsReceivedReported += newPacketsReceived; m_packetsReceivedReported += newPacketsReceived;
m_packetsSentReported += newPacketsSent; m_packetsSentReported += newPacketsSent;
m_packetsUnAckReported += newPacketUnAck;
} }
} }
@ -771,7 +773,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
RTO = Math.Min(RTO * 2, m_maxRTO); RTO = Math.Min(RTO * 2, m_maxRTO);
} }
const int MIN_CALLBACK_MS = 20; const double MIN_CALLBACK_MS = 20.0;
private bool m_isQueueEmptyRunning;
/// <summary> /// <summary>
/// Does an early check to see if this queue empty callback is already /// Does an early check to see if this queue empty callback is already
@ -782,35 +785,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if (!m_isQueueEmptyRunning) if (!m_isQueueEmptyRunning)
{ {
int start = Environment.TickCount & Int32.MaxValue; if (!HasUpdates(categories))
return;
double start = Util.GetTimeStampMS();
if (start < m_nextOnQueueEmpty) if (start < m_nextOnQueueEmpty)
return; return;
m_isQueueEmptyRunning = true; m_isQueueEmptyRunning = true;
m_nextOnQueueEmpty = start + MIN_CALLBACK_MS; m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
if (m_nextOnQueueEmpty == 0)
m_nextOnQueueEmpty = 1;
if (HasUpdates(categories)) // Asynchronously run the callback
{ if (m_udpServer.OqrEngine.IsRunning)
if (!m_udpServer.OqrEngine.IsRunning) m_udpServer.OqrEngine.QueueJob(AgentID.ToString(), () => FireQueueEmpty(categories));
{
// Asynchronously run the callback
Util.FireAndForget(FireQueueEmpty, categories, "LLUDPClient.BeginFireQueueEmpty");
}
else
{
m_udpServer.OqrEngine.QueueJob(AgentID.ToString(), () => FireQueueEmpty(categories));
}
}
else else
m_isQueueEmptyRunning = false; Util.FireAndForget(FireQueueEmpty, categories, "LLUDPClient.BeginFireQueueEmpty");
} }
} }
private bool m_isQueueEmptyRunning;
/// <summary> /// <summary>

View File

@ -81,7 +81,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uint port = (uint)scene.RegionInfo.InternalEndPoint.Port; uint port = (uint)scene.RegionInfo.InternalEndPoint.Port;
IPAddress listenIP = scene.RegionInfo.InternalEndPoint.Address; IPAddress listenIP = scene.RegionInfo.InternalEndPoint.Address;
Initialise(listenIP, ref port, scene.RegionInfo.ProxyOffset, scene.RegionInfo.m_allow_alternate_ports, m_Config, scene.AuthenticateHandler); Initialise(listenIP, ref port, scene.RegionInfo.ProxyOffset, m_Config, scene.AuthenticateHandler);
scene.RegionInfo.InternalEndPoint.Port = (int)port; scene.RegionInfo.InternalEndPoint.Port = (int)port;
AddScene(scene); AddScene(scene);
@ -98,9 +98,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
#endregion #endregion
public virtual void Initialise(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) public virtual void Initialise(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, IConfigSource configSource, AgentCircuitManager circuitManager)
{ {
m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager); m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, configSource, circuitManager);
} }
public virtual void AddScene(IScene scene) public virtual void AddScene(IScene scene)
@ -323,10 +323,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected int m_elapsedMSSinceLastStatReport = 0; protected int m_elapsedMSSinceLastStatReport = 0;
/// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary> /// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary>
protected int m_tickLastOutgoingPacketHandler; protected double m_tickLastOutgoingPacketHandler;
/// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary> /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary>
protected int m_elapsedMSOutgoingPacketHandler; protected double m_elapsedMSOutgoingPacketHandler;
/// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary> /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary>
protected int m_elapsed100MSOutgoingPacketHandler; protected int m_elapsed100MSOutgoingPacketHandler;
@ -356,20 +356,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>(); protected ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
/// <summary>
/// Event used to signal when queued packets are available for sending.
/// </summary>
/// <remarks>
/// This allows the outbound loop to only operate when there is data to send rather than continuously polling.
/// Some data is sent immediately and not queued. That data would not trigger this event.
/// WRONG use. May be usefull in future revision
/// </remarks>
// protected AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false);
protected Pool<IncomingPacket> m_incomingPacketPool; protected Pool<IncomingPacket> m_incomingPacketPool;
/// <summary> /// <summary>
@ -442,12 +430,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public JobEngine OqrEngine { get; protected set; } public JobEngine OqrEngine { get; protected set; }
public LLUDPServer( public LLUDPServer(
IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IPAddress listenIP, ref uint port, int proxyPortOffsetParm,
IConfigSource configSource, AgentCircuitManager circuitManager) IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port) : base(listenIP, (int)port)
{ {
#region Environment.TickCount Measurement #region Environment.TickCount Measurement
// Update the port with the one we actually got
port = (uint)Port;
// Measure the resolution of Environment.TickCount // Measure the resolution of Environment.TickCount
TickCountResolution = 0f; TickCountResolution = 0f;
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
@ -456,10 +447,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int now = start; int now = start;
while (now == start) while (now == start)
now = Environment.TickCount; now = Environment.TickCount;
TickCountResolution += (float)(now - start) * 0.1f; TickCountResolution += (float)(now - start);
} }
TickCountResolution = (float)Math.Ceiling(TickCountResolution); m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution * 0.1f + "ms");
m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
TickCountResolution = 0f;
for (int i = 0; i < 100; i++)
{
double start = Util.GetTimeStampMS();
double now = start;
while (now == start)
now = Util.GetTimeStampMS();
TickCountResolution += (float)((now - start));
}
TickCountResolution = (float)Math.Round(TickCountResolution * 0.01f,6,MidpointRounding.AwayFromZero);
m_log.Info("[LLUDPSERVER]: Average Util.GetTimeStampMS resolution: " + TickCountResolution + "ms");
#endregion Environment.TickCount Measurement #endregion Environment.TickCount Measurement
@ -467,8 +470,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int sceneThrottleBps = 0; int sceneThrottleBps = 0;
bool usePools = false; bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"]; IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null) if (config != null)
{ {
@ -523,7 +524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// if (usePools) // if (usePools)
// EnablePools(); // EnablePools();
DisablePools(); base.DisablePools();
} }
public void Start() public void Start()
@ -927,10 +928,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
PacketPool.Instance.ReturnPacket(packet); PacketPool.Instance.ReturnPacket(packet);
/// WRONG use. May be usefull in future revision
// if (packetQueued)
// m_dataPresentEvent.Set();
} }
/// <summary> /// <summary>
@ -2079,19 +2076,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_sendPing = false; m_sendPing = false;
// Update elapsed time // Update elapsed time
int thisTick = Environment.TickCount & Int32.MaxValue; double thisTick = Util.GetTimeStampMS();
if (m_tickLastOutgoingPacketHandler > thisTick)
m_elapsedMSOutgoingPacketHandler += ((Int32.MaxValue - m_tickLastOutgoingPacketHandler) + thisTick);
else
m_elapsedMSOutgoingPacketHandler += (thisTick - m_tickLastOutgoingPacketHandler);
// update some 1ms resolution chained timers
m_elapsedMSOutgoingPacketHandler += thisTick - m_tickLastOutgoingPacketHandler;
m_tickLastOutgoingPacketHandler = thisTick; m_tickLastOutgoingPacketHandler = thisTick;
// Check for pending outgoing resends every 100ms // Check for pending outgoing resends every 100ms
if (m_elapsedMSOutgoingPacketHandler >= 100) if (m_elapsedMSOutgoingPacketHandler >= 100.0)
{ {
m_resendUnacked = true; m_resendUnacked = true;
m_elapsedMSOutgoingPacketHandler = 0; m_elapsedMSOutgoingPacketHandler = 0.0;
m_elapsed100MSOutgoingPacketHandler += 1; m_elapsed100MSOutgoingPacketHandler += 1;
} }
@ -2109,15 +2104,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_sendPing = true; m_sendPing = true;
m_elapsed500MSOutgoingPacketHandler = 0; m_elapsed500MSOutgoingPacketHandler = 0;
} }
#endregion Update Timers #endregion Update Timers
// Use this for emergency monitoring -- bug hunting
//if (m_scene.EmergencyMonitoring)
// clientPacketHandler = MonitoredClientOutgoingPacketHandler;
//else
// clientPacketHandler = ClientOutgoingPacketHandler;
// Handle outgoing packets, resends, acknowledgements, and pings for each // Handle outgoing packets, resends, acknowledgements, and pings for each
// client. m_packetSent will be set to true if a packet is sent // client. m_packetSent will be set to true if a packet is sent
Scene.ForEachClient(clientPacketHandler); Scene.ForEachClient(clientPacketHandler);
@ -2129,7 +2117,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if(Scene.GetNumberOfClients() == 0) if(Scene.GetNumberOfClients() == 0)
{ {
Thread.Sleep(250); // be friendly to PIs, but how long ?? Thread.Sleep(100);
} }
else if (!m_packetSent) else if (!m_packetSent)
// Thread.Sleep((int)TickCountResolution); outch this is bad on linux // Thread.Sleep((int)TickCountResolution); outch this is bad on linux
@ -2204,99 +2192,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
public long IncomingPacketsProcessed { get; protected set; } public long IncomingPacketsProcessed { get; protected set; }
protected void MonitoredClientOutgoingPacketHandler(IClientAPI client)
{
nticks++;
watch1.Start();
m_currentOutgoingClient = client;
try
{
if (client is LLClientView)
{
LLClientView llClient = (LLClientView)client;
LLUDPClient udpClient = llClient.UDPClient;
if (udpClient.IsConnected)
{
if (m_resendUnacked)
{
nticksUnack++;
watch2.Start();
HandleUnacked(llClient);
watch2.Stop();
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
watch2.Reset();
}
if (m_sendAcks)
{
nticksAck++;
watch2.Start();
SendAcks(udpClient);
watch2.Stop();
avgSendAcksTicks = (nticksAck - 1) / (float)nticksAck * avgSendAcksTicks + (watch2.ElapsedTicks / (float)nticksAck);
watch2.Reset();
}
if (m_sendPing)
{
nticksPing++;
watch2.Start();
SendPing(udpClient);
watch2.Stop();
avgSendPingTicks = (nticksPing - 1) / (float)nticksPing * avgSendPingTicks + (watch2.ElapsedTicks / (float)nticksPing);
watch2.Reset();
}
watch2.Start();
// Dequeue any outgoing packets that are within the throttle limits
if (udpClient.DequeueOutgoing())
{
m_packetSent = true;
npacksSent++;
}
else
{
npackNotSent++;
}
watch2.Stop();
avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
watch2.Reset();
}
else
{
m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
}
}
}
catch (Exception ex)
{
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
" threw an exception: " + ex.Message, ex);
}
watch1.Stop();
avgProcessingTicks = (nticks - 1) / (float)nticks * avgProcessingTicks + (watch1.ElapsedTicks / (float)nticks);
watch1.Reset();
// reuse this -- it's every ~100ms
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);
npackNotSent = npacksSent = 0;
}
}
#endregion #endregion
protected void ProcessInPacket(IncomingPacket incomingPacket) protected void ProcessInPacket(IncomingPacket incomingPacket)

View File

@ -107,6 +107,11 @@ namespace OpenMetaverse
/// </summary> /// </summary>
public float AverageReceiveTicksForLastSamplePeriod { get; private set; } public float AverageReceiveTicksForLastSamplePeriod { get; private set; }
public int Port
{
get { return m_udpPort; }
}
#region PacketDropDebugging #region PacketDropDebugging
/// <summary> /// <summary>
/// For debugging purposes only... random number generator for dropping /// For debugging purposes only... random number generator for dropping
@ -179,6 +184,11 @@ namespace OpenMetaverse
// m_dropRandomGenerator = new Random(); // m_dropRandomGenerator = new Random();
} }
~OpenSimUDPBase()
{
if(m_udpSocket !=null)
try { m_udpSocket.Close(); } catch { }
}
/// <summary> /// <summary>
/// Start inbound UDP packet handling. /// Start inbound UDP packet handling.
/// </summary> /// </summary>
@ -212,10 +222,6 @@ namespace OpenMetaverse
SocketType.Dgram, SocketType.Dgram,
ProtocolType.Udp); ProtocolType.Udp);
// OpenSim may need this but in AVN, this messes up automated
// sim restarts badly
//m_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
try try
{ {
if (m_udpSocket.Ttl < 128) if (m_udpSocket.Ttl < 128)
@ -243,13 +249,22 @@ namespace OpenMetaverse
// we never want two regions to listen on the same port as they cannot demultiplex each other's messages, // we never want two regions to listen on the same port as they cannot demultiplex each other's messages,
// leading to a confusing bug. // leading to a confusing bug.
// By default, Windows does not allow two sockets to bind to the same port. // By default, Windows does not allow two sockets to bind to the same port.
m_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false); //
// Unfortunately, this also causes a crashed sim to leave the socket in a state
// where it appears to be in use but is really just hung from the old process
// crashing rather than closing it. While this protects agains misconfiguration,
// allowing crashed sims to be started up again right away, rather than having to
// wait 2 minutes for the socket to clear is more valuable. Commented 12/13/2016
// m_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, false);
if (recvBufferSize != 0) if (recvBufferSize != 0)
m_udpSocket.ReceiveBufferSize = recvBufferSize; m_udpSocket.ReceiveBufferSize = recvBufferSize;
m_udpSocket.Bind(ipep); m_udpSocket.Bind(ipep);
if (m_udpPort == 0)
m_udpPort = ((IPEndPoint)m_udpSocket.LocalEndPoint).Port;
IsRunningInbound = true; IsRunningInbound = true;
// kick off an async receive. The Start() method will return, the // kick off an async receive. The Start() method will return, the

View File

@ -92,19 +92,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Asset = throttleConfig.GetInt("asset_default", 10500); Asset = throttleConfig.GetInt("asset_default", 10500);
Total = Resend + Land + Wind + Cloud + Task + Texture + Asset; Total = Resend + Land + Wind + Cloud + Task + Texture + Asset;
// 3000000 bps default max // 5120000 bps default max
ClientMaxRate = throttleConfig.GetInt("client_throttle_max_bps", 375000); ClientMaxRate = throttleConfig.GetInt("client_throttle_max_bps", 640000);
if (ClientMaxRate > 1000000) if (ClientMaxRate > 1000000)
ClientMaxRate = 1000000; // no more than 8Mbps ClientMaxRate = 1000000; // no more than 8Mbps
BrustTime = (float)throttleConfig.GetInt("client_throttle_burtsTimeMS", 10); BrustTime = (float)throttleConfig.GetInt("client_throttle_burtsTimeMS", 10);
BrustTime *= 1e-3f; BrustTime *= 1e-3f;
AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false); // Adaptive is broken
// AdaptiveThrottlesEnabled = throttleConfig.GetBoolean("enable_adaptive_throttles", false);
AdaptiveThrottlesEnabled = false;
MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000); MinimumAdaptiveThrottleRate = throttleConfig.GetInt("adaptive_throttle_min_bps", 32000);
CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f); // http textures do use udp bandwidth setting
CannibalizeTextureRate = Util.Clamp<double>(CannibalizeTextureRate,0.0, 0.9); // CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f);
// CannibalizeTextureRate = Util.Clamp<double>(CannibalizeTextureRate,0.0, 0.9);
CannibalizeTextureRate = 0f;
} }
catch (Exception) { } catch (Exception) { }
} }

View File

@ -62,8 +62,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
protected const float m_minimumDripRate = 1500; protected const float m_minimumDripRate = 1500;
/// <summary>Time of the last drip, in system ticks</summary> /// <summary>Time of the last drip</summary>
protected Int32 m_lastDrip; protected double m_lastDrip;
/// <summary> /// <summary>
/// The number of bytes that can be sent at this moment. This is the /// The number of bytes that can be sent at this moment. This is the
@ -97,7 +97,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
protected float m_burst; protected float m_burst;
public virtual float MaxDripRate { get; set; } protected float m_maxDripRate = 0;
public virtual float MaxDripRate
{
get { return m_maxDripRate; }
set { m_maxDripRate = value; }
}
public float RequestedBurst public float RequestedBurst
{ {
@ -134,7 +139,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// the system tick interval (typically around 15-22ms)</remarks> /// the system tick interval (typically around 15-22ms)</remarks>
protected float m_dripRate; protected float m_dripRate;
public virtual float RequestedDripRate public float RequestedDripRate
{ {
get { return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); } get { return (m_dripRate == 0 ? m_totalDripRequest : m_dripRate); }
set { set {
@ -146,7 +151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
public virtual float DripRate public float DripRate
{ {
get { get {
float rate = Math.Min(RequestedDripRate,TotalDripRequest); float rate = Math.Min(RequestedDripRate,TotalDripRequest);
@ -166,10 +171,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary> /// </summary>
protected float m_totalDripRequest; protected float m_totalDripRequest;
public float TotalDripRequest public float TotalDripRequest
{ {
get { return m_totalDripRequest; } get { return m_totalDripRequest; }
set { m_totalDripRequest = value; } set { m_totalDripRequest = value; }
} }
#endregion Properties #endregion Properties
@ -193,9 +198,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Parent = parent; Parent = parent;
RequestedDripRate = dripRate; RequestedDripRate = dripRate;
RequestedBurst = MaxBurst; RequestedBurst = MaxBurst;
// TotalDripRequest = dripRate; // this will be overwritten when a child node registers m_lastDrip = Util.GetTimeStampMS() + 100000.0; // skip first drip
// MaxBurst = (Int64)((double)dripRate * m_quantumsPerBurst);
m_lastDrip = Util.EnvironmentTickCount() + 100000;
} }
#endregion Constructor #endregion Constructor
@ -210,7 +213,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected float DripRateModifier() protected float DripRateModifier()
{ {
float driprate = DripRate; float driprate = DripRate;
return driprate >= TotalDripRequest ? 1.0f : driprate / TotalDripRequest; return driprate >= TotalDripRequest ? 1.0f : (driprate / TotalDripRequest);
} }
/// <summary> /// <summary>
@ -313,14 +316,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return; return;
} }
Int32 now = Util.EnvironmentTickCount(); double now = Util.GetTimeStampMS();
Int32 deltaMS = now - m_lastDrip; double deltaMS = now - m_lastDrip;
m_lastDrip = now; m_lastDrip = now;
if (deltaMS <= 0) if (deltaMS <= 0)
return; return;
m_tokenCount += deltaMS * DripRate * m_timeScale; m_tokenCount += (float)deltaMS * DripRate * m_timeScale;
float burst = Burst; float burst = Burst;
if (m_tokenCount > burst) if (m_tokenCount > burst)
@ -346,7 +349,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// greater than this. // greater than this.
// </summary> // </summary>
protected float m_maxDripRate = 0;
public override float MaxDripRate public override float MaxDripRate
{ {
get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); } get { return (m_maxDripRate == 0 ? m_totalDripRequest : m_maxDripRate); }
@ -361,7 +363,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// <summary> // <summary>
// Adjust drip rate in response to network conditions. // Adjust drip rate in response to network conditions.
// </summary> // </summary>
public virtual float AdjustedDripRate public float AdjustedDripRate
{ {
get { return m_dripRate; } get { return m_dripRate; }
set set
@ -382,12 +384,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
m_enabled = enabled; m_enabled = enabled;
MaxDripRate = maxDripRate; m_maxDripRate = (maxDripRate == 0 ? m_totalDripRequest : Math.Max(maxDripRate, m_minimumFlow));
if (enabled) if (enabled)
AdjustedDripRate = m_maxDripRate * .5f; m_dripRate = m_maxDripRate * .5f;
else else
AdjustedDripRate = m_maxDripRate; m_dripRate = m_maxDripRate;
if (m_parent != null)
m_parent.RegisterRequest(this, m_dripRate);
} }
/// <summary> /// <summary>

View File

@ -74,6 +74,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Holds information about pending removals</summary> /// <summary>Holds information about pending removals</summary>
private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>(); private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>();
public void Clear()
{
m_packets.Clear();
m_pendingAdds = null;
m_pendingAcknowledgements = null;
m_pendingRemoves = null;
}
/// <summary> /// <summary>
/// Add an unacked packet to the collection /// Add an unacked packet to the collection
/// </summary> /// </summary>

View File

@ -255,7 +255,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
// check user level // check user level
if (avatar != null) if (avatar != null)
{ {
if (avatar.UserLevel < m_levelUpload) if (avatar.GodController.UserLevel < m_levelUpload)
{ {
remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
return; return;

View File

@ -57,13 +57,13 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
/// <summary>List of client methods to notify of results of decode</summary> /// <summary>List of client methods to notify of results of decode</summary>
private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>(); private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>();
/// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary> /// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary>
private IImprovedAssetCache m_cache; private IAssetCache m_cache;
private IImprovedAssetCache Cache private IAssetCache Cache
{ {
get get
{ {
if (m_cache == null) if (m_cache == null)
m_cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); m_cache = m_scene.RequestModuleInterface<IAssetCache>();
return m_cache; return m_cache;
} }

View File

@ -91,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Asset
/// </code> /// </code>
/// </example> /// </example>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CenomeMemoryAssetCache")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CenomeMemoryAssetCache")]
public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule public class CenomeMemoryAssetCache : IAssetCache, ISharedRegionModule
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Asset
expirationTime); expirationTime);
} }
#region IImprovedAssetCache Members #region IAssetCache Members
public bool Check(string id) public bool Check(string id)
{ {
@ -221,6 +221,11 @@ namespace OpenSim.Region.CoreModules.Asset
} }
public void CacheNegative(string id)
{
// We don't do negative caching
}
/// <summary> /// <summary>
/// Clear asset cache. /// Clear asset cache.
/// </summary> /// </summary>
@ -308,7 +313,7 @@ namespace OpenSim.Region.CoreModules.Asset
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{ {
if (m_enabled) if (m_enabled)
scene.RegisterModuleInterface<IImprovedAssetCache>(this); scene.RegisterModuleInterface<IAssetCache>(this);
} }
/// <summary> /// <summary>

View File

@ -40,7 +40,7 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Asset namespace OpenSim.Region.CoreModules.Asset
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CoreAssetCache")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CoreAssetCache")]
public class CoreAssetCache : ISharedRegionModule, IImprovedAssetCache public class CoreAssetCache : ISharedRegionModule, IAssetCache
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger( LogManager.GetLogger(
@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.Asset
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{ {
if (m_Enabled) if (m_Enabled)
scene.RegisterModuleInterface<IImprovedAssetCache>(this); scene.RegisterModuleInterface<IAssetCache>(this);
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -110,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Asset
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// IImprovedAssetCache // IAssetCache
// //
public bool Check(string id) public bool Check(string id)
{ {
@ -124,6 +124,11 @@ namespace OpenSim.Region.CoreModules.Asset
m_Cache.Store(asset.ID, asset); m_Cache.Store(asset.ID, asset);
} }
public void CacheNegative(string id)
{
// We don't do negative caching
}
public AssetBase Get(string id) public AssetBase Get(string id)
{ {
return (AssetBase)m_Cache.Get(id); return (AssetBase)m_Cache.Get(id);

View File

@ -55,13 +55,15 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Asset namespace OpenSim.Region.CoreModules.Asset
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FlotsamAssetCache")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FlotsamAssetCache")]
public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService public class FlotsamAssetCache : ISharedRegionModule, IAssetCache, IAssetService
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger( LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled; private bool m_Enabled;
private bool m_timerRunning;
private bool m_cleanupRunning;
private const string m_ModuleName = "FlotsamAssetCache"; private const string m_ModuleName = "FlotsamAssetCache";
private const string m_DefaultCacheDirectory = "./assetcache"; private const string m_DefaultCacheDirectory = "./assetcache";
@ -76,6 +78,7 @@ namespace OpenSim.Region.CoreModules.Asset
private static ulong m_RequestsForInprogress; private static ulong m_RequestsForInprogress;
private static ulong m_DiskHits; private static ulong m_DiskHits;
private static ulong m_MemoryHits; private static ulong m_MemoryHits;
private static ulong m_weakRefHits;
#if WAIT_ON_INPROGRESS_REQUESTS #if WAIT_ON_INPROGRESS_REQUESTS
private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>();
@ -89,12 +92,17 @@ namespace OpenSim.Region.CoreModules.Asset
private ExpiringCache<string, AssetBase> m_MemoryCache; private ExpiringCache<string, AssetBase> m_MemoryCache;
private bool m_MemoryCacheEnabled = false; private bool m_MemoryCacheEnabled = false;
private ExpiringCache<string, object> m_negativeCache;
private bool m_negativeCacheEnabled = true;
private bool m_negativeCacheSliding = false;
// Expiration is expressed in hours. // Expiration is expressed in hours.
private const double m_DefaultMemoryExpiration = 2; private double m_MemoryExpiration = 0.016;
private const double m_DefaultFileExpiration = 48; private const double m_DefaultFileExpiration = 48;
private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration); // Negative cache is in seconds
private int m_negativeExpiration = 120;
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration); private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166); private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0);
private static int m_CacheDirectoryTiers = 1; private static int m_CacheDirectoryTiers = 1;
private static int m_CacheDirectoryTierLen = 3; private static int m_CacheDirectoryTierLen = 3;
@ -104,6 +112,11 @@ namespace OpenSim.Region.CoreModules.Asset
private IAssetService m_AssetService; private IAssetService m_AssetService;
private List<Scene> m_Scenes = new List<Scene>(); private List<Scene> m_Scenes = new List<Scene>();
private object timerLock = new object();
private Dictionary<string,WeakReference> weakAssetReferences = new Dictionary<string, WeakReference>();
private object weakAssetReferencesLock = new object();
private bool m_updateFileTimeOnCacheHit = false;
public FlotsamAssetCache() public FlotsamAssetCache()
{ {
@ -132,6 +145,7 @@ namespace OpenSim.Region.CoreModules.Asset
if (name == Name) if (name == Name)
{ {
m_MemoryCache = new ExpiringCache<string, AssetBase>(); m_MemoryCache = new ExpiringCache<string, AssetBase>();
m_negativeCache = new ExpiringCache<string, object>();
m_Enabled = true; m_Enabled = true;
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name); m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} enabled", this.Name);
@ -148,7 +162,13 @@ namespace OpenSim.Region.CoreModules.Asset
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory); m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled); m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled);
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration)); m_MemoryExpiration = assetConfig.GetDouble("MemoryCacheTimeout", m_MemoryExpiration);
m_MemoryExpiration *= 3600.0; // config in hours to seconds
m_negativeCacheEnabled = assetConfig.GetBoolean("NegativeCacheEnabled", m_negativeCacheEnabled);
m_negativeExpiration = assetConfig.GetInt("NegativeCacheTimeout", m_negativeExpiration);
m_negativeCacheSliding = assetConfig.GetBoolean("NegativeCacheSliding", m_negativeCacheSliding);
m_updateFileTimeOnCacheHit = assetConfig.GetBoolean("UpdateFileTimeOnCacheHit", m_updateFileTimeOnCacheHit);
#if WAIT_ON_INPROGRESS_REQUESTS #if WAIT_ON_INPROGRESS_REQUESTS
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000); m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
@ -170,14 +190,6 @@ namespace OpenSim.Region.CoreModules.Asset
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory); m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
{
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
m_CacheCleanTimer.AutoReset = true;
m_CacheCleanTimer.Elapsed += CleanupExpiredFiles;
lock (m_CacheCleanTimer)
m_CacheCleanTimer.Start();
}
if (m_CacheDirectoryTiers < 1) if (m_CacheDirectoryTiers < 1)
{ {
@ -217,9 +229,8 @@ namespace OpenSim.Region.CoreModules.Asset
{ {
if (m_Enabled) if (m_Enabled)
{ {
scene.RegisterModuleInterface<IImprovedAssetCache>(this); scene.RegisterModuleInterface<IAssetCache>(this);
m_Scenes.Add(scene); m_Scenes.Add(scene);
} }
} }
@ -227,23 +238,61 @@ namespace OpenSim.Region.CoreModules.Asset
{ {
if (m_Enabled) if (m_Enabled)
{ {
scene.UnregisterModuleInterface<IImprovedAssetCache>(this); scene.UnregisterModuleInterface<IAssetCache>(this);
m_Scenes.Remove(scene); m_Scenes.Remove(scene);
lock(timerLock)
{
if(m_timerRunning && m_Scenes.Count <= 0)
{
m_timerRunning = false;
m_CacheCleanTimer.Stop();
m_CacheCleanTimer.Close();
}
}
} }
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
{ {
if (m_Enabled && m_AssetService == null) if (m_Enabled)
m_AssetService = scene.RequestModuleInterface<IAssetService>(); {
if(m_AssetService == null)
m_AssetService = scene.RequestModuleInterface<IAssetService>();
lock(timerLock)
{
if(!m_timerRunning)
{
if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
{
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
m_CacheCleanTimer.AutoReset = false;
m_CacheCleanTimer.Elapsed += CleanupExpiredFiles;
m_CacheCleanTimer.Start();
m_timerRunning = true;
}
}
}
if (m_MemoryCacheEnabled)
m_MemoryCache = new ExpiringCache<string, AssetBase>();
lock(weakAssetReferencesLock)
weakAssetReferences = new Dictionary<string, WeakReference>();
}
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// IImprovedAssetCache // IAssetCache
// //
private void UpdateWeakReference(string key, AssetBase asset)
{
WeakReference aref = new WeakReference(asset);
lock(weakAssetReferencesLock)
weakAssetReferences[key] = aref;
}
private void UpdateMemoryCache(string key, AssetBase asset) private void UpdateMemoryCache(string key, AssetBase asset)
{ {
// NOTE DO NOT USE SLIDEEXPIRE option on current libomv
m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration); m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
} }
@ -306,6 +355,7 @@ namespace OpenSim.Region.CoreModules.Asset
if (asset != null) if (asset != null)
{ {
//m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID); //m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID);
UpdateWeakReference(asset.ID, asset);
if (m_MemoryCacheEnabled) if (m_MemoryCacheEnabled)
UpdateMemoryCache(asset.ID, asset); UpdateMemoryCache(asset.ID, asset);
@ -315,6 +365,17 @@ namespace OpenSim.Region.CoreModules.Asset
} }
} }
public void CacheNegative(string id)
{
if (m_negativeCacheEnabled)
{
if (m_negativeCacheSliding)
m_negativeCache.AddOrUpdate(id, null, TimeSpan.FromSeconds(m_negativeExpiration));
else
m_negativeCache.AddOrUpdate(id, null, m_negativeExpiration);
}
}
/// <summary> /// <summary>
/// Updates the cached file with the current time. /// Updates the cached file with the current time.
/// </summary> /// </summary>
@ -333,6 +394,25 @@ namespace OpenSim.Region.CoreModules.Asset
} }
} }
private AssetBase GetFromWeakReference(string id)
{
AssetBase asset = null;
WeakReference aref;
lock(weakAssetReferencesLock)
{
if (weakAssetReferences.TryGetValue(id, out aref))
{
asset = aref.Target as AssetBase;
if(asset == null)
weakAssetReferences.Remove(id);
else
m_weakRefHits++;
}
}
return asset;
}
/// <summary> /// <summary>
/// Try to get an asset from the in-memory cache. /// Try to get an asset from the in-memory cache.
/// </summary> /// </summary>
@ -455,19 +535,42 @@ namespace OpenSim.Region.CoreModules.Asset
{ {
m_Requests++; m_Requests++;
AssetBase asset = null; object dummy;
if (m_negativeCache.TryGetValue(id, out dummy))
return null;
if (m_MemoryCacheEnabled) AssetBase asset = null;
asset = GetFromWeakReference(id);
if (asset != null && m_updateFileTimeOnCacheHit)
{
string filename = GetFileName(id);
UpdateFileLastAccessTime(filename);
}
if (m_MemoryCacheEnabled && asset == null)
{
asset = GetFromMemoryCache(id); asset = GetFromMemoryCache(id);
if(asset != null)
{
UpdateWeakReference(id,asset);
if (m_updateFileTimeOnCacheHit)
{
string filename = GetFileName(id);
UpdateFileLastAccessTime(filename);
}
}
}
if (asset == null && m_FileCacheEnabled) if (asset == null && m_FileCacheEnabled)
{ {
asset = GetFromFileCache(id); asset = GetFromFileCache(id);
if(asset != null)
if (m_MemoryCacheEnabled && asset != null) UpdateWeakReference(id,asset);
UpdateMemoryCache(id, asset);
} }
if (m_MemoryCacheEnabled && asset != null)
UpdateMemoryCache(id, asset);
if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
{ {
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit"); m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit");
@ -475,6 +578,12 @@ namespace OpenSim.Region.CoreModules.Asset
GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l));
} }
if(asset == null)
{
}
return asset; return asset;
} }
@ -511,6 +620,9 @@ namespace OpenSim.Region.CoreModules.Asset
if (m_MemoryCacheEnabled) if (m_MemoryCacheEnabled)
m_MemoryCache.Remove(id); m_MemoryCache.Remove(id);
lock(weakAssetReferencesLock)
weakAssetReferences.Remove(id);
} }
catch (Exception e) catch (Exception e)
{ {
@ -534,7 +646,12 @@ namespace OpenSim.Region.CoreModules.Asset
} }
if (m_MemoryCacheEnabled) if (m_MemoryCacheEnabled)
m_MemoryCache.Clear(); m_MemoryCache = new ExpiringCache<string, AssetBase>();
if (m_negativeCacheEnabled)
m_negativeCache = new ExpiringCache<string, object>();
lock(weakAssetReferencesLock)
weakAssetReferences = new Dictionary<string, WeakReference>();
} }
private void CleanupExpiredFiles(object source, ElapsedEventArgs e) private void CleanupExpiredFiles(object source, ElapsedEventArgs e)
@ -542,6 +659,12 @@ namespace OpenSim.Region.CoreModules.Asset
if (m_LogLevel >= 2) if (m_LogLevel >= 2)
m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration); m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Checking for expired files older then {0}.", m_FileExpiration);
lock(timerLock)
{
if(!m_timerRunning || m_cleanupRunning)
return;
m_cleanupRunning = true;
}
// Purge all files last accessed prior to this point // Purge all files last accessed prior to this point
DateTime purgeLine = DateTime.Now - m_FileExpiration; DateTime purgeLine = DateTime.Now - m_FileExpiration;
@ -554,6 +677,13 @@ namespace OpenSim.Region.CoreModules.Asset
{ {
CleanExpiredFiles(dir, purgeLine); CleanExpiredFiles(dir, purgeLine);
} }
lock(timerLock)
{
if(m_timerRunning)
m_CacheCleanTimer.Start();
m_cleanupRunning = false;
}
} }
/// <summary> /// <summary>
@ -789,9 +919,15 @@ namespace OpenSim.Region.CoreModules.Asset
s.ForEachSOG(delegate(SceneObjectGroup e) s.ForEachSOG(delegate(SceneObjectGroup e)
{ {
if(!m_timerRunning && !storeUncached)
return;
gatherer.AddForInspection(e); gatherer.AddForInspection(e);
gatherer.GatherAll(); gatherer.GatherAll();
if(!m_timerRunning && !storeUncached)
return;
foreach (UUID assetID in gatherer.GatheredUuids.Keys) foreach (UUID assetID in gatherer.GatheredUuids.Keys)
{ {
if (!assetsFound.ContainsKey(assetID)) if (!assetsFound.ContainsKey(assetID))
@ -801,6 +937,7 @@ namespace OpenSim.Region.CoreModules.Asset
if (File.Exists(filename)) if (File.Exists(filename))
{ {
UpdateFileLastAccessTime(filename); UpdateFileLastAccessTime(filename);
assetsFound[assetID] = true;
} }
else if (storeUncached) else if (storeUncached)
{ {
@ -820,7 +957,14 @@ namespace OpenSim.Region.CoreModules.Asset
} }
gatherer.GatheredUuids.Clear(); gatherer.GatheredUuids.Clear();
if(!m_timerRunning && !storeUncached)
return;
if(!storeUncached)
Thread.Sleep(50);
}); });
if(!m_timerRunning && !storeUncached)
break;
} }
return assetsFound.Count; return assetsFound.Count;
@ -864,22 +1008,35 @@ namespace OpenSim.Region.CoreModules.Asset
{ {
List<string> outputLines = new List<string>(); List<string> outputLines = new List<string>();
double fileHitRate = (double)m_DiskHits / m_Requests * 100.0; double invReq = 100.0 / m_Requests;
double weakHitRate = m_weakRefHits * invReq;
int weakEntries = weakAssetReferences.Count;
double fileHitRate = m_DiskHits * invReq;
double TotalHitRate = weakHitRate + fileHitRate;
outputLines.Add( outputLines.Add(
string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests)); string.Format("Total requests: {0}", m_Requests));
outputLines.Add(
string.Format("unCollected Hit Rate: {0}% ({1} entries)", weakHitRate.ToString("0.00"),weakEntries));
outputLines.Add(
string.Format("File Hit Rate: {0}%", fileHitRate.ToString("0.00")));
if (m_MemoryCacheEnabled) if (m_MemoryCacheEnabled)
{ {
double memHitRate = (double)m_MemoryHits / m_Requests * 100.0; double HitRate = m_MemoryHits * invReq;
outputLines.Add( outputLines.Add(
string.Format("Memory Hit Rate: {0}% for {1} requests", memHitRate.ToString("0.00"), m_Requests)); string.Format("Memory Hit Rate: {0}%", HitRate.ToString("0.00")));
TotalHitRate += HitRate;
} }
outputLines.Add(
string.Format("Total Hit Rate: {0}%", TotalHitRate.ToString("0.00")));
outputLines.Add( outputLines.Add(
string.Format( string.Format(
"Unnecessary requests due to requests for assets that are currently downloading: {0}", "Requests overlap during file writing: {0}", m_RequestsForInprogress));
m_RequestsForInprogress));
return outputLines; return outputLines;
} }
@ -978,11 +1135,42 @@ namespace OpenSim.Region.CoreModules.Asset
break; break;
case "assets": case "assets":
con.Output("Ensuring assets are cached for all scenes."); lock(timerLock)
{
if(m_cleanupRunning)
{
con.OutputFormat("FloatSam assets check already running");
return;
}
m_cleanupRunning = true;
}
con.Output("FloatSam Ensuring assets are cached for all scenes.");
WorkManager.RunInThread(delegate WorkManager.RunInThread(delegate
{ {
bool wasRunning= false;
lock(timerLock)
{
if(m_timerRunning)
{
m_CacheCleanTimer.Stop();
m_timerRunning = false;
wasRunning = true;
Thread.Sleep(100);
}
}
int assetReferenceTotal = TouchAllSceneAssets(true); int assetReferenceTotal = TouchAllSceneAssets(true);
GC.Collect();
lock(timerLock)
{
if(wasRunning)
{
m_CacheCleanTimer.Start();
m_timerRunning = true;
}
m_cleanupRunning = false;
}
con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal);
}, null, "TouchAllSceneAssets"); }, null, "TouchAllSceneAssets");

View File

@ -41,7 +41,7 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Asset namespace OpenSim.Region.CoreModules.Asset
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GlynnTuckerAssetCache")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GlynnTuckerAssetCache")]
public class GlynnTuckerAssetCache : ISharedRegionModule, IImprovedAssetCache public class GlynnTuckerAssetCache : ISharedRegionModule, IAssetCache
{ {
private static readonly ILog m_log = private static readonly ILog m_log =
LogManager.GetLogger( LogManager.GetLogger(
@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Asset
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{ {
if (m_Enabled) if (m_Enabled)
scene.RegisterModuleInterface<IImprovedAssetCache>(this); scene.RegisterModuleInterface<IAssetCache>(this);
} }
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
@ -112,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Asset
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// IImprovedAssetCache // IAssetCache
// //
public bool Check(string id) public bool Check(string id)
@ -126,6 +126,11 @@ namespace OpenSim.Region.CoreModules.Asset
m_Cache.AddOrUpdate(asset.ID, asset); m_Cache.AddOrUpdate(asset.ID, asset);
} }
public void CacheNegative(string id)
{
// We don't do negative caching
}
public AssetBase Get(string id) public AssetBase Get(string id)
{ {
Object asset = null; Object asset = null;

View File

@ -616,11 +616,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
} }
public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
{ {
return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null); return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
} }
public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc) public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)
{ {
if (!Enabled) if (!Enabled)
return null; return null;
@ -1118,7 +1118,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
SceneObjectGroup objatt; SceneObjectGroup objatt;
UUID rezGroupID = sp.ControllingClient.ActiveGroupId; UUID rezGroupID;
// This will fail if the user aborts login. sp will exist
// but ControllintClient will be null.
try
{
rezGroupID = sp.ControllingClient.ActiveGroupId;
}
catch
{
return null;
}
if (itemID != UUID.Zero) if (itemID != UUID.Zero)
objatt = m_invAccessModule.RezObject(sp.ControllingClient, objatt = m_invAccessModule.RezObject(sp.ControllingClient,

View File

@ -288,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
if (bakedTextures.Count == 0) if (bakedTextures.Count == 0)
return false; return false;
IImprovedAssetCache cache = sp.Scene.RequestModuleInterface<IImprovedAssetCache>(); IAssetCache cache = sp.Scene.RequestModuleInterface<IAssetCache>();
if(cache == null) if(cache == null)
return true; // no baked local caching so nothing to do return true; // no baked local caching so nothing to do
@ -364,7 +364,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return false; return false;
// npcs dont have baked cache // npcs dont have baked cache
if (((ScenePresence)sp).isNPC) if (((ScenePresence)sp).IsNPC)
return true; return true;
// uploaded baked textures will be in assets local cache // uploaded baked textures will be in assets local cache
@ -507,7 +507,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{ {
int hits = 0; int hits = 0;
if (((ScenePresence)sp).isNPC) if (((ScenePresence)sp).IsNPC)
return true; return true;
lock (m_setAppearanceLock) lock (m_setAppearanceLock)
@ -701,11 +701,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
{ {
if (((ScenePresence)sp).isNPC) if (((ScenePresence)sp).IsNPC)
return 0; return 0;
int texturesRebaked = 0; int texturesRebaked = 0;
// IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>(); // IAssetCache cache = m_scene.RequestModuleInterface<IAssetCache>();
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{ {

View File

@ -53,6 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
private UTF8Encoding enc = new UTF8Encoding(); private UTF8Encoding enc = new UTF8Encoding();
private string m_URL = String.Empty; private string m_URL = String.Empty;
private static XmlSerializer m_serializer = new XmlSerializer(typeof(AssetBase)); private static XmlSerializer m_serializer = new XmlSerializer(typeof(AssetBase));
private static bool m_enabled = false;
private static IServiceAuth m_Auth; private static IServiceAuth m_Auth;
@ -63,11 +64,19 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
return; return;
m_URL = config.GetString("URL", String.Empty); m_URL = config.GetString("URL", String.Empty);
if (m_URL == String.Empty)
return;
m_enabled = true;
m_Auth = ServiceAuth.Create(configSource, "XBakes"); m_Auth = ServiceAuth.Create(configSource, "XBakes");
} }
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
{ {
if (!m_enabled)
return;
// m_log.InfoFormat("[XBakes]: Enabled for region {0}", scene.RegionInfo.RegionName); // m_log.InfoFormat("[XBakes]: Enabled for region {0}", scene.RegionInfo.RegionName);
m_Scene = scene; m_Scene = scene;

View File

@ -55,9 +55,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
protected List<string> FreezeCache = new List<string>(); protected List<string> FreezeCache = new List<string>();
protected string m_adminPrefix = ""; protected string m_adminPrefix = "";
protected object m_syncy = new object(); protected object m_syncy = new object();
protected IConfig m_config; protected IConfig m_config;
#region ISharedRegionModule Members #region ISharedRegionModule Members
public virtual void Initialise(IConfigSource config) public virtual void Initialise(IConfigSource config)
{ {
@ -231,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
fromPos = avatar.AbsolutePosition; fromPos = avatar.AbsolutePosition;
fromName = avatar.Name; fromName = avatar.Name;
fromID = c.Sender.AgentId; fromID = c.Sender.AgentId;
if (avatar.GodLevel >= 200) if (avatar.IsViewerUIGod)
{ // let gods speak to outside or things may get confusing { // let gods speak to outside or things may get confusing
fromNamePrefix = m_adminPrefix; fromNamePrefix = m_adminPrefix;
checkParcelHide = false; checkParcelHide = false;
@ -307,7 +305,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
{ {
if (checkParcelHide) if (checkParcelHide)
{ {
if (sourceParcelID != Presencecheck.LandData.GlobalID && presence.GodLevel < 200) if (sourceParcelID != Presencecheck.LandData.GlobalID && !presence.IsViewerUIGod)
return; return;
} }
if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)

View File

@ -118,7 +118,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// If we're in god mode, we reverse the meaning. Offer // If we're in god mode, we reverse the meaning. Offer
// calling card becomes "Take a calling card" for that // calling card becomes "Take a calling card" for that
// person, no matter if they agree or not. // person, no matter if they agree or not.
if (sp.GodLevel >= 200) if (sp.IsViewerUIGod)
{ {
CreateCallingCard(client.AgentId, destID, UUID.Zero, true); CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
return; return;

View File

@ -369,6 +369,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client) public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
{ {
if (client == null)
return false;
UUID agentID = client.AgentId; UUID agentID = client.AgentId;
// Check if the online friends list is needed // Check if the online friends list is needed

View File

@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (avatar == null) if (avatar == null)
return; return;
if (avatar.UserLevel < m_levelHGFriends) if (avatar.GodController.UserLevel < m_levelHGFriends)
{ {
client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false); client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false);
return; return;
@ -337,7 +337,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (UUID.TryParse(friendID, out id)) if (UUID.TryParse(friendID, out id))
return base.FriendshipMessage(friendID); return base.FriendshipMessage(friendID);
return "Please confirm this friendship you made while you were away."; return "Please confirm this friendship you made while you where on another HG grid";
} }
protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
@ -456,6 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
// local grid users // local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local"); m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
DeletePreviousHGRelations(agentID, friendID);
base.StoreFriendships(agentID, friendID); base.StoreFriendships(agentID, friendID);
return; return;
} }
@ -624,6 +625,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
private void DeletePreviousHGRelations(UUID a1, UUID a2)
{
// Delete any previous friendship relations
FriendInfo[] finfos = null;
finfos = GetFriendsFromCache(a1);
if (finfos != null)
{
foreach (FriendInfo f in finfos)
{
if (f.TheirFlags == -1)
{
if (f.Friend.StartsWith(a2.ToString()))
{
FriendsService.Delete(a1, f.Friend);
// and also the converse
FriendsService.Delete(f.Friend, a1.ToString());
}
}
}
}
finfos = GetFriendsFromCache(a1);
if (finfos != null)
{
foreach (FriendInfo f in finfos)
{
if (f.TheirFlags == -1)
{
if (f.Friend.StartsWith(a1.ToString()))
{
FriendsService.Delete(a2, f.Friend);
// and also the converse
FriendsService.Delete(f.Friend, a2.ToString());
}
}
}
}
}
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
{ {
Boolean agentIsLocal = true; Boolean agentIsLocal = true;

View File

@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
if (god == null || god.ControllingClient.SessionId != godSessionID) if (god == null || god.ControllingClient.SessionId != godSessionID)
return String.Empty; return String.Empty;
KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason)); KickUser(godID, agentID, kickFlags, Util.StringToBytes1024(reason));
} }
else else
{ {
@ -162,59 +162,53 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
} }
public void RequestGodlikePowers( public void RequestGodlikePowers(
UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) UUID agentID, UUID sessionID, UUID token, bool godLike)
{ {
ScenePresence sp = m_scene.GetScenePresence(agentID); ScenePresence sp = m_scene.GetScenePresence(agentID);
if(sp == null || sp.IsDeleted || sp.IsNPC)
return;
if (sp != null) if (sessionID != sp.ControllingClient.SessionId)
{ return;
if (godLike == false)
{
sp.GrantGodlikePowers(agentID, sessionID, token, godLike);
return;
}
// First check that this is the sim owner sp.GrantGodlikePowers(token, godLike);
if (m_scene.Permissions.IsGod(agentID))
{ if (godLike && !sp.IsViewerUIGod && DialogModule != null)
// Next we check for spoofing..... DialogModule.SendAlertToUser(agentID, "Request for god powers denied");
UUID testSessionID = sp.ControllingClient.SessionId;
if (sessionID == testSessionID)
{
if (sessionID == controllingClient.SessionId)
{
//m_log.Info("godlike: " + godLike.ToString());
sp.GrantGodlikePowers(agentID, testSessionID, token, godLike);
}
}
}
else
{
if (DialogModule != null)
DialogModule.SendAlertToUser(agentID, "Request for god powers denied");
}
}
} }
/// <summary> /// <summary>
/// Kicks User specified from the simulator. This logs them off of the grid /// Kicks or freezes User specified from the simulator. This logs them off of the grid
/// If the client gets the UUID: 44e87126e7944ded05b37c42da3d5cdb it assumes
/// that you're kicking it even if the avatar's UUID isn't the UUID that the
/// agent is assigned
/// </summary> /// </summary>
/// <param name="godID">The person doing the kicking</param> /// <param name="godID">The person doing the kicking</param>
/// <param name="sessionID">The session of the person doing the kicking</param>
/// <param name="agentID">the person that is being kicked</param> /// <param name="agentID">the person that is being kicked</param>
/// <param name="kickflags">Tells what to do to the user</param> /// <param name="kickflags">Tells what to do to the user</param>
/// <param name="reason">The message to send to the user after it's been turned into a field</param> /// <param name="reason">The message to send to the user after it's been turned into a field</param>
public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason) public void KickUser(UUID godID, UUID agentID, uint kickflags, byte[] reason)
{ {
if (!m_scene.Permissions.IsGod(godID)) // assuming automatic god rights on this for fast griefing reaction
// this is also needed for kick via message
if(!m_scene.Permissions.IsGod(godID))
return; return;
ScenePresence sp = m_scene.GetScenePresence(agentID); int godlevel = 200;
// update level so higher gods can kick lower ones
ScenePresence god = m_scene.GetScenePresence(godID);
if(god != null && god.GodController.GodLevel > godlevel)
godlevel = god.GodController.GodLevel;
if (sp == null && agentID != ALL_AGENTS) if(agentID == ALL_AGENTS)
{
m_scene.ForEachRootScenePresence(delegate(ScenePresence p)
{
if (p.UUID != godID && godlevel > p.GodController.GodLevel)
doKickmodes(godID, p, kickflags, reason);
});
return;
}
ScenePresence sp = m_scene.GetScenePresence(agentID);
if (sp == null || sp.IsChildAgent)
{ {
IMessageTransferModule transferModule = IMessageTransferModule transferModule =
m_scene.RequestModuleInterface<IMessageTransferModule>(); m_scene.RequestModuleInterface<IMessageTransferModule>();
@ -230,48 +224,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
return; return;
} }
if (godlevel <= sp.GodController.GodLevel) // no god wars
return;
if(sp.UUID == godID)
return;
doKickmodes(godID, sp, kickflags, reason);
}
private void doKickmodes(UUID godID, ScenePresence sp, uint kickflags, byte[] reason)
{
switch (kickflags) switch (kickflags)
{ {
case 0: case 0:
if (sp != null)
{
KickPresence(sp, Utils.BytesToString(reason)); KickPresence(sp, Utils.BytesToString(reason));
} break;
else if (agentID == ALL_AGENTS) case 1:
{
m_scene.ForEachRootScenePresence(
delegate(ScenePresence p)
{
if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
KickPresence(p, Utils.BytesToString(reason));
}
);
}
break;
case 1:
if (sp != null)
{
sp.AllowMovement = false; sp.AllowMovement = false;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason)); m_dialogModule.SendAlertToUser(sp.UUID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Frozen"); m_dialogModule.SendAlertToUser(godID, "User Frozen");
} break;
break; case 2:
case 2:
if (sp != null)
{
sp.AllowMovement = true; sp.AllowMovement = true;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason)); m_dialogModule.SendAlertToUser(sp.UUID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Unfrozen"); m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
} break;
break; default:
default: break;
break;
} }
} }
private void KickPresence(ScenePresence sp, string reason) private void KickPresence(ScenePresence sp, string reason)
{ {
if (sp.IsChildAgent) if(sp.IsDeleted || sp.IsChildAgent)
return; return;
sp.ControllingClient.Kick(reason); sp.ControllingClient.Kick(reason);
sp.Scene.CloseAgent(sp.UUID, true); sp.Scene.CloseAgent(sp.UUID, true);
@ -286,7 +273,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
UUID godID = new UUID(msg.fromAgentID); UUID godID = new UUID(msg.fromAgentID);
uint kickMode = (uint)msg.binaryBucket[0]; uint kickMode = (uint)msg.binaryBucket[0];
KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason)); KickUser(godID, agentID, kickMode, Util.StringToBytes1024(reason));
} }
} }
} }

View File

@ -45,10 +45,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
private static readonly ILog m_log = LogManager.GetLogger( private static readonly ILog m_log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
protected Timer m_logTimer = new Timer(10000);
protected List<GridInstantMessage> m_logData = new List<GridInstantMessage>();
protected string m_restUrl;
/// <value> /// <value>
/// Is this module enabled? /// Is this module enabled?
/// </value> /// </value>
@ -68,12 +64,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
"InstantMessageModule", "InstantMessageModule") != "InstantMessageModule", "InstantMessageModule") !=
"InstantMessageModule") "InstantMessageModule")
return; return;
m_restUrl = config.Configs["Messaging"].GetString("LogURL", String.Empty);
} }
m_enabled = true; m_enabled = true;
m_logTimer.AutoReset = false;
m_logTimer.Elapsed += LogTimerElapsed;
} }
public virtual void AddRegion(Scene scene) public virtual void AddRegion(Scene scene)
@ -153,20 +146,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
} }
#endregion #endregion
/*
public virtual void OnViewerInstantMessage(IClientAPI client, GridInstantMessage im) public virtual void OnViewerInstantMessage(IClientAPI client, GridInstantMessage im)
{ {
im.fromAgentName = client.FirstName + " " + client.LastName; im.fromAgentName = client.FirstName + " " + client.LastName;
OnInstantMessage(client, im); OnInstantMessage(client, im);
} }
*/
public virtual void OnInstantMessage(IClientAPI client, GridInstantMessage im) public virtual void OnInstantMessage(IClientAPI client, GridInstantMessage im)
{ {
byte dialog = im.dialog; byte dialog = im.dialog;
if (client != null && dialog == (byte)InstantMessageDialog.MessageFromAgent)
LogInstantMesssage(im);
if (dialog != (byte)InstantMessageDialog.MessageFromAgent if (dialog != (byte)InstantMessageDialog.MessageFromAgent
&& dialog != (byte)InstantMessageDialog.StartTyping && dialog != (byte)InstantMessageDialog.StartTyping
&& dialog != (byte)InstantMessageDialog.StopTyping && dialog != (byte)InstantMessageDialog.StopTyping
@ -243,35 +233,5 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
// //
OnInstantMessage(null, msg); OnInstantMessage(null, msg);
} }
protected virtual void LogInstantMesssage(GridInstantMessage im)
{
if (m_logData.Count < 20)
{
// Restart the log write timer
m_logTimer.Stop();
}
if (!m_logTimer.Enabled)
m_logTimer.Start();
lock (m_logData)
{
m_logData.Add(im);
}
}
protected virtual void LogTimerElapsed(object source, ElapsedEventArgs e)
{
lock (m_logData)
{
if (m_restUrl != String.Empty && m_logData.Count > 0)
{
bool success = SynchronousRestObjectRequester.MakeRequest<List<GridInstantMessage>, bool>("POST", m_restUrl + "/LogMessages/", m_logData);
if (!success)
m_log.ErrorFormat("[INSTANT MESSAGE]: Failed to save log data");
}
m_logData.Clear();
}
}
} }
} }

View File

@ -565,8 +565,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return null; return null;
} }
return account;
/*
try try
{ {
string encpass = Util.Md5Hash(pass); string encpass = Util.Md5Hash(pass);
@ -587,7 +585,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e); m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e);
return null; return null;
} }
*/
} }
/// <summary> /// <summary>

View File

@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
GridInstantMessage m; GridInstantMessage m;
if (scene.Permissions.IsAdministrator(client.AgentId) && presence.GodLevel >= 200 && (!scene.Permissions.IsAdministrator(targetid))) if (scene.Permissions.IsAdministrator(client.AgentId) && presence.IsViewerUIGod && (!scene.Permissions.IsAdministrator(targetid)))
{ {
m = new GridInstantMessage(scene, client.AgentId, m = new GridInstantMessage(scene, client.AgentId,
client.FirstName+" "+client.LastName, targetid, client.FirstName+" "+client.LastName, targetid,

View File

@ -154,7 +154,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
name = account.FirstName + " " + account.LastName; name = account.FirstName + " " + account.LastName;
created = account.Created; created = account.Created;
} }
Byte[] charterMember = Utils.StringToBytes(name); Byte[] membershipType = Utils.StringToBytes(name);
profileUrl = "No profile data"; profileUrl = "No profile data";
aboutText = string.Empty; aboutText = string.Empty;
@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
remoteClient.SendAvatarProperties(avatarID, aboutText, remoteClient.SendAvatarProperties(avatarID, aboutText,
Util.ToDateTime(created).ToString( Util.ToDateTime(created).ToString(
"M/d/yyyy", CultureInfo.InvariantCulture), "M/d/yyyy", CultureInfo.InvariantCulture),
charterMember, firstLifeAboutText, membershipType, firstLifeAboutText,
(uint)(0 & 0xff), (uint)(0 & 0xff),
firstLifeImage, image, profileUrl, partner); firstLifeImage, image, profileUrl, partner);

View File

@ -455,6 +455,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
position = emergencyPos; position = emergencyPos;
} }
// Check Default Location (Also See ScenePresence.CompleteMovement)
if (position.X == 128f && position.Y == 128f && position.Z == 22.5f)
position = sp.Scene.RegionInfo.DefaultLandingPoint;
// TODO: Get proper AVG Height // TODO: Get proper AVG Height
float localHalfAVHeight = 0.8f; float localHalfAVHeight = 0.8f;
if (sp.Appearance != null) if (sp.Appearance != null)
@ -594,12 +598,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
uint x = 0, y = 0; uint x = 0, y = 0;
Util.RegionHandleToWorldLoc(regionHandle, out x, out y); Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
GridRegion reg;
// handle legacy HG. linked regions are mapped into y = 0 and have no size information
// so we can only search by base handle
if( y == 0)
{
reg = gridService.GetRegionByPosition(scope, (int)x, (int)y);
return reg;
}
// Compute the world location we're teleporting to // Compute the world location we're teleporting to
double worldX = (double)x + position.X; double worldX = (double)x + position.X;
double worldY = (double)y + position.Y; double worldY = (double)y + position.Y;
// Find the region that contains the position // Find the region that contains the position
GridRegion reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY); reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY);
if (reg != null) if (reg != null)
{ {
@ -762,6 +776,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
else if (sp.Flying) else if (sp.Flying)
teleportFlags |= (uint)TeleportFlags.IsFlying; teleportFlags |= (uint)TeleportFlags.IsFlying;
sp.IsInTransit = true;
if (DisableInterRegionTeleportCancellation) if (DisableInterRegionTeleportCancellation)
teleportFlags |= (uint)TeleportFlags.DisableCancel; teleportFlags |= (uint)TeleportFlags.DisableCancel;
@ -813,8 +829,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (OutSideViewRange) if (OutSideViewRange)
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} size {3},{4} needs new child agent for agent {5} from {6}",
finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); finalDestination.RegionName, newRegionX, newRegionY,newSizeX, newSizeY, sp.Name, Scene.Name);
//sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
#region IP Translation for NAT #region IP Translation for NAT
@ -864,7 +880,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
sp.ControllingClient.SendTeleportFailed(reason); sp.ControllingClient.SendTeleportFailed(reason);
sp.IsInTransit = false;
return; return;
} }
@ -875,7 +891,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
@ -885,7 +901,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
@ -946,7 +962,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent", "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
@ -963,7 +979,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
@ -972,6 +988,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
sp.IsInTransit = false;
return; return;
} }
@ -984,7 +1001,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
sp.IsInTransit = false;
return; return;
} }
@ -1021,7 +1038,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.", "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
@ -1030,7 +1047,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
sp.IsInTransit = false;
return; return;
} }
@ -1079,6 +1096,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Thread.Sleep(500); Thread.Sleep(500);
sp.Scene.CloseAgent(sp.UUID, false); sp.Scene.CloseAgent(sp.UUID, false);
} }
sp.IsInTransit = false;
} }
private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
@ -1101,7 +1119,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
sp.ControllingClient.SendTeleportFailed(reason); sp.ControllingClient.SendTeleportFailed(reason);
sp.IsInTransit = false;
return; return;
} }
@ -1113,6 +1131,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
@ -1123,6 +1142,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
@ -1175,7 +1195,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return; return;
} }
@ -1184,6 +1204,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name); sp.Name, finalDestination.RegionName, sp.Scene.Name);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
sp.IsInTransit = false;
return; return;
} }
@ -1241,6 +1262,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Reset(); sp.Reset();
} }
*/ */
sp.IsInTransit = false;
} }
/// <summary> /// <summary>
@ -1977,8 +1999,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
IClientAPI spClient = sp.ControllingClient; IClientAPI spClient = sp.ControllingClient;
if (!seeds.ContainsKey(currentRegionHandler)) // This will fail if the user aborts login
seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath); try
{
if (!seeds.ContainsKey(currentRegionHandler))
seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath);
}
catch
{
return;
}
AgentCircuitData currentAgentCircuit = AgentCircuitData currentAgentCircuit =
spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
@ -2055,6 +2085,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agentpos.Position = sp.AbsolutePosition; agentpos.Position = sp.AbsolutePosition;
agentpos.Velocity = sp.Velocity; agentpos.Velocity = sp.Velocity;
agentpos.RegionHandle = currentRegionHandler; agentpos.RegionHandle = currentRegionHandler;
//agentpos.GodLevel = sp.GodLevel;
agentpos.GodData = sp.GodController.State();
agentpos.Throttles = spClient.GetThrottlesPacked(1); agentpos.Throttles = spClient.GetThrottlesPacked(1);
// agentpos.ChildrenCapSeeds = seeds; // agentpos.ChildrenCapSeeds = seeds;
@ -2079,19 +2111,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
spScene.SimulationService.UpdateAgent(neighbour, agentpos); spScene.SimulationService.UpdateAgent(neighbour, agentpos);
} }
} }
catch (ArgumentOutOfRangeException)
{
m_log.ErrorFormat(
"[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).",
neighbour.ExternalHostName,
neighbour.RegionHandle,
neighbour.RegionLocX,
neighbour.RegionLocY);
}
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat( m_log.ErrorFormat(
"[ENTITY TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", "[ENTITY TRANSFER MODULE]: Error creating child agent at {0} ({1} ({2}, {3}). {4}",
neighbour.ExternalHostName, neighbour.ExternalHostName,
neighbour.RegionHandle, neighbour.RegionHandle,
neighbour.RegionLocX, neighbour.RegionLocX,
@ -2180,8 +2203,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#endregion // NotFoundLocationCache class #endregion // NotFoundLocationCache class
private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache();
// needed for old grid code
protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py) protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
{ {
// Since we don't know how big the regions could be, we have to search a very large area // Since we don't know how big the regions could be, we have to search a very large area
@ -2191,6 +2212,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Given a world position, get the GridRegion info for // Given a world position, get the GridRegion info for
// the region containing that point. // the region containing that point.
// for compatibility with old grids it does a scan to find large regions
// 0.9 grids to that
protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
double px, double py, uint pSizeHint) double px, double py, uint pSizeHint)
{ {
@ -2264,24 +2288,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <param name="a"></param> /// <param name="a"></param>
/// <param name="regionHandle"></param> /// <param name="regionHandle"></param>
/// <param name="endPoint"></param> /// <param name="endPoint"></param>
private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData agentCircData, GridRegion reg,
IPEndPoint endPoint, bool newAgent) IPEndPoint endPoint, bool newAgent)
{ {
if (newAgent) if (newAgent)
{ {
// we may already had lost this sp
if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened
return;
Scene scene = sp.Scene; Scene scene = sp.Scene;
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY); sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY);
string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(agentCircData.CapsPath);
string reason = String.Empty; string reason = String.Empty;
EntityTransferContext ctx = new EntityTransferContext(); EntityTransferContext ctx = new EntityTransferContext();
bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, a, (uint)TeleportFlags.Default, ctx, out reason); bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, agentCircData, (uint)TeleportFlags.Default, ctx, out reason);
if (regionAccepted) if (regionAccepted)
{ {
@ -2291,6 +2319,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_eqModule != null) if (m_eqModule != null)
{ {
#region IP Translation for NAT #region IP Translation for NAT
if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened
return;
IClientIPEndpoint ipepClient; IClientIPEndpoint ipepClient;
if (sp.ClientView.TryGet(out ipepClient)) if (sp.ClientView.TryGet(out ipepClient))
{ {

View File

@ -272,7 +272,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
{ {
// this user is going to another grid // this user is going to another grid
// for local users, check if HyperGrid teleport is allowed, based on user level // for local users, check if HyperGrid teleport is allowed, based on user level
if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.UserLevel < m_levelHGTeleport) if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.GodController.UserLevel < m_levelHGTeleport)
{ {
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
reason = "Hypergrid teleport not allowed"; reason = "Hypergrid teleport not allowed";

View File

@ -322,7 +322,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
{ {
m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); //m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
//if (fromTaskID.Equals(UUID.Zero)) //if (fromTaskID.Equals(UUID.Zero))
//{ //{

View File

@ -532,17 +532,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
} }
else else
{ {
AddPermissions(item, objlist[0], objlist, remoteClient);
item.CreationDate = Util.UnixTimeSinceEpoch(); item.CreationDate = Util.UnixTimeSinceEpoch();
item.Description = asset.Description; item.Description = asset.Description;
item.Name = asset.Name; item.Name = asset.Name;
item.AssetType = asset.Type; item.AssetType = asset.Type;
//preserve perms on return
if(DeRezAction.Return == action)
AddPermissions(item, objlist[0], objlist, null);
else
AddPermissions(item, objlist[0], objlist, remoteClient);
m_Scene.AddInventoryItem(item); m_Scene.AddInventoryItem(item);
if (remoteClient != null && item.Owner == remoteClient.AgentId) if (remoteClient != null && item.Owner == remoteClient.AgentId)
@ -599,15 +595,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
} }
effectivePerms |= (uint)PermissionMask.Move; effectivePerms |= (uint)PermissionMask.Move;
//PermissionsUtil.LogPermissions(item.Name, "Before AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
{ {
// Changing ownership, so apply the "Next Owner" permissions to all of the
// inventory item's permissions.
uint perms = effectivePerms; uint perms = effectivePerms;
PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref perms); uint nextPerms = (perms & 7) << 13;
if ((nextPerms & (uint)PermissionMask.Copy) == 0)
perms &= ~(uint)PermissionMask.Copy;
if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
perms &= ~(uint)PermissionMask.Transfer;
if ((nextPerms & (uint)PermissionMask.Modify) == 0)
perms &= ~(uint)PermissionMask.Modify;
item.BasePermissions = perms & so.RootPart.NextOwnerMask; item.BasePermissions = perms & so.RootPart.NextOwnerMask;
item.CurrentPermissions = item.BasePermissions; item.CurrentPermissions = item.BasePermissions;
@ -620,13 +617,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
} }
else else
{ {
// Not changing ownership.
// In this case we apply the permissions in the object's items ONLY to the inventory
// item's "Next Owner" permissions, but NOT to its "Current", "Base", etc. permissions.
// E.g., if the object contains a No-Transfer item then the item's "Next Owner"
// permissions are also No-Transfer.
PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref allObjectsNextOwnerPerms);
item.BasePermissions = effectivePerms; item.BasePermissions = effectivePerms;
item.CurrentPermissions = effectivePerms; item.CurrentPermissions = effectivePerms;
item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms; item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms;
@ -642,8 +632,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
7); // Preserve folded permissions 7); // Preserve folded permissions
} }
//PermissionsUtil.LogPermissions(item.Name, "After AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
return item; return item;
} }
@ -981,6 +969,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
part.LastOwnerID = part.OwnerID; part.LastOwnerID = part.OwnerID;
part.OwnerID = remoteClient.AgentId; part.OwnerID = remoteClient.AgentId;
part.RezzerID = remoteClient.AgentId;
} }
} }
@ -1150,7 +1139,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
part.LastOwnerID = part.OwnerID; part.LastOwnerID = part.OwnerID;
part.OwnerID = item.Owner; part.OwnerID = item.Owner;
part.RezzerID = item.Owner;
part.Inventory.ChangeInventoryOwner(item.Owner); part.Inventory.ChangeInventoryOwner(item.Owner);
// This applies the base mask from the item as the next
// permissions for the object. This is correct because the
// giver's base mask was masked by the giver's next owner
// mask, so the base mask equals the original next owner mask.
part.NextOwnerMask = item.BasePermissions;
} }
so.ApplyNextOwnerPermissions(); so.ApplyNextOwnerPermissions();
@ -1162,10 +1158,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{ {
if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
{ {
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
part.EveryoneMask = item.EveryOnePermissions & part.BaseMask; part.NextOwnerMask = item.NextPermissions & part.BaseMask;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
part.NextOwnerMask = item.NextPermissions & part.BaseMask;
} }
} }
} }

View File

@ -48,31 +48,16 @@ namespace OpenSim.Region.CoreModules.Framework
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private readonly List<Scene> m_scenes = new List<Scene>(); private readonly List<Scene> m_scenes = new List<Scene>();
private System.Timers.Timer m_timer = new System.Timers.Timer(); private JobEngine m_processorJobEngine;
private Queue<Action> m_RequestQueue = new Queue<Action>();
private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>();
private int m_Interval;
#region ISharedRegionModule #region ISharedRegionModule
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000); m_processorJobEngine = new JobEngine(
"ServiceThrottle","ServiceThrottle");
m_timer = new System.Timers.Timer(); m_processorJobEngine.RequestProcessTimeoutOnStop = 31000; // many webrequests have 30s expire
m_timer.AutoReset = false; m_processorJobEngine.Start();
m_timer.Enabled = true;
m_timer.Interval = 15000; // 15 secs at first
m_timer.Elapsed += ProcessQueue;
m_timer.Start();
//WorkManager.StartThread(
// ProcessQueue,
// "GridServiceRequestThread",
// ThreadPriority.BelowNormal,
// true,
// false);
} }
public void AddRegion(Scene scene) public void AddRegion(Scene scene)
@ -82,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework
m_scenes.Add(scene); m_scenes.Add(scene);
scene.RegisterModuleInterface<IServiceThrottleModule>(this); scene.RegisterModuleInterface<IServiceThrottleModule>(this);
scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
} }
} }
@ -105,6 +89,7 @@ namespace OpenSim.Region.CoreModules.Framework
public void Close() public void Close()
{ {
m_processorJobEngine.Stop();
} }
public string Name public string Name
@ -126,38 +111,24 @@ namespace OpenSim.Region.CoreModules.Framework
client.OnRegionHandleRequest += OnRegionHandleRequest; client.OnRegionHandleRequest += OnRegionHandleRequest;
} }
void OnMakeRootAgent(ScenePresence obj)
{
lock (m_timer)
{
if (!m_timer.Enabled)
{
m_timer.Interval = m_Interval;
m_timer.Enabled = true;
m_timer.Start();
}
}
}
public void OnRegionHandleRequest(IClientAPI client, UUID regionID) public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
{ {
//m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID); //m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
ulong handle = 0;
if (IsLocalRegionHandle(regionID, out handle))
{
client.SendRegionHandle(regionID, handle);
return;
}
Action action = delegate Action action = delegate
{ {
if(!client.IsActive)
return;
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID); GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID);
if(!client.IsActive)
return;
if (r != null && r.RegionHandle != 0) if (r != null && r.RegionHandle != 0)
client.SendRegionHandle(regionID, r.RegionHandle); client.SendRegionHandle(regionID, r.RegionHandle);
}; };
Enqueue("region", regionID.ToString(), action); m_processorJobEngine.QueueJob("regionHandle", action, regionID.ToString());
} }
#endregion Events #endregion Events
@ -166,91 +137,10 @@ namespace OpenSim.Region.CoreModules.Framework
public void Enqueue(string category, string itemid, Action continuation) public void Enqueue(string category, string itemid, Action continuation)
{ {
lock (m_RequestQueue) m_processorJobEngine.QueueJob(category, continuation, itemid);
{
if (m_Pending.ContainsKey(category))
{
if (m_Pending[category].Contains(itemid))
// Don't enqueue, it's already pending
return;
}
else
m_Pending.Add(category, new List<string>());
m_Pending[category].Add(itemid);
m_RequestQueue.Enqueue(delegate
{
lock (m_RequestQueue)
m_Pending[category].Remove(itemid);
continuation();
});
}
} }
#endregion IServiceThrottleModule #endregion IServiceThrottleModule
#region Process Continuation Queue
private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e)
{
//m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count);
while (m_RequestQueue.Count > 0)
{
Action continuation = null;
lock (m_RequestQueue)
continuation = m_RequestQueue.Dequeue();
if (continuation != null)
continuation();
}
if (AreThereRootAgents())
{
lock (m_timer)
{
m_timer.Interval = 1000; // 1 sec
m_timer.Enabled = true;
m_timer.Start();
}
}
else
lock (m_timer)
m_timer.Enabled = false;
}
#endregion Process Continuation Queue
#region Misc
private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
{
regionHandle = 0;
foreach (Scene s in m_scenes)
if (s.RegionInfo.RegionID == regionID)
{
regionHandle = s.RegionInfo.RegionHandle;
return true;
}
return false;
}
private bool AreThereRootAgents()
{
foreach (Scene s in m_scenes)
{
foreach (ScenePresence sp in s.GetScenePresences())
if (!sp.IsChildAgent)
return true;
}
return false;
}
#endregion Misc
} }
} }

View File

@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
} }
// Not found in cache, queue continuation // Not found in cache, queue continuation
m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate m_ServiceThrottle.Enqueue("uuidname", uuid.ToString(), delegate
{ {
//m_log.DebugFormat("[YYY]: Name request {0}", uuid); //m_log.DebugFormat("[YYY]: Name request {0}", uuid);
@ -216,9 +216,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
// So to avoid clients // So to avoid clients
// (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will
// instead drop the request entirely. // instead drop the request entirely.
if(!client.IsActive)
return;
if (GetUser(uuid, out user)) if (GetUser(uuid, out user))
{ {
client.SendNameReply(uuid, user.FirstName, user.LastName); if(client.IsActive)
client.SendNameReply(uuid, user.FirstName, user.LastName);
} }
// else // else
// m_log.DebugFormat( // m_log.DebugFormat(
@ -802,7 +805,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return !userdata.IsUnknownUser; return !userdata.IsUnknownUser;
} }
public virtual void AddUser(UUID uuid, string first, string last) public virtual void AddUser(UUID uuid, string first, string last, bool isNPC = false)
{ {
lock(m_UserCache) lock(m_UserCache)
{ {
@ -813,7 +816,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
user.FirstName = first; user.FirstName = first;
user.LastName = last; user.LastName = last;
user.IsUnknownUser = false; user.IsUnknownUser = false;
user.HasGridUserTried = false; user.HasGridUserTried = isNPC;
m_UserCache.Add(uuid, user); m_UserCache.Add(uuid, user);
} }
} }

View File

@ -131,7 +131,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
uint rx = 0, ry = 0; uint rx = 0, ry = 0;
Util.RegionHandleToWorldLoc(regionHandle, out rx, out ry); Util.RegionHandleToWorldLoc(regionHandle, out rx, out ry);
rx += x;
ry += y;
foreach (Scene s in m_Scenes) foreach (Scene s in m_Scenes)
{ {
uint t = s.RegionInfo.WorldLocX; uint t = s.RegionInfo.WorldLocX;
@ -147,6 +148,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
if( ry < t) if( ry < t)
{ {
// m_log.Debug("[LAND IN CONNECTOR]: Found region to GetLandData from"); // m_log.Debug("[LAND IN CONNECTOR]: Found region to GetLandData from");
x = rx - s.RegionInfo.WorldLocX;
y = ry - s.RegionInfo.WorldLocY;
regionAccess = s.RegionInfo.AccessLevel; regionAccess = s.RegionInfo.AccessLevel;
return s.GetLandData(x, y); return s.GetLandData(x, y);
} }

View File

@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.AgentPreferences
get { return "RemoteAgentPreferencesServicesConnector"; } get { return "RemoteAgentPreferencesServicesConnector"; }
} }
public override void Initialise(IConfigSource source) public new void Initialise(IConfigSource source)
{ {
IConfig moduleConfig = source.Configs["Modules"]; IConfig moduleConfig = source.Configs["Modules"];
if (moduleConfig != null) if (moduleConfig != null)

View File

@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
LogManager.GetLogger( LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private IImprovedAssetCache m_Cache = null; private IAssetCache m_Cache = null;
private IAssetService m_GridService; private IAssetService m_GridService;
private IAssetService m_HGService; private IAssetService m_HGService;
@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
if (m_Cache == null) if (m_Cache == null)
{ {
m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); m_Cache = scene.RequestModuleInterface<IAssetCache>();
if (!(m_Cache is ISharedRegionModule)) if (!(m_Cache is ISharedRegionModule))
m_Cache = null; m_Cache = null;

View File

@ -44,7 +44,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IImprovedAssetCache m_Cache = null; private IAssetCache m_Cache = null;
private IAssetService m_AssetService; private IAssetService m_AssetService;
@ -128,7 +128,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
if (m_Cache == null) if (m_Cache == null)
{ {
m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); m_Cache = scene.RequestModuleInterface<IAssetCache>();
if (!(m_Cache is ISharedRegionModule)) if (!(m_Cache is ISharedRegionModule))
m_Cache = null; m_Cache = null;

View File

@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false; private bool m_Enabled = false;
private IImprovedAssetCache m_Cache; private IAssetCache m_Cache;
public Type ReplaceableInterface public Type ReplaceableInterface
{ {
@ -111,7 +111,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
if (m_Cache == null) if (m_Cache == null)
{ {
m_Cache = scene.RequestModuleInterface<IImprovedAssetCache>(); m_Cache = scene.RequestModuleInterface<IAssetCache>();
// Since we are a shared module and scene data is not // Since we are a shared module and scene data is not
// available for every method, the cache must be shared, too // available for every method, the cache must be shared, too

View File

@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false; private bool m_Enabled = false;
private string m_ThisGatekeeper = string.Empty;
private IGridService m_LocalGridService; private IGridService m_LocalGridService;
private IGridService m_RemoteGridService; private IGridService m_RemoteGridService;
@ -118,13 +119,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
m_LocalGridService = new LocalGridServicesConnector(source, m_RegionInfoCache); m_LocalGridService = new LocalGridServicesConnector(source, m_RegionInfoCache);
if (m_LocalGridService == null) if (m_LocalGridService == null)
{ {
m_log.Error("[REMOTE GRID CONNECTOR]: failed to loar local connector"); m_log.Error("[REMOTE GRID CONNECTOR]: failed to load local connector");
return false; return false;
} }
if(m_RegionInfoCache == null) if(m_RegionInfoCache == null)
m_RegionInfoCache = new RegionInfoCache(); m_RegionInfoCache = new RegionInfoCache();
m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty);
// Legacy. Remove soon!
m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", m_ThisGatekeeper);
Util.checkServiceURI(m_ThisGatekeeper, out m_ThisGatekeeper);
return true; return true;
} }
@ -227,12 +235,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
return rinfo; return rinfo;
} }
public GridRegion GetRegionByName(UUID scopeID, string regionName) public GridRegion GetRegionByName(UUID scopeID, string name)
{ {
GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, regionName); GridRegion rinfo = m_LocalGridService.GetRegionByName(scopeID, name);
if (rinfo != null) if (rinfo != null)
return rinfo; return rinfo;
// HG urls should not get here, strip them
// side effect is that local regions with same name as HG may also be found
// this mb good or bad
string regionName = name;
if(name.Contains("."))
{
if(string.IsNullOrWhiteSpace(m_ThisGatekeeper))
return rinfo; // no HG
string regionURI = "";
if(!Util.buildHGRegionURI(name, out regionURI, out regionName) || string.IsNullOrWhiteSpace(regionName))
return rinfo; // invalid
if(m_ThisGatekeeper != regionURI)
return rinfo; // not local grid
}
rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName); rinfo = m_RemoteGridService.GetRegionByName(scopeID, regionName);
m_RegionInfoCache.Cache(scopeID, rinfo); m_RegionInfoCache.Cache(scopeID, rinfo);
return rinfo; return rinfo;
@ -242,7 +266,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{ {
List<GridRegion> rinfo = m_LocalGridService.GetRegionsByName(scopeID, name, maxNumber); List<GridRegion> rinfo = m_LocalGridService.GetRegionsByName(scopeID, name, maxNumber);
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetRegionsByName {0} found {1} regions", name, rinfo.Count); //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetRegionsByName {0} found {1} regions", name, rinfo.Count);
List<GridRegion> grinfo = m_RemoteGridService.GetRegionsByName(scopeID, name, maxNumber);
// HG urls should not get here, strip them
// side effect is that local regions with same name as HG may also be found
// this mb good or bad
string regionName = name;
if(name.Contains("."))
{
if(string.IsNullOrWhiteSpace(m_ThisGatekeeper))
return rinfo; // no HG
string regionURI = "";
if(!Util.buildHGRegionURI(name, out regionURI, out regionName) || string.IsNullOrWhiteSpace(regionName))
return rinfo; // invalid
if(m_ThisGatekeeper != regionURI)
return rinfo; // not local grid
}
List<GridRegion> grinfo = m_RemoteGridService.GetRegionsByName(scopeID, regionName, maxNumber);
if (grinfo != null) if (grinfo != null)
{ {

View File

@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
public void OnMakeRootAgent(ScenePresence sp) public void OnMakeRootAgent(ScenePresence sp)
{ {
if (sp.isNPC) if (sp.IsNPC)
return; return;
if(sp.gotCrossUpdate) if(sp.gotCrossUpdate)

View File

@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
public void OnMakeRootAgent(ScenePresence sp) public void OnMakeRootAgent(ScenePresence sp)
{ {
if (sp.isNPC) if (sp.IsNPC)
return; return;
if(sp.gotCrossUpdate) if(sp.gotCrossUpdate)

View File

@ -154,14 +154,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
bool inCache = false; bool inCache = false;
UserAccount account; UserAccount account;
lock(m_Cache) account = m_Cache.Get(userID, out inCache);
account = m_Cache.Get(userID, out inCache);
if (inCache) if (inCache)
return account; return account;
account = UserAccountService.GetUserAccount(scopeID, userID); account = UserAccountService.GetUserAccount(scopeID, userID);
lock(m_Cache) m_Cache.Cache(userID, account);
m_Cache.Cache(userID, account);
return account; return account;
} }
@ -170,15 +168,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
bool inCache = false; bool inCache = false;
UserAccount account; UserAccount account;
lock(m_Cache) account = m_Cache.Get(firstName + " " + lastName, out inCache);
account = m_Cache.Get(firstName + " " + lastName, out inCache);
if (inCache) if (inCache)
return account; return account;
account = UserAccountService.GetUserAccount(scopeID, firstName, lastName); account = UserAccountService.GetUserAccount(scopeID, firstName, lastName);
if (account != null) if (account != null)
lock(m_Cache) m_Cache.Cache(account.PrincipalID, account);
m_Cache.Cache(account.PrincipalID, account);
return account; return account;
} }
@ -201,8 +197,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
if(UUID.TryParse(id, out uuid)) if(UUID.TryParse(id, out uuid))
{ {
lock(m_Cache) account = m_Cache.Get(uuid, out inCache);
account = m_Cache.Get(uuid, out inCache);
if (inCache) if (inCache)
ret.Add(account); ret.Add(account);
else else
@ -216,12 +211,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
List<UserAccount> ext = UserAccountService.GetUserAccounts(scopeID, missing); List<UserAccount> ext = UserAccountService.GetUserAccounts(scopeID, missing);
if(ext != null && ext.Count > 0) if(ext != null && ext.Count > 0)
{ {
ret.AddRange(ext);
foreach(UserAccount acc in ext) foreach(UserAccount acc in ext)
{ {
if(acc != null) if(acc != null)
lock(m_Cache) {
m_Cache.Cache(acc.PrincipalID, acc); ret.Add(acc);
m_Cache.Cache(acc.PrincipalID, acc);
}
} }
} }
return ret; return ret;

View File

@ -128,8 +128,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
// flags, title, etc. And country, don't forget country! // flags, title, etc. And country, don't forget country!
private void OnNewClient(IClientAPI client) private void OnNewClient(IClientAPI client)
{ {
lock(m_Cache) m_Cache.Remove(client.Name);
m_Cache.Remove(client.Name);
} }
#region Overwritten methods from IUserAccountService #region Overwritten methods from IUserAccountService
@ -138,15 +137,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
bool inCache = false; bool inCache = false;
UserAccount account; UserAccount account;
lock(m_Cache) account = m_Cache.Get(userID, out inCache);
account = m_Cache.Get(userID, out inCache);
if (inCache) if (inCache)
return account; return account;
account = base.GetUserAccount(scopeID, userID); account = base.GetUserAccount(scopeID, userID);
lock(m_Cache) m_Cache.Cache(userID, account);
if(account != null)
m_Cache.Cache(userID, account);
return account; return account;
} }
@ -155,15 +151,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
bool inCache = false; bool inCache = false;
UserAccount account; UserAccount account;
lock(m_Cache) account = m_Cache.Get(firstName + " " + lastName, out inCache);
account = m_Cache.Get(firstName + " " + lastName, out inCache);
if (inCache) if (inCache)
return account; return account;
account = base.GetUserAccount(scopeID, firstName, lastName); account = base.GetUserAccount(scopeID, firstName, lastName);
if (account != null) if (account != null)
lock(m_Cache) m_Cache.Cache(account.PrincipalID, account);
m_Cache.Cache(account.PrincipalID, account);
return account; return account;
} }
@ -181,8 +175,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
if(UUID.TryParse(id, out uuid)) if(UUID.TryParse(id, out uuid))
{ {
lock(m_Cache) account = m_Cache.Get(uuid, out inCache);
account = m_Cache.Get(uuid, out inCache);
if (inCache) if (inCache)
accs.Add(account); accs.Add(account);
else else
@ -195,16 +188,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
List<UserAccount> ext = base.GetUserAccounts(scopeID, missing); List<UserAccount> ext = base.GetUserAccounts(scopeID, missing);
if(ext != null && ext.Count >0 ) if(ext != null && ext.Count >0 )
{ {
accs.AddRange(ext);
foreach(UserAccount acc in ext) foreach(UserAccount acc in ext)
{ {
if(acc != null) if(acc != null)
lock(m_Cache) {
m_Cache.Cache(acc.PrincipalID, acc); accs.Add(acc);
m_Cache.Cache(acc.PrincipalID, acc);
}
} }
} }
} }
return accs; return accs;
} }

View File

@ -36,7 +36,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
public class UserAccountCache : IUserAccountCacheModule public class UserAccountCache : IUserAccountCacheModule
{ {
private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours! private const double CACHE_ALIEN_EXPIRATION_SECONDS = 172800; // 48 hours
private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour!
private const double CACHE_NULL_EXPIRATION_SECONDS = 600; // 10minutes
// private static readonly ILog m_log = // private static readonly ILog m_log =
// LogManager.GetLogger( // LogManager.GetLogger(
@ -44,6 +46,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
private ExpiringCache<UUID, UserAccount> m_UUIDCache; private ExpiringCache<UUID, UserAccount> m_UUIDCache;
private ExpiringCache<string, UUID> m_NameCache; private ExpiringCache<string, UUID> m_NameCache;
private object accessLock = new object();
public UserAccountCache() public UserAccountCache()
{ {
@ -54,60 +57,95 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
public void Cache(UUID userID, UserAccount account) public void Cache(UUID userID, UserAccount account)
{ {
// Cache even null accounts // Cache even null accounts
m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS); lock(accessLock)
if (account != null) {
m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_EXPIRATION_SECONDS); if (account == null)
m_UUIDCache.AddOrUpdate(userID, null, CACHE_NULL_EXPIRATION_SECONDS);
else if(account.LocalToGrid)
{
m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS);
m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_EXPIRATION_SECONDS);
}
else
{
m_UUIDCache.AddOrUpdate(userID, account, CACHE_ALIEN_EXPIRATION_SECONDS);
m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_ALIEN_EXPIRATION_SECONDS);
}
//m_log.DebugFormat("[USER CACHE]: cached user {0}", userID); //m_log.DebugFormat("[USER CACHE]: cached user {0}", userID);
}
} }
public void Invalidate(UUID userID)
{
m_UUIDCache.Remove(userID);
}
public UserAccount Get(UUID userID, out bool inCache) public UserAccount Get(UUID userID, out bool inCache)
{ {
UserAccount account = null; UserAccount account = null;
inCache = false; inCache = false;
if (m_UUIDCache.TryGetValue(userID, out account)) lock(accessLock)
{ {
//m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName); if (m_UUIDCache.TryGetValue(userID, out account))
inCache = true; {
return account; //m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName);
inCache = true;
return account;
}
} }
return null; return null;
} }
public UserAccount Get(string name, out bool inCache) public UserAccount Get(string name, out bool inCache)
{ {
inCache = false; inCache = false;
if (!m_NameCache.Contains(name)) lock(accessLock)
return null; {
if (!m_NameCache.Contains(name))
return null;
UserAccount account = null; UserAccount account = null;
UUID uuid = UUID.Zero; UUID uuid = UUID.Zero;
if (m_NameCache.TryGetValue(name, out uuid)) if (m_NameCache.TryGetValue(name, out uuid))
if (m_UUIDCache.TryGetValue(uuid, out account))
{ {
inCache = true; if (m_UUIDCache.TryGetValue(uuid, out account))
return account; {
inCache = true;
return account;
}
} }
}
return null; return null;
} }
public void Invalidate(UUID userID)
{
m_UUIDCache.Remove(userID);
}
public void Remove(UUID id)
{
lock(accessLock)
{
if (!m_UUIDCache.Contains(id))
return;
UserAccount account = null;
if (m_UUIDCache.TryGetValue(id, out account) && account != null)
m_NameCache.Remove(account.Name);
m_UUIDCache.Remove(id);
}
}
public void Remove(string name) public void Remove(string name)
{ {
if (!m_NameCache.Contains(name)) lock(accessLock)
return;
UUID uuid = UUID.Zero;
if (m_NameCache.TryGetValue(name, out uuid))
{ {
m_NameCache.Remove(name); if (!m_NameCache.Contains(name))
m_UUIDCache.Remove(uuid); return;
UUID uuid = UUID.Zero;
if (m_NameCache.TryGetValue(name, out uuid))
{
m_NameCache.Remove(name);
m_UUIDCache.Remove(uuid);
}
} }
} }
} }

View File

@ -45,17 +45,22 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected XEstateModule m_EstateModule; protected EstateModule m_EstateModule;
private string token;
uint port = 0;
public EstateConnector(XEstateModule module) public EstateConnector(EstateModule module, string _token, uint _port)
{ {
m_EstateModule = module; m_EstateModule = module;
token = _token;
port = _port;
} }
public void SendTeleportHomeOneUser(uint EstateID, UUID PreyID) public void SendTeleportHomeOneUser(uint EstateID, UUID PreyID)
{ {
Dictionary<string, object> sendData = new Dictionary<string, object>(); Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "teleport_home_one_user"; sendData["METHOD"] = "teleport_home_one_user";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.ToString(); sendData["EstateID"] = EstateID.ToString();
sendData["PreyID"] = PreyID.ToString(); sendData["PreyID"] = PreyID.ToString();
@ -67,6 +72,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
Dictionary<string, object> sendData = new Dictionary<string, object>(); Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "teleport_home_all_users"; sendData["METHOD"] = "teleport_home_all_users";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.ToString(); sendData["EstateID"] = EstateID.ToString();
@ -77,6 +83,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
Dictionary<string, object> sendData = new Dictionary<string, object>(); Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "update_covenant"; sendData["METHOD"] = "update_covenant";
sendData["TOKEN"] = token;
sendData["CovenantID"] = CovenantID.ToString(); sendData["CovenantID"] = CovenantID.ToString();
sendData["EstateID"] = EstateID.ToString(); sendData["EstateID"] = EstateID.ToString();
@ -99,6 +106,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
Dictionary<string, object> sendData = new Dictionary<string, object>(); Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "update_estate"; sendData["METHOD"] = "update_estate";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.ToString(); sendData["EstateID"] = EstateID.ToString();
@ -119,6 +127,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
Dictionary<string, object> sendData = new Dictionary<string, object>(); Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "estate_message"; sendData["METHOD"] = "estate_message";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.ToString(); sendData["EstateID"] = EstateID.ToString();
sendData["FromID"] = FromID.ToString(); sendData["FromID"] = FromID.ToString();
@ -132,47 +141,43 @@ namespace OpenSim.Region.CoreModules.World.Estate
{ {
List<UUID> regions = m_EstateModule.Scenes[0].GetEstateRegions((int)EstateID); List<UUID> regions = m_EstateModule.Scenes[0].GetEstateRegions((int)EstateID);
UUID ScopeID = UUID.Zero; // Don't send to the same instance twice
List<string> done = new List<string>();
// Handle local regions locally // Handle local regions locally
//
lock (m_EstateModule.Scenes) lock (m_EstateModule.Scenes)
{ {
foreach (Scene s in m_EstateModule.Scenes) foreach (Scene s in m_EstateModule.Scenes)
{ {
if (regions.Contains(s.RegionInfo.RegionID)) RegionInfo sreg = s.RegionInfo;
if (regions.Contains(sreg.RegionID))
{ {
// All regions in one estate are in the same scope. string url = sreg.ExternalHostName + ":" + sreg.HttpPort;
// Use that scope. regions.Remove(sreg.RegionID);
// if(!done.Contains(url)) // we may have older regs with same url lost in dbs
ScopeID = s.RegionInfo.ScopeID; done.Add(url);
regions.Remove(s.RegionInfo.RegionID);
} }
} }
} }
// Our own region should always be in the above list. if(regions.Count == 0)
// In a standalone this would not be true. But then, return;
// Scope ID is not relevat there. Use first scope.
//
if (ScopeID == UUID.Zero)
ScopeID = m_EstateModule.Scenes[0].RegionInfo.ScopeID;
// Don't send to the same instance twice Scene baseScene = m_EstateModule.Scenes[0];
// UUID ScopeID = baseScene.RegionInfo.ScopeID;
List<string> done = new List<string>(); IGridService gridService = baseScene.GridService;
if(gridService == null)
return;
// Send to remote regions // Send to remote regions
//
foreach (UUID regionID in regions) foreach (UUID regionID in regions)
{ {
GridRegion region = m_EstateModule.Scenes[0].GridService.GetRegionByUUID(ScopeID, regionID); GridRegion region = gridService.GetRegionByUUID(ScopeID, regionID);
if (region != null) if (region != null)
{ {
string url = "http://" + region.ExternalHostName + ":" + region.HttpPort; string url = region.ExternalHostName + ":" + region.HttpPort;
if (done.Contains(url)) if(done.Contains(url))
continue; continue;
Call(region, sendData); Call(region, sendData);
done.Add(url); done.Add(url);
} }
@ -185,7 +190,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
// m_log.DebugFormat("[XESTATE CONNECTOR]: queryString = {0}", reqString); // m_log.DebugFormat("[XESTATE CONNECTOR]: queryString = {0}", reqString);
try try
{ {
string url = "http://" + region.ExternalHostName + ":" + region.HttpPort; string url = "";
if(port != 0)
url = "http://" + region.ExternalHostName + ":" + port;
else
url = region.ServerURI;
string reply = SynchronousRestFormsRequester.MakeRequest("POST", string reply = SynchronousRestFormsRequester.MakeRequest("POST",
url + "/estate", url + "/estate",
reqString); reqString);

Some files were not shown because too many files have changed in this diff Show More