* Added the ability to restart your individual sims from within them using the estate tools.

* The sims properly restart, however they don't yet notify the existing avatars that they are up.  To see the sim again, you'll need to log-out and back in until I can figure out how to get the proper data to the sims and to the avatar so they reconnect again.
This commit is contained in:
Teravus Ovares
2007-11-25 04:52:14 +00:00
parent 21ce2b0979
commit d263a044b1
10 changed files with 336 additions and 8 deletions

View File

@@ -171,6 +171,12 @@ namespace OpenSim.Region.Environment
if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId))
estateSetRegionTerrainHandler(packet);
break;
case "restart":
if (m_scene.PermissionsMngr.CanRestartSim(remote_client.AgentId))
{
estateRestartSim(packet);
}
break;
default:
MainLog.Instance.Error("EstateOwnerMessage: Unknown method requested\n" + packet.ToString());
break;
@@ -322,6 +328,19 @@ namespace OpenSim.Region.Environment
}
}
}
private void estateRestartSim(EstateOwnerMessagePacket packet)
{
// There's only 1 block in the estateResetSim.. and that's the number of seconds till restart.
foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList)
{
float timeSeconds = 0;
timeSeconds = BitConverter.ToInt16(block.Parameter, 1);
timeSeconds = (int)((timeSeconds / 100) - 3);
m_scene.Restart(timeSeconds);
}
}
#endregion

View File

@@ -306,6 +306,14 @@ namespace OpenSim.Region.Environment
return GenericEstatePermission(user);
}
public virtual bool CanRestartSim(LLUUID user)
{
// Since this is potentially going on a grid...
//return GenericEstatePermission(AgentId);
return m_scene.RegionInfo.MasterAvatarAssignedUUID == user;
}
#endregion
#region Parcel Permissions

View File

@@ -70,6 +70,10 @@ namespace OpenSim.Region.Environment.Scenes
private readonly Mutex updateLock;
public bool m_physicalPrim;
public bool m_sendTasksToChild;
private int m_RestartTimerCounter;
private Timer t_restartTimer = new Timer(15000); // Wait before firing
private int m_incrementsof15seconds = 0;
protected ModuleLoader m_moduleLoader;
protected StorageManager m_storageManager;
protected AgentCircuitManager m_authenticateHandler;
@@ -253,15 +257,80 @@ namespace OpenSim.Region.Environment.Scenes
m_eventManager.OnPermissionError += SendPermissionAlert;
}
public override void OtherRegionUp(RegionInfo otherRegion)
{
// Another region is up. We have to tell all our ScenePresences about it
// This fails to get the desired effect and needs further work.
ForEachScenePresence(delegate(ScenePresence agent)
{
if (!(agent.IsChildAgent))
{
InformClientOfNeighbor(agent, otherRegion);
this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
}
}
);
}
public virtual void Restart(float seconds)
{
if (seconds < 100)
{
t_restartTimer.Stop();
SendGeneralAlert("Restart Aborted");
}
else
{
t_restartTimer.Interval = 15000;
m_incrementsof15seconds = (int) seconds/15;
m_RestartTimerCounter = 0;
t_restartTimer.AutoReset = true;
t_restartTimer.Elapsed += new ElapsedEventHandler(restartTimer_Elapsed);
MainLog.Instance.Error("REGION", "Restarting Region in " + (seconds / 60) + " minutes");
t_restartTimer.Start();
SendGeneralAlert("Restarting in 2 Minutes");
}
}
public void restartTimer_Elapsed(object sender, ElapsedEventArgs e)
{
m_RestartTimerCounter++;
if (m_RestartTimerCounter <= m_incrementsof15seconds)
{
if (m_RestartTimerCounter == 4 || m_RestartTimerCounter == 6 || m_RestartTimerCounter == 7)
SendGeneralAlert("Restarting in " + ((8-m_RestartTimerCounter) * 15) + " seconds");
}
else
{
t_restartTimer.Stop();
MainLog.Instance.Error("REGION", "Closing");
Close();
MainLog.Instance.Error("REGION", "Firing Region Restart Message");
base.Restart(0);
}
}
public override void Close()
{
ForEachScenePresence(delegate(ScenePresence avatar)
{
avatar.ControllingClient.Kick("The region is going down.");
if (avatar.KnownChildRegions.Contains(RegionInfo.RegionHandle))
avatar.KnownChildRegions.Remove(RegionInfo.RegionHandle);
if (!avatar.IsChildAgent)
avatar.ControllingClient.Kick("The simulator is going down.");
avatar.ControllingClient.OutPacket(new libsecondlife.Packets.DisableSimulatorPacket(), ThrottleOutPacketType.Task);
});
Thread.Sleep(500);
ForEachScenePresence(delegate(ScenePresence avatar)
{
avatar.ControllingClient.Stop();
});
@@ -269,7 +338,7 @@ namespace OpenSim.Region.Environment.Scenes
m_heartbeatTimer.Close();
m_innerScene.Close();
m_sceneGridService.Close();
UnRegisterReginWithComms();
foreach (IRegionModule module in this.Modules.Values)
{
@@ -992,6 +1061,14 @@ namespace OpenSim.Region.Environment.Scenes
m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing;
m_sceneGridService.OnCloseAgentConnection += CloseConnection;
}
public void UnRegisterReginWithComms()
{
m_sceneGridService.OnExpectUser -= NewUserConnection;
m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing;
m_sceneGridService.OnCloseAgentConnection -= CloseConnection;
m_sceneGridService.Close();
}
/// <summary>
///
@@ -1060,6 +1137,10 @@ namespace OpenSim.Region.Environment.Scenes
{
m_sceneGridService.EnableNeighbourChildAgents(presence);
}
public void InformClientOfNeighbor(ScenePresence presence, RegionInfo region)
{
m_sceneGridService.InformNeighborChildAgent(presence, region);
}
/// <summary>
///
@@ -1258,9 +1339,15 @@ namespace OpenSim.Region.Environment.Scenes
ClientManager.ForEachClient(delegate (IClientAPI controller)
{
if (controller.AgentId != godid) // Do we really want to kick the initiator of this madness?
ScenePresence p = GetScenePresence(controller.AgentId);
bool childagent = false;
if (!p.Equals(null))
if (p.IsChildAgent)
childagent=true;
if (controller.AgentId != godid && !childagent) // Do we really want to kick the initiator of this madness?
{
controller.Kick(Helpers.FieldToUTF8String(reason));
}
}
);
@@ -1269,7 +1356,13 @@ namespace OpenSim.Region.Environment.Scenes
// Is there another way to make sure *all* clients get this 'inter region' message?
ClientManager.ForEachClient(delegate (IClientAPI controller)
{
if (controller.AgentId != godid) // Do we really want to kick the initiator of this madness?
ScenePresence p = GetScenePresence(controller.AgentId);
bool childagent = false;
if (!p.Equals(null))
if (p.IsChildAgent)
childagent = true;
if (controller.AgentId != godid && !childagent) // Do we really want to kick the initiator of this madness?
{
controller.Close();
}

View File

@@ -27,6 +27,7 @@
*/
using System;
using System.Collections.Generic;
using System.Timers;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
@@ -37,6 +38,13 @@ namespace OpenSim.Region.Environment.Scenes
{
public abstract class SceneBase : IScene
{
#region Events
public event restart OnRestart;
public event regionup OnRegionUp;
#endregion
#region Fields
private readonly ClientManager m_clientManager = new ClientManager();
@@ -48,6 +56,7 @@ namespace OpenSim.Region.Environment.Scenes
protected ulong m_regionHandle;
protected string m_regionName;
protected RegionInfo m_regInfo;
protected RegionStatus m_regStatus;
public TerrainEngine Terrain;
@@ -69,6 +78,12 @@ namespace OpenSim.Region.Environment.Scenes
set { m_assetCache = value; }
}
public RegionStatus Region_Status
{
get { return m_regStatus; }
set { m_regStatus = value; }
}
#endregion
#region Update Methods
@@ -78,6 +93,8 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
public abstract void Update();
#endregion
#region Terrain Methods
@@ -130,6 +147,23 @@ namespace OpenSim.Region.Environment.Scenes
get { return m_nextLocalId++; }
}
#region admin stuff
/// <summary>
/// Region Restart - Seconds till restart.
/// </summary>
/// <param name="seconds"></param>
public virtual void Restart(int seconds)
{
MainLog.Instance.Error("REGION", "passing Restart Message up the namespace");
OnRestart(RegionInfo);
}
public abstract void OtherRegionUp(RegionInfo thisRegion);
#endregion
#region Shutdown
/// <summary>

View File

@@ -149,6 +149,20 @@ namespace OpenSim.Region.Environment.Scenes
}
}
}
public void InformNeighborChildAgent(ScenePresence avatar, RegionInfo region)
{
AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
agent.BaseFolder = LLUUID.Zero;
agent.InventoryFolder = LLUUID.Zero;
agent.startpos = new LLVector3(128, 128, 70);
agent.child = true;
InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
d.BeginInvoke(avatar, agent, region.RegionHandle, region.ExternalEndPoint,
InformClientOfNeighbourCompleted,
d);
}
#endregion
/// <summary>

