30 using System.Reflection;
33 using System.Diagnostics;
34 using System.Threading;
35 using System.Collections.Generic;
39 using OpenSim.Framework;
40 using OpenSim.Framework.Console;
41 using OpenSim.Region.Framework.Interfaces;
42 using OpenSim.Region.Framework.Scenes;
48 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"RestartModule")]
51 private static readonly ILog m_log =
52 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 protected Timer m_CountdownTimer = null;
60 protected bool m_Notice =
false;
62 protected string m_MarkerPath = String.Empty;
63 private int[] m_CurrentAlerts = null;
67 IConfig restartConfig = config.Configs[
"RestartModule"];
68 if (restartConfig != null)
70 m_MarkerPath = restartConfig.GetString(
"MarkerPath", String.Empty);
76 if (m_MarkerPath !=
String.Empty)
77 File.Delete(Path.Combine(m_MarkerPath,
78 scene.RegionInfo.RegionID.ToString()));
83 MainConsole.Instance.Commands.AddCommand(
"Regions",
84 false,
"region restart bluebox",
85 "region restart bluebox <message> <delta seconds>+",
86 "Schedule a region restart",
87 "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.",
90 MainConsole.Instance.Commands.AddCommand(
"Regions",
91 false,
"region restart notice",
92 "region restart notice <message> <delta seconds>+",
93 "Schedule a region restart",
94 "Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.",
97 MainConsole.Instance.Commands.AddCommand(
"Regions",
98 false,
"region restart abort",
99 "region restart abort [<message>]",
100 "Abort a region restart", HandleRegionRestart);
105 m_DialogModule = m_Scene.RequestModuleInterface<
IDialogModule>();
118 get {
return "RestartModule"; }
121 public Type ReplaceableInterface
126 public TimeSpan TimeUntilRestart
128 get {
return DateTime.Now - m_RestartBegin; }
131 public void ScheduleRestart(UUID initiator,
string message,
int[] alerts,
bool notice)
133 if (m_CountdownTimer != null)
135 m_CountdownTimer.Stop();
136 m_CountdownTimer = null;
142 m_Scene.RestartNow();
147 m_Initiator = initiator;
149 m_CurrentAlerts = alerts;
150 m_Alerts =
new List<int>(alerts);
154 if (m_Alerts[0] == 0)
157 m_Scene.RestartNow();
161 int nextInterval = DoOneNotice(
true);
163 SetTimer(nextInterval);
168 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
171 m_Scene.RestartNow();
176 while (m_Alerts.Count > 1)
178 if (m_Alerts[1] == m_Alerts[0])
180 m_Alerts.RemoveAt(0);
183 nextAlert = m_Alerts[1];
187 int currentAlert = m_Alerts[0];
189 m_Alerts.RemoveAt(0);
193 int minutes = currentAlert / 60;
194 string currentAlertString = String.Empty;
198 currentAlertString +=
"1 minute";
200 currentAlertString += String.Format(
"{0} minutes", minutes);
201 if ((currentAlert % 60) != 0)
202 currentAlertString +=
" and ";
204 if ((currentAlert % 60) != 0)
206 int seconds = currentAlert % 60;
208 currentAlertString +=
"1 second";
210 currentAlertString += String.Format(
"{0} seconds", seconds);
213 string msg = String.Format(m_Message, currentAlertString);
215 if (m_DialogModule != null && msg !=
String.Empty)
218 m_DialogModule.SendGeneralAlert(msg);
220 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator,
"System", msg);
224 return currentAlert - nextAlert;
229 if (intervalSeconds > 0)
231 m_CountdownTimer =
new Timer();
232 m_CountdownTimer.AutoReset =
false;
233 m_CountdownTimer.Interval = intervalSeconds * 1000;
234 m_CountdownTimer.Elapsed += OnTimer;
235 m_CountdownTimer.Start();
237 else if (m_CountdownTimer != null)
239 m_CountdownTimer.Stop();
240 m_CountdownTimer = null;
245 "[RESTART MODULE]: Tried to set restart timer to {0} in {1}, which is not a valid interval",
246 intervalSeconds, m_Scene.Name);
250 private void OnTimer(
object source, ElapsedEventArgs e)
252 int nextInterval = DoOneNotice(
true);
254 SetTimer(nextInterval);
259 if (m_CountdownTimer == null)
262 m_CountdownTimer.Stop();
263 m_CountdownTimer = null;
265 m_Alerts =
new List<int>(m_CurrentAlerts);
266 m_Alerts.Add(seconds);
270 int nextInterval = DoOneNotice(
false);
272 SetTimer(nextInterval);
277 if (m_CountdownTimer != null)
279 m_CountdownTimer.Stop();
280 m_CountdownTimer = null;
281 if (m_DialogModule != null && message !=
String.Empty)
282 m_DialogModule.SendNotificationToUsersInRegion(UUID.Zero,
"System", message);
285 if (m_MarkerPath !=
String.Empty)
286 File.Delete(Path.Combine(m_MarkerPath,
287 m_Scene.RegionInfo.RegionID.ToString()));
290 private void HandleRegionRestart(
string module,
string[] args)
302 if (args[2] ==
"abort")
304 string msg = String.Empty;
310 MainConsole.Instance.Output(
"Region restart aborted");
315 MainConsole.Instance.Output(
"Error: restart region <mode> <name> <delta seconds>+");
320 if (args[2] ==
"notice")
323 List<int> times =
new List<int>();
324 for (
int i = 4 ; i < args.Length ; i++)
325 times.Add(Convert.ToInt32(args[i]));
327 MainConsole.Instance.OutputFormat(
328 "Region {0} scheduled for restart in {1} seconds", m_Scene.Name, times.Sum());
330 ScheduleRestart(
UUID.Zero, args[3], times.ToArray(), notice);
335 if (m_MarkerPath ==
String.Empty)
338 string path = Path.Combine(m_MarkerPath, m_Scene.RegionInfo.RegionID.ToString());
341 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
342 FileStream fs = File.Create(path);
343 System.Text.ASCIIEncoding enc =
new System.Text.ASCIIEncoding();
344 Byte[] buf = enc.GetBytes(pidstring);
345 fs.Write(buf, 0, buf.Length);
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
System.Timers.Timer Timer
void SetTimer(int intervalSeconds)
System.Timers.Timer Timer
static ICommandConsole Instance
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void AbortRestart(string message)
Interactive OpenSim region server
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void DelayRestart(int seconds, string message)
int DoOneNotice(bool sendOut)
void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice)
void Initialise(IConfigSource config)
This is called to initialize the region module. For shared modules, this is called exactly once...