opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Linq;
30 using System.Reflection;
31 using System.Timers;
32 using System.Threading;
33 using System.Collections.Generic;
34 using log4net;
35 using Nini.Config;
36 using OpenMetaverse;
37 using OpenSim.Framework;
38 using OpenSim.Framework.Console;
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Region.Framework.Scenes;
41 using Timer=System.Timers.Timer;
42 using Mono.Addins;
43  
44 namespace OpenSim.Region.CoreModules.World.Region
45 {
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")]
47 public class RestartModule : INonSharedRegionModule, IRestartModule
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51  
52 protected Scene m_Scene;
53 protected Timer m_CountdownTimer = null;
54 protected DateTime m_RestartBegin;
55 protected List<int> m_Alerts;
56 protected string m_Message;
57 protected UUID m_Initiator;
58 protected bool m_Notice = false;
59 protected IDialogModule m_DialogModule = null;
60  
61 public void Initialise(IConfigSource config)
62 {
63 }
64  
65 public void AddRegion(Scene scene)
66 {
67 m_Scene = scene;
68  
69 scene.RegisterModuleInterface<IRestartModule>(this);
70 MainConsole.Instance.Commands.AddCommand("Regions",
71 false, "region restart bluebox",
72 "region restart bluebox <message> <delta seconds>+",
73 "Schedule a region restart",
74 "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.",
75 HandleRegionRestart);
76  
77 MainConsole.Instance.Commands.AddCommand("Regions",
78 false, "region restart notice",
79 "region restart notice <message> <delta seconds>+",
80 "Schedule a region restart",
81 "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.",
82 HandleRegionRestart);
83  
84 MainConsole.Instance.Commands.AddCommand("Regions",
85 false, "region restart abort",
86 "region restart abort [<message>]",
87 "Abort a region restart", HandleRegionRestart);
88 }
89  
90 public void RegionLoaded(Scene scene)
91 {
92 m_DialogModule = m_Scene.RequestModuleInterface<IDialogModule>();
93 }
94  
95 public void RemoveRegion(Scene scene)
96 {
97 }
98  
99 public void Close()
100 {
101 }
102  
103 public string Name
104 {
105 get { return "RestartModule"; }
106 }
107  
108 public Type ReplaceableInterface
109 {
110 get { return typeof(IRestartModule); }
111 }
112  
113 public TimeSpan TimeUntilRestart
114 {
115 get { return DateTime.Now - m_RestartBegin; }
116 }
117  
118 public void ScheduleRestart(UUID initiator, string message, int[] alerts, bool notice)
119 {
120 if (m_CountdownTimer != null)
121 return;
122  
123 if (alerts == null)
124 {
125 m_Scene.RestartNow();
126 return;
127 }
128  
129 m_Message = message;
130 m_Initiator = initiator;
131 m_Notice = notice;
132 m_Alerts = new List<int>(alerts);
133 m_Alerts.Sort();
134 m_Alerts.Reverse();
135  
136 if (m_Alerts[0] == 0)
137 {
138 m_Scene.RestartNow();
139 return;
140 }
141  
142 int nextInterval = DoOneNotice();
143  
144 SetTimer(nextInterval);
145 }
146  
147 public int DoOneNotice()
148 {
149 if (m_Alerts.Count == 0 || m_Alerts[0] == 0)
150 {
151 m_Scene.RestartNow();
152 return 0;
153 }
154  
155 int nextAlert = 0;
156 while (m_Alerts.Count > 1)
157 {
158 if (m_Alerts[1] == m_Alerts[0])
159 {
160 m_Alerts.RemoveAt(0);
161 continue;
162 }
163 nextAlert = m_Alerts[1];
164 break;
165 }
166  
167 int currentAlert = m_Alerts[0];
168  
169 m_Alerts.RemoveAt(0);
170  
171 int minutes = currentAlert / 60;
172 string currentAlertString = String.Empty;
173 if (minutes > 0)
174 {
175 if (minutes == 1)
176 currentAlertString += "1 minute";
177 else
178 currentAlertString += String.Format("{0} minutes", minutes);
179 if ((currentAlert % 60) != 0)
180 currentAlertString += " and ";
181 }
182 if ((currentAlert % 60) != 0)
183 {
184 int seconds = currentAlert % 60;
185 if (seconds == 1)
186 currentAlertString += "1 second";
187 else
188 currentAlertString += String.Format("{0} seconds", seconds);
189 }
190  
191 string msg = String.Format(m_Message, currentAlertString);
192  
193 if (m_DialogModule != null && msg != String.Empty)
194 {
195 if (m_Notice)
196 m_DialogModule.SendGeneralAlert(msg);
197 else
198 m_DialogModule.SendNotificationToUsersInRegion(m_Initiator, "System", msg);
199 }
200  
201 return currentAlert - nextAlert;
202 }
203  
204 public void SetTimer(int intervalSeconds)
205 {
206 if (intervalSeconds > 0)
207 {
208 m_CountdownTimer = new Timer();
209 m_CountdownTimer.AutoReset = false;
210 m_CountdownTimer.Interval = intervalSeconds * 1000;
211 m_CountdownTimer.Elapsed += OnTimer;
212 m_CountdownTimer.Start();
213 }
214 else if (m_CountdownTimer != null)
215 {
216 m_CountdownTimer.Stop();
217 m_CountdownTimer = null;
218 }
219 else
220 {
221 m_log.WarnFormat(
222 "[RESTART MODULE]: Tried to set restart timer to {0} in {1}, which is not a valid interval",
223 intervalSeconds, m_Scene.Name);
224 }
225 }
226  
227 private void OnTimer(object source, ElapsedEventArgs e)
228 {
229 SetTimer(DoOneNotice());
230 }
231  
232 public void AbortRestart(string message)
233 {
234 if (m_CountdownTimer != null)
235 {
236 m_CountdownTimer.Stop();
237 m_CountdownTimer = null;
238 if (m_DialogModule != null && message != String.Empty)
239 m_DialogModule.SendGeneralAlert(message);
240 }
241 }
242  
243 private void HandleRegionRestart(string module, string[] args)
244 {
245 if (!(MainConsole.Instance.ConsoleScene is Scene))
246 return;
247  
248 if (MainConsole.Instance.ConsoleScene != m_Scene)
249 return;
250  
251 if (args.Length < 5)
252 {
253 if (args.Length > 2)
254 {
255 if (args[2] == "abort")
256 {
257 string msg = String.Empty;
258 if (args.Length > 3)
259 msg = args[3];
260  
261 AbortRestart(msg);
262  
263 MainConsole.Instance.Output("Region restart aborted");
264 return;
265 }
266 }
267  
268 MainConsole.Instance.Output("Error: restart region <mode> <name> <delta seconds>+");
269 return;
270 }
271  
272 bool notice = false;
273 if (args[2] == "notice")
274 notice = true;
275  
276 List<int> times = new List<int>();
277 for (int i = 4 ; i < args.Length ; i++)
278 times.Add(Convert.ToInt32(args[i]));
279  
280 MainConsole.Instance.OutputFormat(
281 "Region {0} scheduled for restart in {1} seconds", m_Scene.Name, times.Sum());
282  
283 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
284 }
285 }
286 }