View File

@@ -34,8 +34,12 @@ using OpenSim.Framework.Console;
namespace OpenSim.Region.Environment.Scenes
{
public delegate void ReStartSim(RegionInfo thisregion);
public class SceneManager
{
public event ReStartSim OnReStartSim;
private readonly List<Scene> m_localScenes;
private Scene m_currentScene = null;
@@ -72,11 +76,63 @@ namespace OpenSim.Region.Environment.Scenes
}
}
public void Add(Scene scene)
public void Close(Scene cscene)
{
m_localScenes.Add(scene);
if (m_localScenes.Contains(cscene))
{
for (int i = 0; i < m_localScenes.Count; i++)
{
if (m_localScenes[i].Equals(cscene))
{
m_localScenes[i].Close();
}
}
}
}
public void Add(Scene scene)
{
scene.OnRestart += handleRestart;
m_localScenes.Add(scene);
}
public void handleRestart(RegionInfo rdata)
{
MainLog.Instance.Error("SCENEMANAGER", "Got Restart message for region:" + rdata.RegionName +" Sending up to main");
int RegionSceneElement = -1;
for (int i = 0; i < m_localScenes.Count; i++)
{
if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName)
RegionSceneElement = i;
}
// Now we make sure the region is no longer known about by the SceneManager
// Prevents Duplicates.
if (RegionSceneElement >= 0)
m_localScenes.RemoveAt(RegionSceneElement);
// Send signal to main that we're restarting this sim.
OnReStartSim(rdata);
}
public void SendSimOnlineNotification(ulong regionHandle)
{
for (int i = 0; i < m_localScenes.Count; i++)
{
if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle)
{
// Inform other regions to tell their avatar about me
m_localScenes[i].OtherRegionUp(m_localScenes[i].RegionInfo);
}
}
}
public void SaveCurrentSceneToXml(string filename)
{
CurrentOrFirstScene.SavePrimsToXml(filename);