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

View File

@ -89,6 +89,7 @@ what it is today.
* dmiles (Daxtron Labs)
* Dong Jun Lan (IBM)
* DoranZemlja
* Drake Arconis
* dr0b3rts
* dslake
* eeyore
@ -107,6 +108,7 @@ what it is today.
* Flyte Xevious
* Freaky Tech
* Garmin Kawaguichi
* Geir Noklebye
* Glenn Martin (MOSES)
* Gryc Ueusp
* H-H-H (ginge264)
@ -115,6 +117,7 @@ what it is today.
* Imaze Rhiano
* Intimidated
* Jak Daniels
* Jeff Kelly
* Jeremy Bongio (IBM)
* jhurliman
* John R Sohn (XenReborn)
@ -136,6 +139,7 @@ what it is today.
* Magnuz Binder
* maimedleech
* Mana Janus
* Mandarinka Tasty
* MarcelEdward
* Matt Lehmann
* Mic Bowman
@ -158,6 +162,7 @@ what it is today.
* openlifegrid.com
* otakup0pe
* Pixel Tomsen
* Quill Littlefeather
* ralphos
* RemedyTomm
* Revolution
@ -183,6 +188,7 @@ what it is today.
* TBG Renfold
* tglion
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
* TomDataWorks
* TomTheDragon (muckwaddle)
* tyre
* 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);
im.imSessionID = UUID.Zero.Guid;
im.imSessionID = UUID.Zero.Guid;
im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
OutgoingInstantMessage(im, ejecteeID);
@ -756,7 +756,7 @@ namespace OpenSim.Groups
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));
return UUID.Zero;
@ -781,8 +781,8 @@ namespace OpenSim.Groups
if (groupID != UUID.Zero)
{
if (money != null)
money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate);
if (money != null && money.GroupCreationCharge > 0)
money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate, name);
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);
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;
// 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 (money != null && groupRecord.MembershipFee > 0)
money.ApplyCharge(remoteClient.AgentId, groupRecord.MembershipFee, MoneyTransactionType.GroupJoin, groupRecord.GroupName);
remoteClient.SendJoinGroupReply(groupID, true);

View File

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

View File

@ -307,20 +307,20 @@ namespace OpenSim.Groups
m.Contribution = Int32.Parse(d.Data["Contribution"]);
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
GridUserData gud = m_GridUserService.Get(d.PrincipalID);
if (gud != null)
{
if (bool.Parse(gud.Data["Online"]))
{
m.OnlineStatus = @"Online";
}
else
{
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!
m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy");
}
}
GridUserData gud = m_GridUserService.Get(d.PrincipalID);
if (gud != null)
{
if (bool.Parse(gud.Data["Online"]))
{
m.OnlineStatus = @"Online";
}
else
{
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!
m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy");
}
}
// Is this person an owner of the group?
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
@ -496,7 +496,7 @@ namespace OpenSim.Groups
if (!unlimited && limited)
{
// 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)
{
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;
// check permissions
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
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);
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);
if (rolemember == null)
@ -812,7 +825,7 @@ namespace OpenSim.Groups
if (RoleID != UUID.Zero)
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
// Make thit this active group
// Make this the active group
PrincipalData pdata = new PrincipalData();
pdata.PrincipalID = AgentID;
pdata.ActiveGroupID = GroupID;

View File

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

View File

@ -136,11 +136,16 @@ namespace OpenSim.Framework.Capabilities
}
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_capsActive.Reset();
}
~Caps()
{
m_capsActive.Dispose();
}
/// <summary>
/// Register a handler. This allows modules to register handlers.
/// </summary>

View File

@ -53,31 +53,15 @@ namespace OpenSim.Framework.Capabilities
/// <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(BaseHttpServer 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)
{
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
{
m_httpListener = httpListener;
m_httpListenerHostName = httpListenerHostname;
m_httpListenerPort = httpListenerPort;
m_useSSL = https;
if (httpListener != null && m_useSSL)
{
m_httpListenerHostName = httpListener.SSLCommonName;
m_httpListenerPort = httpListener.SSLPort;
}
if (httpListener != null && httpListener.UseSSL)
m_useSSL = true;
else
m_useSSL = false;
}
/// <summary>

View File

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

View File

@ -204,7 +204,7 @@ namespace OpenSim.Data.MySQL
foreach (RegionData r in dbret)
{
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);
}
return ret;

View File

@ -167,7 +167,7 @@ namespace OpenSim.Data.MySQL
"SitTargetOrientY, SitTargetOrientZ, " +
"RegionUUID, CreatorID, " +
"OwnerID, GroupID, " +
"LastOwnerID, SceneGroupID, " +
"LastOwnerID, RezzerID, SceneGroupID, " +
"PayPrice, PayButton1, " +
"PayButton2, PayButton3, " +
"PayButton4, LoopedSound, " +
@ -207,7 +207,7 @@ namespace OpenSim.Data.MySQL
"?SitTargetOrientW, ?SitTargetOrientX, " +
"?SitTargetOrientY, ?SitTargetOrientZ, " +
"?RegionUUID, ?CreatorID, ?OwnerID, " +
"?GroupID, ?LastOwnerID, ?SceneGroupID, " +
"?GroupID, ?LastOwnerID, ?RezzerID, ?SceneGroupID, " +
"?PayPrice, ?PayButton1, ?PayButton2, " +
"?PayButton3, ?PayButton4, ?LoopedSound, " +
"?LoopedSoundGain, ?TextureAnimation, " +
@ -1279,6 +1279,10 @@ namespace OpenSim.Data.MySQL
prim.OwnerID = DBGuid.FromDB(row["OwnerID"]);
prim.GroupID = DBGuid.FromDB(row["GroupID"]);
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
// 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("GroupID", prim.GroupID.ToString());
cmd.Parameters.AddWithValue("LastOwnerID", prim.LastOwnerID.ToString());
cmd.Parameters.AddWithValue("RezzerID", prim.RezzerID.ToString());
cmd.Parameters.AddWithValue("OwnerMask", prim.OwnerMask);
cmd.Parameters.AddWithValue("NextOwnerMask", prim.NextOwnerMask);
cmd.Parameters.AddWithValue("GroupMask", prim.GroupMask);

View File

