Merge branch 'master' into careminster
Conflicts: OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs OpenSim/Region/Framework/Scenes/Scene.csavinationmerge
commit
2f365ea80b
|
@ -623,10 +623,13 @@ namespace OpenSim.Groups
|
||||||
if (agent != null)
|
if (agent != null)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (agent == null) // oops
|
if (agent != null)
|
||||||
return AgentID.ToString();
|
return Util.ProduceUserUniversalIdentifier(agent);
|
||||||
|
|
||||||
|
// we don't know anything about this foreign user
|
||||||
|
// try asking the user management module, which may know more
|
||||||
|
return m_UserManagement.GetUserUUI(AgentID);
|
||||||
|
|
||||||
return Util.ProduceUserUniversalIdentifier(agent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string AgentUUIForOutside(string AgentIDStr)
|
private string AgentUUIForOutside(string AgentIDStr)
|
||||||
|
|
|
@ -81,6 +81,7 @@ namespace OpenSim.Data
|
||||||
bool Delete(UUID regionID);
|
bool Delete(UUID regionID);
|
||||||
|
|
||||||
List<RegionData> GetDefaultRegions(UUID scopeID);
|
List<RegionData> GetDefaultRegions(UUID scopeID);
|
||||||
|
List<RegionData> GetDefaultHypergridRegions(UUID scopeID);
|
||||||
List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
|
List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
|
||||||
List<RegionData> GetHyperlinks(UUID scopeID);
|
List<RegionData> GetHyperlinks(UUID scopeID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -315,6 +315,11 @@ namespace OpenSim.Data.MSSQL
|
||||||
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<RegionData> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
return Get((int)RegionFlags.DefaultHGRegion, scopeID);
|
||||||
|
}
|
||||||
|
|
||||||
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
||||||
|
|
|
@ -310,6 +310,11 @@ namespace OpenSim.Data.MySQL
|
||||||
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<RegionData> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
return Get((int)RegionFlags.DefaultHGRegion, scopeID);
|
||||||
|
}
|
||||||
|
|
||||||
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
||||||
|
|
|
@ -239,6 +239,11 @@ namespace OpenSim.Data.Null
|
||||||
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<RegionData> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
return Get((int)RegionFlags.DefaultHGRegion, scopeID);
|
||||||
|
}
|
||||||
|
|
||||||
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
||||||
|
|
|
@ -48,6 +48,7 @@ namespace OpenSim.Framework
|
||||||
NoMove = 64, // Don't allow moving this region
|
NoMove = 64, // Don't allow moving this region
|
||||||
Reservation = 128, // This is an inactive reservation
|
Reservation = 128, // This is an inactive reservation
|
||||||
Authenticate = 256, // Require authentication
|
Authenticate = 256, // Require authentication
|
||||||
Hyperlink = 512 // Record represents a HG link
|
Hyperlink = 512, // Record represents a HG link
|
||||||
|
DefaultHGRegion = 1024 // Record represents a default region for hypergrid teleports only.
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -130,7 +130,7 @@ namespace OpenSim.Framework
|
||||||
private static SmartThreadPool m_ThreadPool;
|
private static SmartThreadPool m_ThreadPool;
|
||||||
|
|
||||||
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
|
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
|
||||||
private static readonly DateTime unixEpoch =
|
public static readonly DateTime UnixEpoch =
|
||||||
DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime();
|
DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime();
|
||||||
|
|
||||||
private static readonly string rawUUIDPattern
|
private static readonly string rawUUIDPattern
|
||||||
|
@ -521,20 +521,18 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public static int ToUnixTime(DateTime stamp)
|
public static int ToUnixTime(DateTime stamp)
|
||||||
{
|
{
|
||||||
TimeSpan t = stamp.ToUniversalTime() - unixEpoch;
|
TimeSpan t = stamp.ToUniversalTime() - UnixEpoch;
|
||||||
return (int) t.TotalSeconds;
|
return (int)t.TotalSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DateTime ToDateTime(ulong seconds)
|
public static DateTime ToDateTime(ulong seconds)
|
||||||
{
|
{
|
||||||
DateTime epoch = unixEpoch;
|
return UnixEpoch.AddSeconds(seconds);
|
||||||
return epoch.AddSeconds(seconds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DateTime ToDateTime(int seconds)
|
public static DateTime ToDateTime(int seconds)
|
||||||
{
|
{
|
||||||
DateTime epoch = unixEpoch;
|
return UnixEpoch.AddSeconds(seconds);
|
||||||
return epoch.AddSeconds(seconds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void AddForClient()
|
public void TestAddForClient()
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// log4net.Config.XmlConfigurator.Configure();
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
@ -88,7 +88,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void RemoveForClient()
|
public void TestRemoveForClient()
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// TestHelpers.EnableLogging();
|
// TestHelpers.EnableLogging();
|
||||||
|
|
|
@ -372,21 +372,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||||
UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
|
UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
|
||||||
string message, ChatSourceType src, bool ignoreDistance)
|
string message, ChatSourceType src, bool ignoreDistance)
|
||||||
{
|
{
|
||||||
// don't send chat to child agents
|
if (presence.LifecycleState != ScenePresenceState.Running)
|
||||||
if (presence.IsChildAgent) return false;
|
|
||||||
|
|
||||||
Vector3 fromRegionPos = fromPos + regionPos;
|
|
||||||
Vector3 toRegionPos = presence.AbsolutePosition +
|
|
||||||
new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize,
|
|
||||||
presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
|
|
||||||
|
|
||||||
int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
|
|
||||||
|
|
||||||
if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
|
|
||||||
type == ChatTypeEnum.Say && dis > m_saydistance ||
|
|
||||||
type == ChatTypeEnum.Shout && dis > m_shoutdistance)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!ignoreDistance)
|
||||||
|
{
|
||||||
|
Vector3 fromRegionPos = fromPos + regionPos;
|
||||||
|
Vector3 toRegionPos = presence.AbsolutePosition +
|
||||||
|
new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize,
|
||||||
|
presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0);
|
||||||
|
|
||||||
|
int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos);
|
||||||
|
|
||||||
|
if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance ||
|
||||||
|
type == ChatTypeEnum.Say && dis > m_saydistance ||
|
||||||
|
type == ChatTypeEnum.Shout && dis > m_shoutdistance)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: should change so the message is sent through the avatar rather than direct to the ClientView
|
// TODO: should change so the message is sent through the avatar rather than direct to the ClientView
|
||||||
|
|
|
@ -1212,7 +1212,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
||||||
json.Add("jsonrpc", OSD.FromString("2.0"));
|
json.Add("jsonrpc", OSD.FromString("2.0"));
|
||||||
json.Add("id", OSD.FromString(jsonId));
|
json.Add("id", OSD.FromString(jsonId));
|
||||||
json.Add("method", OSD.FromString(method));
|
json.Add("method", OSD.FromString(method));
|
||||||
// Experiment
|
|
||||||
json.Add("params", OSD.SerializeMembers(parameters));
|
json.Add("params", OSD.SerializeMembers(parameters));
|
||||||
|
|
||||||
string jsonRequestData = OSDParser.SerializeJsonString(json);
|
string jsonRequestData = OSDParser.SerializeJsonString(json);
|
||||||
|
@ -1240,8 +1240,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream rstream = webResponse.GetResponseStream();
|
Stream rstream = webResponse.GetResponseStream();
|
||||||
if (rstream.Length < 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
OSDMap mret = new OSDMap();
|
OSDMap mret = new OSDMap();
|
||||||
try
|
try
|
||||||
|
@ -1318,8 +1316,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream rstream = webResponse.GetResponseStream();
|
Stream rstream = webResponse.GetResponseStream();
|
||||||
if (rstream.Length < 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
OSDMap response = new OSDMap();
|
OSDMap response = new OSDMap();
|
||||||
try
|
try
|
||||||
|
|
|
@ -925,6 +925,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
|
|
||||||
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
||||||
{
|
{
|
||||||
|
if (!sp.Scene.IncomingPreCloseAgent(sp))
|
||||||
|
return;
|
||||||
|
|
||||||
// We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
|
// We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
|
||||||
// they regard the new region as the current region after receiving the AgentMovementComplete
|
// they regard the new region as the current region after receiving the AgentMovementComplete
|
||||||
// response. If close is sent before then, it will cause the viewer to quit instead.
|
// response. If close is sent before then, it will cause the viewer to quit instead.
|
||||||
|
@ -1087,6 +1090,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
||||||
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
||||||
{
|
{
|
||||||
|
if (!sp.Scene.IncomingPreCloseAgent(sp))
|
||||||
|
return;
|
||||||
|
|
||||||
// RED ALERT!!!!
|
// RED ALERT!!!!
|
||||||
// PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
|
// PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
|
||||||
// THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
|
// THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
|
||||||
|
@ -1100,6 +1106,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||||
// then this will be handled in IncomingCloseAgent under lock conditions
|
// then this will be handled in IncomingCloseAgent under lock conditions
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
|
"[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
|
||||||
|
|
||||||
sp.Scene.IncomingCloseAgent(sp.UUID, false);
|
sp.Scene.IncomingCloseAgent(sp.UUID, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -481,14 +481,20 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public string GetUserUUI(UUID userID)
|
public string GetUserUUI(UUID userID)
|
||||||
{
|
{
|
||||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
|
|
||||||
if (account != null)
|
|
||||||
return userID.ToString();
|
|
||||||
|
|
||||||
UserData ud;
|
UserData ud;
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
m_UserCache.TryGetValue(userID, out ud);
|
m_UserCache.TryGetValue(userID, out ud);
|
||||||
|
|
||||||
|
if (ud == null) // It's not in the cache
|
||||||
|
{
|
||||||
|
string[] names = new string[2];
|
||||||
|
// This will pull the data from either UserAccounts or GridUser
|
||||||
|
// and stick it into the cache
|
||||||
|
TryGetUserNamesFromServices(userID, names);
|
||||||
|
lock (m_UserCache)
|
||||||
|
m_UserCache.TryGetValue(userID, out ud);
|
||||||
|
}
|
||||||
|
|
||||||
if (ud != null)
|
if (ud != null)
|
||||||
{
|
{
|
||||||
string homeURL = ud.HomeURL;
|
string homeURL = ud.HomeURL;
|
||||||
|
|
|
@ -235,6 +235,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
return m_GridService.GetDefaultRegions(scopeID);
|
return m_GridService.GetDefaultRegions(scopeID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
return m_GridService.GetDefaultHypergridRegions(scopeID);
|
||||||
|
}
|
||||||
|
|
||||||
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
return m_GridService.GetFallbackRegions(scopeID, x, y);
|
return m_GridService.GetFallbackRegions(scopeID, x, y);
|
||||||
|
|
|
@ -277,6 +277,26 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||||
return rinfo;
|
return rinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
List<GridRegion> rinfo = m_LocalGridService.GetDefaultHypergridRegions(scopeID);
|
||||||
|
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetDefaultHypergridRegions {0} found {1} regions", name, rinfo.Count);
|
||||||
|
List<GridRegion> grinfo = m_RemoteGridService.GetDefaultHypergridRegions(scopeID);
|
||||||
|
|
||||||
|
if (grinfo != null)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultHypergridRegions {0} found {1} regions", name, grinfo.Count);
|
||||||
|
foreach (GridRegion r in grinfo)
|
||||||
|
{
|
||||||
|
m_RegionInfoCache.Cache(r);
|
||||||
|
if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null)
|
||||||
|
rinfo.Add(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rinfo;
|
||||||
|
}
|
||||||
|
|
||||||
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
List<GridRegion> rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y);
|
List<GridRegion> rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y);
|
||||||
|
|
|
@ -3854,10 +3854,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// We need to ensure that we are not already removing the scene presence before we ask it not to be
|
// We need to ensure that we are not already removing the scene presence before we ask it not to be
|
||||||
// closed.
|
// closed.
|
||||||
if (sp != null && sp.IsChildAgent && sp.LifecycleState == ScenePresenceState.Running)
|
if (sp != null && sp.IsChildAgent
|
||||||
|
&& (sp.LifecycleState == ScenePresenceState.Running
|
||||||
|
|| sp.LifecycleState == ScenePresenceState.PreRemove))
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name);
|
"[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}",
|
||||||
|
sp.Name, sp.LifecycleState, Name);
|
||||||
|
|
||||||
// In the case where, for example, an A B C D region layout, an avatar may
|
// In the case where, for example, an A B C D region layout, an avatar may
|
||||||
// teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
|
// teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
|
||||||
|
@ -3879,6 +3882,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// }
|
// }
|
||||||
// else if (EntityTransferModule.IsInTransit(sp.UUID))
|
// else if (EntityTransferModule.IsInTransit(sp.UUID))
|
||||||
|
|
||||||
|
sp.LifecycleState = ScenePresenceState.Running;
|
||||||
|
|
||||||
if (EntityTransferModule.IsInTransit(sp.UUID))
|
if (EntityTransferModule.IsInTransit(sp.UUID))
|
||||||
{
|
{
|
||||||
sp.DoNotCloseAfterTeleport = true;
|
sp.DoNotCloseAfterTeleport = true;
|
||||||
|
@ -4018,6 +4023,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// uses down the line.
|
// uses down the line.
|
||||||
sp.TeleportFlags = (TPFlags)teleportFlags;
|
sp.TeleportFlags = (TPFlags)teleportFlags;
|
||||||
|
|
||||||
|
// We must carry out a further authorization check if there's an
|
||||||
|
// attempt to make a child agent into a root agent, since SeeIntoRegion may have allowed a child
|
||||||
|
// agent to login to a region where a full avatar would not be allowed.
|
||||||
|
//
|
||||||
|
// We determine whether this is a CreateAgent for a future non-child agent by inspecting
|
||||||
|
// TeleportFlags, which will be default for a child connection. This relies on input from the source
|
||||||
|
// region.
|
||||||
|
if (sp.TeleportFlags != TPFlags.Default)
|
||||||
|
{
|
||||||
|
if (!AuthorizeUser(acd, false, out reason))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (sp.IsChildAgent)
|
if (sp.IsChildAgent)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
|
@ -4526,10 +4544,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
|
ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
|
||||||
if (childAgentUpdate != null)
|
if (childAgentUpdate != null)
|
||||||
{
|
{
|
||||||
if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID)
|
// if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID)
|
||||||
// Only warn for now
|
// // Only warn for now
|
||||||
m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?",
|
// m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?",
|
||||||
childAgentUpdate.UUID, cAgentData.SessionID);
|
// childAgentUpdate.UUID, cAgentData.SessionID);
|
||||||
|
|
||||||
// I can't imagine *yet* why we would get an update if the agent is a root agent..
|
// I can't imagine *yet* why we would get an update if the agent is a root agent..
|
||||||
// however to avoid a race condition crossing borders..
|
// however to avoid a race condition crossing borders..
|
||||||
|
@ -4630,6 +4648,50 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return IncomingCloseAgent(agentID, true);
|
return IncomingCloseAgent(agentID, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tell a single agent to prepare to close.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This should only be called if we may close the agent but there will be some delay in so doing. Meant for
|
||||||
|
/// internal use - other callers should almost certainly called IncomingCloseAgent().
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="sp"></param>
|
||||||
|
/// <returns>true if pre-close state notification was successful. false if the agent
|
||||||
|
/// was not in a state where it could transition to pre-close.</returns>
|
||||||
|
public bool IncomingPreCloseAgent(ScenePresence sp)
|
||||||
|
{
|
||||||
|
lock (m_removeClientLock)
|
||||||
|
{
|
||||||
|
// We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
|
||||||
|
// teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
|
||||||
|
// want to obey this close since C may have renewed the child agent lease on B.
|
||||||
|
if (sp.DoNotCloseAfterTeleport)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection",
|
||||||
|
sp.IsChildAgent ? "child" : "root", sp.Name, Name);
|
||||||
|
|
||||||
|
// Need to reset the flag so that a subsequent close after another teleport can succeed.
|
||||||
|
sp.DoNotCloseAfterTeleport = false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sp.LifecycleState != ScenePresenceState.Running)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}",
|
||||||
|
sp.Name, Name, sp.LifecycleState);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.LifecycleState = ScenePresenceState.PreRemove;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tell a single agent to disconnect from the region.
|
/// Tell a single agent to disconnect from the region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4649,16 +4711,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (sp == null)
|
if (sp == null)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}",
|
"[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}",
|
||||||
agentID, Name);
|
agentID, Name);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp.LifecycleState != ScenePresenceState.Running)
|
if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}",
|
"[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}",
|
||||||
sp.Name, Name, sp.LifecycleState);
|
sp.Name, Name, sp.LifecycleState);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -6025,7 +6087,7 @@ Environment.Exit(1);
|
||||||
{
|
{
|
||||||
if (!AuthorizeUser(aCircuit, false, out reason))
|
if (!AuthorizeUser(aCircuit, false, out reason))
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
|
//m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// This is a state machine.
|
/// This is a state machine.
|
||||||
///
|
///
|
||||||
/// [Entry] => Running
|
/// [Entry] => Running
|
||||||
/// Running => Removing
|
/// Running => PreRemove, Removing
|
||||||
|
/// PreRemove => Running, Removing
|
||||||
/// Removing => Removed
|
/// Removing => Removed
|
||||||
///
|
///
|
||||||
/// All other methods should only see the scene presence in running state - this is the normal operational state
|
/// All other methods should only see the scene presence in running state - this is the normal operational state
|
||||||
|
@ -46,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public enum ScenePresenceState
|
public enum ScenePresenceState
|
||||||
{
|
{
|
||||||
Running, // Normal operation state. The scene presence is available.
|
Running, // Normal operation state. The scene presence is available.
|
||||||
|
PreRemove, // The presence is due to be removed but can still be returning to running.
|
||||||
Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient.
|
Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient.
|
||||||
Removed, // The presence has been removed from the scene and is effectively dead.
|
Removed, // The presence has been removed from the scene and is effectively dead.
|
||||||
// There is no exit from this state.
|
// There is no exit from this state.
|
||||||
|
@ -80,8 +82,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
if (newState == ScenePresenceState.Removing && m_state == ScenePresenceState.Running)
|
if (newState == m_state)
|
||||||
|
return;
|
||||||
|
else if (newState == ScenePresenceState.Running && m_state == ScenePresenceState.PreRemove)
|
||||||
transitionOkay = true;
|
transitionOkay = true;
|
||||||
|
else if (newState == ScenePresenceState.PreRemove && m_state == ScenePresenceState.Running)
|
||||||
|
transitionOkay = true;
|
||||||
|
else if (newState == ScenePresenceState.Removing)
|
||||||
|
{
|
||||||
|
if (m_state == ScenePresenceState.Running || m_state == ScenePresenceState.PreRemove)
|
||||||
|
transitionOkay = true;
|
||||||
|
}
|
||||||
else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing)
|
else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing)
|
||||||
transitionOkay = true;
|
transitionOkay = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -624,9 +624,16 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden
|
||||||
int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
|
int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum();
|
||||||
avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
|
avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1);
|
||||||
|
|
||||||
|
string childAgentStatus;
|
||||||
|
|
||||||
|
if (llClient.SceneAgent != null)
|
||||||
|
childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y";
|
||||||
|
else
|
||||||
|
childAgentStatus = "Off!";
|
||||||
|
|
||||||
m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}",
|
m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}",
|
||||||
scene.RegionInfo.RegionName, llClient.Name,
|
scene.RegionInfo.RegionName, llClient.Name,
|
||||||
llClient.SceneAgent.IsChildAgent ? "N" : "Y",
|
childAgentStatus,
|
||||||
(DateTime.Now - cinfo.StartedTime).Minutes,
|
(DateTime.Now - cinfo.StartedTime).Minutes,
|
||||||
avg_reqs,
|
avg_reqs,
|
||||||
string.Format(
|
string.Format(
|
||||||
|
|
|
@ -106,6 +106,9 @@ namespace OpenSim.Server.Handlers.Grid
|
||||||
case "get_default_regions":
|
case "get_default_regions":
|
||||||
return GetDefaultRegions(request);
|
return GetDefaultRegions(request);
|
||||||
|
|
||||||
|
case "get_default_hypergrid_regions":
|
||||||
|
return GetDefaultHypergridRegions(request);
|
||||||
|
|
||||||
case "get_fallback_regions":
|
case "get_fallback_regions":
|
||||||
return GetFallbackRegions(request);
|
return GetFallbackRegions(request);
|
||||||
|
|
||||||
|
@ -444,6 +447,36 @@ namespace OpenSim.Server.Handlers.Grid
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] GetDefaultHypergridRegions(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat("[GRID HANDLER]: GetDefaultRegions");
|
||||||
|
UUID scopeID = UUID.Zero;
|
||||||
|
if (request.ContainsKey("SCOPEID"))
|
||||||
|
UUID.TryParse(request["SCOPEID"].ToString(), out scopeID);
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region range");
|
||||||
|
|
||||||
|
List<GridRegion> rinfos = m_GridService.GetDefaultHypergridRegions(scopeID);
|
||||||
|
|
||||||
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||||
|
if ((rinfos == null) || ((rinfos != null) && (rinfos.Count == 0)))
|
||||||
|
result["result"] = "null";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
foreach (GridRegion rinfo in rinfos)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> rinfoDict = rinfo.ToKeyValuePairs();
|
||||||
|
result["region" + i] = rinfoDict;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString);
|
||||||
|
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||||
|
}
|
||||||
|
|
||||||
byte[] GetFallbackRegions(Dictionary<string, object> request)
|
byte[] GetFallbackRegions(Dictionary<string, object> request)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[GRID HANDLER]: GetRegionRange");
|
//m_log.DebugFormat("[GRID HANDLER]: GetRegionRange");
|
||||||
|
|
|
@ -525,6 +525,57 @@ namespace OpenSim.Services.Connectors
|
||||||
return rinfos;
|
return rinfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
sendData["SCOPEID"] = scopeID.ToString();
|
||||||
|
|
||||||
|
sendData["METHOD"] = "get_default_hypergrid_regions";
|
||||||
|
|
||||||
|
List<GridRegion> rinfos = new List<GridRegion>();
|
||||||
|
string reply = string.Empty;
|
||||||
|
string uri = m_ServerURI + "/grid";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||||
|
uri,
|
||||||
|
ServerUtils.BuildQueryString(sendData));
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message);
|
||||||
|
return rinfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply != string.Empty)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
|
||||||
|
|
||||||
|
if (replyData != null)
|
||||||
|
{
|
||||||
|
Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
|
||||||
|
foreach (object r in rinfosList)
|
||||||
|
{
|
||||||
|
if (r is Dictionary<string, object>)
|
||||||
|
{
|
||||||
|
GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
|
||||||
|
rinfos.Add(rinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions {0} received null response",
|
||||||
|
scopeID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions received null reply");
|
||||||
|
|
||||||
|
return rinfos;
|
||||||
|
}
|
||||||
|
|
||||||
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
|
|
|
@ -341,6 +341,12 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
return new List<GridRegion>(0);
|
return new List<GridRegion>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
// TODO: Allow specifying the default grid location
|
||||||
|
return GetDefaultRegions(scopeID);
|
||||||
|
}
|
||||||
|
|
||||||
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true);
|
GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true);
|
||||||
|
|
|
@ -265,8 +265,9 @@ namespace OpenSim.Services.GridService
|
||||||
m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
|
m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}",
|
m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3} with flags {4}",
|
||||||
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY);
|
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY,
|
||||||
|
(OpenSim.Framework.RegionFlags)flags);
|
||||||
|
|
||||||
return String.Empty;
|
return String.Empty;
|
||||||
}
|
}
|
||||||
|
@ -478,6 +479,33 @@ namespace OpenSim.Services.GridService
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
|
||||||
|
{
|
||||||
|
List<GridRegion> ret = new List<GridRegion>();
|
||||||
|
|
||||||
|
List<RegionData> regions = m_Database.GetDefaultHypergridRegions(scopeID);
|
||||||
|
|
||||||
|
foreach (RegionData r in regions)
|
||||||
|
{
|
||||||
|
if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0)
|
||||||
|
ret.Add(RegionData2RegionInfo(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
int hgDefaultRegionsFoundOnline = regions.Count;
|
||||||
|
|
||||||
|
// For now, hypergrid default regions will always be given precedence but we will also return simple default
|
||||||
|
// regions in case no specific hypergrid regions are specified.
|
||||||
|
ret.AddRange(GetDefaultRegions(scopeID));
|
||||||
|
|
||||||
|
int normalDefaultRegionsFoundOnline = ret.Count - hgDefaultRegionsFoundOnline;
|
||||||
|
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[GRID SERVICE]: GetDefaultHypergridRegions returning {0} hypergrid default and {1} normal default regions",
|
||||||
|
hgDefaultRegionsFoundOnline, normalDefaultRegionsFoundOnline);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||||
{
|
{
|
||||||
List<GridRegion> ret = new List<GridRegion>();
|
List<GridRegion> ret = new List<GridRegion>();
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace OpenSim.Services.GridService
|
||||||
{
|
{
|
||||||
if (m_DefaultRegion == null)
|
if (m_DefaultRegion == null)
|
||||||
{
|
{
|
||||||
List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
|
List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
|
||||||
if (defs != null && defs.Count > 0)
|
if (defs != null && defs.Count > 0)
|
||||||
m_DefaultRegion = defs[0];
|
m_DefaultRegion = defs[0];
|
||||||
else
|
else
|
||||||
|
|
|
@ -171,7 +171,7 @@ namespace OpenSim.Services.HypergridService
|
||||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName);
|
m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName);
|
||||||
if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty)
|
if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty)
|
||||||
{
|
{
|
||||||
List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID);
|
List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
|
||||||
if (defs != null && defs.Count > 0)
|
if (defs != null && defs.Count > 0)
|
||||||
{
|
{
|
||||||
region = defs[0];
|
region = defs[0];
|
||||||
|
|
|
@ -97,6 +97,7 @@ namespace OpenSim.Services.Interfaces
|
||||||
List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax);
|
List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax);
|
||||||
|
|
||||||
List<GridRegion> GetDefaultRegions(UUID scopeID);
|
List<GridRegion> GetDefaultRegions(UUID scopeID);
|
||||||
|
List<GridRegion> GetDefaultHypergridRegions(UUID scopeID);
|
||||||
List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y);
|
List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y);
|
||||||
List<GridRegion> GetHyperlinks(UUID scopeID);
|
List<GridRegion> GetHyperlinks(UUID scopeID);
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,44 @@ namespace OpenSim.Services.UserAccountService
|
||||||
public GridUserService(IConfigSource config) : base(config)
|
public GridUserService(IConfigSource config) : base(config)
|
||||||
{
|
{
|
||||||
m_log.Debug("[GRID USER SERVICE]: Starting user grid service");
|
m_log.Debug("[GRID USER SERVICE]: Starting user grid service");
|
||||||
|
|
||||||
|
MainConsole.Instance.Commands.AddCommand(
|
||||||
|
"Users", false,
|
||||||
|
"show grid users online",
|
||||||
|
"show grid users online",
|
||||||
|
"Show number of grid users registered as online.",
|
||||||
|
"This number may not be accurate as a region may crash or not be cleanly shutdown and leave grid users shown as online\n."
|
||||||
|
+ "For this reason, users online for more than 5 days are not currently counted",
|
||||||
|
HandleShowGridUsersOnline);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void HandleShowGridUsersOnline(string module, string[] cmdparams)
|
||||||
|
{
|
||||||
|
// if (cmdparams.Length != 4)
|
||||||
|
// {
|
||||||
|
// MainConsole.Instance.Output("Usage: show grid users online");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// int onlineCount;
|
||||||
|
int onlineRecentlyCount = 0;
|
||||||
|
|
||||||
|
DateTime now = DateTime.UtcNow;
|
||||||
|
|
||||||
|
foreach (GridUserData gu in m_Database.GetAll(""))
|
||||||
|
{
|
||||||
|
if (bool.Parse(gu.Data["Online"]))
|
||||||
|
{
|
||||||
|
// onlineCount++;
|
||||||
|
|
||||||
|
int unixLoginTime = int.Parse(gu.Data["Login"]);
|
||||||
|
|
||||||
|
if ((now - Util.ToDateTime(unixLoginTime)).Days < 5)
|
||||||
|
onlineRecentlyCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.OutputFormat("Users online: {0}", onlineRecentlyCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual GridUserInfo GetGridUserInfo(string userID)
|
public virtual GridUserInfo GetGridUserInfo(string userID)
|
||||||
|
|
|
@ -35,6 +35,11 @@ namespace pCampBot
|
||||||
{
|
{
|
||||||
public class AbstractBehaviour : IBehaviour
|
public class AbstractBehaviour : IBehaviour
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Abbreviated name of this behaviour.
|
||||||
|
/// </summary>
|
||||||
|
public string AbbreviatedName { get; protected set; }
|
||||||
|
|
||||||
public string Name { get; protected set; }
|
public string Name { get; protected set; }
|
||||||
|
|
||||||
public Bot Bot { get; protected set; }
|
public Bot Bot { get; protected set; }
|
||||||
|
@ -45,5 +50,7 @@ namespace pCampBot
|
||||||
{
|
{
|
||||||
Bot = bot;
|
Bot = bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void Close() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,11 @@ namespace pCampBot
|
||||||
|
|
||||||
public const int m_regionCrossingTimeout = 1000 * 60;
|
public const int m_regionCrossingTimeout = 1000 * 60;
|
||||||
|
|
||||||
public CrossBehaviour() { Name = "Cross"; }
|
public CrossBehaviour()
|
||||||
|
{
|
||||||
|
AbbreviatedName = "c";
|
||||||
|
Name = "Cross";
|
||||||
|
}
|
||||||
|
|
||||||
public override void Action()
|
public override void Action()
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@ using OpenMetaverse;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using pCampBot.Interfaces;
|
using pCampBot.Interfaces;
|
||||||
|
|
||||||
namespace pCampBot
|
namespace pCampBot
|
||||||
|
@ -41,7 +42,11 @@ namespace pCampBot
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class GrabbingBehaviour : AbstractBehaviour
|
public class GrabbingBehaviour : AbstractBehaviour
|
||||||
{
|
{
|
||||||
public GrabbingBehaviour() { Name = "Grabbing"; }
|
public GrabbingBehaviour()
|
||||||
|
{
|
||||||
|
AbbreviatedName = "g";
|
||||||
|
Name = "Grabbing";
|
||||||
|
}
|
||||||
|
|
||||||
public override void Action()
|
public override void Action()
|
||||||
{
|
{
|
||||||
|
@ -56,6 +61,8 @@ namespace pCampBot
|
||||||
Bot.Client.Self.Grab(prim.LocalID);
|
Bot.Client.Self.Grab(prim.LocalID);
|
||||||
Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero);
|
Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero);
|
||||||
Bot.Client.Self.DeGrab(prim.LocalID);
|
Bot.Client.Self.DeGrab(prim.LocalID);
|
||||||
|
|
||||||
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,6 +38,10 @@ namespace pCampBot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NoneBehaviour : AbstractBehaviour
|
public class NoneBehaviour : AbstractBehaviour
|
||||||
{
|
{
|
||||||
public NoneBehaviour() { Name = "None"; }
|
public NoneBehaviour()
|
||||||
|
{
|
||||||
|
AbbreviatedName = "n";
|
||||||
|
Name = "None";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,6 +46,7 @@ namespace pCampBot
|
||||||
|
|
||||||
public PhysicsBehaviour()
|
public PhysicsBehaviour()
|
||||||
{
|
{
|
||||||
|
AbbreviatedName = "p";
|
||||||
Name = "Physics";
|
Name = "Physics";
|
||||||
talkarray = readexcuses();
|
talkarray = readexcuses();
|
||||||
}
|
}
|
||||||
|
@ -77,6 +78,12 @@ namespace pCampBot
|
||||||
Bot.Client.Self.Chat(randomf, 0, ChatType.Normal);
|
Bot.Client.Self.Chat(randomf, 0, ChatType.Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Close()
|
||||||
|
{
|
||||||
|
if (Bot.ConnectionState == ConnectionState.Connected)
|
||||||
|
Bot.Client.Self.Jump(false);
|
||||||
|
}
|
||||||
|
|
||||||
private string[] readexcuses()
|
private string[] readexcuses()
|
||||||
{
|
{
|
||||||
string allexcuses = "";
|
string allexcuses = "";
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using pCampBot.Interfaces;
|
using pCampBot.Interfaces;
|
||||||
|
@ -42,7 +43,11 @@ namespace pCampBot
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public TeleportBehaviour() { Name = "Teleport"; }
|
public TeleportBehaviour()
|
||||||
|
{
|
||||||
|
AbbreviatedName = "t";
|
||||||
|
Name = "Teleport";
|
||||||
|
}
|
||||||
|
|
||||||
public override void Action()
|
public override void Action()
|
||||||
{
|
{
|
||||||
|
@ -70,6 +75,8 @@ namespace pCampBot
|
||||||
Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition);
|
Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition);
|
||||||
|
|
||||||
Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition);
|
Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition);
|
||||||
|
|
||||||
|
Thread.Sleep(Bot.Random.Next(3000, 10000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -72,9 +72,10 @@ namespace pCampBot
|
||||||
/// Behaviours implemented by this bot.
|
/// Behaviours implemented by this bot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Lock this list before manipulating it.
|
/// Indexed by abbreviated name. There can only be one instance of a particular behaviour.
|
||||||
|
/// Lock this structure before manipulating it.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public List<IBehaviour> Behaviours { get; private set; }
|
public Dictionary<string, IBehaviour> Behaviours { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Objects that the bot has discovered.
|
/// Objects that the bot has discovered.
|
||||||
|
@ -165,8 +166,6 @@ namespace pCampBot
|
||||||
{
|
{
|
||||||
ConnectionState = ConnectionState.Disconnected;
|
ConnectionState = ConnectionState.Disconnected;
|
||||||
|
|
||||||
behaviours.ForEach(b => b.Initialize(this));
|
|
||||||
|
|
||||||
Random = new Random(Environment.TickCount);// We do stuff randomly here
|
Random = new Random(Environment.TickCount);// We do stuff randomly here
|
||||||
FirstName = firstName;
|
FirstName = firstName;
|
||||||
LastName = lastName;
|
LastName = lastName;
|
||||||
|
@ -176,12 +175,53 @@ namespace pCampBot
|
||||||
StartLocation = startLocation;
|
StartLocation = startLocation;
|
||||||
|
|
||||||
Manager = bm;
|
Manager = bm;
|
||||||
Behaviours = behaviours;
|
|
||||||
|
Behaviours = new Dictionary<string, IBehaviour>();
|
||||||
|
foreach (IBehaviour behaviour in behaviours)
|
||||||
|
AddBehaviour(behaviour);
|
||||||
|
|
||||||
// Only calling for use as a template.
|
// Only calling for use as a template.
|
||||||
CreateLibOmvClient();
|
CreateLibOmvClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryGetBehaviour(string abbreviatedName, out IBehaviour behaviour)
|
||||||
|
{
|
||||||
|
lock (Behaviours)
|
||||||
|
return Behaviours.TryGetValue(abbreviatedName, out behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool AddBehaviour(IBehaviour behaviour)
|
||||||
|
{
|
||||||
|
lock (Behaviours)
|
||||||
|
{
|
||||||
|
if (!Behaviours.ContainsKey(behaviour.AbbreviatedName))
|
||||||
|
{
|
||||||
|
behaviour.Initialize(this);
|
||||||
|
Behaviours.Add(behaviour.AbbreviatedName, behaviour);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemoveBehaviour(string abbreviatedName)
|
||||||
|
{
|
||||||
|
lock (Behaviours)
|
||||||
|
{
|
||||||
|
IBehaviour behaviour;
|
||||||
|
|
||||||
|
if (!Behaviours.TryGetValue(abbreviatedName, out behaviour))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
behaviour.Close();
|
||||||
|
Behaviours.Remove(abbreviatedName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CreateLibOmvClient()
|
private void CreateLibOmvClient()
|
||||||
{
|
{
|
||||||
GridClient newClient = new GridClient();
|
GridClient newClient = new GridClient();
|
||||||
|
@ -237,16 +277,25 @@ namespace pCampBot
|
||||||
private void Action()
|
private void Action()
|
||||||
{
|
{
|
||||||
while (ConnectionState != ConnectionState.Disconnecting)
|
while (ConnectionState != ConnectionState.Disconnecting)
|
||||||
|
{
|
||||||
lock (Behaviours)
|
lock (Behaviours)
|
||||||
Behaviours.ForEach(
|
{
|
||||||
b =>
|
foreach (IBehaviour behaviour in Behaviours.Values)
|
||||||
{
|
{
|
||||||
Thread.Sleep(Random.Next(3000, 10000));
|
// Thread.Sleep(Random.Next(3000, 10000));
|
||||||
|
|
||||||
// m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType());
|
// m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType());
|
||||||
b.Action();
|
behaviour.Action();
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
|
|
||||||
|
// XXX: This is a really shitty way of yielding so that behaviours can be added/removed
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (Behaviours)
|
||||||
|
foreach (IBehaviour b in Behaviours.Values)
|
||||||
|
b.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -140,7 +140,7 @@ namespace pCampBot
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Behaviour switches for bots.
|
/// Behaviour switches for bots.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private HashSet<string> m_behaviourSwitches = new HashSet<string>();
|
private HashSet<string> m_defaultBehaviourSwitches = new HashSet<string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor Creates MainConsole.Instance to take commands and provide the place to write data
|
/// Constructor Creates MainConsole.Instance to take commands and provide the place to write data
|
||||||
|
@ -194,6 +194,20 @@ namespace pCampBot
|
||||||
+ "If no <n> is given, then all currently connected bots are disconnected.",
|
+ "If no <n> is given, then all currently connected bots are disconnected.",
|
||||||
HandleDisconnect);
|
HandleDisconnect);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand(
|
||||||
|
"bot", false, "add behaviour", "add behaviour <abbreviated-name> [<bot-number>]",
|
||||||
|
"Add a behaviour to a bot",
|
||||||
|
"If no bot number is specified then behaviour is added to all bots.\n"
|
||||||
|
+ "Can be performed on connected or disconnected bots.",
|
||||||
|
HandleAddBehaviour);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand(
|
||||||
|
"bot", false, "remove behaviour", "remove behaviour <abbreviated-name> [<bot-number>]",
|
||||||
|
"Remove a behaviour from a bot",
|
||||||
|
"If no bot number is specified then behaviour is added to all bots.\n"
|
||||||
|
+ "Can be performed on connected or disconnected bots.",
|
||||||
|
HandleRemoveBehaviour);
|
||||||
|
|
||||||
m_console.Commands.AddCommand(
|
m_console.Commands.AddCommand(
|
||||||
"bot", false, "sit", "sit", "Sit all bots on the ground.",
|
"bot", false, "sit", "sit", "Sit all bots on the ground.",
|
||||||
HandleSit);
|
HandleSit);
|
||||||
|
@ -212,7 +226,7 @@ namespace pCampBot
|
||||||
"bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus);
|
"bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus);
|
||||||
|
|
||||||
m_console.Commands.AddCommand(
|
m_console.Commands.AddCommand(
|
||||||
"bot", false, "show bot", "show bot <n>",
|
"bot", false, "show bot", "show bot <bot-number>",
|
||||||
"Shows the detailed status and settings of a particular bot.", HandleShowBotStatus);
|
"Shows the detailed status and settings of a particular bot.", HandleShowBotStatus);
|
||||||
|
|
||||||
m_bots = new List<Bot>();
|
m_bots = new List<Bot>();
|
||||||
|
@ -235,7 +249,7 @@ namespace pCampBot
|
||||||
m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last"));
|
m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last"));
|
||||||
|
|
||||||
Array.ForEach<string>(
|
Array.ForEach<string>(
|
||||||
startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b));
|
startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_defaultBehaviourSwitches.Add(b));
|
||||||
|
|
||||||
for (int i = 0; i < botcount; i++)
|
for (int i = 0; i < botcount; i++)
|
||||||
{
|
{
|
||||||
|
@ -243,30 +257,52 @@ namespace pCampBot
|
||||||
{
|
{
|
||||||
string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber);
|
string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber);
|
||||||
|
|
||||||
// We must give each bot its own list of instantiated behaviours since they store state.
|
CreateBot(
|
||||||
List<IBehaviour> behaviours = new List<IBehaviour>();
|
this,
|
||||||
|
CreateBehavioursFromAbbreviatedNames(m_defaultBehaviourSwitches),
|
||||||
// Hard-coded for now
|
m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting);
|
||||||
if (m_behaviourSwitches.Contains("c"))
|
|
||||||
behaviours.Add(new CrossBehaviour());
|
|
||||||
|
|
||||||
if (m_behaviourSwitches.Contains("g"))
|
|
||||||
behaviours.Add(new GrabbingBehaviour());
|
|
||||||
|
|
||||||
if (m_behaviourSwitches.Contains("n"))
|
|
||||||
behaviours.Add(new NoneBehaviour());
|
|
||||||
|
|
||||||
if (m_behaviourSwitches.Contains("p"))
|
|
||||||
behaviours.Add(new PhysicsBehaviour());
|
|
||||||
|
|
||||||
if (m_behaviourSwitches.Contains("t"))
|
|
||||||
behaviours.Add(new TeleportBehaviour());
|
|
||||||
|
|
||||||
CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<IBehaviour> CreateBehavioursFromAbbreviatedNames(HashSet<string> abbreviatedNames)
|
||||||
|
{
|
||||||
|
// We must give each bot its own list of instantiated behaviours since they store state.
|
||||||
|
List<IBehaviour> behaviours = new List<IBehaviour>();
|
||||||
|
|
||||||
|
// Hard-coded for now
|
||||||
|
foreach (string abName in abbreviatedNames)
|
||||||
|
{
|
||||||
|
IBehaviour newBehaviour = null;
|
||||||
|
|
||||||
|
if (abName == "c")
|
||||||
|
newBehaviour = new CrossBehaviour();
|
||||||
|
|
||||||
|
if (abName == "g")
|
||||||
|
newBehaviour = new GrabbingBehaviour();
|
||||||
|
|
||||||
|
if (abName == "n")
|
||||||
|
newBehaviour = new NoneBehaviour();
|
||||||
|
|
||||||
|
if (abName == "p")
|
||||||
|
newBehaviour = new PhysicsBehaviour();
|
||||||
|
|
||||||
|
if (abName == "t")
|
||||||
|
newBehaviour = new TeleportBehaviour();
|
||||||
|
|
||||||
|
if (newBehaviour != null)
|
||||||
|
{
|
||||||
|
behaviours.Add(newBehaviour);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("No behaviour with abbreviated name {0} found", abName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return behaviours;
|
||||||
|
}
|
||||||
|
|
||||||
public void ConnectBots(int botcount)
|
public void ConnectBots(int botcount)
|
||||||
{
|
{
|
||||||
ConnectingBots = true;
|
ConnectingBots = true;
|
||||||
|
@ -453,6 +489,118 @@ namespace pCampBot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleAddBehaviour(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
if (cmd.Length < 3 || cmd.Length > 4)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("Usage: add behaviour <abbreviated-behaviour> [<bot-number>]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string rawBehaviours = cmd[2];
|
||||||
|
|
||||||
|
List<Bot> botsToEffect = new List<Bot>();
|
||||||
|
|
||||||
|
if (cmd.Length == 3)
|
||||||
|
{
|
||||||
|
lock (m_bots)
|
||||||
|
botsToEffect.AddRange(m_bots);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int botNumber;
|
||||||
|
if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bot bot = GetBotFromNumber(botNumber);
|
||||||
|
|
||||||
|
if (bot == null)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
botsToEffect.Add(bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HashSet<string> rawAbbreviatedSwitchesToAdd = new HashSet<string>();
|
||||||
|
Array.ForEach<string>(rawBehaviours.Split(new char[] { ',' }), b => rawAbbreviatedSwitchesToAdd.Add(b));
|
||||||
|
|
||||||
|
foreach (Bot bot in botsToEffect)
|
||||||
|
{
|
||||||
|
List<IBehaviour> behavioursAdded = new List<IBehaviour>();
|
||||||
|
|
||||||
|
foreach (IBehaviour behaviour in CreateBehavioursFromAbbreviatedNames(rawAbbreviatedSwitchesToAdd))
|
||||||
|
{
|
||||||
|
if (bot.AddBehaviour(behaviour))
|
||||||
|
behavioursAdded.Add(behaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.OutputFormat(
|
||||||
|
"Added behaviours {0} to bot {1}",
|
||||||
|
string.Join(", ", behavioursAdded.ConvertAll<string>(b => b.Name).ToArray()), bot.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleRemoveBehaviour(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
if (cmd.Length < 3 || cmd.Length > 4)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("Usage: remove behaviour <abbreviated-behaviour> [<bot-number>]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string rawBehaviours = cmd[2];
|
||||||
|
|
||||||
|
List<Bot> botsToEffect = new List<Bot>();
|
||||||
|
|
||||||
|
if (cmd.Length == 3)
|
||||||
|
{
|
||||||
|
lock (m_bots)
|
||||||
|
botsToEffect.AddRange(m_bots);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int botNumber;
|
||||||
|
if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bot bot = GetBotFromNumber(botNumber);
|
||||||
|
|
||||||
|
if (bot == null)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
botsToEffect.Add(bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
HashSet<string> abbreviatedBehavioursToRemove = new HashSet<string>();
|
||||||
|
Array.ForEach<string>(rawBehaviours.Split(new char[] { ',' }), b => abbreviatedBehavioursToRemove.Add(b));
|
||||||
|
|
||||||
|
foreach (Bot bot in botsToEffect)
|
||||||
|
{
|
||||||
|
List<IBehaviour> behavioursRemoved = new List<IBehaviour>();
|
||||||
|
|
||||||
|
foreach (string b in abbreviatedBehavioursToRemove)
|
||||||
|
{
|
||||||
|
IBehaviour behaviour;
|
||||||
|
|
||||||
|
if (bot.TryGetBehaviour(b, out behaviour))
|
||||||
|
{
|
||||||
|
bot.RemoveBehaviour(b);
|
||||||
|
behavioursRemoved.Add(behaviour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.OutputFormat(
|
||||||
|
"Removed behaviours {0} to bot {1}",
|
||||||
|
string.Join(", ", behavioursRemoved.ConvertAll<string>(b => b.Name).ToArray()), bot.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleDisconnect(string module, string[] cmd)
|
private void HandleDisconnect(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
lock (m_bots)
|
lock (m_bots)
|
||||||
|
@ -572,10 +720,11 @@ namespace pCampBot
|
||||||
private void HandleShowBotsStatus(string module, string[] cmd)
|
private void HandleShowBotsStatus(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||||
cdt.AddColumn("Name", 30);
|
cdt.AddColumn("Name", 24);
|
||||||
cdt.AddColumn("Region", 30);
|
cdt.AddColumn("Region", 24);
|
||||||
cdt.AddColumn("Status", 14);
|
cdt.AddColumn("Status", 13);
|
||||||
cdt.AddColumn("Connections", 11);
|
cdt.AddColumn("Conns", 5);
|
||||||
|
cdt.AddColumn("Behaviours", 20);
|
||||||
|
|
||||||
Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>();
|
Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>();
|
||||||
foreach (object o in Enum.GetValues(typeof(ConnectionState)))
|
foreach (object o in Enum.GetValues(typeof(ConnectionState)))
|
||||||
|
@ -583,13 +732,17 @@ namespace pCampBot
|
||||||
|
|
||||||
lock (m_bots)
|
lock (m_bots)
|
||||||
{
|
{
|
||||||
foreach (Bot pb in m_bots)
|
foreach (Bot bot in m_bots)
|
||||||
{
|
{
|
||||||
Simulator currentSim = pb.Client.Network.CurrentSim;
|
Simulator currentSim = bot.Client.Network.CurrentSim;
|
||||||
totals[pb.ConnectionState]++;
|
totals[bot.ConnectionState]++;
|
||||||
|
|
||||||
cdt.AddRow(
|
cdt.AddRow(
|
||||||
pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState, pb.SimulatorsCount);
|
bot.Name,
|
||||||
|
currentSim != null ? currentSim.Name : "(none)",
|
||||||
|
bot.ConnectionState,
|
||||||
|
bot.SimulatorsCount,
|
||||||
|
string.Join(",", bot.Behaviours.Keys.ToArray()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,16 +769,11 @@ namespace pCampBot
|
||||||
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber))
|
if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string name = string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber);
|
Bot bot = GetBotFromNumber(botNumber);
|
||||||
|
|
||||||
Bot bot;
|
|
||||||
|
|
||||||
lock (m_bots)
|
|
||||||
bot = m_bots.Find(b => b.Name == name);
|
|
||||||
|
|
||||||
if (bot == null)
|
if (bot == null)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("No bot found with name {0}", name);
|
MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,12 +793,39 @@ namespace pCampBot
|
||||||
MainConsole.Instance.Output("Settings");
|
MainConsole.Instance.Output("Settings");
|
||||||
|
|
||||||
ConsoleDisplayList statusCdl = new ConsoleDisplayList();
|
ConsoleDisplayList statusCdl = new ConsoleDisplayList();
|
||||||
|
|
||||||
|
statusCdl.AddRow(
|
||||||
|
"Behaviours",
|
||||||
|
string.Join(", ", bot.Behaviours.Values.ToList().ConvertAll<string>(b => b.Name).ToArray()));
|
||||||
|
|
||||||
GridClient botClient = bot.Client;
|
GridClient botClient = bot.Client;
|
||||||
statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES);
|
statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES);
|
||||||
|
|
||||||
MainConsole.Instance.Output(statusCdl.ToString());
|
MainConsole.Instance.Output(statusCdl.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a specific bot from its number.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>null if no bot was found</returns>
|
||||||
|
/// <param name='botNumber'></param>
|
||||||
|
private Bot GetBotFromNumber(int botNumber)
|
||||||
|
{
|
||||||
|
string name = GenerateBotNameFromNumber(botNumber);
|
||||||
|
|
||||||
|
Bot bot;
|
||||||
|
|
||||||
|
lock (m_bots)
|
||||||
|
bot = m_bots.Find(b => b.Name == name);
|
||||||
|
|
||||||
|
return bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GenerateBotNameFromNumber(int botNumber)
|
||||||
|
{
|
||||||
|
return string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber);
|
||||||
|
}
|
||||||
|
|
||||||
internal void Grid_GridRegion(object o, GridRegionEventArgs args)
|
internal void Grid_GridRegion(object o, GridRegionEventArgs args)
|
||||||
{
|
{
|
||||||
lock (RegionsKnown)
|
lock (RegionsKnown)
|
||||||
|
|
|
@ -31,6 +31,11 @@ namespace pCampBot.Interfaces
|
||||||
{
|
{
|
||||||
public interface IBehaviour
|
public interface IBehaviour
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Abbreviated name of this behaviour.
|
||||||
|
/// </summary>
|
||||||
|
string AbbreviatedName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of this behaviour.
|
/// Name of this behaviour.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -45,6 +50,14 @@ namespace pCampBot.Interfaces
|
||||||
/// <param name="bot"></param>
|
/// <param name="bot"></param>
|
||||||
void Initialize(Bot bot);
|
void Initialize(Bot bot);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Close down this behaviour.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is triggered if a behaviour is removed via explicit command and when a bot is disconnected
|
||||||
|
/// </remarks>
|
||||||
|
void Close();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Action to take when this behaviour is invoked.
|
/// Action to take when this behaviour is invoked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -151,7 +151,8 @@ HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:Asset
|
||||||
; *
|
; *
|
||||||
[GridService]
|
[GridService]
|
||||||
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
|
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
|
||||||
HypergridLinker = true
|
|
||||||
|
HypergridLinker = true
|
||||||
|
|
||||||
; Realm = "regions"
|
; Realm = "regions"
|
||||||
; AllowDuplicateNames = "True"
|
; AllowDuplicateNames = "True"
|
||||||
|
@ -168,16 +169,31 @@ HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:Asset
|
||||||
;; Next, we can specify properties of regions, including default and fallback regions
|
;; Next, we can specify properties of regions, including default and fallback regions
|
||||||
;; The syntax is: Region_<RegionName> = "<flags>"
|
;; The syntax is: Region_<RegionName> = "<flags>"
|
||||||
;; or: Region_<RegionID> = "<flags>"
|
;; or: Region_<RegionID> = "<flags>"
|
||||||
;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut,Reservation,NoMove,Authenticate
|
;; where <flags> can be DefaultRegion, DefaultHGRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut, Reservation, NoMove, Authenticate
|
||||||
;; For example:
|
;;
|
||||||
|
;; DefaultRegion If a local login cannot be placed in the required region (e.g. home region does not exist, avatar is not allowed entry, etc.)
|
||||||
|
;; then this region becomes the destination. Only the first online default region will be used. If no DefaultHGRegion
|
||||||
|
;; is specified then this will also be used as the region for hypergrid connections that require it (commonly because they have not specified
|
||||||
|
;; an explicit region.
|
||||||
|
;;
|
||||||
|
;; DefaultHGRegion If an avatar connecting via the hypergrid does not specify a region, then they are placed here. Only the first online
|
||||||
|
;; region will be used.
|
||||||
|
;;
|
||||||
|
;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the
|
||||||
|
;; order specified. This only applies to local logins at this time, not Hypergrid connections.
|
||||||
|
;;
|
||||||
|
;; NoDirectLogin A hypergrid user cannot directly connect to this region. This does not apply to local logins.
|
||||||
|
;;
|
||||||
|
;; Persistent When the simulator is shutdown, the region is signalled as offline but left registered on the grid.
|
||||||
|
;;
|
||||||
; Region_Welcome_Area = "DefaultRegion, FallbackRegion"
|
; Region_Welcome_Area = "DefaultRegion, FallbackRegion"
|
||||||
; (replace spaces with underscore)
|
; (replace spaces with underscore)
|
||||||
|
|
||||||
;; Allow Hyperlinks to be created at the console
|
;; Allow Hyperlinks to be created at the console
|
||||||
HypergridLinker = true
|
HypergridLinker = true
|
||||||
|
|
||||||
;; If you have this set under [Hypergrid], no need to set it here, leave it commented
|
;; If you have this set under [Hypergrid], no need to set it here, leave it commented
|
||||||
; GatekeeperURI = "http://127.0.0.1:8002"
|
; GatekeeperURI = "http://127.0.0.1:8002"
|
||||||
|
|
||||||
|
|
||||||
; * This is the configuration for the freeswitch server in grid mode
|
; * This is the configuration for the freeswitch server in grid mode
|
||||||
|
|
|
@ -132,8 +132,24 @@ MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnecto
|
||||||
;; Next, we can specify properties of regions, including default and fallback regions
|
;; Next, we can specify properties of regions, including default and fallback regions
|
||||||
;; The syntax is: Region_<RegionName> = "<flags>"
|
;; The syntax is: Region_<RegionName> = "<flags>"
|
||||||
;; or: Region_<RegionID> = "<flags>"
|
;; or: Region_<RegionID> = "<flags>"
|
||||||
;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut,Reservation,NoMove,Authenticate
|
;; where <flags> can be DefaultRegion, DefaultHGRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut, Reservation, NoMove, Authenticate
|
||||||
;; For example:
|
;;
|
||||||
|
;; DefaultRegion If a local login cannot be placed in the required region (e.g. home region does not exist, avatar is not allowed entry, etc.)
|
||||||
|
;; then this region becomes the destination. Only the first online default region will be used. If no DefaultHGRegion
|
||||||
|
;; is specified then this will also be used as the region for hypergrid connections that require it (commonly because they have not specified
|
||||||
|
;; an explicit region.
|
||||||
|
;;
|
||||||
|
;; DefaultHGRegion If an avatar connecting via the hypergrid does not specify a region, then they are placed here. Only the first online
|
||||||
|
;; region will be used.
|
||||||
|
;;
|
||||||
|
;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the
|
||||||
|
;; order specified. This only applies to local logins at this time, not Hypergrid connections.
|
||||||
|
;;
|
||||||
|
;; NoDirectLogin A hypergrid user cannot directly connect to this region. This does not apply to local logins.
|
||||||
|
;;
|
||||||
|
;; Persistent When the simulator is shutdown, the region is signalled as offline but left registered on the grid.
|
||||||
|
;;
|
||||||
|
;; Example specification:
|
||||||
; Region_Welcome_Area = "DefaultRegion, FallbackRegion"
|
; Region_Welcome_Area = "DefaultRegion, FallbackRegion"
|
||||||
; (replace spaces with underscore)
|
; (replace spaces with underscore)
|
||||||
|
|
||||||
|
|
|
@ -81,11 +81,27 @@
|
||||||
;; Next, we can specify properties of regions, including default and fallback regions
|
;; Next, we can specify properties of regions, including default and fallback regions
|
||||||
;; The syntax is: Region_<RegioName> = "<flags>"
|
;; The syntax is: Region_<RegioName> = "<flags>"
|
||||||
;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut
|
;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut
|
||||||
|
;;
|
||||||
|
;; DefaultRegion If a local login cannot be placed in the required region (e.g. home region does not exist, avatar is not allowed entry, etc.)
|
||||||
|
;; then this region becomes the destination. Only the first online default region will be used. If no DefaultHGRegion
|
||||||
|
;; is specified then this will also be used as the region for hypergrid connections that require it (commonly because they have not specified
|
||||||
|
;; an explicit region.
|
||||||
|
;;
|
||||||
|
;; DefaultHGRegion If an avatar connecting via the hypergrid does not specify a region, then they are placed here. Only the first online
|
||||||
|
;; region will be used.
|
||||||
|
;;
|
||||||
|
;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the
|
||||||
|
;; order specified. This only applies to local logins at this time, not Hypergrid connections.
|
||||||
|
;;
|
||||||
|
;; NoDirectLogin A hypergrid user cannot directly connect to this region. This does not apply to local logins.
|
||||||
|
;;
|
||||||
|
;; Persistent When the simulator is shutdown, the region is signalled as offline but left registered on the grid.
|
||||||
|
;;
|
||||||
;; For example:
|
;; For example:
|
||||||
Region_Welcome_Area = "DefaultRegion, FallbackRegion"
|
Region_Welcome_Area = "DefaultRegion, FallbackRegion"
|
||||||
|
|
||||||
; === HG ONLY ===
|
; === HG ONLY ===
|
||||||
;; If you have this set under [Hypergrid], no need to set it here, leave it commented
|
;; If you have this set under [Hypergrid], no need to set it here, leave it commented
|
||||||
; GatekeeperURI="http://127.0.0.1:9000"
|
; GatekeeperURI="http://127.0.0.1:9000"
|
||||||
|
|
||||||
[LibraryModule]
|
[LibraryModule]
|
||||||
|
@ -94,7 +110,7 @@
|
||||||
|
|
||||||
[LoginService]
|
[LoginService]
|
||||||
WelcomeMessage = "Welcome, Avatar!"
|
WelcomeMessage = "Welcome, Avatar!"
|
||||||
;; If you have Gatekeeper set under [Hypergrid], no need to set it here, leave it commented
|
;; If you have Gatekeeper set under [Hypergrid], no need to set it here, leave it commented
|
||||||
; GatekeeperURI = "http://127.0.0.1:9000"
|
; GatekeeperURI = "http://127.0.0.1:9000"
|
||||||
|
|
||||||
SRV_HomeURI = "http://127.0.0.1:9000"
|
SRV_HomeURI = "http://127.0.0.1:9000"
|
||||||
|
|
Loading…
Reference in New Issue