From: Alan M Webb <alan_webb@us.ibm.com>
Added support for access control lists. Scene: Added test to AddNewClient for an entry in the access list when connecting to a region with limited access. EstateSettings: Added an HasAccess(UUID) property to test for an entry in the estate's access list. RemoteAdmin: Add RPC calls for admin_acl_list, clear, add, and remove.0.6.5-rc1
parent
8dbcfc70bf
commit
515e62dc2f
|
@ -102,19 +102,26 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
Dictionary<string, XmlRpcMethod> availableMethods = new Dictionary<string, XmlRpcMethod>();
|
Dictionary<string, XmlRpcMethod> availableMethods = new Dictionary<string, XmlRpcMethod>();
|
||||||
availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod;
|
availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod;
|
||||||
availableMethods["admin_delete_region"] = XmlRpcDeleteRegionMethod;
|
availableMethods["admin_delete_region"] = XmlRpcDeleteRegionMethod;
|
||||||
|
availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
|
||||||
availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
|
availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
|
||||||
availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
|
availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
|
||||||
availableMethods["admin_restart"] = XmlRpcRestartMethod;
|
availableMethods["admin_restart"] = XmlRpcRestartMethod;
|
||||||
availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
|
availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
|
||||||
|
// User management
|
||||||
availableMethods["admin_create_user"] = XmlRpcCreateUserMethod;
|
availableMethods["admin_create_user"] = XmlRpcCreateUserMethod;
|
||||||
availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod;
|
availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod;
|
||||||
availableMethods["admin_exists_user"] = XmlRpcUserExistsMethod;
|
availableMethods["admin_exists_user"] = XmlRpcUserExistsMethod;
|
||||||
availableMethods["admin_update_user"] = XmlRpcUpdateUserAccountMethod;
|
availableMethods["admin_update_user"] = XmlRpcUpdateUserAccountMethod;
|
||||||
|
// Region state management
|
||||||
availableMethods["admin_load_xml"] = XmlRpcLoadXMLMethod;
|
availableMethods["admin_load_xml"] = XmlRpcLoadXMLMethod;
|
||||||
availableMethods["admin_save_xml"] = XmlRpcSaveXMLMethod;
|
availableMethods["admin_save_xml"] = XmlRpcSaveXMLMethod;
|
||||||
availableMethods["admin_load_oar"] = XmlRpcLoadOARMethod;
|
availableMethods["admin_load_oar"] = XmlRpcLoadOARMethod;
|
||||||
availableMethods["admin_save_oar"] = XmlRpcSaveOARMethod;
|
availableMethods["admin_save_oar"] = XmlRpcSaveOARMethod;
|
||||||
availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
|
// Estate access list management
|
||||||
|
availableMethods["admin_acl_clear"] = XmlRpcAccessListClear;
|
||||||
|
availableMethods["admin_acl_add"] = XmlRpcAccessListAdd;
|
||||||
|
availableMethods["admin_acl_remove"] = XmlRpcAccessListRemove;
|
||||||
|
availableMethods["admin_acl_list"] = XmlRpcAccessListList;
|
||||||
|
|
||||||
// Either enable full remote functionality or just selected features
|
// Either enable full remote functionality or just selected features
|
||||||
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
||||||
|
@ -1496,8 +1503,287 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public XmlRpcResponse XmlRpcAccessListClear(XmlRpcRequest request)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Received Access List Clear Request");
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
Hashtable responseData = new Hashtable();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
responseData["success"] = "true";
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable) request.Params[0];
|
||||||
|
|
||||||
|
if (!requestData.Contains("password"))
|
||||||
|
throw new Exception(String.Format("missing required parameter"));
|
||||||
|
if (!String.IsNullOrEmpty(requiredPassword) &&
|
||||||
|
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
|
||||||
|
|
||||||
|
if (requestData.Contains("region_uuid"))
|
||||||
|
{
|
||||||
|
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
|
||||||
|
}
|
||||||
|
else if (requestData.Contains("region_name"))
|
||||||
|
{
|
||||||
|
string region_name = (string) requestData["region_name"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_name));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
|
||||||
|
}
|
||||||
|
else throw new Exception("neither region_name nor region_uuid given");
|
||||||
|
|
||||||
|
Scene s = m_app.SceneManager.CurrentScene;
|
||||||
|
s.RegionInfo.EstateSettings.EstateAccess = new UUID[]{};
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[RADMIN] Access List Clear Request: {0}", e.Message);
|
||||||
|
|
||||||
|
responseData["success"] = "false";
|
||||||
|
responseData["error"] = e.Message;
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
response.Value = responseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Access List Clear Request complete");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlRpcResponse XmlRpcAccessListAdd(XmlRpcRequest request)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Received Access List Add Request");
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
Hashtable responseData = new Hashtable();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
responseData["success"] = "true";
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable) request.Params[0];
|
||||||
|
|
||||||
|
if (!requestData.Contains("password"))
|
||||||
|
throw new Exception(String.Format("missing required parameter"));
|
||||||
|
if (!String.IsNullOrEmpty(requiredPassword) &&
|
||||||
|
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
|
||||||
|
|
||||||
|
if (requestData.Contains("region_uuid"))
|
||||||
|
{
|
||||||
|
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
|
||||||
|
}
|
||||||
|
else if (requestData.Contains("region_name"))
|
||||||
|
{
|
||||||
|
string region_name = (string) requestData["region_name"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_name));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
|
||||||
|
}
|
||||||
|
else throw new Exception("neither region_name nor region_uuid given");
|
||||||
|
|
||||||
|
int addk = 0;
|
||||||
|
|
||||||
|
if(requestData.Contains("users"))
|
||||||
|
{
|
||||||
|
UserProfileCacheService ups = m_app.CommunicationsManager.UserProfileCacheService;
|
||||||
|
Scene s = m_app.SceneManager.CurrentScene;
|
||||||
|
Hashtable users = (Hashtable) requestData["users"];
|
||||||
|
List<UUID> uuids = new List<UUID>();
|
||||||
|
foreach(string name in users.Values)
|
||||||
|
{
|
||||||
|
string[] parts = name.Split();
|
||||||
|
uuids.Add(ups.GetUserDetails(parts[0],parts[1]).UserProfile.ID);
|
||||||
|
}
|
||||||
|
List<UUID> acl = new List<UUID>(s.RegionInfo.EstateSettings.EstateAccess);
|
||||||
|
foreach(UUID uuid in uuids)
|
||||||
|
{
|
||||||
|
if(!acl.Contains(uuid))
|
||||||
|
{
|
||||||
|
acl.Add(uuid);
|
||||||
|
addk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.RegionInfo.EstateSettings.EstateAccess = acl.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
responseData["added"] = addk;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[RADMIN] Access List Add Request: {0}", e.Message);
|
||||||
|
|
||||||
|
responseData["success"] = "false";
|
||||||
|
responseData["error"] = e.Message;
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
response.Value = responseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Access List Add Request complete");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlRpcResponse XmlRpcAccessListRemove(XmlRpcRequest request)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Received Access List Remove Request");
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
Hashtable responseData = new Hashtable();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
responseData["success"] = "true";
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable) request.Params[0];
|
||||||
|
|
||||||
|
if (!requestData.Contains("password"))
|
||||||
|
throw new Exception(String.Format("missing required parameter"));
|
||||||
|
if (!String.IsNullOrEmpty(requiredPassword) &&
|
||||||
|
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
|
||||||
|
|
||||||
|
if (requestData.Contains("region_uuid"))
|
||||||
|
{
|
||||||
|
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
|
||||||
|
}
|
||||||
|
else if (requestData.Contains("region_name"))
|
||||||
|
{
|
||||||
|
string region_name = (string) requestData["region_name"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_name));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
|
||||||
|
}
|
||||||
|
else throw new Exception("neither region_name nor region_uuid given");
|
||||||
|
|
||||||
|
int remk = 0;
|
||||||
|
|
||||||
|
if(requestData.Contains("users"))
|
||||||
|
{
|
||||||
|
UserProfileCacheService ups = m_app.CommunicationsManager.UserProfileCacheService;
|
||||||
|
Scene s = m_app.SceneManager.CurrentScene;
|
||||||
|
Hashtable users = (Hashtable) requestData["users"];
|
||||||
|
List<UUID> uuids = new List<UUID>();
|
||||||
|
foreach(string name in users.Values)
|
||||||
|
{
|
||||||
|
string[] parts = name.Split();
|
||||||
|
uuids.Add(ups.GetUserDetails(parts[0],parts[1]).UserProfile.ID);
|
||||||
|
}
|
||||||
|
List<UUID> acl = new List<UUID>(s.RegionInfo.EstateSettings.EstateAccess);
|
||||||
|
foreach(UUID uuid in uuids)
|
||||||
|
{
|
||||||
|
if(acl.Contains(uuid))
|
||||||
|
{
|
||||||
|
acl.Remove(uuid);
|
||||||
|
remk++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.RegionInfo.EstateSettings.EstateAccess = acl.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
responseData["added"] = remk;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[RADMIN] Access List Remove Request: {0}", e.Message);
|
||||||
|
|
||||||
|
responseData["success"] = "false";
|
||||||
|
responseData["error"] = e.Message;
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
response.Value = responseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Access List Remove Request complete");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlRpcResponse XmlRpcAccessListList(XmlRpcRequest request)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Received Access List List Request");
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
Hashtable responseData = new Hashtable();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
responseData["success"] = "true";
|
||||||
|
|
||||||
|
Hashtable requestData = (Hashtable) request.Params[0];
|
||||||
|
|
||||||
|
if (!requestData.Contains("password"))
|
||||||
|
throw new Exception(String.Format("missing required parameter"));
|
||||||
|
if (!String.IsNullOrEmpty(requiredPassword) &&
|
||||||
|
(string) requestData["password"] != requiredPassword) throw new Exception("wrong password");
|
||||||
|
|
||||||
|
if (requestData.Contains("region_uuid"))
|
||||||
|
{
|
||||||
|
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
|
||||||
|
}
|
||||||
|
else if (requestData.Contains("region_name"))
|
||||||
|
{
|
||||||
|
string region_name = (string) requestData["region_name"];
|
||||||
|
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
|
||||||
|
throw new Exception(String.Format("failed to switch to region {0}", region_name));
|
||||||
|
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
|
||||||
|
}
|
||||||
|
else throw new Exception("neither region_name nor region_uuid given");
|
||||||
|
|
||||||
|
Scene s = m_app.SceneManager.CurrentScene;
|
||||||
|
UUID[] acl = s.RegionInfo.EstateSettings.EstateAccess;
|
||||||
|
Hashtable users = new Hashtable();
|
||||||
|
|
||||||
|
foreach(UUID user in acl)
|
||||||
|
{
|
||||||
|
users[user.ToString()] =
|
||||||
|
m_app.CommunicationsManager.UserProfileCacheService.GetUserDetails(user).UserProfile.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
responseData["users"] = users;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.InfoFormat("[RADMIN] Acces List List: {0}", e.Message);
|
||||||
|
|
||||||
|
responseData["success"] = "false";
|
||||||
|
responseData["error"] = e.Message;
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
response.Value = responseData;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.Info("[RADMIN]: Access List List Request complete");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,6 +358,11 @@ namespace OpenSim.Framework
|
||||||
l_EstateBans.Remove(ban);
|
l_EstateBans.Remove(ban);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasAccess(UUID user)
|
||||||
|
{
|
||||||
|
return l_EstateAccess.Contains(user);
|
||||||
|
}
|
||||||
|
|
||||||
public void loadConfigurationOptions()
|
public void loadConfigurationOptions()
|
||||||
{
|
{
|
||||||
configMember.addConfigurationOption("billable_factor",
|
configMember.addConfigurationOption("billable_factor",
|
||||||
|
|
|
@ -1846,11 +1846,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public override void AddNewClient(IClientAPI client)
|
public override void AddNewClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
if (m_regInfo.EstateSettings.IsBanned(client.AgentId))
|
bool welcome = true;
|
||||||
|
|
||||||
|
if(m_regInfo.EstateSettings.IsBanned(client.AgentId))
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
|
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
|
||||||
client.AgentId, client.FirstName, client.LastName, RegionInfo.RegionName);
|
client.AgentId, client.FirstName, client.LastName, RegionInfo.RegionName);
|
||||||
client.SendAlertMessage("Denied access to region " + RegionInfo.RegionName + ". You have been banned from that region.");
|
client.SendAlertMessage("Denied access to region " + RegionInfo.RegionName + ". You have been banned from that region.");
|
||||||
|
welcome = false;
|
||||||
|
}
|
||||||
|
else if (!m_regInfo.EstateSettings.PublicAccess && !m_regInfo.EstateSettings.HasAccess(client.AgentId))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access",
|
||||||
|
client.AgentId, client.FirstName, client.LastName, RegionInfo.RegionName);
|
||||||
|
client.SendAlertMessage("Denied access to private region " + RegionInfo.RegionName + ". You do not have access to this region.");
|
||||||
|
welcome = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!welcome)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IEventQueue eq = RequestModuleInterface<IEventQueue>();
|
IEventQueue eq = RequestModuleInterface<IEventQueue>();
|
||||||
|
@ -1867,50 +1881,52 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SCENE]: Exception while closing banned client {0} {1}: {2}", client.FirstName, client.LastName, e.Message);
|
m_log.DebugFormat("[SCENE]: Exception while closing unwelcome client {0} {1}: {2}", client.FirstName, client.LastName, e.Message);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SubscribeToClientEvents(client);
|
|
||||||
ScenePresence presence;
|
|
||||||
|
|
||||||
if (m_restorePresences.ContainsKey(client.AgentId))
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[SCENE]: Restoring agent {0} {1} in {2}", client.Name, client.AgentId, RegionInfo.RegionName);
|
|
||||||
|
|
||||||
presence = m_restorePresences[client.AgentId];
|
|
||||||
m_restorePresences.Remove(client.AgentId);
|
|
||||||
|
|
||||||
// This is one of two paths to create avatars that are
|
|
||||||
// used. This tends to get called more in standalone
|
|
||||||
// than grid, not really sure why, but as such needs
|
|
||||||
// an explicity appearance lookup here.
|
|
||||||
AvatarAppearance appearance = null;
|
|
||||||
GetAvatarAppearance(client, out appearance);
|
|
||||||
presence.Appearance = appearance;
|
|
||||||
|
|
||||||
presence.initializeScenePresence(client, RegionInfo, this);
|
|
||||||
|
|
||||||
m_sceneGraph.AddScenePresence(presence);
|
|
||||||
|
|
||||||
lock (m_restorePresences)
|
|
||||||
{
|
|
||||||
Monitor.PulseAll(m_restorePresences);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
SubscribeToClientEvents(client);
|
||||||
"[SCENE]: Adding new child agent for {0} in {1}",
|
ScenePresence presence;
|
||||||
client.Name, RegionInfo.RegionName);
|
|
||||||
|
|
||||||
CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
|
if (m_restorePresences.ContainsKey(client.AgentId))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[SCENE]: Restoring agent {0} {1} in {2}", client.Name, client.AgentId, RegionInfo.RegionName);
|
||||||
|
|
||||||
CreateAndAddScenePresence(client);
|
presence = m_restorePresences[client.AgentId];
|
||||||
|
m_restorePresences.Remove(client.AgentId);
|
||||||
|
|
||||||
|
// This is one of two paths to create avatars that are
|
||||||
|
// used. This tends to get called more in standalone
|
||||||
|
// than grid, not really sure why, but as such needs
|
||||||
|
// an explicity appearance lookup here.
|
||||||
|
AvatarAppearance appearance = null;
|
||||||
|
GetAvatarAppearance(client, out appearance);
|
||||||
|
presence.Appearance = appearance;
|
||||||
|
|
||||||
|
presence.initializeScenePresence(client, RegionInfo, this);
|
||||||
|
|
||||||
|
m_sceneGraph.AddScenePresence(presence);
|
||||||
|
|
||||||
|
lock (m_restorePresences)
|
||||||
|
{
|
||||||
|
Monitor.PulseAll(m_restorePresences);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SCENE]: Adding new child agent for {0} in {1}",
|
||||||
|
client.Name, RegionInfo.RegionName);
|
||||||
|
|
||||||
|
CommsManager.UserProfileCacheService.AddNewUser(client.AgentId);
|
||||||
|
|
||||||
|
CreateAndAddScenePresence(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_LastLogin = Environment.TickCount;
|
||||||
|
EventManager.TriggerOnNewClient(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LastLogin = Environment.TickCount;
|
|
||||||
EventManager.TriggerOnNewClient(client);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void SubscribeToClientEvents(IClientAPI client)
|
protected virtual void SubscribeToClientEvents(IClientAPI client)
|
||||||
|
|
Loading…
Reference in New Issue