OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
RegionCommandsModule.cs
Go to the documentation of this file.
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.Collections.Generic;
30 using System.Reflection;
31 using System.Text;
32 using System.Text.RegularExpressions;
33 using log4net;
34 using Mono.Addins;
35 using NDesk.Options;
36 using Nini.Config;
37 using OpenMetaverse;
38 using OpenSim.Framework;
39 using OpenSim.Framework.Console;
40 using OpenSim.Framework.Monitoring;
41 using OpenSim.Region.Framework.Interfaces;
42 using OpenSim.Region.Framework.Scenes;
43 
44 namespace OpenSim.Region.CoreModules.World.Objects.Commands
45 {
49  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionCommandsModule")]
51  {
52  private Scene m_scene;
53  private ICommandConsole m_console;
54 
55  public string Name { get { return "Region Commands Module"; } }
56 
57  public Type ReplaceableInterface { get { return null; } }
58 
59  public void Initialise(IConfigSource source)
60  {
61 // m_log.DebugFormat("[REGION COMMANDS MODULE]: INITIALIZED MODULE");
62  }
63 
64  public void PostInitialise()
65  {
66 // m_log.DebugFormat("[REGION COMMANDS MODULE]: POST INITIALIZED MODULE");
67  }
68 
69  public void Close()
70  {
71 // m_log.DebugFormat("[REGION COMMANDS MODULE]: CLOSED MODULE");
72  }
73 
74  public void AddRegion(Scene scene)
75  {
76 // m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
77 
78  m_scene = scene;
79  m_console = MainConsole.Instance;
80 
81  m_console.Commands.AddCommand(
82  "Regions", false, "show scene",
83  "show scene",
84  "Show live information for the currently selected scene (fps, prims, etc.).", HandleShowScene);
85 
86  m_console.Commands.AddCommand(
87  "Regions", false, "show region",
88  "show region",
89  "Show control information for the currently selected region (host name, max physical prim size, etc).",
90  "A synonym for \"region get\"",
91  HandleShowRegion);
92 
93  m_console.Commands.AddCommand(
94  "Regions", false, "region get",
95  "region get",
96  "Show control information for the currently selected region (host name, max physical prim size, etc).",
97  "Some parameters can be set with the \"region set\" command.\n"
98  + "Others must be changed via a viewer (usually via the region/estate dialog box).",
99  HandleShowRegion);
100 
101  m_console.Commands.AddCommand(
102  "Regions", false, "region set",
103  "region set",
104  "Set control information for the currently selected region.",
105  "Currently, the following parameters can be set:\n"
106  + "agent-limit <int> - Current root agent limit. This is persisted over restart.\n"
107  + "max-agent-limit <int> - Maximum root agent limit. agent-limit cannot exceed this."
108  + " This is not persisted over restart - to set it every time you must add a MaxAgents entry to your regions file.",
109  HandleRegionSet);
110  }
111 
112  public void RemoveRegion(Scene scene)
113  {
114 // m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
115  }
116 
117  public void RegionLoaded(Scene scene)
118  {
119 // m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
120  }
121 
122  private void HandleShowRegion(string module, string[] cmd)
123  {
124  if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
125  return;
126 
129 
130  StringBuilder sb = new StringBuilder();
131  sb.AppendFormat("Region information for {0}\n", m_scene.Name);
132 
133  ConsoleDisplayList dispList = new ConsoleDisplayList();
134  dispList.AddRow("Region ID", ri.RegionID);
135  dispList.AddRow("Region handle", ri.RegionHandle);
136  dispList.AddRow("Region location", string.Format("{0},{1}", ri.RegionLocX, ri.RegionLocY));
137  dispList.AddRow("Region size", string.Format("{0}x{1}", ri.RegionSizeX, ri.RegionSizeY));
138  //dispList.AddRow("Region type", ri.RegionType);
139  dispList.AddRow("Maturity", rs.Maturity);
140  dispList.AddRow("Region address", ri.ServerURI);
141  dispList.AddRow("From region file", ri.RegionFile);
142  dispList.AddRow("External endpoint", ri.ExternalEndPoint);
143  dispList.AddRow("Internal endpoint", ri.InternalEndPoint);
144  dispList.AddRow("Access level", ri.AccessLevel);
145  dispList.AddRow("Agent limit", rs.AgentLimit);
146  dispList.AddRow("Max agent limit", ri.AgentCapacity);
147  dispList.AddRow("Linkset capacity", ri.LinksetCapacity <= 0 ? "not set" : ri.LinksetCapacity.ToString());
148  dispList.AddRow("Prim capacity", ri.ObjectCapacity);
149  dispList.AddRow("Prim bonus", rs.ObjectBonus);
150  dispList.AddRow("Max prims per user", ri.MaxPrimsPerUser < 0 ? "n/a" : ri.MaxPrimsPerUser.ToString());
151  dispList.AddRow("Clamp prim size", ri.ClampPrimSize);
152  dispList.AddRow("Non physical prim min size", ri.NonphysPrimMin <= 0 ? "not set" : string.Format("{0} m", ri.NonphysPrimMin));
153  dispList.AddRow("Non physical prim max size", ri.NonphysPrimMax <= 0 ? "not set" : string.Format("{0} m", ri.NonphysPrimMax));
154  dispList.AddRow("Physical prim min size", ri.PhysPrimMin <= 0 ? "not set" : string.Format("{0} m", ri.PhysPrimMin));
155  dispList.AddRow("Physical prim max size", ri.PhysPrimMax <= 0 ? "not set" : string.Format("{0} m", ri.PhysPrimMax));
156 
157  dispList.AddRow("Allow Damage", rs.AllowDamage);
158  dispList.AddRow("Allow Land join/divide", rs.AllowLandJoinDivide);
159  dispList.AddRow("Allow land resell", rs.AllowLandResell);
160  dispList.AddRow("Block fly", rs.BlockFly);
161  dispList.AddRow("Block show in search", rs.BlockShowInSearch);
162  dispList.AddRow("Block terraform", rs.BlockTerraform);
163  dispList.AddRow("Covenant UUID", rs.Covenant);
164  dispList.AddRow("Convenant change Unix time", rs.CovenantChangedDateTime);
165  dispList.AddRow("Disable collisions", rs.DisableCollisions);
166  dispList.AddRow("Disable physics", rs.DisablePhysics);
167  dispList.AddRow("Disable scripts", rs.DisableScripts);
168  dispList.AddRow("Restrict pushing", rs.RestrictPushing);
169  dispList.AddRow("Fixed sun", rs.FixedSun);
170  dispList.AddRow("Sun position", rs.SunPosition);
171  dispList.AddRow("Sun vector", rs.SunVector);
172  dispList.AddRow("Use estate sun", rs.UseEstateSun);
173  dispList.AddRow("Telehub UUID", rs.TelehubObject);
174  dispList.AddRow("Terrain lower limit", string.Format("{0} m", rs.TerrainLowerLimit));
175  dispList.AddRow("Terrain raise limit", string.Format("{0} m", rs.TerrainRaiseLimit));
176  dispList.AddRow("Water height", string.Format("{0} m", rs.WaterHeight));
177 
178  dispList.AddRow("Maptile static file", ri.MaptileStaticFile);
179  dispList.AddRow("Maptile static UUID", ri.MaptileStaticUUID);
180  dispList.AddRow("Last map refresh", ri.lastMapRefresh);
181  dispList.AddRow("Last map UUID", ri.lastMapUUID);
182 
183  dispList.AddToStringBuilder(sb);
184 
185  MainConsole.Instance.Output(sb.ToString());
186  }
187 
188  private void HandleRegionSet(string module, string[] args)
189  {
190  if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
191  return;
192 
193  if (args.Length != 4)
194  {
195  MainConsole.Instance.OutputFormat("Usage: region set <param> <value>");
196  return;
197  }
198 
199  string param = args[2];
200  string rawValue = args[3];
201 
202  if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
203  return;
204 
207 
208  if (param == "agent-limit")
209  {
210  int newValue;
211 
212  if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, rawValue, out newValue))
213  return;
214 
215  if (newValue > ri.AgentCapacity)
216  {
217  MainConsole.Instance.OutputFormat(
218  "Cannot set {0} to {1} in {2} as max-agent-limit is {3}", "agent-limit",
219  newValue, m_scene.Name, ri.AgentCapacity);
220  }
221  else
222  {
223  rs.AgentLimit = newValue;
224 
225  MainConsole.Instance.OutputFormat(
226  "{0} set to {1} in {2}", "agent-limit", newValue, m_scene.Name);
227  }
228 
229  rs.Save();
230  }
231  else if (param == "max-agent-limit")
232  {
233  int newValue;
234 
235  if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, rawValue, out newValue))
236  return;
237 
238  ri.AgentCapacity = newValue;
239 
240  MainConsole.Instance.OutputFormat(
241  "{0} set to {1} in {2}", "max-agent-limit", newValue, m_scene.Name);
242 
243  if (ri.AgentCapacity < rs.AgentLimit)
244  {
245  rs.AgentLimit = ri.AgentCapacity;
246 
247  MainConsole.Instance.OutputFormat(
248  "Reducing {0} to {1} in {2}", "agent-limit", rs.AgentLimit, m_scene.Name);
249  }
250 
251  rs.Save();
252  }
253  }
254 
255  private void HandleShowScene(string module, string[] cmd)
256  {
257  if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene))
258  return;
259 
260  SimStatsReporter r = m_scene.StatsReporter;
261  float[] stats = r.LastReportedSimStats;
262 
263  float timeDilation = stats[0];
264  float simFps = stats[1];
265  float physicsFps = stats[2];
266  float agentUpdates = stats[3];
267  float rootAgents = stats[4];
268  float childAgents = stats[5];
269  float totalPrims = stats[6];
270  float activePrims = stats[7];
271  float totalFrameTime = stats[8];
272 // float netFrameTime = stats.StatsBlock[9].StatValue; // Ignored - not used by OpenSimulator
273  float physicsFrameTime = stats[10];
274  float otherFrameTime = stats[12];
275 // float imageFrameTime = stats.StatsBlock[11].StatValue; // Ignored
276  float inPacketsPerSecond = stats[13];
277  float outPacketsPerSecond = stats[14];
278  float unackedBytes = stats[15];
279 // float agentFrameTime = stats.StatsBlock[16].StatValue; // Not really used
280  float pendingDownloads = stats[17];
281  float pendingUploads = stats[18];
282  float activeScripts = stats[19];
283  float scriptLinesPerSecond = stats[23];
284 
285  StringBuilder sb = new StringBuilder();
286  sb.AppendFormat("Scene statistics for {0}\n", m_scene.RegionInfo.RegionName);
287 
288  ConsoleDisplayList dispList = new ConsoleDisplayList();
289  dispList.AddRow("Time Dilation", timeDilation);
290  dispList.AddRow("Sim FPS", simFps);
291  dispList.AddRow("Physics FPS", physicsFps);
292  dispList.AddRow("Avatars", rootAgents);
293  dispList.AddRow("Child agents", childAgents);
294  dispList.AddRow("Total prims", totalPrims);
295  dispList.AddRow("Scripts", activeScripts);
296  dispList.AddRow("Script lines processed per second", scriptLinesPerSecond);
297  dispList.AddRow("Physics enabled prims", activePrims);
298  dispList.AddRow("Total frame time", totalFrameTime);
299  dispList.AddRow("Physics frame time", physicsFrameTime);
300  dispList.AddRow("Other frame time", otherFrameTime);
301  dispList.AddRow("Agent Updates per second", agentUpdates);
302  dispList.AddRow("Packets processed from clients per second", inPacketsPerSecond);
303  dispList.AddRow("Packets sent to clients per second", outPacketsPerSecond);
304  dispList.AddRow("Bytes unacknowledged by clients", unackedBytes);
305  dispList.AddRow("Pending asset downloads to clients", pendingDownloads);
306  dispList.AddRow("Pending asset uploads from clients", pendingUploads);
307 
308  dispList.AddToStringBuilder(sb);
309 
310  MainConsole.Instance.Output(sb.ToString());
311  }
312  }
313 }
Used to generated a formatted table for the console.
OpenSim.Framework.RegionInfo RegionInfo
OpenSim.Framework.RegionSettings RegionSettings
A module that holds commands for manipulating objects in the scene.
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
static ICommandConsole Instance
Definition: MainConsole.cs:35
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
static bool TryParseConsoleNaturalInt(ICommandConsole console, string rawConsoleInt, out int i)
Convert a console integer to a natural int, automatically complaining if a console is given...
Definition: ConsoleUtil.cs:245
Collect statistics from the scene to send to the client and for access by other monitoring tools...
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...