@ -193,7 +193,9 @@ namespace OpenSim.Data.MySQL
{
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("?type", (int)AssetType.Gesture);
@ -212,7 +214,10 @@ namespace OpenSim.Data.MySQL
{
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("?AssetID", assetID.ToString());

View File

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

View File

@ -97,7 +97,7 @@ CREATE TABLE IF NOT EXISTS `prims` (
PRIMARY KEY (`UUID`),
KEY `prims_regionuuid` (`RegionUUID`),
KEY `prims_scenegroupid` (`SceneGroupID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `primshapes` (
`Shape` int(11) DEFAULT NULL,
@ -130,7 +130,7 @@ CREATE TABLE IF NOT EXISTS `primshapes` (
`Media` text,
`LastAttachPoint` int(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`UUID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `primitems` (
`invType` int(11) DEFAULT NULL,
@ -154,13 +154,13 @@ CREATE TABLE IF NOT EXISTS `primitems` (
`lastOwnerID` char(36) DEFAULT NULL,
PRIMARY KEY (`itemID`),
KEY `primitems_primid` (`primID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `terrain` (
`RegionUUID` varchar(255) DEFAULT NULL,
`Revision` int(11) DEFAULT NULL,
`Heightfield` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `land` (
`UUID` varchar(255) NOT NULL,
@ -204,21 +204,21 @@ CREATE TABLE IF NOT EXISTS `land` (
`ObscureMusic` tinyint(1) NOT NULL DEFAULT '0',
`ObscureMedia` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`UUID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `landaccesslist` (
`LandUUID` varchar(255) DEFAULT NULL,
`AccessUUID` varchar(255) DEFAULT NULL,
`Flags` int(11) DEFAULT NULL,
`Expires` int(11) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `regionban` (
`regionUUID` varchar(36) NOT NULL,
`bannedUUID` varchar(36) NOT NULL,
`bannedIp` 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` (
`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',
`covenant_datetime` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`regionUUID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `regionwindlight` (
`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;
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,
`notes` text NOT NULL,
UNIQUE KEY `useruuid` (`useruuid`,`targetuuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `userpicks` (
@ -46,7 +46,7 @@ CREATE TABLE IF NOT EXISTS `userpicks` (
`enabled` enum('true','false') NOT NULL,
`gatekeeper` varchar(255),
PRIMARY KEY (`pickuuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `userprofile` (
@ -65,7 +65,7 @@ CREATE TABLE IF NOT EXISTS `userprofile` (
`profileFirstImage` varchar(36) NOT NULL,
`profileFirstText` text NOT NULL,
PRIMARY KEY (`useruuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `userdata` (
`UserId` char(36) NOT NULL,
@ -73,7 +73,7 @@ CREATE TABLE IF NOT EXISTS `userdata` (
`DataKey` varchar(255),
`DataVal` varchar(255),
PRIMARY KEY (`UserId`,`TagId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `usersettings` (
`useruuid` varchar(36) NOT NULL,
@ -81,6 +81,6 @@ CREATE TABLE IF NOT EXISTS `usersettings` (
`visible` enum('true','false') NOT NULL,
`email` varchar(254) NOT NULL,
PRIMARY KEY (`useruuid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
commit;

View File

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

View File

@ -211,7 +211,7 @@ namespace OpenSim.Data.PGSQL
foreach (RegionData r in dbret)
{
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);
}
return ret;

View File

@ -174,7 +174,9 @@ namespace OpenSim.Data.PGSQL
{
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.TryParse(principalID, out princID);
@ -194,11 +196,18 @@ namespace OpenSim.Data.PGSQL
{
using (NpgsqlCommand cmd = new NpgsqlCommand())
{
/*
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""::uuid = :PrincipalID
and ""assetID"" = :AssetID
group by ""assetID"" ");
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID));
cmd.Parameters.Add(m_database.CreateParameter("AssetID", assetID));

View File

@ -363,3 +363,11 @@ CREATE TABLE IF NOT EXISTS bakedterrain(
Heightfield blob);
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, "GroupID", typeof(String));
createCol(prims, "LastOwnerID", typeof(String));
createCol(prims, "RezzerID", typeof(String));
createCol(prims, "OwnerMask", typeof(Int32));
createCol(prims, "NextOwnerMask", typeof(Int32));
createCol(prims, "GroupMask", typeof(Int32));
@ -1679,6 +1680,7 @@ namespace OpenSim.Data.SQLite
prim.OwnerID = new UUID((String)row["OwnerID"]);
prim.GroupID = new UUID((String)row["GroupID"]);
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.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]);
prim.GroupMask = Convert.ToUInt32(row["GroupMask"]);
@ -2125,6 +2127,7 @@ namespace OpenSim.Data.SQLite
row["OwnerID"] = prim.OwnerID.ToString();
row["GroupID"] = prim.GroupID.ToString();
row["LastOwnerID"] = prim.LastOwnerID.ToString();
row["RezzerID"] = prim.RezzerID.ToString();
row["OwnerMask"] = prim.OwnerMask;
row["NextOwnerMask"] = prim.NextOwnerMask;
row["GroupMask"] = prim.GroupMask;

View File

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

View File

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

View File

@ -531,14 +531,14 @@ namespace OpenSim.Framework
{
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 (AvatarAttachment attach in kvp.Value)
alist.Add(new AvatarAttachment(attach));
}
return alist;
}
return alist;
}
}
internal void AppendAttachment(AvatarAttachment attach)

View File

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

View File

@ -89,6 +89,8 @@ namespace OpenSim.Framework
public Vector3 AtAxis;
public Vector3 LeftAxis;
public Vector3 UpAxis;
//public int GodLevel;
public OSD GodData = null;
public bool ChangedGrid;
// This probably shouldn't be here
@ -116,6 +118,16 @@ namespace OpenSim.Framework
args["far"] = OSD.FromReal(Far);
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))
args["throttles"] = OSD.FromBinary(Throttles);
@ -174,6 +186,11 @@ namespace OpenSim.Framework
if (args["changed_grid"] != null)
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)
Far = (float)(args["far"].AsReal());
@ -348,7 +365,8 @@ namespace OpenSim.Framework
public Quaternion BodyRotation;
public uint ControlFlags;
public float EnergyLevel;
public Byte GodLevel;
public OSD GodData = null;
//public Byte GodLevel;
public bool AlwaysRun;
public UUID PreyAgent;
public Byte AgentAccess;
@ -422,7 +440,14 @@ namespace OpenSim.Framework
args["control_flags"] = OSD.FromString(ControlFlags.ToString());
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["prey_agent"] = OSD.FromUUID(PreyAgent);
args["agent_access"] = OSD.FromString(AgentAccess.ToString());
@ -600,8 +625,11 @@ namespace OpenSim.Framework
if (args["energy_level"] != null)
EnergyLevel = (float)(args["energy_level"].AsReal());
if (args["god_level"] != null)
Byte.TryParse(args["god_level"].AsString(), out GodLevel);
//if (args["god_level"] != null)
// 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)
AlwaysRun = args["always_run"].AsBoolean();

View File

@ -34,6 +34,7 @@ using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Timers;
using OpenMetaverse;
using Nini.Config;
using OpenSim.Framework.Servers.HttpServer;
@ -41,51 +42,147 @@ using log4net;
namespace OpenSim.Framework.Console
{
public class ConsoleConnection
{
public int last;
public long lastLineSeen;
public bool newConnection = true;
}
// A console that uses REST interfaces
//
public class RemoteConsole : CommandConsole
{
private IHttpServer m_Server = null;
private IConfigSource m_Config = null;
// Connection specific data, indexed by a session ID
// 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>();
private ManualResetEvent m_DataEvent = new ManualResetEvent(false);
private List<string> m_InputData = new List<string>();
private long m_LineNumber = 0;
private Dictionary<UUID, ConsoleConnection> m_Connections =
// Last line of scrollback posted to this client
public long lastLineSeen;
// True if this is a new connection, e.g. has never
// 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>();
private string m_UserName = String.Empty;
private string m_Password = String.Empty;
private string m_AllowedOrigin = String.Empty;
// Timer to control expiration of sessions that have been
// 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)
{
// 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)
{
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"];
if (netConfig == null)
return;
// Get the username and password.
m_UserName = netConfig.GetString("ConsoleUser", 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);
}
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;
// Add our handlers
m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession);
m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession);
m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand);
@ -93,38 +190,84 @@ namespace OpenSim.Framework.Console
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)
{
// Prune the scrollback to the length se send as connect
// burst to give the user some context.
while (m_Scrollback.Count >= 1000)
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());
// Also display it for debugging.
System.Console.WriteLine(text.Trim());
}
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)
{
// 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)
Output("+++"+p);
{
m_expectingInput = true;
m_expectingCommand = true;
Output(p, String.Empty, true, true, false);
m_lastPromptUsed = p;
}
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();
string cmdinput;
// Check for empty input. Read input if not empty.
lock (m_InputData)
{
if (m_InputData.Count == 0)
{
m_DataEvent.Reset();
m_expectingInput = false;
m_expectingCommand = false;
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)
{
// 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));
if (cmd.Length != 0)
@ -151,18 +305,23 @@ namespace OpenSim.Framework.Console
return String.Empty;
}
}
// Return the raw input string if not a command.
return cmdinput;
}
private Hashtable CheckOrigin(Hashtable result)
// Very simplistic static access control header.
protected Hashtable CheckOrigin(Hashtable result)
{
if (!string.IsNullOrEmpty(m_AllowedOrigin))
result["access_control_allow_origin"] = m_AllowedOrigin;
return result;
}
/* TODO: Figure out how PollServiceHTTPHandler can access the request headers
* 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))
{
@ -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>();
lock (m_Connections)
{
// Mark the expired ones
foreach (KeyValuePair<UUID, ConsoleConnection> kvp in m_Connections)
{
if (System.Environment.TickCount - kvp.Value.last > 500000)
expired.Add(kvp.Key);
}
// Delete them
foreach (UUID id in expired)
{
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 reply = new Hashtable();
@ -208,6 +372,7 @@ namespace OpenSim.Framework.Console
reply["int_response_code"] = 401;
reply["content_type"] = "text/plain";
// Check user name and password
if (m_UserName == String.Empty)
return reply;
@ -220,22 +385,28 @@ namespace OpenSim.Framework.Console
return reply;
}
// Set up the new console connection record
ConsoleConnection c = new ConsoleConnection();
c.last = System.Environment.TickCount;
c.lastLineSeen = 0;
// Assign session ID
UUID sessionID = UUID.Random();
// Add connection to list.
lock (m_Connections)
{
m_Connections[sessionID] = c;
}
// This call is a CAP. The URL is the authentication.
string uri = "/ReadResponses/" + sessionID.ToString() + "/";
m_Server.AddPollServiceHTTPHandler(
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();
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
"", "");
@ -252,12 +423,13 @@ namespace OpenSim.Framework.Console
rootElement.AppendChild(id);
XmlElement prompt = xmldoc.CreateElement("", "Prompt", "");
prompt.AppendChild(xmldoc.CreateTextNode(DefaultPrompt));
prompt.AppendChild(xmldoc.CreateTextNode(m_lastPromptUsed));
rootElement.AppendChild(prompt);
rootElement.AppendChild(MainConsole.Instance.Commands.GetXml(xmldoc));
// Set up the response and check origin
reply["str_response_string"] = xmldoc.InnerXml;
reply["int_response_code"] = 200;
reply["content_type"] = "text/xml";
@ -266,10 +438,9 @@ namespace OpenSim.Framework.Console
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 reply = new Hashtable();
@ -316,10 +487,9 @@ namespace OpenSim.Framework.Console
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 reply = new Hashtable();
@ -327,6 +497,7 @@ namespace OpenSim.Framework.Console
reply["int_response_code"] = 404;
reply["content_type"] = "text/plain";
// Check the ID
if (post["ID"] == null)
return reply;
@ -334,21 +505,25 @@ namespace OpenSim.Framework.Console
if (!UUID.TryParse(post["ID"].ToString(), out id))
return reply;
// Find the connection for that ID.
lock (m_Connections)
{
if (!m_Connections.ContainsKey(id))
return reply;
}
// Empty post. Just error out.
if (post["COMMAND"] == null)
return reply;
// Place the input data in the buffer.
lock (m_InputData)
{
m_DataEvent.Set();
m_InputData.Add(post["COMMAND"].ToString());
}
// Create the XML reply document.
XmlDocument xmldoc = new XmlDocument();
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
"", "");
@ -372,7 +547,8 @@ namespace OpenSim.Framework.Console
return reply;
}
private Hashtable DecodePostString(string data)
// Decode a HTTP form post to a Hashtable
protected Hashtable DecodePostString(string data)
{
Hashtable result = new Hashtable();
@ -396,6 +572,7 @@ namespace OpenSim.Framework.Console
return result;
}
// Close the CAP receiver for the responses for a given client.
public void CloseConnection(UUID id)
{
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;
@ -420,13 +599,15 @@ namespace OpenSim.Framework.Console
c = m_Connections[sessionID];
}
c.last = System.Environment.TickCount;
if (c.lastLineSeen < m_LineNumber)
if (c.lastLineSeen < m_lineNumber)
return true;
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;
lock (m_Connections)
@ -435,12 +616,15 @@ namespace OpenSim.Framework.Console
return NoEvents(RequestID, UUID.Zero);
c = m_Connections[sessionID];
}
// If we have nothing to send, send the no events response.
c.last = System.Environment.TickCount;
if (c.lastLineSeen >= m_LineNumber)
if (c.lastLineSeen >= m_lineNumber)
return NoEvents(RequestID, UUID.Zero);
Hashtable result = new Hashtable();
// Create the response document.
XmlDocument xmldoc = new XmlDocument();
XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration,
"", "");
@ -449,30 +633,53 @@ namespace OpenSim.Framework.Console
XmlElement rootElement = xmldoc.CreateElement("", "ConsoleSession",
"");
if (c.newConnection)
{
c.newConnection = false;
Output("+++" + DefaultPrompt);
}
//if (c.newConnection)
//{
// c.newConnection = false;
// Output("+++" + DefaultPrompt);
//}
lock (m_Scrollback)
{
long startLine = m_LineNumber - m_Scrollback.Count;
long startLine = m_lineNumber - m_Scrollback.Count;
long sendStart = startLine;
if (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", "");
long line = i + 1;
res.SetAttribute("Number", line.ToString());
res.AppendChild(xmldoc.CreateTextNode(m_Scrollback[(int)(i - startLine)]));
res.SetAttribute("Number", e.lineNumber.ToString());
res.SetAttribute("Level", e.level);
// 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);
}
}
c.lastLineSeen = m_LineNumber;
c.lastLineSeen = m_lineNumber;
c.newConnection = false;
xmldoc.AppendChild(rootElement);
@ -486,7 +693,9 @@ namespace OpenSim.Framework.Console
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();

View File

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

View File

@ -29,7 +29,7 @@ using OpenSim.Framework;
namespace OpenSim.Framework
{
public interface IImprovedAssetCache
public interface IAssetCache
{
/// <summary>
/// Cache the specified asset.
@ -38,6 +38,12 @@ namespace OpenSim.Framework
void Cache(AssetBase asset);
/// <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.
/// </summary>
/// <param name='id'></param>

View File

@ -227,10 +227,10 @@ namespace OpenSim.Framework
byte RayEndIsIntersection);
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(
UUID GodAgentID, UUID GodSessionID, UUID AgentID, uint kickflags, byte[] reason);
UUID GodAgentID, UUID AgentID, uint kickflags, byte[] reason);
public delegate void CreateInventoryFolder(
IClientAPI remoteClient, UUID folderID, ushort folderType, string folderName, UUID parentID);
@ -1293,7 +1293,7 @@ namespace OpenSim.Framework
void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks);
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);
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 IsInTransit { get; }
bool isNPC { get;}
bool IsNPC { get;}
bool Invulnerable { get; set; }
/// <summary>

View File

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

View File

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

View File

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

View File

@ -138,8 +138,6 @@ namespace OpenSim.Framework
protected uint m_httpPort;
protected string m_serverURI;
protected string m_regionName = String.Empty;
protected bool Allow_Alternate_Ports;
public bool m_allow_alternate_ports;
protected string m_externalHostName;
protected IPEndPoint m_internalEndPoint;
protected uint m_remotingPort;
@ -147,6 +145,7 @@ namespace OpenSim.Framework
public string RemotingAddress;
public UUID ScopeID = UUID.Zero;
private UUID m_maptileStaticUUID = UUID.Zero;
private bool m_resolveAddress = false;
public uint WorldLocX = 0;
public uint WorldLocY = 0;
@ -176,6 +175,9 @@ namespace OpenSim.Framework
/// </remarks>
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>();
// 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)
{
// bool creatingNew = false;
bool creatingNew = false;
if (source.Configs.Count == 0)
{
@ -565,7 +567,7 @@ namespace OpenSim.Framework
source.AddConfig(name);
// creatingNew = true;
creatingNew = true;
}
if (name == String.Empty)
@ -669,18 +671,19 @@ namespace OpenSim.Framework
}
m_internalEndPoint = new IPEndPoint(address, port);
// AllowAlternatePorts
// ResolveAddress
//
allKeys.Remove("AllowAlternatePorts");
if (config.Contains("AllowAlternatePorts"))
allKeys.Remove("ResolveAddress");
if (config.Contains("ResolveAddress"))
{
m_allow_alternate_ports = config.GetBoolean("AllowAlternatePorts", true);
m_resolveAddress = config.GetBoolean("ResolveAddress", false);
}
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
@ -703,15 +706,36 @@ namespace OpenSim.Framework
"[REGIONINFO]: Resolving SYSTEMIP to {0} for external hostname of region {1}",
m_externalHostName, name);
}
else
else if (!m_resolveAddress)
{
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
m_regionType = config.GetString("RegionType", String.Empty);
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
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.
// Must be multiples of legacy region size (256).
private void DoRegionSizeSanityChecks()
@ -843,8 +909,6 @@ namespace OpenSim.Framework
config.Set("InternalAddress", m_internalEndPoint.Address.ToString());
config.Set("InternalPort", m_internalEndPoint.Port);
config.Set("AllowAlternatePorts", m_allow_alternate_ports.ToString());
config.Set("ExternalHostName", m_externalHostName);
if (m_nonphysPrimMin > 0)
@ -937,10 +1001,6 @@ namespace OpenSim.Framework
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Internal IP Port for incoming UDP client connections",
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",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"External Host Name", m_externalHostName, true);
@ -1010,9 +1070,6 @@ namespace OpenSim.Framework
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Internal IP Port for incoming UDP client connections",
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",
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"External Host Name", "127.0.0.1", false);
@ -1083,9 +1140,6 @@ namespace OpenSim.Framework
case "internal_ip_port":
m_internalEndPoint.Port = (int) configuration_result;
break;
case "allow_alternate_ports":
m_allow_alternate_ports = (bool) configuration_result;
break;
case "external_host_name":
if ((string) configuration_result != "SYSTEMIP")
{
@ -1162,7 +1216,6 @@ namespace OpenSim.Framework
if ((RemotingAddress != null) && !RemotingAddress.Equals(""))
args["remoting_address"] = OSD.FromString(RemotingAddress);
args["remoting_port"] = OSD.FromString(RemotingPort.ToString());
args["allow_alt_ports"] = OSD.FromBoolean(m_allow_alternate_ports);
if ((proxyUrl != null) && !proxyUrl.Equals(""))
args["proxy_url"] = OSD.FromString(proxyUrl);
if (RegionType != String.Empty)
@ -1217,8 +1270,6 @@ namespace OpenSim.Framework
RemotingAddress = args["remoting_address"].AsString();
if (args["remoting_port"] != null)
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)
proxyUrl = args["proxy_url"].AsString();
if (args["region_type"] != null)
@ -1256,7 +1307,8 @@ namespace OpenSim.Framework
kvp["http_port"] = HttpPort.ToString();
kvp["internal_ip_address"] = InternalEndPoint.Address.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;
return kvp;

View File

@ -430,11 +430,11 @@ namespace OpenSim.Framework
using (Stream dst = _request.GetRequestStream())
{
m_log.Info("[REST]: GetRequestStream is ok");
m_log.Debug("[REST]: GetRequestStream is ok");
byte[] buf = new byte[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)
{
dst.Write(buf, 0, length);

View File

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

View File

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

View File

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

View File

@ -27,6 +27,8 @@
using System;
using OpenMetaverse;
using System.Collections.Generic;
namespace OpenSim.Framework
{
@ -122,5 +124,18 @@ namespace OpenSim.Framework
public string UserId = UUID.Zero.ToString();
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;
}
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)
where T : IComparable<T>
{
@ -1591,12 +1725,16 @@ namespace OpenSim.Framework
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();
regionHandle = Utils.BytesToUInt64(bytes);
x = Utils.BytesToUInt(bytes, 8) & 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)
@ -1685,6 +1823,8 @@ namespace OpenSim.Framework
// hide the password in the connection string
passPosition = connectionString.IndexOf("password", StringComparison.OrdinalIgnoreCase);
if (passPosition == -1)
return connectionString;
passPosition = connectionString.IndexOf("=", passPosition);
if (passPosition < connectionString.Length)
passPosition += 1;

View File

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

View File

@ -50,7 +50,7 @@ namespace OpenSim.Framework
return retitems;
}
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
public static WearableCacheItem[] FromOSD(OSD pInput, IAssetCache dataCache)
{
List<WearableCacheItem> ret = new List<WearableCacheItem>();
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();
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
/// 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++;
@ -1034,6 +1035,8 @@ namespace OpenSim.Framework
request.Method = verb;
if (timeoutsecs > 0)
request.Timeout = timeoutsecs * 1000;
if(!keepalive && request is HttpWebRequest)
((HttpWebRequest)request).KeepAlive = false;
if (auth != null)
auth.AddAuthorization(request.Headers);
@ -1062,11 +1065,10 @@ namespace OpenSim.Framework
if (WebUtil.DebugLevel >= 5)
WebUtil.LogOutgoingDetail("SEND", reqnum, System.Text.Encoding.UTF8.GetString(data));
Stream requestStream = null;
try
{
requestStream = request.GetRequestStream();
requestStream.Write(data, 0, length);
using(Stream requestStream = request.GetRequestStream())
requestStream.Write(data,0,length);
}
catch (Exception e)
{
@ -1076,9 +1078,6 @@ namespace OpenSim.Framework
}
finally
{
if (requestStream != null)
requestStream.Dispose();
// capture how much time was spent writing
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
}
@ -1129,16 +1128,6 @@ namespace OpenSim.Framework
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)
{
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");
// Verify the Threadpool allocates or uses enough worker and IO completion threads
// .NET 2.0, workerthreads default to 50 * numcores
// .NET 3.0, workerthreads defaults to 250 * numcores
// .NET 4.0, workerthreads are dynamic based on bitness and OS resources
// .NET 2.0, workerthreads default to 50 * numcores
// .NET 3.0, workerthreads defaults to 250 * numcores
// .NET 4.0, workerthreads are dynamic based on bitness and OS resources
// 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
int workerThreadsMin = 500;
int workerThreadsMax = 1000; // may need further adjustment to match other CLR
int iocpThreadsMin = 1000;
int iocpThreadsMax = 2000; // may need further adjustment to match other CLR
int workerThreadsMin = 500;
int workerThreadsMax = 1000; // may need further adjustment to match other CLR
int iocpThreadsMin = 1000;
int iocpThreadsMax = 2000; // may need further adjustment to match other CLR
{
int currentMinWorkerThreads, currentMinIocpThreads;
@ -138,30 +138,30 @@ namespace OpenSim
m_log.InfoFormat("[OPENSIM MAIN]: Limiting max worker threads to {0}",workerThreads);
}
// Increase the number of IOCP threads available.
// Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17)
if (iocpThreads < iocpThreadsMin)
// Increase the number of IOCP threads available.
// Mono defaults to a tragically low number (24 on 6-core / 8GB Fedora 17)
if (iocpThreads < iocpThreadsMin)
{
iocpThreads = iocpThreadsMin;
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 )
{
iocpThreads = iocpThreadsMax;
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) )
{
m_log.InfoFormat(
{
m_log.InfoFormat(
"[OPENSIM MAIN]: Threadpool set to {0} max worker threads and {1} max IOCP threads",
workerThreads, iocpThreads);
}
else
{
m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect.");
}
}
else
{
m_log.Warn("[OPENSIM MAIN]: Threadpool reconfiguration failed, runtime defaults still in effect.");
}
// Check if the system is compatible with OpenSimulator.
// Ensures that the minimum system requirements are met

View File

@ -348,13 +348,10 @@ namespace OpenSim
config.Set("meshing", "Meshmerizer");
config.Set("physical_prim", true);
config.Set("serverside_object_permissions", true);
config.Set("storage_prim_inventories", true);
config.Set("startup_console_commands_file", String.Empty);
config.Set("shutdown_console_commands_file", String.Empty);
config.Set("DefaultScriptEngine", "XEngine");
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.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
@ -74,7 +75,7 @@ namespace OpenSim
private string m_timedScript = "disabled";
private int m_timeInterval = 1200;
private Timer m_scriptTimer;
private System.Timers.Timer m_scriptTimer;
public OpenSim(IConfigSource configSource) : base(configSource)
{
@ -125,6 +126,21 @@ namespace OpenSim
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>
/// Performs initialisation of the scene, such as loading configuration from disk.
/// </summary>
@ -134,6 +150,24 @@ namespace OpenSim
m_log.Info("========================= STARTING OPENSIM =========================");
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());
// http://msdn.microsoft.com/en-us/library/bb384202.aspx
//GCSettings.LatencyMode = GCLatencyMode.Batch;
@ -172,6 +206,7 @@ namespace OpenSim
MainServer.Instance.AddStreamHandler(new OpenSim.XSimStatusHandler(this));
if (userStatsURI != String.Empty)
MainServer.Instance.AddStreamHandler(new OpenSim.UXSimStatusHandler(this));
MainServer.Instance.AddStreamHandler(new OpenSim.SimRobotsHandler());
if (managedStatsURI != String.Empty)
{
@ -217,7 +252,7 @@ namespace OpenSim
// Start timer script (run a script every xx seconds)
if (m_timedScript != "disabled")
{
m_scriptTimer = new Timer();
m_scriptTimer = new System.Timers.Timer();
m_scriptTimer.Enabled = true;
m_scriptTimer.Interval = m_timeInterval*1000;
m_scriptTimer.Elapsed += RunAutoTimerScript;
@ -242,22 +277,22 @@ namespace OpenSim
ChangeSelectedRegion);
m_console.Commands.AddCommand("Archiving", false, "save xml",
"save xml",
"save xml [<file name>]",
"Save a region's data in XML format",
SaveXml);
m_console.Commands.AddCommand("Archiving", false, "save xml2",
"save xml2",
"save xml2 [<file name>]",
"Save a region's data in XML2 format",
SaveXml2);
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",
LoadXml);
m_console.Commands.AddCommand("Archiving", false, "load xml2",
"load xml2",
"load xml2 [<file name>]",
"Load a region's data from XML2 format",
LoadXml2);
@ -741,7 +776,7 @@ namespace OpenSim
CreateRegion(regInfo, true, out scene);
if (changed)
m_estateDataService.StoreEstateSettings(regInfo.EstateSettings);
m_estateDataService.StoreEstateSettings(regInfo.EstateSettings);
scene.Start();
}
@ -1068,7 +1103,7 @@ namespace OpenSim
/// <param name="cmdparams"></param>
protected void SavePrimsXml2(string module, string[] cmdparams)
{
if (cmdparams.Length > 5)
if (cmdparams.Length > 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.");
if (cmdparams.Length > 0)
if (cmdparams.Length > 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
/// <summary>
@ -1083,10 +1103,10 @@ namespace OpenSim
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

View File

@ -29,9 +29,11 @@ using System;
using System.Timers;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
@ -125,6 +127,8 @@ namespace OpenSim.Region.ClientStack.Linden
private bool m_AllowCapHomeLocation = true;
private bool m_AllowCapGroupMemberData = true;
private IUserManagement m_UserManager;
private enum FileAgentInventoryState : int
{
@ -196,6 +200,9 @@ namespace OpenSim.Region.ClientStack.Linden
m_assetService = m_Scene.AssetService;
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();
@ -229,6 +236,7 @@ namespace OpenSim.Region.ClientStack.Linden
RegisterRegionServiceHandlers();
RegisterInventoryServiceHandlers();
RegisterOtherHandlers();
}
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>
/// Construct a client response detailing all the capabilities this server can provide.
/// </summary>
@ -513,7 +537,7 @@ namespace OpenSim.Region.ClientStack.Linden
// check user level
if (avatar != null)
{
if (avatar.UserLevel < m_levelUpload)
if (avatar.GodController.UserLevel < m_levelUpload)
{
LLSDAssetUploadError resperror = new LLSDAssetUploadError();
resperror.message = "Insufficient permissions to upload";
@ -970,7 +994,6 @@ namespace OpenSim.Region.ClientStack.Linden
pbs.TextureEntry = textureEntry.GetBytes();
bool hasmesh = false;
if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ...
{
int meshindx = inner_instance_list["mesh"].AsInteger();
@ -980,10 +1003,34 @@ namespace OpenSim.Region.ClientStack.Linden
pbs.SculptType = (byte)SculptType.Mesh;
pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction
// 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();
Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
@ -994,23 +1041,6 @@ namespace OpenSim.Region.ClientStack.Linden
// int material = inner_instance_list["material"].AsInteger();
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
= new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
@ -1022,6 +1052,7 @@ namespace OpenSim.Region.ClientStack.Linden
prim.OwnerID = owner_id;
prim.GroupID = UUID.Zero;
prim.LastOwnerID = creatorID;
prim.RezzerID = creatorID;
prim.CreationDate = Util.UnixTimeSinceEpoch();
if (grp == null)
@ -1069,6 +1100,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
grp = new SceneObjectGroup(prim);
grp.LastOwnerID = creatorID;
grp.RezzerID = creatorID;
}
else
grp.AddPart(prim);
@ -1649,7 +1681,7 @@ namespace OpenSim.Region.ClientStack.Linden
if(fail)
{
if(client != null)
client.SendAlertMessage(message, "HomePositionSet");
client.SendAlertMessage(message);
response = OSDParser.SerializeLLSDXmlString(resp);
return response;
}
@ -1794,6 +1826,72 @@ namespace OpenSim.Region.ClientStack.Linden
response = OSDParser.SerializeLLSDXmlString(resp);
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

View File

@ -71,7 +71,6 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
IConfigSource config = new IniConfigSource();
config.AddConfig("Startup");
config.Configs["Startup"].Set("EventQueue", "true");
CapabilitiesModule capsModule = new CapabilitiesModule();
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");
foreach (Thread t in m_workerThreads)
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["display_name_next_update"] = new OSDDate(DateTime.Now);
// data["legacy_first_name"] = sp.Firstname;
data["mesh_upload_status"] = "valid";
data["mesh_upload_status"] = "valid";
// data["display_name"] = sp.Firstname + " " + sp.Lastname;
// data["legacy_last_name"] = sp.Lastname;
// data["id"] = m_agentID;

View File

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

View File

@ -346,12 +346,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool m_VelocityInterpolate = false;
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>
/// 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
@ -511,7 +505,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = scene;
m_entityUpdates = 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_attachmentsSent = new HashSet<uint>();
@ -594,13 +587,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(disable, ThrottleOutPacketType.Unknown);
}
// Shutdown the image manager
ImageManager.Close();
// Fire the callback for this connection closing
if (OnConnectionClosed != null)
OnConnectionClosed(this);
// Flush all of the packets out of the UDP server for this client
if (m_udpServer != null)
m_udpServer.Flush(m_udpClient);
@ -614,12 +606,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//m_scene.CloseAllAgents(CircuitCode);
// Disable UDP handling for this client
m_udpClient.OnQueueEmpty -= HandleQueueEmpty;
m_udpClient.HasUpdates -= HandleHasUpdates;
m_udpClient.OnPacketStats -= PopulateStats;
m_udpClient.Shutdown();
// Shutdown the image manager
ImageManager.Close();
ImageManager = null;
//m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
//GC.Collect();
//m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
m_entityUpdates = new PriorityQueue(1);
m_entityProps = new PriorityQueue(1);
m_killRecord.Clear();
GroupsInView.Clear();
if(m_scene.GetNumberOfClients() == 0)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
public void Kick(string message)
@ -2702,7 +2708,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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,
UUID partnerID)
{
@ -2714,7 +2720,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else
avatarReply.PropertiesData.AboutText = Utils.EmptyBytes;
avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn);
avatarReply.PropertiesData.CharterMember = charterMember;
avatarReply.PropertiesData.CharterMember = membershipType;
if (flAbout != null)
avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout);
else
@ -2856,6 +2862,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendSelectedPartsProprieties(List<ISceneEntity> parts)
{
/* not in use
// udp part
ObjectPropertiesPacket packet =
(ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
@ -2893,6 +2900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
llsdBody.Add("ObjectData", array);
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());
}
part.UpdatePhysRequired = false;
}
}
@ -2991,7 +2998,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return;
}
int WearableOut = 0;
bool isWearable = false;
isWearable = ((AssetType) req.AssetInf.Type ==
@ -3121,10 +3127,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
reply.Data.ActualArea = land.Area;
reply.Data.BillableArea = land.Area; // TODO: what is this?
// Bit 0: Mature, bit 7: on sale, other bits: no idea
reply.Data.Flags = (byte)(
(info.AccessLevel > 13 ? (1 << 0) : 0) +
((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0));
reply.Data.Flags = (byte)Util.ConvertAccessLevelToMaturity((byte)info.AccessLevel);
if((land.Flags & (uint)ParcelFlags.ForSale) != 0)
reply.Data.Flags |= (byte)((1 << 7));
Vector3 pos = land.UserLocation;
if (pos.Equals(Vector3.Zero))
@ -4094,19 +4099,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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)
{
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>> compressedUpdates = 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>>();
// Check to see if this is a flush
if (maxUpdatesBytes <= 0)
{
@ -4327,7 +4331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
else
ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId);
objectUpdateBlocks.Value.Add(ablock);
objectUpdateBlocks.Add(ablock);
objectUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length;
@ -4336,7 +4340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
ObjectUpdateCompressedPacket.ObjectDataBlock ablock =
CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags);
compressedUpdateBlocks.Value.Add(ablock);
compressedUpdateBlocks.Add(ablock);
compressedUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length;
}
@ -4347,14 +4351,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
// ALL presence updates go into a special list
ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
terseAgentUpdateBlocks.Value.Add(ablock);
terseAgentUpdateBlocks.Add(ablock);
terseAgentUpdates.Value.Add(update);
}
else
{
// Everything else goes here
ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
terseUpdateBlocks.Value.Add(ablock);
terseUpdateBlocks.Add(ablock);
terseUpdates.Value.Add(update);
}
maxUpdatesBytes -= ablock.Length;
@ -4365,74 +4369,72 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Packet Sending
// const float TIME_DILATION = 1.0f;
ushort timeDilation;
// if(updatesThisCall > 0)
// timeDilation = Utils.FloatToUInt16(avgTimeDilation/updatesThisCall, 0.0f, 1.0f);
// else
// timeDilation = ushort.MaxValue; // 1.0;
if(!IsActive)
return;
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)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
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++)
packet.ObjectData[i] = blocks[i];
for (int i = 0; i < terseAgentUpdateBlocks.Count; i++)
packet.ObjectData[i] = terseAgentUpdateBlocks[i];
terseAgentUpdateBlocks.Clear();
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);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
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++)
packet.ObjectData[i] = blocks[i];
for (int i = 0; i < objectUpdateBlocks.Count; i++)
packet.ObjectData[i] = objectUpdateBlocks[i];
objectUpdateBlocks.Clear();
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);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
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++)
packet.ObjectData[i] = blocks[i];
for (int i = 0; i < compressedUpdateBlocks.Count; i++)
packet.ObjectData[i] = compressedUpdateBlocks[i];
compressedUpdateBlocks.Clear();
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)PacketPool.Instance.GetPacket(
PacketType.ImprovedTerseObjectUpdate);
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
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++)
packet.ObjectData[i] = blocks[i];
for (int i = 0; i < terseUpdateBlocks.Count; i++)
packet.ObjectData[i] = terseUpdateBlocks[i];
terseUpdateBlocks.Clear();
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)
{
// if (!m_udpServer.IsRunningOutbound)
// return;
if(m_scene == null)
return;
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);
if (m_entityUpdates.Count > 0)
@ -4670,23 +4655,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
internal bool HandleHasUpdates(ThrottleOutPacketTypeFlags categories)
{
bool hasUpdates = false;
if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
{
if (m_entityUpdates.Count > 0)
hasUpdates = true;
else if (m_entityProps.Count > 0)
hasUpdates = true;
return true;
if (m_entityProps.Count > 0)
return true;
}
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
{
if (ImageManager.HasUpdates())
hasUpdates = true;
return true;
}
return hasUpdates;
return false;
}
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));
}
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)
{
OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks =
new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>();
// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
// new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
// 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;
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;
ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
objectFamilyBlocks.Value.Add(objPropDB);
familyUpdates.Value.Add(update);
objectFamilyBlocks.Add(objPropDB);
// familyUpdates.Value.Add(update);
maxUpdateBytes -= objPropDB.Length;
}
}
@ -4890,24 +4874,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (update.Entity is SceneObjectPart)
{
SceneObjectPart sop = (SceneObjectPart)update.Entity;
needPhysics.Add(sop);
ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
objectPropertiesBlocks.Value.Add(objPropDB);
propertyUpdates.Value.Add(update);
objectPropertiesBlocks.Add(objPropDB);
// propertyUpdates.Value.Add(update);
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);
packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count];
for (int i = 0; i < blocks.Count; i++)
packet.ObjectData[i] = blocks[i];
packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[objectPropertiesBlocks.Count];
for (int i = 0; i < objectPropertiesBlocks.Count; i++)
packet.ObjectData[i] = objectPropertiesBlocks[i];
objectPropertiesBlocks.Clear();
packet.Header.Zerocoded = true;
// 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,
// delegate(OutgoingPacket oPacket)
// {
// ResendPropertyUpdates(updates, oPacket);
// ResendPropertyUpdates(propertyUpdates.Value, oPacket);
// });
OutPacket(packet, ThrottleOutPacketType.Task, true);
@ -4927,23 +4911,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Int32 fpcnt = 0;
// Int32 fbcnt = 0;
if (objectFamilyBlocks.IsValueCreated)
if (objectFamilyBlocks.Count > 0)
{
List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
// 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)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
packet.ObjectData = blocks[i];
packet.ObjectData = objectFamilyBlocks[i];
packet.Header.Zerocoded = true;
// 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
List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
updates.Add(familyUpdates.Value[i]);
// List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
// updates.Add(familyUpdates.Value[i]);
// HACK : Remove intelligent resending until it's fixed in core
//OutPacket(packet, ThrottleOutPacketType.Task, true,
// delegate(OutgoingPacket oPacket)
@ -4955,7 +4937,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// fpcnt++;
// 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);
@ -6245,9 +6253,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return false;
}
uint seq = packet.Header.Sequence;
TotalAgentUpdates++;
// 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()
// called by scenepresence on completemovement
@ -6255,6 +6266,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true;
}
m_thisAgentUpdateArgs.lastpacketSequence = seq;
bool movement = CheckAgentMovementUpdateSignificance(x);
bool camera = CheckAgentCameraUpdateSignificance(x);
@ -6268,6 +6281,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
m_thisAgentUpdateArgs.State = x.State;
m_thisAgentUpdateArgs.NeedsCameraCollision = !camera;
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
@ -6287,6 +6302,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_thisAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
m_thisAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
m_thisAgentUpdateArgs.NeedsCameraCollision = true;
UpdateAgent handlerAgentCameraUpdate = OnAgentCameraUpdate;
if (handlerAgentCameraUpdate != null)
@ -8547,7 +8564,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// surrounding scene
if ((ImageType)block.Type == ImageType.Baked)
args.Priority *= 2.0f;
int wearableout = 0;
ImageManager.EnqueueReq(args);
}
@ -9597,61 +9613,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#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)
{
UUID currentUUID;
RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest;
if (handlerRegionHandleRequest == null)
return true;
RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
lock (RegionHandleRequests)
if (handlerRegionHandleRequest != null)
{
if (RegionHandleRequestsInService)
{
// 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;
RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack;
handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID);
}
while (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
return true;
}
private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack)
@ -10483,6 +10455,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool HandleRequestGodlikePowers(IClientAPI sender, Packet Pack)
{
RequestGodlikePowersPacket rglpPack = (RequestGodlikePowersPacket)Pack;
if (rglpPack.AgentData.SessionID != SessionId ||
rglpPack.AgentData.AgentID != AgentId)
return true;
RequestGodlikePowersPacket.RequestBlockBlock rblock = rglpPack.RequestBlock;
UUID token = rblock.Token;
@ -10492,7 +10469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (handlerReqGodlikePowers != null)
{
handlerReqGodlikePowers(ablock.AgentID, ablock.SessionID, token, rblock.Godlike, this);
handlerReqGodlikePowers(ablock.AgentID, ablock.SessionID, token, rblock.Godlike);
}
return true;
@ -10503,6 +10480,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
GodUpdateRegionInfoPacket GodUpdateRegionInfo =
(GodUpdateRegionInfoPacket)Packet;
if (GodUpdateRegionInfo.AgentData.SessionID != SessionId ||
GodUpdateRegionInfo.AgentData.AgentID != AgentId)
return true;
GodUpdateRegionInfoUpdate handlerGodUpdateRegionInfo = OnGodUpdateRegionInfoUpdate;
if (handlerGodUpdateRegionInfo != null)
{
@ -10536,6 +10517,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
GodlikeMessagePacket GodlikeMessage =
(GodlikeMessagePacket)Packet;
if (GodlikeMessage.AgentData.SessionID != SessionId ||
GodlikeMessage.AgentData.AgentID != AgentId)
return true;
GodlikeMessage handlerGodlikeMessage = onGodlikeMessage;
if (handlerGodlikeMessage != null)
{
@ -10552,6 +10537,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
StateSavePacket SaveStateMessage =
(StateSavePacket)Packet;
if (SaveStateMessage.AgentData.SessionID != SessionId ||
SaveStateMessage.AgentData.AgentID != AgentId)
return true;
SaveStateHandler handlerSaveStatePacket = OnSaveState;
if (handlerSaveStatePacket != null)
{
@ -10565,30 +10555,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
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;
if (handlerGodKickUser != null)
{
handlerGodKickUser(gkupack.UserInfo.GodID, gkupack.UserInfo.GodSessionID,
gkupack.UserInfo.AgentID, gkupack.UserInfo.KickFlags, gkupack.UserInfo.Reason);
}
handlerGodKickUser(gkupack.UserInfo.GodID, 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;
}
#endregion GodPackets
@ -11479,7 +11455,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ScenePresence p;
if (scene.TryGetScenePresence(sender.AgentId, out p))
{
if (p.GodLevel >= 200)
if (p.IsViewerUIGod)
{
groupProfileReply.GroupData.OpenEnrollment = true;
groupProfileReply.GroupData.MembershipFee = 0;
@ -12928,9 +12904,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// provide your own method.</param>
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.Contains(packet.Type.ToString()))
{
PacketPool.Instance.ReturnPacket(packet);
return;
}
}
if (DebugPacketLevel > 0)
{

View File

@ -120,13 +120,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Circuit code that this client is connected on</summary>
public readonly uint CircuitCode;
/// <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>
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>
public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
public DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
/// <summary>Current packet sequence number</summary>
public int CurrentSequence;
@ -161,15 +161,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Total byte count of unacked packets sent to this client</summary>
public int UnackedBytes;
private int m_packetsUnAckReported;
/// <summary>Total number of received packets that we have reported to the OnPacketStats event(s)</summary>
private int m_packetsReceivedReported;
/// <summary>Total number of sent packets that we have reported to the OnPacketStats event(s)</summary>
private int m_packetsSentReported;
/// <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>
private readonly AdaptiveTokenBucket m_throttleClient;
private AdaptiveTokenBucket m_throttleClient;
public AdaptiveTokenBucket FlowThrottle
{
get { return m_throttleClient; }
@ -178,10 +179,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>Throttle buckets for each packet category</summary>
private readonly TokenBucket[] m_throttleCategories;
/// <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
/// 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>
private readonly LLUDPServer m_udpServer;
@ -292,9 +293,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// pull the throttle out of the scene throttle
m_throttleClient.Parent.UnregisterRequest(m_throttleClient);
OnPacketStats = null;
OnQueueEmpty = null;
}
PendingAcks.Clear();
NeedAcks.Clear();
}
/// <summary>
/// Gets information about this client connection
@ -389,11 +390,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
int newPacketsReceived = PacketsReceived - m_packetsReceivedReported;
int newPacketsSent = PacketsSent - m_packetsSentReported;
int newPacketUnAck = UnackedBytes - m_packetsUnAckReported;
callback(newPacketsReceived, newPacketsSent, UnackedBytes);
m_packetsReceivedReported += newPacketsReceived;
m_packetsSentReported += newPacketsSent;
m_packetsUnAckReported += newPacketUnAck;
}
}
@ -771,7 +773,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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>
/// 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)
{
int start = Environment.TickCount & Int32.MaxValue;
if (!HasUpdates(categories))
return;
double start = Util.GetTimeStampMS();
if (start < m_nextOnQueueEmpty)
return;
m_isQueueEmptyRunning = true;
m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
if (m_nextOnQueueEmpty == 0)
m_nextOnQueueEmpty = 1;
if (HasUpdates(categories))
{
if (!m_udpServer.OqrEngine.IsRunning)
{
// Asynchronously run the callback
Util.FireAndForget(FireQueueEmpty, categories, "LLUDPClient.BeginFireQueueEmpty");
}
else
{
m_udpServer.OqrEngine.QueueJob(AgentID.ToString(), () => FireQueueEmpty(categories));
}
}
// Asynchronously run the callback
if (m_udpServer.OqrEngine.IsRunning)
m_udpServer.OqrEngine.QueueJob(AgentID.ToString(), () => FireQueueEmpty(categories));
else
m_isQueueEmptyRunning = false;
Util.FireAndForget(FireQueueEmpty, categories, "LLUDPClient.BeginFireQueueEmpty");
}
}
private bool m_isQueueEmptyRunning;
/// <summary>

View File

@ -81,7 +81,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uint port = (uint)scene.RegionInfo.InternalEndPoint.Port;
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;
AddScene(scene);
@ -98,9 +98,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#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)
@ -323,10 +323,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected int m_elapsedMSSinceLastStatReport = 0;
/// <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>
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>
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>>();
/// <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;
/// <summary>
@ -442,12 +430,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public JobEngine OqrEngine { get; protected set; }
public LLUDPServer(
IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
IPAddress listenIP, ref uint port, int proxyPortOffsetParm,
IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port)
{
#region Environment.TickCount Measurement
// Update the port with the one we actually got
port = (uint)Port;
// Measure the resolution of Environment.TickCount
TickCountResolution = 0f;
for (int i = 0; i < 10; i++)
@ -456,10 +447,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int now = start;
while (now == start)
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 + "ms");
m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution * 0.1f + "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
@ -467,8 +470,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
int sceneThrottleBps = 0;
bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null)
{
@ -523,7 +524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// if (usePools)
// EnablePools();
DisablePools();
base.DisablePools();
}
public void Start()
@ -927,10 +928,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
PacketPool.Instance.ReturnPacket(packet);
/// WRONG use. May be usefull in future revision
// if (packetQueued)
// m_dataPresentEvent.Set();
}
/// <summary>
@ -2079,19 +2076,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_sendPing = false;
// Update elapsed time
int thisTick = Environment.TickCount & Int32.MaxValue;
if (m_tickLastOutgoingPacketHandler > thisTick)
m_elapsedMSOutgoingPacketHandler += ((Int32.MaxValue - m_tickLastOutgoingPacketHandler) + thisTick);
else
m_elapsedMSOutgoingPacketHandler += (thisTick - m_tickLastOutgoingPacketHandler);
double thisTick = Util.GetTimeStampMS();
// update some 1ms resolution chained timers
m_elapsedMSOutgoingPacketHandler += thisTick - m_tickLastOutgoingPacketHandler;
m_tickLastOutgoingPacketHandler = thisTick;
// Check for pending outgoing resends every 100ms
if (m_elapsedMSOutgoingPacketHandler >= 100)
if (m_elapsedMSOutgoingPacketHandler >= 100.0)
{
m_resendUnacked = true;
m_elapsedMSOutgoingPacketHandler = 0;
m_elapsedMSOutgoingPacketHandler = 0.0;
m_elapsed100MSOutgoingPacketHandler += 1;
}
@ -2109,15 +2104,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_sendPing = true;
m_elapsed500MSOutgoingPacketHandler = 0;
}
#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
// client. m_packetSent will be set to true if a packet is sent
Scene.ForEachClient(clientPacketHandler);
@ -2129,7 +2117,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if(Scene.GetNumberOfClients() == 0)
{
Thread.Sleep(250); // be friendly to PIs, but how long ??
Thread.Sleep(100);
}
else if (!m_packetSent)
// Thread.Sleep((int)TickCountResolution); outch this is bad on linux
@ -2204,99 +2192,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// </summary>
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
protected void ProcessInPacket(IncomingPacket incomingPacket)

View File

@ -107,6 +107,11 @@ namespace OpenMetaverse
/// </summary>
public float AverageReceiveTicksForLastSamplePeriod { get; private set; }
public int Port
{
get { return m_udpPort; }
}
#region PacketDropDebugging
/// <summary>
/// For debugging purposes only... random number generator for dropping
@ -179,6 +184,11 @@ namespace OpenMetaverse
// m_dropRandomGenerator = new Random();
}
~OpenSimUDPBase()
{
if(m_udpSocket !=null)
try { m_udpSocket.Close(); } catch { }
}
/// <summary>
/// Start inbound UDP packet handling.
/// </summary>
@ -212,10 +222,6 @@ namespace OpenMetaverse
SocketType.Dgram,
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
{
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,
// leading to a confusing bug.
// 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)
m_udpSocket.ReceiveBufferSize = recvBufferSize;
m_udpSocket.Bind(ipep);
if (m_udpPort == 0)
m_udpPort = ((IPEndPoint)m_udpSocket.LocalEndPoint).Port;
IsRunningInbound = true;
// 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);
Total = Resend + Land + Wind + Cloud + Task + Texture + Asset;
// 3000000 bps default max
ClientMaxRate = throttleConfig.GetInt("client_throttle_max_bps", 375000);
// 5120000 bps default max
ClientMaxRate = throttleConfig.GetInt("client_throttle_max_bps", 640000);
if (ClientMaxRate > 1000000)
ClientMaxRate = 1000000; // no more than 8Mbps
BrustTime = (float)throttleConfig.GetInt("client_throttle_burtsTimeMS", 10);
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);
CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f);
CannibalizeTextureRate = Util.Clamp<double>(CannibalizeTextureRate,0.0, 0.9);
// http textures do use udp bandwidth setting
// CannibalizeTextureRate = (double)throttleConfig.GetFloat("CannibalizeTextureRate", 0.0f);
// CannibalizeTextureRate = Util.Clamp<double>(CannibalizeTextureRate,0.0, 0.9);
CannibalizeTextureRate = 0f;
}
catch (Exception) { }
}

View File

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

View File

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

View File

@ -255,7 +255,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
// check user level
if (avatar != null)
{
if (avatar.UserLevel < m_levelUpload)
if (avatar.GodController.UserLevel < m_levelUpload)
{
remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
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>
private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>();
/// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary>
private IImprovedAssetCache m_cache;
private IImprovedAssetCache Cache
private IAssetCache m_cache;
private IAssetCache Cache
{
get
{
if (m_cache == null)
m_cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
m_cache = m_scene.RequestModuleInterface<IAssetCache>();
return m_cache;
}

View File

@ -91,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Asset
/// </code>
/// </example>
[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);
@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Asset
expirationTime);
}
#region IImprovedAssetCache Members
#region IAssetCache Members
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>
/// Clear asset cache.
/// </summary>
@ -308,7 +313,7 @@ namespace OpenSim.Region.CoreModules.Asset
public void AddRegion(Scene scene)
{
if (m_enabled)
scene.RegisterModuleInterface<IImprovedAssetCache>(this);
scene.RegisterModuleInterface<IAssetCache>(this);
}
/// <summary>

View File

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

View File

@ -55,13 +55,15 @@ using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Asset
{
[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 =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled;
private bool m_timerRunning;
private bool m_cleanupRunning;
private const string m_ModuleName = "FlotsamAssetCache";
private const string m_DefaultCacheDirectory = "./assetcache";
@ -76,6 +78,7 @@ namespace OpenSim.Region.CoreModules.Asset
private static ulong m_RequestsForInprogress;
private static ulong m_DiskHits;
private static ulong m_MemoryHits;
private static ulong m_weakRefHits;
#if WAIT_ON_INPROGRESS_REQUESTS
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 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.
private const double m_DefaultMemoryExpiration = 2;
private double m_MemoryExpiration = 0.016;
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_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166);
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(1.0);
private static int m_CacheDirectoryTiers = 1;
private static int m_CacheDirectoryTierLen = 3;
@ -104,6 +112,11 @@ namespace OpenSim.Region.CoreModules.Asset
private IAssetService m_AssetService;
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()
{
@ -132,6 +145,7 @@ namespace OpenSim.Region.CoreModules.Asset
if (name == Name)
{
m_MemoryCache = new ExpiringCache<string, AssetBase>();
m_negativeCache = new ExpiringCache<string, object>();
m_Enabled = true;
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_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
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);
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)
{
@ -217,9 +229,8 @@ namespace OpenSim.Region.CoreModules.Asset
{
if (m_Enabled)
{
scene.RegisterModuleInterface<IImprovedAssetCache>(this);
scene.RegisterModuleInterface<IAssetCache>(this);
m_Scenes.Add(scene);
}
}
@ -227,23 +238,61 @@ namespace OpenSim.Region.CoreModules.Asset
{
if (m_Enabled)
{
scene.UnregisterModuleInterface<IImprovedAssetCache>(this);
scene.UnregisterModuleInterface<IAssetCache>(this);
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)
{
if (m_Enabled && m_AssetService == null)
m_AssetService = scene.RequestModuleInterface<IAssetService>();
if (m_Enabled)
{
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)
{
// NOTE DO NOT USE SLIDEEXPIRE option on current libomv
m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
}
@ -306,6 +355,7 @@ namespace OpenSim.Region.CoreModules.Asset
if (asset != null)
{
//m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID);
UpdateWeakReference(asset.ID, asset);
if (m_MemoryCacheEnabled)
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>
/// Updates the cached file with the current time.
/// </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>
/// Try to get an asset from the in-memory cache.
/// </summary>
@ -455,19 +535,42 @@ namespace OpenSim.Region.CoreModules.Asset
{
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);
if(asset != null)
{
UpdateWeakReference(id,asset);
if (m_updateFileTimeOnCacheHit)
{
string filename = GetFileName(id);
UpdateFileLastAccessTime(filename);
}
}
}
if (asset == null && m_FileCacheEnabled)
{
asset = GetFromFileCache(id);
if (m_MemoryCacheEnabled && asset != null)
UpdateMemoryCache(id, asset);
if(asset != null)
UpdateWeakReference(id,asset);
}
if (m_MemoryCacheEnabled && asset != null)
UpdateMemoryCache(id, asset);
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");
@ -475,6 +578,12 @@ namespace OpenSim.Region.CoreModules.Asset
GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l));
}
if(asset == null)
{
}
return asset;
}
@ -511,6 +620,9 @@ namespace OpenSim.Region.CoreModules.Asset
if (m_MemoryCacheEnabled)
m_MemoryCache.Remove(id);
lock(weakAssetReferencesLock)
weakAssetReferences.Remove(id);
}
catch (Exception e)
{
@ -534,7 +646,12 @@ namespace OpenSim.Region.CoreModules.Asset
}
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)
@ -542,6 +659,12 @@ namespace OpenSim.Region.CoreModules.Asset
if (m_LogLevel >= 2)
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
DateTime purgeLine = DateTime.Now - m_FileExpiration;
@ -554,6 +677,13 @@ namespace OpenSim.Region.CoreModules.Asset
{
CleanExpiredFiles(dir, purgeLine);
}
lock(timerLock)
{
if(m_timerRunning)
m_CacheCleanTimer.Start();
m_cleanupRunning = false;
}
}
/// <summary>
@ -789,9 +919,15 @@ namespace OpenSim.Region.CoreModules.Asset
s.ForEachSOG(delegate(SceneObjectGroup e)
{
if(!m_timerRunning && !storeUncached)
return;
gatherer.AddForInspection(e);
gatherer.GatherAll();
if(!m_timerRunning && !storeUncached)
return;
foreach (UUID assetID in gatherer.GatheredUuids.Keys)
{
if (!assetsFound.ContainsKey(assetID))
@ -801,6 +937,7 @@ namespace OpenSim.Region.CoreModules.Asset
if (File.Exists(filename))
{
UpdateFileLastAccessTime(filename);
assetsFound[assetID] = true;
}
else if (storeUncached)
{
@ -820,7 +957,14 @@ namespace OpenSim.Region.CoreModules.Asset
}
gatherer.GatheredUuids.Clear();
if(!m_timerRunning && !storeUncached)
return;
if(!storeUncached)
Thread.Sleep(50);
});
if(!m_timerRunning && !storeUncached)
break;
}
return assetsFound.Count;
@ -864,22 +1008,35 @@ namespace OpenSim.Region.CoreModules.Asset
{
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(
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)
{
double memHitRate = (double)m_MemoryHits / m_Requests * 100.0;
double HitRate = m_MemoryHits * invReq;
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(
string.Format(
"Unnecessary requests due to requests for assets that are currently downloading: {0}",
m_RequestsForInprogress));
"Requests overlap during file writing: {0}", m_RequestsForInprogress));
return outputLines;
}
@ -978,11 +1135,42 @@ namespace OpenSim.Region.CoreModules.Asset
break;
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
{
bool wasRunning= false;
lock(timerLock)
{
if(m_timerRunning)
{
m_CacheCleanTimer.Stop();
m_timerRunning = false;
wasRunning = true;
Thread.Sleep(100);
}
}
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);
}, null, "TouchAllSceneAssets");

View File

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

View File

@ -616,11 +616,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
}
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)
return null;
@ -1118,7 +1118,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
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)
objatt = m_invAccessModule.RezObject(sp.ControllingClient,

View File

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

View File

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

View File

@ -55,9 +55,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
protected List<string> FreezeCache = new List<string>();
protected string m_adminPrefix = "";
protected object m_syncy = new object();
protected IConfig m_config;
#region ISharedRegionModule Members
public virtual void Initialise(IConfigSource config)
{
@ -231,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
fromPos = avatar.AbsolutePosition;
fromName = avatar.Name;
fromID = c.Sender.AgentId;
if (avatar.GodLevel >= 200)
if (avatar.IsViewerUIGod)
{ // let gods speak to outside or things may get confusing
fromNamePrefix = m_adminPrefix;
checkParcelHide = false;
@ -307,7 +305,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
{
if (checkParcelHide)
{
if (sourceParcelID != Presencecheck.LandData.GlobalID && presence.GodLevel < 200)
if (sourceParcelID != Presencecheck.LandData.GlobalID && !presence.IsViewerUIGod)
return;
}
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
// calling card becomes "Take a calling card" for that
// person, no matter if they agree or not.
if (sp.GodLevel >= 200)
if (sp.IsViewerUIGod)
{
CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
return;

View File

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

View File

@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (avatar == null)
return;
if (avatar.UserLevel < m_levelHGFriends)
if (avatar.GodController.UserLevel < m_levelHGFriends)
{
client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false);
return;
@ -337,7 +337,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (UUID.TryParse(friendID, out id))
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)
@ -456,6 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
// local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
DeletePreviousHGRelations(agentID, friendID);
base.StoreFriendships(agentID, friendID);
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)
{
Boolean agentIsLocal = true;

View File

@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
if (god == null || god.ControllingClient.SessionId != godSessionID)
return String.Empty;
KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
KickUser(godID, agentID, kickFlags, Util.StringToBytes1024(reason));
}
else
{
@ -162,59 +162,53 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
}
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);
if(sp == null || sp.IsDeleted || sp.IsNPC)
return;
if (sp != null)
{
if (godLike == false)
{
sp.GrantGodlikePowers(agentID, sessionID, token, godLike);
return;
}
if (sessionID != sp.ControllingClient.SessionId)
return;
// First check that this is the sim owner
if (m_scene.Permissions.IsGod(agentID))
{
// Next we check for spoofing.....
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");
}
}
sp.GrantGodlikePowers(token, godLike);
if (godLike && !sp.IsViewerUIGod && DialogModule != null)
DialogModule.SendAlertToUser(agentID, "Request for god powers denied");
}
/// <summary>
/// Kicks 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
/// Kicks or freezes User specified from the simulator. This logs them off of the grid
/// </summary>
/// <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="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>
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;
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 =
m_scene.RequestModuleInterface<IMessageTransferModule>();
@ -230,48 +224,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
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)
{
case 0:
if (sp != null)
{
case 0:
KickPresence(sp, Utils.BytesToString(reason));
}
else if (agentID == ALL_AGENTS)
{
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)
{
break;
case 1:
sp.AllowMovement = false;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(sp.UUID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Frozen");
}
break;
case 2:
if (sp != null)
{
break;
case 2:
sp.AllowMovement = true;
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(sp.UUID, Utils.BytesToString(reason));
m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
}
break;
default:
break;
break;
default:
break;
}
}
private void KickPresence(ScenePresence sp, string reason)
{
if (sp.IsChildAgent)
if(sp.IsDeleted || sp.IsChildAgent)
return;
sp.ControllingClient.Kick(reason);
sp.Scene.CloseAgent(sp.UUID, true);
@ -286,7 +273,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
UUID godID = new UUID(msg.fromAgentID);
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(
MethodBase.GetCurrentMethod().DeclaringType);
protected Timer m_logTimer = new Timer(10000);
protected List<GridInstantMessage> m_logData = new List<GridInstantMessage>();
protected string m_restUrl;
/// <value>
/// Is this module enabled?
/// </value>
@ -68,12 +64,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
"InstantMessageModule", "InstantMessageModule") !=
"InstantMessageModule")
return;
m_restUrl = config.Configs["Messaging"].GetString("LogURL", String.Empty);
}
m_enabled = true;
m_logTimer.AutoReset = false;
m_logTimer.Elapsed += LogTimerElapsed;
}
public virtual void AddRegion(Scene scene)
@ -153,20 +146,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
}
#endregion
/*
public virtual void OnViewerInstantMessage(IClientAPI client, GridInstantMessage im)
{
im.fromAgentName = client.FirstName + " " + client.LastName;
OnInstantMessage(client, im);
}
*/
public virtual void OnInstantMessage(IClientAPI client, GridInstantMessage im)
{
byte dialog = im.dialog;
if (client != null && dialog == (byte)InstantMessageDialog.MessageFromAgent)
LogInstantMesssage(im);
if (dialog != (byte)InstantMessageDialog.MessageFromAgent
&& dialog != (byte)InstantMessageDialog.StartTyping
&& dialog != (byte)InstantMessageDialog.StopTyping
@ -243,35 +233,5 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
//
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 account;
/*
try
{
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);
return null;
}
*/
}
/// <summary>

View File

@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
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,
client.FirstName+" "+client.LastName, targetid,

View File

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

View File

@ -455,6 +455,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
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
float localHalfAVHeight = 0.8f;
if (sp.Appearance != null)
@ -594,12 +598,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
uint x = 0, y = 0;
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
double worldX = (double)x + position.X;
double worldY = (double)y + position.Y;
// Find the region that contains the position
GridRegion reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY);
reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY);
if (reg != null)
{
@ -762,6 +776,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
else if (sp.Flying)
teleportFlags |= (uint)TeleportFlags.IsFlying;
sp.IsInTransit = true;
if (DisableInterRegionTeleportCancellation)
teleportFlags |= (uint)TeleportFlags.DisableCancel;
@ -813,8 +829,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (OutSideViewRange)
{
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
"[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,newSizeX, newSizeY, sp.Name, Scene.Name);
//sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
#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.ControllingClient.SendTeleportFailed(reason);
sp.IsInTransit = false;
return;
}
@ -875,7 +891,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return;
}
else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
@ -885,7 +901,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[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.IsInTransit = false;
return;
}
@ -946,7 +962,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return;
}
@ -963,7 +979,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[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.IsInTransit = false;
return;
}
@ -972,6 +988,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
sp.IsInTransit = false;
return;
}
@ -984,7 +1001,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name);
CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
sp.IsInTransit = false;
return;
}
@ -1021,7 +1038,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[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.IsInTransit = false;
return;
}
@ -1030,7 +1047,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
sp.IsInTransit = false;
return;
}
@ -1079,6 +1096,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
Thread.Sleep(500);
sp.Scene.CloseAgent(sp.UUID, false);
}
sp.IsInTransit = false;
}
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.ControllingClient.SendTeleportFailed(reason);
sp.IsInTransit = false;
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",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return;
}
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.",
sp.Name, finalDestination.RegionName, sp.Scene.Name);
sp.IsInTransit = false;
return;
}
@ -1175,7 +1195,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat(
"[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.IsInTransit = false;
return;
}
@ -1184,6 +1204,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Name, finalDestination.RegionName, sp.Scene.Name);
Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
sp.IsInTransit = false;
return;
}
@ -1241,6 +1262,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
sp.Reset();
}
*/
sp.IsInTransit = false;
}
/// <summary>
@ -1977,8 +1999,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
IClientAPI spClient = sp.ControllingClient;
if (!seeds.ContainsKey(currentRegionHandler))
seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath);
// This will fail if the user aborts login
try
{
if (!seeds.ContainsKey(currentRegionHandler))
seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath);
}
catch
{
return;
}
AgentCircuitData currentAgentCircuit =
spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
@ -2055,6 +2085,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
agentpos.Position = sp.AbsolutePosition;
agentpos.Velocity = sp.Velocity;
agentpos.RegionHandle = currentRegionHandler;
//agentpos.GodLevel = sp.GodLevel;
agentpos.GodData = sp.GodController.State();
agentpos.Throttles = spClient.GetThrottlesPacked(1);
// agentpos.ChildrenCapSeeds = seeds;
@ -2079,19 +2111,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
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)
{
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.RegionHandle,
neighbour.RegionLocX,
@ -2180,8 +2203,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#endregion // NotFoundLocationCache class
private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache();
// needed for old grid code
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
@ -2191,6 +2212,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Given a world position, get the GridRegion info for
// 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,
double px, double py, uint pSizeHint)
{
@ -2264,24 +2288,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <param name="a"></param>
/// <param name="regionHandle"></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)
{
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;
m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
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;
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)
{
@ -2291,6 +2319,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_eqModule != null)
{
#region IP Translation for NAT
if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened
return;
IClientIPEndpoint 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
// 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.");
reason = "Hypergrid teleport not allowed";

View File

@ -322,7 +322,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
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))
//{

View File

@ -532,17 +532,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
else
{
AddPermissions(item, objlist[0], objlist, remoteClient);
item.CreationDate = Util.UnixTimeSinceEpoch();
item.Description = asset.Description;
item.Name = asset.Name;
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);
if (remoteClient != null && item.Owner == remoteClient.AgentId)
@ -599,15 +595,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
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())
{
// Changing ownership, so apply the "Next Owner" permissions to all of the
// inventory item's permissions.
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.CurrentPermissions = item.BasePermissions;
@ -620,13 +617,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
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.CurrentPermissions = effectivePerms;
item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms;
@ -642,8 +632,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
7); // Preserve folded permissions
}
//PermissionsUtil.LogPermissions(item.Name, "After AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
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.
part.LastOwnerID = part.OwnerID;
part.OwnerID = remoteClient.AgentId;
part.RezzerID = remoteClient.AgentId;
}
}
@ -1150,7 +1139,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
part.LastOwnerID = part.OwnerID;
part.OwnerID = item.Owner;
part.RezzerID = 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();
@ -1162,10 +1158,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
{
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
part.NextOwnerMask = item.NextPermissions & part.BaseMask;
part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
part.NextOwnerMask = item.NextPermissions & part.BaseMask;
}
}
}

View File

@ -48,31 +48,16 @@ namespace OpenSim.Region.CoreModules.Framework
MethodBase.GetCurrentMethod().DeclaringType);
private readonly List<Scene> m_scenes = new List<Scene>();
private System.Timers.Timer m_timer = new System.Timers.Timer();
private Queue<Action> m_RequestQueue = new Queue<Action>();
private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>();
private int m_Interval;
private JobEngine m_processorJobEngine;
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000);
m_timer = new System.Timers.Timer();
m_timer.AutoReset = false;
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);
m_processorJobEngine = new JobEngine(
"ServiceThrottle","ServiceThrottle");
m_processorJobEngine.RequestProcessTimeoutOnStop = 31000; // many webrequests have 30s expire
m_processorJobEngine.Start();
}
public void AddRegion(Scene scene)
@ -82,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework
m_scenes.Add(scene);
scene.RegisterModuleInterface<IServiceThrottleModule>(this);
scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
}
}
@ -105,6 +89,7 @@ namespace OpenSim.Region.CoreModules.Framework
public void Close()
{
m_processorJobEngine.Stop();
}
public string Name
@ -126,38 +111,24 @@ namespace OpenSim.Region.CoreModules.Framework
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)
{
//m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
ulong handle = 0;
if (IsLocalRegionHandle(regionID, out handle))
{
client.SendRegionHandle(regionID, handle);
return;
}
Action action = delegate
{
if(!client.IsActive)
return;
GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID);
if(!client.IsActive)
return;
if (r != null && r.RegionHandle != 0)
client.SendRegionHandle(regionID, r.RegionHandle);
};
Enqueue("region", regionID.ToString(), action);
m_processorJobEngine.QueueJob("regionHandle", action, regionID.ToString());
}
#endregion Events
@ -166,91 +137,10 @@ namespace OpenSim.Region.CoreModules.Framework
public void Enqueue(string category, string itemid, Action continuation)
{
lock (m_RequestQueue)
{
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();
});
}
m_processorJobEngine.QueueJob(category, continuation, itemid);
}
#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
m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate
m_ServiceThrottle.Enqueue("uuidname", uuid.ToString(), delegate
{
//m_log.DebugFormat("[YYY]: Name request {0}", uuid);
@ -216,9 +216,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
// So to avoid clients
// (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will
// instead drop the request entirely.
if(!client.IsActive)
return;
if (GetUser(uuid, out user))
{
client.SendNameReply(uuid, user.FirstName, user.LastName);
if(client.IsActive)
client.SendNameReply(uuid, user.FirstName, user.LastName);
}
// else
// m_log.DebugFormat(
@ -802,7 +805,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
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)
{
@ -813,7 +816,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
user.FirstName = first;
user.LastName = last;
user.IsUnknownUser = false;
user.HasGridUserTried = false;
user.HasGridUserTried = isNPC;
m_UserCache.Add(uuid, user);
}
}

View File

@ -131,7 +131,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
uint rx = 0, ry = 0;
Util.RegionHandleToWorldLoc(regionHandle, out rx, out ry);
rx += x;
ry += y;
foreach (Scene s in m_Scenes)
{
uint t = s.RegionInfo.WorldLocX;
@ -147,6 +148,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
if( ry < t)
{
// 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;
return s.GetLandData(x, y);
}

View File

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

View File

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

View File

@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
MethodBase.GetCurrentMethod().DeclaringType);
private bool m_Enabled = false;
private IImprovedAssetCache m_Cache;
private IAssetCache m_Cache;
public Type ReplaceableInterface
{
@ -111,7 +111,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
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
// 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);
private bool m_Enabled = false;
private string m_ThisGatekeeper = string.Empty;
private IGridService m_LocalGridService;
private IGridService m_RemoteGridService;
@ -118,13 +119,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
m_LocalGridService = new LocalGridServicesConnector(source, m_RegionInfoCache);
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;
}
if(m_RegionInfoCache == null)
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;
}
@ -227,12 +235,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
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)
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);
m_RegionInfoCache.Cache(scopeID, rinfo);
return rinfo;
@ -242,7 +266,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{
List<GridRegion> rinfo = m_LocalGridService.GetRegionsByName(scopeID, name, maxNumber);
//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)
{

View File

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

View File

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

View File

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

View File

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

View File

@ -36,7 +36,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{
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 =
// LogManager.GetLogger(
@ -44,6 +46,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
private ExpiringCache<UUID, UserAccount> m_UUIDCache;
private ExpiringCache<string, UUID> m_NameCache;
private object accessLock = new object();
public UserAccountCache()
{
@ -54,60 +57,95 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
public void Cache(UUID userID, UserAccount account)
{
// Cache even null accounts
m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS);
if (account != null)
m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_EXPIRATION_SECONDS);
lock(accessLock)
{
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);
}
}
public void Invalidate(UUID userID)
{
m_UUIDCache.Remove(userID);
}
public UserAccount Get(UUID userID, out bool inCache)
{
UserAccount account = null;
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);
inCache = true;
return account;
if (m_UUIDCache.TryGetValue(userID, out account))
{
//m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName);
inCache = true;
return account;
}
}
return null;
}
public UserAccount Get(string name, out bool inCache)
{
inCache = false;
if (!m_NameCache.Contains(name))
return null;
lock(accessLock)
{
if (!m_NameCache.Contains(name))
return null;
UserAccount account = null;
UUID uuid = UUID.Zero;
if (m_NameCache.TryGetValue(name, out uuid))
if (m_UUIDCache.TryGetValue(uuid, out account))
UserAccount account = null;
UUID uuid = UUID.Zero;
if (m_NameCache.TryGetValue(name, out uuid))
{
inCache = true;
return account;
if (m_UUIDCache.TryGetValue(uuid, out account))
{
inCache = true;
return account;
}
}
}
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)
{
if (!m_NameCache.Contains(name))
return;
UUID uuid = UUID.Zero;
if (m_NameCache.TryGetValue(name, out uuid))
lock(accessLock)
{
m_NameCache.Remove(name);
m_UUIDCache.Remove(uuid);
if (!m_NameCache.Contains(name))
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);
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;
token = _token;
port = _port;
}
public void SendTeleportHomeOneUser(uint EstateID, UUID PreyID)
{
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "teleport_home_one_user";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.ToString();
sendData["PreyID"] = PreyID.ToString();
@ -67,6 +72,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "teleport_home_all_users";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.ToString();
@ -77,6 +83,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "update_covenant";
sendData["TOKEN"] = token;
sendData["CovenantID"] = CovenantID.ToString();
sendData["EstateID"] = EstateID.ToString();
@ -99,6 +106,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "update_estate";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.ToString();
@ -119,6 +127,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
{
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["METHOD"] = "estate_message";
sendData["TOKEN"] = token;
sendData["EstateID"] = EstateID.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);
UUID ScopeID = UUID.Zero;
// Don't send to the same instance twice
List<string> done = new List<string>();
// Handle local regions locally
//
lock (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.
// Use that scope.
//
ScopeID = s.RegionInfo.ScopeID;
regions.Remove(s.RegionInfo.RegionID);
string url = sreg.ExternalHostName + ":" + sreg.HttpPort;
regions.Remove(sreg.RegionID);
if(!done.Contains(url)) // we may have older regs with same url lost in dbs
done.Add(url);
}
}
}
// Our own region should always be in the above list.
// In a standalone this would not be true. But then,
// Scope ID is not relevat there. Use first scope.
//
if (ScopeID == UUID.Zero)
ScopeID = m_EstateModule.Scenes[0].RegionInfo.ScopeID;
if(regions.Count == 0)
return;
// Don't send to the same instance twice
//
List<string> done = new List<string>();
Scene baseScene = m_EstateModule.Scenes[0];
UUID ScopeID = baseScene.RegionInfo.ScopeID;
IGridService gridService = baseScene.GridService;
if(gridService == null)
return;
// Send to remote 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)
{
string url = "http://" + region.ExternalHostName + ":" + region.HttpPort;
if (done.Contains(url))
string url = region.ExternalHostName + ":" + region.HttpPort;
if(done.Contains(url))
continue;
Call(region, sendData);
done.Add(url);
}
@ -185,7 +190,12 @@ namespace OpenSim.Region.CoreModules.World.Estate
// m_log.DebugFormat("[XESTATE CONNECTOR]: queryString = {0}", reqString);
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",
url + "/estate",
reqString);

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