aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMelanie2011-05-08 20:20:40 +0100
committerMelanie2011-05-08 20:20:40 +0100
commit1be67914fab348115faa1fc9e9ecffbf7c303093 (patch)
tree7ad4917efae6aebeefa51fe03b1d1aac3e95efcb /OpenSim
parentEnable compressed (gzip) fatpack transfers. (diff)
parentMantis #5472 (diff)
downloadopensim-SC_OLD-1be67914fab348115faa1fc9e9ecffbf7c303093.zip
opensim-SC_OLD-1be67914fab348115faa1fc9e9ecffbf7c303093.tar.gz
opensim-SC_OLD-1be67914fab348115faa1fc9e9ecffbf7c303093.tar.bz2
opensim-SC_OLD-1be67914fab348115faa1fc9e9ecffbf7c303093.tar.xz
Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Capabilities/Caps.cs4
-rw-r--r--OpenSim/Data/MSSQL/Resources/GridUserStore.migrations19
-rw-r--r--OpenSim/Data/MySQL/MySQLAvatarData.cs2
-rw-r--r--OpenSim/Data/MySQL/MySQLEstateData.cs4
-rw-r--r--OpenSim/Data/MySQL/MySQLGenericTableHandler.cs2
-rw-r--r--OpenSim/Data/MySQL/MySQLPresenceData.cs2
-rw-r--r--OpenSim/Data/MySQL/MySQLXInventoryData.cs2
-rw-r--r--OpenSim/Data/SQLite/SQLiteAuthenticationData.cs4
-rw-r--r--OpenSim/Data/SQLite/SQLiteAvatarData.cs2
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs2
-rw-r--r--OpenSim/Framework/ConfigSettings.cs116
-rw-r--r--OpenSim/Framework/MainServer.cs5
-rw-r--r--OpenSim/Framework/NetworkServersInfo.cs15
-rw-r--r--OpenSim/Framework/PriorityQueue.cs2
-rw-r--r--OpenSim/Framework/RegionInfo.cs245
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs14
-rw-r--r--OpenSim/Region/Application/ConfigurationLoader.cs16
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs2
-rw-r--r--OpenSim/Region/ClientStack/RegionApplicationBase.cs16
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs21
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs61
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs8
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs122
-rw-r--r--OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml1
-rw-r--r--OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs929
-rw-r--r--OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs126
-rw-r--r--OpenSim/Server/Base/HttpServerBase.cs77
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs56
34 files changed, 1495 insertions, 418 deletions
diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs
index e188896..56ccfd6 100644
--- a/OpenSim/Capabilities/Caps.cs
+++ b/OpenSim/Capabilities/Caps.cs
@@ -50,8 +50,8 @@ namespace OpenSim.Framework.Capabilities
50 50
51 public class Caps 51 public class Caps
52 { 52 {
53 private static readonly ILog m_log = 53// private static readonly ILog m_log =
54 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private string m_httpListenerHostName; 56 private string m_httpListenerHostName;
57 private uint m_httpListenPort; 57 private uint m_httpListenPort;
diff --git a/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations b/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations
new file mode 100644
index 0000000..7a7cecd
--- /dev/null
+++ b/OpenSim/Data/MSSQL/Resources/GridUserStore.migrations
@@ -0,0 +1,19 @@
1:VERSION 1 # --------------------------
2
3BEGIN TRANSACTION
4
5CREATE TABLE "GridUser" (
6 "UserID" VARCHAR(255) NOT NULL,
7 "HomeRegionID" CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8 "HomePosition" CHAR(64) NOT NULL DEFAULT '<0,0,0>',
9 "HomeLookAt" CHAR(64) NOT NULL DEFAULT '<0,0,0>',
10 "LastRegionID" CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
11 "LastPosition" CHAR(64) NOT NULL DEFAULT '<0,0,0>',
12 "LastLookAt" CHAR(64) NOT NULL DEFAULT '<0,0,0>',
13 "Online" CHAR(5) NOT NULL DEFAULT 'false',
14 "Login" CHAR(16) NOT NULL DEFAULT '0',
15 "Logout" CHAR(16) NOT NULL DEFAULT '0',
16 PRIMARY KEY ("UserID")
17)
18
19COMMIT
diff --git a/OpenSim/Data/MySQL/MySQLAvatarData.cs b/OpenSim/Data/MySQL/MySQLAvatarData.cs
index 5611302..8c841ab 100644
--- a/OpenSim/Data/MySQL/MySQLAvatarData.cs
+++ b/OpenSim/Data/MySQL/MySQLAvatarData.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Data.MySQL
43 public class MySQLAvatarData : MySQLGenericTableHandler<AvatarBaseData>, 43 public class MySQLAvatarData : MySQLGenericTableHandler<AvatarBaseData>,
44 IAvatarData 44 IAvatarData
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 public MySQLAvatarData(string connectionString, string realm) : 48 public MySQLAvatarData(string connectionString, string realm) :
49 base(connectionString, realm, "Avatar") 49 base(connectionString, realm, "Avatar")
diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs
index 86416d1..9dcf5e2 100644
--- a/OpenSim/Data/MySQL/MySQLEstateData.cs
+++ b/OpenSim/Data/MySQL/MySQLEstateData.cs
@@ -48,7 +48,7 @@ namespace OpenSim.Data.MySQL
48 private string m_connectionString; 48 private string m_connectionString;
49 private long m_waitTimeout; 49 private long m_waitTimeout;
50 private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond; 50 private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
51 private long m_lastConnectionUse; 51// private long m_lastConnectionUse;
52 52
53 private FieldInfo[] m_Fields; 53 private FieldInfo[] m_Fields;
54 private Dictionary<string, FieldInfo> m_FieldMap = 54 private Dictionary<string, FieldInfo> m_FieldMap =
@@ -127,7 +127,7 @@ namespace OpenSim.Data.MySQL
127 } 127 }
128 } 128 }
129 129
130 m_lastConnectionUse = DateTime.Now.Ticks; 130// m_lastConnectionUse = DateTime.Now.Ticks;
131 131
132 m_log.DebugFormat( 132 m_log.DebugFormat(
133 "[REGION DB]: Connection wait timeout {0} seconds", 133 "[REGION DB]: Connection wait timeout {0} seconds",
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
index 50b6dbe..cfffbd8 100644
--- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
+++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
@@ -39,7 +39,7 @@ namespace OpenSim.Data.MySQL
39{ 39{
40 public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new() 40 public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new()
41 { 41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 43
44 protected Dictionary<string, FieldInfo> m_Fields = 44 protected Dictionary<string, FieldInfo> m_Fields =
45 new Dictionary<string, FieldInfo>(); 45 new Dictionary<string, FieldInfo>();
diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs
index 2390feb..fc625f0 100644
--- a/OpenSim/Data/MySQL/MySQLPresenceData.cs
+++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Data.MySQL
43 public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>, 43 public class MySQLPresenceData : MySQLGenericTableHandler<PresenceData>,
44 IPresenceData 44 IPresenceData
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 public MySQLPresenceData(string connectionString, string realm) : 48 public MySQLPresenceData(string connectionString, string realm) :
49 base(connectionString, realm, "Presence") 49 base(connectionString, realm, "Presence")
diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
index 287c4dd..481da49 100644
--- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs
+++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
@@ -189,7 +189,7 @@ namespace OpenSim.Data.MySQL
189 { 189 {
190 cmd.ExecuteNonQuery(); 190 cmd.ExecuteNonQuery();
191 } 191 }
192 catch (Exception e) 192 catch (Exception)
193 { 193 {
194 return false; 194 return false;
195 } 195 }
diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
index c54bd74..c3b65bb 100644
--- a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
+++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs
@@ -33,7 +33,7 @@ using System.Reflection;
33using log4net; 33using log4net;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using log4net; 36
37#if CSharpSqlite 37#if CSharpSqlite
38 using Community.CsharpSqlite.Sqlite; 38 using Community.CsharpSqlite.Sqlite;
39#else 39#else
@@ -49,7 +49,6 @@ namespace OpenSim.Data.SQLite
49 private string m_Realm; 49 private string m_Realm;
50 private List<string> m_ColumnNames; 50 private List<string> m_ColumnNames;
51 private int m_LastExpire; 51 private int m_LastExpire;
52 private string m_connectionString;
53 52
54 protected static SqliteConnection m_Connection; 53 protected static SqliteConnection m_Connection;
55 private static bool m_initialized = false; 54 private static bool m_initialized = false;
@@ -58,7 +57,6 @@ namespace OpenSim.Data.SQLite
58 : base(connectionString) 57 : base(connectionString)
59 { 58 {
60 m_Realm = realm; 59 m_Realm = realm;
61 m_connectionString = connectionString;
62 60
63 if (!m_initialized) 61 if (!m_initialized)
64 { 62 {
diff --git a/OpenSim/Data/SQLite/SQLiteAvatarData.cs b/OpenSim/Data/SQLite/SQLiteAvatarData.cs
index 60a1a3e..faf34da 100644
--- a/OpenSim/Data/SQLite/SQLiteAvatarData.cs
+++ b/OpenSim/Data/SQLite/SQLiteAvatarData.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite
47 public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>, 47 public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>,
48 IAvatarData 48 IAvatarData
49 { 49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 public SQLiteAvatarData(string connectionString, string realm) : 52 public SQLiteAvatarData(string connectionString, string realm) :
53 base(connectionString, realm, "Avatar") 53 base(connectionString, realm, "Avatar")
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index 28fe3ba..710a57d 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -460,7 +460,7 @@ namespace OpenSim.Framework
460 { 460 {
461 info["state"] = OSD.FromString(AttachmentObjectStates[i++]); 461 info["state"] = OSD.FromString(AttachmentObjectStates[i++]);
462 } 462 }
463 catch (IndexOutOfRangeException e) 463 catch (IndexOutOfRangeException)
464 { 464 {
465 m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list."); 465 m_log.WarnFormat("[CHILD AGENT DATA]: scripts list is shorter than object list.");
466 } 466 }
diff --git a/OpenSim/Framework/ConfigSettings.cs b/OpenSim/Framework/ConfigSettings.cs
index be77341..50328d7 100644
--- a/OpenSim/Framework/ConfigSettings.cs
+++ b/OpenSim/Framework/ConfigSettings.cs
@@ -29,113 +29,13 @@ namespace OpenSim.Framework
29{ 29{
30 public class ConfigSettings 30 public class ConfigSettings
31 { 31 {
32 private string m_physicsEngine; 32 public string PhysicsEngine { get; set; }
33 33 public string MeshEngineName { get; set; }
34 public string PhysicsEngine 34 public bool See_into_region_from_neighbor { get; set; }
35 { 35 public string StorageDll { get; set; }
36 get { return m_physicsEngine; } 36 public string ClientstackDll { get; set; }
37 set { m_physicsEngine = value; } 37 public bool PhysicalPrim { get; set; }
38 } 38 public string LibrariesXMLFile { get; set; }
39 private string m_meshEngineName;
40
41 public string MeshEngineName
42 {
43 get { return m_meshEngineName; }
44 set { m_meshEngineName = value; }
45 }
46
47 private bool m_see_into_region_from_neighbor;
48
49 public bool See_into_region_from_neighbor
50 {
51 get { return m_see_into_region_from_neighbor; }
52 set { m_see_into_region_from_neighbor = value; }
53 }
54
55 private string m_storageDll;
56
57 public string StorageDll
58 {
59 get { return m_storageDll; }
60 set { m_storageDll = value; }
61 }
62
63 private string m_clientstackDll;
64
65 public string ClientstackDll
66 {
67 get { return m_clientstackDll; }
68 set { m_clientstackDll = value; }
69 }
70
71 private bool m_physicalPrim;
72
73 public bool PhysicalPrim
74 {
75 get { return m_physicalPrim; }
76 set { m_physicalPrim = value; }
77 }
78
79 private bool m_standaloneAuthenticate = false;
80
81 public bool StandaloneAuthenticate
82 {
83 get { return m_standaloneAuthenticate; }
84 set { m_standaloneAuthenticate = value; }
85 }
86
87 private string m_standaloneWelcomeMessage = null;
88
89 public string StandaloneWelcomeMessage
90 {
91 get { return m_standaloneWelcomeMessage; }
92 set { m_standaloneWelcomeMessage = value; }
93 }
94
95 private string m_standaloneInventoryPlugin;
96
97 public string StandaloneInventoryPlugin
98 {
99 get { return m_standaloneInventoryPlugin; }
100 set { m_standaloneInventoryPlugin = value; }
101 }
102
103 private string m_standaloneUserPlugin;
104
105 public string StandaloneUserPlugin
106 {
107 get { return m_standaloneUserPlugin; }
108 set { m_standaloneUserPlugin = value; }
109 }
110
111 private string m_standaloneInventorySource;
112
113 public string StandaloneInventorySource
114 {
115 get { return m_standaloneInventorySource; }
116 set { m_standaloneInventorySource = value; }
117 }
118
119 private string m_standaloneUserSource;
120
121 public string StandaloneUserSource
122 {
123 get { return m_standaloneUserSource; }
124 set { m_standaloneUserSource = value; }
125 }
126
127 protected string m_librariesXMLFile;
128 public string LibrariesXMLFile
129 {
130 get
131 {
132 return m_librariesXMLFile;
133 }
134 set
135 {
136 m_librariesXMLFile = value;
137 }
138 }
139 39
140 public const uint DefaultAssetServerHttpPort = 8003; 40 public const uint DefaultAssetServerHttpPort = 8003;
141 public const uint DefaultRegionHttpPort = 9000; 41 public const uint DefaultRegionHttpPort = 9000;
@@ -146,4 +46,4 @@ namespace OpenSim.Framework
146 public const uint DefaultGridServerHttpPort = 8003; 46 public const uint DefaultGridServerHttpPort = 8003;
147 public const uint DefaultInventoryServerHttpPort = 8003; 47 public const uint DefaultInventoryServerHttpPort = 8003;
148 } 48 }
149} 49} \ No newline at end of file
diff --git a/OpenSim/Framework/MainServer.cs b/OpenSim/Framework/MainServer.cs
index 0515b16..a3e0a26 100644
--- a/OpenSim/Framework/MainServer.cs
+++ b/OpenSim/Framework/MainServer.cs
@@ -52,6 +52,11 @@ namespace OpenSim.Framework
52 return GetHttpServer(port,null); 52 return GetHttpServer(port,null);
53 } 53 }
54 54
55 public static void AddHttpServer(BaseHttpServer server)
56 {
57 m_Servers.Add(server.Port, server);
58 }
59
55 public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr) 60 public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
56 { 61 {
57 if (port == 0) 62 if (port == 0)
diff --git a/OpenSim/Framework/NetworkServersInfo.cs b/OpenSim/Framework/NetworkServersInfo.cs
index b25f8b9..5bb4111 100644
--- a/OpenSim/Framework/NetworkServersInfo.cs
+++ b/OpenSim/Framework/NetworkServersInfo.cs
@@ -49,6 +49,12 @@ namespace OpenSim.Framework
49 public string HttpSSLCN = ""; 49 public string HttpSSLCN = "";
50 public uint httpSSLPort = 9001; 50 public uint httpSSLPort = 9001;
51 51
52 // "Out of band" managemnt https
53 public bool ssl_listener = false;
54 public uint https_port = 0;
55 public string cert_path = String.Empty;
56 public string cert_pass = String.Empty;
57
52 public string MessagingURL = String.Empty; 58 public string MessagingURL = String.Empty;
53 59
54 public NetworkServersInfo() 60 public NetworkServersInfo()
@@ -86,6 +92,15 @@ namespace OpenSim.Framework
86 secureInventoryServer = config.Configs["Network"].GetBoolean("secure_inventory_server", true); 92 secureInventoryServer = config.Configs["Network"].GetBoolean("secure_inventory_server", true);
87 93
88 MessagingURL = config.Configs["Network"].GetString("messaging_server_url", string.Empty); 94 MessagingURL = config.Configs["Network"].GetString("messaging_server_url", string.Empty);
95
96 // "Out of band management https"
97 ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false);
98 if( ssl_listener)
99 {
100 cert_path = config.Configs["Network"].GetString("cert_path",String.Empty);
101 cert_pass = config.Configs["Network"].GetString("cert_pass",String.Empty);
102 https_port = (uint)config.Configs["Network"].GetInt("https_port", 0);
103 }
89 } 104 }
90 } 105 }
91} 106}
diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs
index 3e6fdaa..e7a7f7f 100644
--- a/OpenSim/Framework/PriorityQueue.cs
+++ b/OpenSim/Framework/PriorityQueue.cs
@@ -38,7 +38,7 @@ namespace OpenSim.Framework
38{ 38{
39 public class PriorityQueue 39 public class PriorityQueue
40 { 40 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 41// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 42
43 public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); 43 public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity);
44 44
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 239ce3d..4c007d6 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -96,251 +96,6 @@ namespace OpenSim.Framework
96 96
97 } 97 }
98 98
99 [Serializable]
100 public class SimpleRegionInfo
101 {
102// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
103
104 /// <summary>
105 /// The port by which http communication occurs with the region (most noticeably, CAPS communication)
106 /// </summary>
107 public uint HttpPort
108 {
109 get { return m_httpPort; }
110 set { m_httpPort = value; }
111 }
112 protected uint m_httpPort;
113
114 /// <summary>
115 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
116 /// </summary>
117 public string ServerURI
118 {
119 get {
120 if ( m_serverURI != string.Empty ) {
121 return m_serverURI;
122 } else {
123 return "http://" + m_externalHostName + ":" + m_httpPort + "/";
124 }
125 }
126 set {
127 if ( value.EndsWith("/") ) {
128 m_serverURI = value;
129 } else {
130 m_serverURI = value + '/';
131 }
132 }
133 }
134 protected string m_serverURI;
135
136 public string RegionName
137 {
138 get { return m_regionName; }
139 set { m_regionName = value; }
140 }
141 protected string m_regionName = String.Empty;
142
143 protected bool Allow_Alternate_Ports;
144 public bool m_allow_alternate_ports;
145 protected string m_externalHostName;
146
147 protected IPEndPoint m_internalEndPoint;
148 protected uint? m_regionLocX;
149 protected uint? m_regionLocY;
150 protected uint m_remotingPort;
151 public UUID RegionID = UUID.Zero;
152 public string RemotingAddress;
153 public UUID ScopeID = UUID.Zero;
154
155 public SimpleRegionInfo()
156 {
157 m_serverURI = string.Empty;
158 }
159
160 public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri)
161 {
162 m_regionLocX = regionLocX;
163 m_regionLocY = regionLocY;
164
165 m_internalEndPoint = internalEndPoint;
166 m_externalHostName = externalUri;
167 m_serverURI = string.Empty;
168 }
169
170 public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port)
171 {
172 m_regionLocX = regionLocX;
173 m_regionLocY = regionLocY;
174
175 m_externalHostName = externalUri;
176
177 m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port);
178 m_serverURI = string.Empty;
179 }
180
181 public SimpleRegionInfo(RegionInfo ConvertFrom)
182 {
183 m_regionName = ConvertFrom.RegionName;
184 m_regionLocX = ConvertFrom.RegionLocX;
185 m_regionLocY = ConvertFrom.RegionLocY;
186 m_internalEndPoint = ConvertFrom.InternalEndPoint;
187 m_externalHostName = ConvertFrom.ExternalHostName;
188 m_remotingPort = ConvertFrom.RemotingPort;
189 m_httpPort = ConvertFrom.HttpPort;
190 m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports;
191 RemotingAddress = ConvertFrom.RemotingAddress;
192 RegionID = UUID.Zero;
193 ServerURI = ConvertFrom.ServerURI;
194 }
195
196 public uint RemotingPort
197 {
198 get { return m_remotingPort; }
199 set { m_remotingPort = value; }
200 }
201
202 /// <value>
203 /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw.
204 ///
205 /// XXX Isn't this really doing too much to be a simple getter, rather than an explict method?
206 /// </value>
207 public IPEndPoint ExternalEndPoint
208 {
209 get
210 {
211 // Old one defaults to IPv6
212 //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port);
213
214 IPAddress ia = null;
215 // If it is already an IP, don't resolve it - just return directly
216 if (IPAddress.TryParse(m_externalHostName, out ia))
217 return new IPEndPoint(ia, m_internalEndPoint.Port);
218
219 // Reset for next check
220 ia = null;
221 try
222 {
223 foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName))
224 {
225 if (ia == null)
226 ia = Adr;
227
228 if (Adr.AddressFamily == AddressFamily.InterNetwork)
229 {
230 ia = Adr;
231 break;
232 }
233 }
234 }
235 catch (SocketException e)
236 {
237 throw new Exception(
238 "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" +
239 e + "' attached to this exception", e);
240 }
241
242 return new IPEndPoint(ia, m_internalEndPoint.Port);
243 }
244
245 set { m_externalHostName = value.ToString(); }
246 }
247
248 public string ExternalHostName
249 {
250 get { return m_externalHostName; }
251 set { m_externalHostName = value; }
252 }
253
254 public IPEndPoint InternalEndPoint
255 {
256 get { return m_internalEndPoint; }
257 set { m_internalEndPoint = value; }
258 }
259
260 public uint RegionLocX
261 {
262 get { return m_regionLocX.Value; }
263 set { m_regionLocX = value; }
264 }
265
266 public uint RegionLocY
267 {
268 get { return m_regionLocY.Value; }
269 set { m_regionLocY = value; }
270 }
271
272 public ulong RegionHandle
273 {
274 get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); }
275 }
276
277 public int getInternalEndPointPort()
278 {
279 return m_internalEndPoint.Port;
280 }
281
282 public Dictionary<string, object> ToKeyValuePairs()
283 {
284 Dictionary<string, object> kvp = new Dictionary<string, object>();
285 kvp["uuid"] = RegionID.ToString();
286 kvp["locX"] = RegionLocX.ToString();
287 kvp["locY"] = RegionLocY.ToString();
288 kvp["external_ip_address"] = ExternalEndPoint.Address.ToString();
289 kvp["external_port"] = ExternalEndPoint.Port.ToString();
290 kvp["external_host_name"] = ExternalHostName;
291 kvp["http_port"] = HttpPort.ToString();
292 kvp["internal_ip_address"] = InternalEndPoint.Address.ToString();
293 kvp["internal_port"] = InternalEndPoint.Port.ToString();
294 kvp["alternate_ports"] = m_allow_alternate_ports.ToString();
295 kvp["server_uri"] = ServerURI;
296
297 return kvp;
298 }
299
300 public SimpleRegionInfo(Dictionary<string, object> kvp)
301 {
302 if ((kvp["external_ip_address"] != null) && (kvp["external_port"] != null))
303 {
304 int port = 0;
305 Int32.TryParse((string)kvp["external_port"], out port);
306 IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["external_ip_address"]), port);
307 ExternalEndPoint = ep;
308 }
309 else
310 ExternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
311
312 if (kvp["external_host_name"] != null)
313 ExternalHostName = (string)kvp["external_host_name"];
314
315 if (kvp["http_port"] != null)
316 {
317 UInt32 port = 0;
318 UInt32.TryParse((string)kvp["http_port"], out port);
319 HttpPort = port;
320 }
321
322 if ((kvp["internal_ip_address"] != null) && (kvp["internal_port"] != null))
323 {
324 int port = 0;
325 Int32.TryParse((string)kvp["internal_port"], out port);
326 IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["internal_ip_address"]), port);
327 InternalEndPoint = ep;
328 }
329 else
330 InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
331
332 if (kvp["alternate_ports"] != null)
333 {
334 bool alts = false;
335 Boolean.TryParse((string)kvp["alternate_ports"], out alts);
336 m_allow_alternate_ports = alts;
337 }
338
339 if (kvp["server_uri"] != null)
340 ServerURI = (string)kvp["server_uri"];
341 }
342 }
343
344 public class RegionInfo 99 public class RegionInfo
345 { 100 {
346 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 101 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index ba89e21..598e5d1 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -32,6 +32,7 @@ using System.Collections.Specialized;
32using System.IO; 32using System.IO;
33using System.Net; 33using System.Net;
34using System.Net.Sockets; 34using System.Net.Sockets;
35using System.Security.Cryptography.X509Certificates;
35using System.Reflection; 36using System.Reflection;
36using System.Globalization; 37using System.Globalization;
37using System.Text; 38using System.Text;
@@ -72,6 +73,7 @@ namespace OpenSim.Framework.Servers.HttpServer
72 protected uint m_port; 73 protected uint m_port;
73 protected uint m_sslport; 74 protected uint m_sslport;
74 protected bool m_ssl; 75 protected bool m_ssl;
76 private X509Certificate2 m_cert;
75 protected bool m_firstcaps = true; 77 protected bool m_firstcaps = true;
76 protected string m_SSLCommonName = ""; 78 protected string m_SSLCommonName = "";
77 79
@@ -123,6 +125,14 @@ namespace OpenSim.Framework.Servers.HttpServer
123 } 125 }
124 } 126 }
125 127
128 public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl)
129 {
130 if (m_ssl)
131 {
132 m_cert = new X509Certificate2(CPath, CPass);
133 }
134 }
135
126 /// <summary> 136 /// <summary>
127 /// Add a stream handler to the http server. If the handler already exists, then nothing happens. 137 /// Add a stream handler to the http server. If the handler already exists, then nothing happens.
128 /// </summary> 138 /// </summary>
@@ -1683,6 +1693,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1683 try 1693 try
1684 { 1694 {
1685 //m_httpListener = new HttpListener(); 1695 //m_httpListener = new HttpListener();
1696
1686 NotSocketErrors = 0; 1697 NotSocketErrors = 0;
1687 if (!m_ssl) 1698 if (!m_ssl)
1688 { 1699 {
@@ -1702,6 +1713,9 @@ namespace OpenSim.Framework.Servers.HttpServer
1702 { 1713 {
1703 //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/"); 1714 //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/");
1704 //m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); 1715 //m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
1716 m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert);
1717 m_httpListener2.ExceptionThrown += httpServerException;
1718 m_httpListener2.LogWriter = httpserverlog;
1705 } 1719 }
1706 1720
1707 m_httpListener2.RequestReceived += OnRequest; 1721 m_httpListener2.RequestReceived += OnRequest;
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs
index 40ab765..2d81ea8 100644
--- a/OpenSim/Region/Application/ConfigurationLoader.cs
+++ b/OpenSim/Region/Application/ConfigurationLoader.cs
@@ -372,21 +372,7 @@ namespace OpenSim
372 = startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll"); 372 = startupConfig.GetString("clientstack_plugin", "OpenSim.Region.ClientStack.LindenUDP.dll");
373 } 373 }
374 374
375 IConfig standaloneConfig = m_config.Source.Configs["StandAlone"];
376 if (standaloneConfig != null)
377 {
378 m_configSettings.StandaloneAuthenticate = standaloneConfig.GetBoolean("accounts_authenticate", true);
379 m_configSettings.StandaloneWelcomeMessage = standaloneConfig.GetString("welcome_message");
380
381 m_configSettings.StandaloneInventoryPlugin = standaloneConfig.GetString("inventory_plugin");
382 m_configSettings.StandaloneInventorySource = standaloneConfig.GetString("inventory_source");
383 m_configSettings.StandaloneUserPlugin = standaloneConfig.GetString("userDatabase_plugin");
384 m_configSettings.StandaloneUserSource = standaloneConfig.GetString("user_source");
385
386 m_configSettings.LibrariesXMLFile = standaloneConfig.GetString("LibrariesXMLFile");
387 }
388
389 m_networkServersInfo.loadFromConfiguration(m_config.Source); 375 m_networkServersInfo.loadFromConfiguration(m_config.Source);
390 } 376 }
391 } 377 }
392} 378} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 43903ce..025c6e6 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5982,7 +5982,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5982 AvatarWearingArgs wearingArgs = new AvatarWearingArgs(); 5982 AvatarWearingArgs wearingArgs = new AvatarWearingArgs();
5983 for (int i = 0; i < nowWearing.WearableData.Length; i++) 5983 for (int i = 0; i < nowWearing.WearableData.Length; i++)
5984 { 5984 {
5985 m_log.DebugFormat("[XXX]: Wearable type {0} item {1}", nowWearing.WearableData[i].WearableType, nowWearing.WearableData[i].ItemID); 5985 //m_log.DebugFormat("[XXX]: Wearable type {0} item {1}", nowWearing.WearableData[i].WearableType, nowWearing.WearableData[i].ItemID);
5986 AvatarWearingArgs.Wearable wearable = 5986 AvatarWearingArgs.Wearable wearable =
5987 new AvatarWearingArgs.Wearable(nowWearing.WearableData[i].ItemID, 5987 new AvatarWearingArgs.Wearable(nowWearing.WearableData[i].ItemID,
5988 nowWearing.WearableData[i].WearableType); 5988 nowWearing.WearableData[i].WearableType);
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index ea1317a..6e3a58e 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -96,6 +96,22 @@ namespace OpenSim.Region.ClientStack
96 96
97 MainServer.Instance = m_httpServer; 97 MainServer.Instance = m_httpServer;
98 98
99 // "OOB" Server
100 if (m_networkServersInfo.ssl_listener)
101 {
102 BaseHttpServer server = null;
103 server = new BaseHttpServer(
104 m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path,
105 m_networkServersInfo.cert_pass);
106 // Add the server to m_Servers
107 if(server != null)
108 {
109 m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port);
110 MainServer.AddHttpServer(server);
111 server.Start();
112 }
113 }
114
99 base.StartupSpecific(); 115 base.StartupSpecific();
100 } 116 }
101 117
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 08ac624..e92f072 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
76 } 76 }
77 77
78 if (m_scene == null) 78 if (m_scene == null)
79 m_scene = scene; 79 m_scene = scene;
80 } 80 }
81 81
82 public void PostInitialise() 82 public void PostInitialise()
@@ -162,12 +162,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
162 // one and we're done otherwise, ask for a rebake 162 // one and we're done otherwise, ask for a rebake
163 if (checkonly) return false; 163 if (checkonly) return false;
164 164
165 m_log.InfoFormat("[AVFACTORY] missing baked texture {0}, request rebake",face.TextureID); 165 m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake",face.TextureID);
166 client.SendRebakeAvatarTextures(face.TextureID); 166 client.SendRebakeAvatarTextures(face.TextureID);
167 } 167 }
168 } 168 }
169 169
170 m_log.DebugFormat("[AVFACTORY]: complete texture check for {0}", client.AgentId); 170 m_log.DebugFormat("[AVFACTORY]: completed texture check for {0}", client.AgentId);
171 171
172 // If we only found default textures, then the appearance is not cached 172 // If we only found default textures, then the appearance is not cached
173 return (defonly ? false : true); 173 return (defonly ? false : true);
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 111d808..eb776fe 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -66,8 +66,8 @@ namespace OpenSim.Region.CoreModules.Framework
66 m_scene = scene; 66 m_scene = scene;
67 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); 67 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
68 MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps", 68 MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
69 "show capabilities", 69 "show caps",
70 "Shows all registered capabilities", CapabilitiesCommand); 70 "Shows all registered capabilities", CapabilitiesCommand);
71 } 71 }
72 72
73 public void RegionLoaded(Scene scene) 73 public void RegionLoaded(Scene scene)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 73f07ba..da3a541 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -892,6 +892,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
892 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 892 if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent))
893 { 893 {
894 // region doesn't take it 894 // region doesn't take it
895 ReInstantiateScripts(agent);
895 ResetFromTransit(agent.UUID); 896 ResetFromTransit(agent.UUID);
896 return agent; 897 return agent;
897 } 898 }
@@ -1761,14 +1762,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1761 protected void ReInstantiateScripts(ScenePresence sp) 1762 protected void ReInstantiateScripts(ScenePresence sp)
1762 { 1763 {
1763 int i = 0; 1764 int i = 0;
1764 sp.Attachments.ForEach(delegate(SceneObjectGroup sog) 1765 if (sp.InTransitScriptStates.Count > 0)
1765 { 1766 {
1766 sog.SetState(sp.InTransitScriptStates[i++], sp.Scene); 1767 sp.Attachments.ForEach(delegate(SceneObjectGroup sog)
1767 sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0); 1768 {
1768 sog.ResumeScripts(); 1769 if (i < sp.InTransitScriptStates.Count)
1769 }); 1770 {
1771 sog.SetState(sp.InTransitScriptStates[i++], sp.Scene);
1772 sog.CreateScriptInstances(0, false, sp.Scene.DefaultScriptEngine, 0);
1773 sog.ResumeScripts();
1774 }
1775 else
1776 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}", sp.InTransitScriptStates.Count, sp.Attachments.Count);
1777 });
1770 1778
1771 sp.InTransitScriptStates.Clear(); 1779 sp.InTransitScriptStates.Clear();
1780 }
1772 } 1781 }
1773 #endregion 1782 #endregion
1774 1783
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 9b565ed..a552a28 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -78,7 +78,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
78 78
79 private int m_TotalUrls = 100; 79 private int m_TotalUrls = 100;
80 80
81 private uint https_port = 0;
81 private IHttpServer m_HttpServer = null; 82 private IHttpServer m_HttpServer = null;
83 private IHttpServer m_HttpsServer = null;
82 84
83 private string m_ExternalHostNameForLSL = ""; 85 private string m_ExternalHostNameForLSL = "";
84 86
@@ -100,6 +102,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
100 public void Initialise(IConfigSource config) 102 public void Initialise(IConfigSource config)
101 { 103 {
102 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName); 104 m_ExternalHostNameForLSL = config.Configs["Network"].GetString("ExternalHostNameForLSL", System.Environment.MachineName);
105 bool ssl_enabled = config.Configs["Network"].GetBoolean("https_listener",false);
106 if (ssl_enabled)
107 {
108 https_port = (uint) config.Configs["Network"].GetInt("https_port",0);
109 }
103 } 110 }
104 111
105 public void PostInitialise() 112 public void PostInitialise()
@@ -113,6 +120,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
113 // There can only be one 120 // There can only be one
114 // 121 //
115 m_HttpServer = MainServer.Instance; 122 m_HttpServer = MainServer.Instance;
123 //
124 // We can use the https if it is enabled
125 if (https_port > 0)
126 {
127 m_HttpsServer = MainServer.GetHttpServer(https_port);
128 }
116 } 129 }
117 130
118 scene.RegisterModuleInterface<IUrlModule>(this); 131 scene.RegisterModuleInterface<IUrlModule>(this);
@@ -171,7 +184,40 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
171 { 184 {
172 UUID urlcode = UUID.Random(); 185 UUID urlcode = UUID.Random();
173 186
174 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); 187 if (m_HttpsServer == null)
188 {
189 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
190 return urlcode;
191 }
192
193 lock (m_UrlMap)
194 {
195 if (m_UrlMap.Count >= m_TotalUrls)
196 {
197 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" });
198 return urlcode;
199 }
200 string url = "https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/";
201
202 UrlData urlData = new UrlData();
203 urlData.hostID = host.UUID;
204 urlData.itemID = itemID;
205 urlData.engine = engine;
206 urlData.url = url;
207 urlData.urlcode = urlcode;
208 urlData.requests = new Dictionary<UUID, RequestData>();
209
210
211 m_UrlMap[url] = urlData;
212
213 string uri = "/lslhttps/" + urlcode.ToString() + "/";
214
215 m_HttpsServer.AddPollServiceHTTPHandler(uri,HandleHttpPoll,
216 new PollServiceEventArgs(HttpRequestHandler,HasEvents, GetEvents, NoEvents,
217 urlcode));
218
219 engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url });
220 }
175 221
176 return urlcode; 222 return urlcode;
177 } 223 }
@@ -345,7 +391,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
345 } 391 }
346 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) 392 private Hashtable GetEvents(UUID requestID, UUID sessionID, string request)
347 { 393 {
348 UrlData url = null; 394 UrlData url = null;
349 RequestData requestData = null; 395 RequestData requestData = null;
350 396
351 lock (m_RequestMap) 397 lock (m_RequestMap)
@@ -391,11 +437,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
391 lock (request) 437 lock (request)
392 { 438 {
393 string uri = request["uri"].ToString(); 439 string uri = request["uri"].ToString();
394 440 bool is_ssl = uri.Contains("lslhttps");
441
395 try 442 try
396 { 443 {
397 Hashtable headers = (Hashtable)request["headers"]; 444 Hashtable headers = (Hashtable)request["headers"];
398 445
399// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/"; 446// string uri_full = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri;// "/lslhttp/" + urlcode.ToString() + "/";
400 447
401 int pos1 = uri.IndexOf("/");// /lslhttp 448 int pos1 = uri.IndexOf("/");// /lslhttp
@@ -409,7 +456,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
409 456
410 pathInfo = uri.Substring(pos3); 457 pathInfo = uri.Substring(pos3);
411 458
412 UrlData url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp]; 459 UrlData url = null;
460 if (!is_ssl)
461 url = m_UrlMap["http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + uri_tmp];
462 else
463 url = m_UrlMap["https://" + m_ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + uri_tmp];
413 464
414 //for llGetHttpHeader support we need to store original URI here 465 //for llGetHttpHeader support we need to store original URI here
415 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers 466 //to make x-path-info / x-query-string / x-script-url / x-remote-ip headers
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index ab6a598..e983239 100644
--- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -64,19 +64,26 @@ namespace OpenSim.Region.CoreModules.World.Region
64 public void AddRegion(Scene scene) 64 public void AddRegion(Scene scene)
65 { 65 {
66 m_Scene = scene; 66 m_Scene = scene;
67
67 scene.RegisterModuleInterface<IRestartModule>(this); 68 scene.RegisterModuleInterface<IRestartModule>(this);
68 MainConsole.Instance.Commands.AddCommand("RestartModule", 69 MainConsole.Instance.Commands.AddCommand("RestartModule",
69 false, "region restart bluebox", 70 false, "region restart bluebox",
70 "region restart bluebox <message> <time> ...", 71 "region restart bluebox <message> <delta seconds>+",
71 "Restart the region", HandleRegionRestart); 72 "Schedule a region restart",
73 "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.",
74 HandleRegionRestart);
75
72 MainConsole.Instance.Commands.AddCommand("RestartModule", 76 MainConsole.Instance.Commands.AddCommand("RestartModule",
73 false, "region restart notice", 77 false, "region restart notice",
74 "region restart notice <message> <time> ...", 78 "region restart notice <message> <delta seconds>+",
75 "Restart the region", HandleRegionRestart); 79 "Schedule a region restart",
80 "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.",
81 HandleRegionRestart);
82
76 MainConsole.Instance.Commands.AddCommand("RestartModule", 83 MainConsole.Instance.Commands.AddCommand("RestartModule",
77 false, "region restart abort", 84 false, "region restart abort",
78 "region restart abort [<message>]", 85 "region restart abort [<message>]",
79 "Restart the region", HandleRegionRestart); 86 "Abort a region restart", HandleRegionRestart);
80 } 87 }
81 88
82 public void RegionLoaded(Scene scene) 89 public void RegionLoaded(Scene scene)
@@ -245,7 +252,7 @@ namespace OpenSim.Region.CoreModules.World.Region
245 } 252 }
246 } 253 }
247 254
248 MainConsole.Instance.Output("Error: restart region <mode> <name> <time> ..."); 255 MainConsole.Instance.Output("Error: restart region <mode> <name> <delta seconds>+");
249 return; 256 return;
250 } 257 }
251 258
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index b0f0de6..cd01a05 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -713,7 +713,7 @@ namespace OpenSim.Region.Framework.Scenes
713 newName = item.Name; 713 newName = item.Name;
714 } 714 }
715 715
716 if (remoteClient.AgentId == oldAgentID) 716 if (remoteClient.AgentId == oldAgentID || (LibraryService != null && LibraryService.LibraryRootFolder != null && oldAgentID == LibraryService.LibraryRootFolder.Owner))
717 { 717 {
718 CreateNewInventoryItem( 718 CreateNewInventoryItem(
719 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType, 719 remoteClient, item.CreatorId, item.CreatorData, newFolderID, newName, item.Flags, callbackID, asset, (sbyte)item.InvType,
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index b537381..49fbe33 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -775,6 +775,8 @@ namespace OpenSim.Region.Framework.Scenes
775 m_regInfo = regInfo; 775 m_regInfo = regInfo;
776 m_eventManager = new EventManager(); 776 m_eventManager = new EventManager();
777 777
778 m_permissions = new ScenePermissions(this);
779
778 m_lastUpdate = Util.EnvironmentTickCount(); 780 m_lastUpdate = Util.EnvironmentTickCount();
779 } 781 }
780 782
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 631c91b..f6295b1 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2430,8 +2430,12 @@ namespace OpenSim.Region.Framework.Scenes
2430 float speed = Velocity.Length(); 2430 float speed = Velocity.Length();
2431 float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity); 2431 float velocidyDiff = Vector3.Distance(lastVelocitySentToAllClients, Velocity);
2432 2432
2433 // assuming 5 ms. worst case precision for timer, use 2x that
2434 // for distance error threshold
2435 float distanceErrorThreshold = speed * 0.01f;
2436
2433 if (speed < 0.01f // allow rotation updates if avatar position is unchanged 2437 if (speed < 0.01f // allow rotation updates if avatar position is unchanged
2434 || Math.Abs(distanceError) > 0.25f // arbitrary distance error threshold 2438 || Math.Abs(distanceError) > distanceErrorThreshold
2435 || velocidyDiff > 0.01f) // did velocity change from last update? 2439 || velocidyDiff > 0.01f) // did velocity change from last update?
2436 { 2440 {
2437 m_perfMonMS = currentTick; 2441 m_perfMonMS = currentTick;
@@ -3151,7 +3155,7 @@ namespace OpenSim.Region.Framework.Scenes
3151 { 3155 {
3152 cAgent.AttachmentObjects = new List<ISceneObject>(); 3156 cAgent.AttachmentObjects = new List<ISceneObject>();
3153 cAgent.AttachmentObjectStates = new List<string>(); 3157 cAgent.AttachmentObjectStates = new List<string>();
3154 IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); 3158// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3155 m_InTransitScriptStates.Clear(); 3159 m_InTransitScriptStates.Clear();
3156 foreach (SceneObjectGroup sog in m_attachments) 3160 foreach (SceneObjectGroup sog in m_attachments)
3157 { 3161 {
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index db17d8f..8f8124e 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -107,11 +107,10 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
107 107
108 scene.AddCommand( 108 scene.AddCommand(
109 this, "emergency-monitoring", 109 this, "emergency-monitoring",
110 "Go on/off emergency monitoring mode", 110 "emergency-monitoring",
111 "Go on/off emergency monitoring mode", 111 "Go on/off emergency monitoring mode",
112 "Go on/off emergency monitoring mode", 112 "Go on/off emergency monitoring mode",
113 EmergencyMonitoring); 113 EmergencyMonitoring);
114
115 } 114 }
116 115
117 public void RemoveRegion(Scene scene) 116 public void RemoveRegion(Scene scene)
@@ -190,7 +189,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
190 int maxNameLength = 18; 189 int maxNameLength = 18;
191 int maxRegionNameLength = 14; 190 int maxRegionNameLength = 14;
192 int maxTypeLength = 4; 191 int maxTypeLength = 4;
193 int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding; 192// int totalInfoFieldsLength = maxNameLength + columnPadding + maxRegionNameLength + columnPadding + maxTypeLength + columnPadding;
194 193
195 report.Append(GetColumnEntry("User", maxNameLength, columnPadding)); 194 report.Append(GetColumnEntry("User", maxNameLength, columnPadding));
196 report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding)); 195 report.Append(GetColumnEntry("Region", maxRegionNameLength, columnPadding));
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
new file mode 100644
index 0000000..8589901
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -0,0 +1,122 @@
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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Framework.Statistics;
39using OpenSim.Region.ClientStack.LindenUDP;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42
43namespace OpenSim.Region.OptionalModules.Avatar.Appearance
44{
45 /// <summary>
46 /// A module that just holds commands for inspecting avatar appearance.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AppearanceInfoModule")]
49 public class AppearanceInfoModule : ISharedRegionModule
50 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 protected Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
54 protected IAvatarFactory m_avatarFactory;
55
56 public string Name { get { return "Appearance Information Module"; } }
57
58 public Type ReplaceableInterface { get { return null; } }
59
60 public void Initialise(IConfigSource source)
61 {
62// m_log.DebugFormat("[APPEARANCE INFO MODULE]: INITIALIZED MODULE");
63 }
64
65 public void PostInitialise()
66 {
67// m_log.DebugFormat("[APPEARANCE INFO MODULE]: POST INITIALIZED MODULE");
68 }
69
70 public void Close()
71 {
72// m_log.DebugFormat("[APPEARANCE INFO MODULE]: CLOSED MODULE");
73 }
74
75 public void AddRegion(Scene scene)
76 {
77// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
78 }
79
80 public void RemoveRegion(Scene scene)
81 {
82// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
83
84 lock (m_scenes)
85 m_scenes.Remove(scene.RegionInfo.RegionID);
86 }
87
88 public void RegionLoaded(Scene scene)
89 {
90// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
91
92 lock (m_scenes)
93 m_scenes[scene.RegionInfo.RegionID] = scene;
94
95 scene.AddCommand(
96 this, "appearance show",
97 "appearance show",
98 "Show appearance information for each avatar in the simulator. At the moment, ",
99 ShowAppearanceInfo);
100 }
101
102 protected void ShowAppearanceInfo(string module, string[] cmd)
103 {
104 lock (m_scenes)
105 {
106 foreach (Scene scene in m_scenes.Values)
107 {
108 scene.ForEachClient(
109 delegate(IClientAPI client)
110 {
111 if (client is LLClientView && !((LLClientView)client).ChildAgentStatus())
112 {
113 bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(client);
114 MainConsole.Instance.OutputFormat(
115 "{0} baked apperance texture is {1}", client.Name, bakedTextureValid ? "OK" : "corrupt");
116 }
117 });
118 }
119 }
120 }
121 }
122} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml b/OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml
index 5eea286..8691343 100644
--- a/OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml
+++ b/OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml
@@ -13,5 +13,6 @@
13 <RegionModule id="Concierge" type="OpenSim.Region.OptionalModules.Avatar.Concierge.ConciergeModule" /> 13 <RegionModule id="Concierge" type="OpenSim.Region.OptionalModules.Avatar.Concierge.ConciergeModule" />
14 <RegionModule id="VivoxVoice" type="OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice.VivoxVoiceModule" /> 14 <RegionModule id="VivoxVoice" type="OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice.VivoxVoiceModule" />
15 <RegionModule id="WorldViewModule" type="OpenSim.Region.OptionalModules.World.WorldView.WorldViewModule" /> 15 <RegionModule id="WorldViewModule" type="OpenSim.Region.OptionalModules.World.WorldView.WorldViewModule" />
16 <RegionModule id="AutoBackupModule" type="OpenSim.Region.OptionalModules.World.AutoBackup.AutoBackupModule" />
16 </Extension> 17 </Extension>
17</Addin> 18</Addin>
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
new file mode 100644
index 0000000..ce9a448
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs
@@ -0,0 +1,929 @@
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
28using System;
29using System.Collections.Generic;
30using System.Diagnostics;
31using System.IO;
32using System.Reflection;
33using System.Timers;
34using System.Text.RegularExpressions;
35using log4net;
36using Nini.Config;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40
41namespace OpenSim.Region.OptionalModules.World.AutoBackup
42{
43 /// <summary>
44 /// Choose between ways of naming the backup files that are generated.
45 /// </summary>
46 /// <remarks>Time: OARs are named by a timestamp.
47 /// Sequential: OARs are named by counting (Region_1.oar, Region_2.oar, etc.)
48 /// Overwrite: Only one file per region is created; it's overwritten each time a backup is made.</remarks>
49 public enum NamingType
50 {
51 Time,
52 Sequential,
53 Overwrite
54 }
55
56 ///<summary>
57 /// AutoBackupModule: save OAR region backups to disk periodically
58 /// </summary>
59 /// <remarks>
60 /// Config Settings Documentation.
61 /// At the TOP LEVEL, e.g. in OpenSim.ini, we have the following options:
62 /// EACH REGION, in OpenSim.ini, can have the following settings under the [AutoBackupModule] section.
63 /// IMPORTANT: You may optionally specify the key name as follows for a per-region key: [Region Name].[Key Name]
64 /// Example: My region is named Foo.
65 /// If I wanted to specify the "AutoBackupInterval" key just for this region, I would name my key "Foo.AutoBackupInterval", under the [AutoBackupModule] section of OpenSim.ini.
66 /// Instead of specifying them on a per-region basis, you can also omit the region name to specify the default setting for all regions.
67 /// Region-specific settings take precedence.
68 ///
69 /// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module. This setting does not support per-region basis.
70 /// All other settings under [AutoBackupModule] are ignored if AutoBackupModuleEnabled is false, even per-region settings!
71 /// AutoBackup: True/False. Default: False. If True, activate auto backup functionality.
72 /// This is the only required option for enabling auto-backup; the other options have sane defaults.
73 /// If False for a particular region, the auto-backup module becomes a no-op for the region, and all other AutoBackup* settings are ignored.
74 /// If False globally (the default), only regions that specifically override this with "FooRegion.AutoBackup = true" will get AutoBackup functionality.
75 /// AutoBackupInterval: Double, non-negative value. Default: 720 (12 hours).
76 /// The number of minutes between each backup attempt.
77 /// If a negative or zero value is given, it is equivalent to setting AutoBackup = False.
78 /// AutoBackupBusyCheck: True/False. Default: True.
79 /// If True, we will only take an auto-backup if a set of conditions are met.
80 /// These conditions are heuristics to try and avoid taking a backup when the sim is busy.
81 /// AutoBackupScript: String. Default: not specified (disabled).
82 /// File path to an executable script or binary to run when an automatic backup is taken.
83 /// The file should really be (Windows) an .exe or .bat, or (Linux/Mac) a shell script or binary.
84 /// Trying to "run" directories, or things with weird file associations on Win32, might cause unexpected results!
85 /// argv[1] of the executed file/script will be the file name of the generated OAR.
86 /// If the process can't be spawned for some reason (file not found, no execute permission, etc), write a warning to the console.
87 /// AutoBackupNaming: string. Default: Time.
88 /// One of three strings (case insensitive):
89 /// "Time": Current timestamp is appended to file name. An existing file will never be overwritten.
90 /// "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten.
91 /// "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file.
92 /// AutoBackupDir: String. Default: "." (the current directory).
93 /// A directory (absolute or relative) where backups should be saved.
94 /// AutoBackupDilationThreshold: float. Default: 0.5. Lower bound on time dilation required for BusyCheck heuristics to pass.
95 /// If the time dilation is below this value, don't take a backup right now.
96 /// AutoBackupAgentThreshold: int. Default: 10. Upper bound on # of agents in region required for BusyCheck heuristics to pass.
97 /// If the number of agents is greater than this value, don't take a backup right now
98 /// Save memory by setting low initial capacities. Minimizes impact in common cases of all regions using same interval, and instances hosting 1 ~ 4 regions.
99 /// Also helps if you don't want AutoBackup at all.
100 /// </remarks>
101 public class AutoBackupModule : ISharedRegionModule
102 {
103 private static readonly ILog m_log =
104 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
105 private readonly Dictionary<Guid, IScene> m_pendingSaves = new Dictionary<Guid, IScene>(1);
106 private readonly AutoBackupModuleState m_defaultState = new AutoBackupModuleState();
107 private readonly Dictionary<IScene, AutoBackupModuleState> m_states =
108 new Dictionary<IScene, AutoBackupModuleState>(1);
109 private readonly Dictionary<Timer, List<IScene>> m_timerMap =
110 new Dictionary<Timer, List<IScene>>(1);
111 private readonly Dictionary<double, Timer> m_timers = new Dictionary<double, Timer>(1);
112
113 private delegate T DefaultGetter<T>(string settingName, T defaultValue);
114 private bool m_enabled;
115
116 /// <summary>
117 /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState!
118 /// </summary>
119 private bool m_closed;
120
121 private IConfigSource m_configSource;
122
123 /// <summary>
124 /// Required by framework.
125 /// </summary>
126 public bool IsSharedModule
127 {
128 get { return true; }
129 }
130
131 #region ISharedRegionModule Members
132
133 /// <summary>
134 /// Identifies the module to the system.
135 /// </summary>
136 string IRegionModuleBase.Name
137 {
138 get { return "AutoBackupModule"; }
139 }
140
141 /// <summary>
142 /// We don't implement an interface, this is a single-use module.
143 /// </summary>
144 Type IRegionModuleBase.ReplaceableInterface
145 {
146 get { return null; }
147 }
148
149 /// <summary>
150 /// Called once in the lifetime of the module at startup.
151 /// </summary>
152 /// <param name="source">The input config source for OpenSim.ini.</param>
153 void IRegionModuleBase.Initialise(IConfigSource source)
154 {
155 // Determine if we have been enabled at all in OpenSim.ini -- this is part and parcel of being an optional module
156 this.m_configSource = source;
157 IConfig moduleConfig = source.Configs["AutoBackupModule"];
158 if (moduleConfig == null)
159 {
160 this.m_enabled = false;
161 return;
162 }
163 else
164 {
165 this.m_enabled = moduleConfig.GetBoolean("AutoBackupModuleEnabled", false);
166 if (this.m_enabled)
167 {
168 m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled");
169 }
170 else
171 {
172 return;
173 }
174 }
175
176 Timer defTimer = new Timer(43200000);
177 this.m_defaultState.Timer = defTimer;
178 this.m_timers.Add(43200000, defTimer);
179 defTimer.Elapsed += this.HandleElapsed;
180 defTimer.AutoReset = true;
181 defTimer.Start();
182
183 AutoBackupModuleState abms = this.ParseConfig(null, true);
184 m_log.Debug("[AUTO BACKUP]: Here is the default config:");
185 m_log.Debug(abms.ToString());
186 }
187
188 /// <summary>
189 /// Called once at de-init (sim shutting down).
190 /// </summary>
191 void IRegionModuleBase.Close()
192 {
193 if (!this.m_enabled)
194 {
195 return;
196 }
197
198 // We don't want any timers firing while the sim's coming down; strange things may happen.
199 this.StopAllTimers();
200 }
201
202 /// <summary>
203 /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded.
204 /// </summary>
205 /// <param name="scene"></param>
206 void IRegionModuleBase.AddRegion(Scene scene)
207 {
208 }
209
210 /// <summary>
211 /// Here we just clean up some resources and stop the OAR backup (if any) for the given scene.
212 /// </summary>
213 /// <param name="scene">The scene (region) to stop performing AutoBackup on.</param>
214 void IRegionModuleBase.RemoveRegion(Scene scene)
215 {
216 if (!this.m_enabled)
217 {
218 return;
219 }
220
221 if (this.m_states.ContainsKey(scene))
222 {
223 AutoBackupModuleState abms = this.m_states[scene];
224
225 // Remove this scene out of the timer map list
226 Timer timer = abms.Timer;
227 List<IScene> list = this.m_timerMap[timer];
228 list.Remove(scene);
229
230 // Shut down the timer if this was the last scene for the timer
231 if (list.Count == 0)
232 {
233 this.m_timerMap.Remove(timer);
234 this.m_timers.Remove(timer.Interval);
235 timer.Close();
236 }
237 this.m_states.Remove(scene);
238 }
239 }
240
241 /// <summary>
242 /// Most interesting/complex code paths in AutoBackup begin here.
243 /// We read lots of Nini config, maybe set a timer, add members to state tracking Dictionaries, etc.
244 /// </summary>
245 /// <param name="scene">The scene to (possibly) perform AutoBackup on.</param>
246 void IRegionModuleBase.RegionLoaded(Scene scene)
247 {
248 if (!this.m_enabled)
249 {
250 return;
251 }
252
253 // This really ought not to happen, but just in case, let's pretend it didn't...
254 if (scene == null)
255 {
256 return;
257 }
258
259 AutoBackupModuleState abms = this.ParseConfig(scene, false);
260 m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName);
261 m_log.Debug((abms == null ? "DEFAULT" : abms.ToString()));
262 }
263
264 /// <summary>
265 /// Currently a no-op.
266 /// </summary>
267 void ISharedRegionModule.PostInitialise()
268 {
269 }
270
271 #endregion
272
273 /// <summary>
274 /// Set up internal state for a given scene. Fairly complex code.
275 /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene.
276 /// </summary>
277 /// <param name="scene">The scene to look at.</param>
278 /// <param name="parseDefault">Whether this call is intended to figure out what we consider the "default" config (applied to all regions unless overridden by per-region settings).</param>
279 /// <returns>An AutoBackupModuleState contains most information you should need to know relevant to auto-backup, as applicable to a single region.</returns>
280 private AutoBackupModuleState ParseConfig(IScene scene, bool parseDefault)
281 {
282 string sRegionName;
283 string sRegionLabel;
284 string prepend;
285 AutoBackupModuleState state;
286
287 if (parseDefault)
288 {
289 sRegionName = null;
290 sRegionLabel = "DEFAULT";
291 prepend = "";
292 state = this.m_defaultState;
293 }
294 else
295 {
296 sRegionName = scene.RegionInfo.RegionName;
297 sRegionLabel = sRegionName;
298 prepend = sRegionName + ".";
299 state = null;
300 }
301
302 // Read the config settings and set variables.
303 IConfig regionConfig = (scene != null ? scene.Config.Configs[sRegionName] : null);
304 IConfig config = this.m_configSource.Configs["AutoBackupModule"];
305 if (config == null)
306 {
307 // defaultState would be disabled too if the section doesn't exist.
308 state = this.m_defaultState;
309 return state;
310 }
311
312 bool tmpEnabled = ResolveBoolean("AutoBackup", this.m_defaultState.Enabled, config, regionConfig);
313 if (state == null && tmpEnabled != this.m_defaultState.Enabled)
314 //Varies from default state
315 {
316 state = new AutoBackupModuleState();
317 }
318
319 if (state != null)
320 {
321 state.Enabled = tmpEnabled;
322 }
323
324 // If you don't want AutoBackup, we stop.
325 if ((state == null && !this.m_defaultState.Enabled) || (state != null && !state.Enabled))
326 {
327 return state;
328 }
329 else
330 {
331 m_log.Info("[AUTO BACKUP]: Region " + sRegionLabel + " is AutoBackup ENABLED.");
332 }
333
334 // Borrow an existing timer if one exists for the same interval; otherwise, make a new one.
335 double interval =
336 this.ResolveDouble("AutoBackupInterval", this.m_defaultState.IntervalMinutes,
337 config, regionConfig) * 60000.0;
338 if (state == null && interval != this.m_defaultState.IntervalMinutes*60000.0)
339 {
340 state = new AutoBackupModuleState();
341 }
342
343 if (this.m_timers.ContainsKey(interval))
344 {
345 if (state != null)
346 {
347 state.Timer = this.m_timers[interval];
348 }
349 m_log.Debug("[AUTO BACKUP]: Reusing timer for " + interval + " msec for region " +
350 sRegionLabel);
351 }
352 else
353 {
354 // 0 or negative interval == do nothing.
355 if (interval <= 0.0 && state != null)
356 {
357 state.Enabled = false;
358 return state;
359 }
360 if (state == null)
361 {
362 state = new AutoBackupModuleState();
363 }
364 Timer tim = new Timer(interval);
365 state.Timer = tim;
366 //Milliseconds -> minutes
367 this.m_timers.Add(interval, tim);
368 tim.Elapsed += this.HandleElapsed;
369 tim.AutoReset = true;
370 tim.Start();
371 }
372
373 // Add the current region to the list of regions tied to this timer.
374 if (scene != null)
375 {
376 if (state != null)
377 {
378 if (this.m_timerMap.ContainsKey(state.Timer))
379 {
380 this.m_timerMap[state.Timer].Add(scene);
381 }
382 else
383 {
384 List<IScene> scns = new List<IScene>(1);
385 scns.Add(scene);
386 this.m_timerMap.Add(state.Timer, scns);
387 }
388 }
389 else
390 {
391 if (this.m_timerMap.ContainsKey(this.m_defaultState.Timer))
392 {
393 this.m_timerMap[this.m_defaultState.Timer].Add(scene);
394 }
395 else
396 {
397 List<IScene> scns = new List<IScene>(1);
398 scns.Add(scene);
399 this.m_timerMap.Add(this.m_defaultState.Timer, scns);
400 }
401 }
402 }
403
404 bool tmpBusyCheck = ResolveBoolean("AutoBackupBusyCheck",
405 this.m_defaultState.BusyCheck, config, regionConfig);
406 if (state == null && tmpBusyCheck != this.m_defaultState.BusyCheck)
407 {
408 state = new AutoBackupModuleState();
409 }
410
411 if (state != null)
412 {
413 state.BusyCheck = tmpBusyCheck;
414 }
415
416 // Set file naming algorithm
417 string stmpNamingType = ResolveString("AutoBackupNaming",
418 this.m_defaultState.NamingType.ToString(), config, regionConfig);
419 NamingType tmpNamingType;
420 if (stmpNamingType.Equals("Time", StringComparison.CurrentCultureIgnoreCase))
421 {
422 tmpNamingType = NamingType.Time;
423 }
424 else if (stmpNamingType.Equals("Sequential", StringComparison.CurrentCultureIgnoreCase))
425 {
426 tmpNamingType = NamingType.Sequential;
427 }
428 else if (stmpNamingType.Equals("Overwrite", StringComparison.CurrentCultureIgnoreCase))
429 {
430 tmpNamingType = NamingType.Overwrite;
431 }
432 else
433 {
434 m_log.Warn("Unknown naming type specified for region " + sRegionLabel + ": " +
435 stmpNamingType);
436 tmpNamingType = NamingType.Time;
437 }
438
439 if (state == null && tmpNamingType != this.m_defaultState.NamingType)
440 {
441 state = new AutoBackupModuleState();
442 }
443
444 if (state != null)
445 {
446 state.NamingType = tmpNamingType;
447 }
448
449 string tmpScript = ResolveString("AutoBackupScript",
450 this.m_defaultState.Script, config, regionConfig);
451 if (state == null && tmpScript != this.m_defaultState.Script)
452 {
453 state = new AutoBackupModuleState();
454 }
455
456 if (state != null)
457 {
458 state.Script = tmpScript;
459 }
460
461 string tmpBackupDir = ResolveString("AutoBackupDir", ".", config, regionConfig);
462 if (state == null && tmpBackupDir != this.m_defaultState.BackupDir)
463 {
464 state = new AutoBackupModuleState();
465 }
466
467 if (state != null)
468 {
469 state.BackupDir = tmpBackupDir;
470 // Let's give the user some convenience and auto-mkdir
471 if (state.BackupDir != ".")
472 {
473 try
474 {
475 DirectoryInfo dirinfo = new DirectoryInfo(state.BackupDir);
476 if (!dirinfo.Exists)
477 {
478 dirinfo.Create();
479 }
480 }
481 catch (Exception e)
482 {
483 m_log.Warn(
484 "BAD NEWS. You won't be able to save backups to directory " +
485 state.BackupDir +
486 " because it doesn't exist or there's a permissions issue with it. Here's the exception.",
487 e);
488 }
489 }
490 }
491
492 return state;
493 }
494
495 /// <summary>
496 /// Helper function for ParseConfig.
497 /// </summary>
498 /// <param name="settingName"></param>
499 /// <param name="defaultValue"></param>
500 /// <param name="global"></param>
501 /// <param name="local"></param>
502 /// <returns></returns>
503 private bool ResolveBoolean(string settingName, bool defaultValue, IConfig global, IConfig local)
504 {
505 if(local != null)
506 {
507 return local.GetBoolean(settingName, global.GetBoolean(settingName, defaultValue));
508 }
509 else
510 {
511 return global.GetBoolean(settingName, defaultValue);
512 }
513 }
514
515 /// <summary>
516 /// Helper function for ParseConfig.
517 /// </summary>
518 /// <param name="settingName"></param>
519 /// <param name="defaultValue"></param>
520 /// <param name="global"></param>
521 /// <param name="local"></param>
522 /// <returns></returns>
523 private double ResolveDouble(string settingName, double defaultValue, IConfig global, IConfig local)
524 {
525 if (local != null)
526 {
527 return local.GetDouble(settingName, global.GetDouble(settingName, defaultValue));
528 }
529 else
530 {
531 return global.GetDouble(settingName, defaultValue);
532 }
533 }
534
535 /// <summary>
536 /// Helper function for ParseConfig.
537 /// </summary>
538 /// <param name="settingName"></param>
539 /// <param name="defaultValue"></param>
540 /// <param name="global"></param>
541 /// <param name="local"></param>
542 /// <returns></returns>
543 private int ResolveInt(string settingName, int defaultValue, IConfig global, IConfig local)
544 {
545 if (local != null)
546 {
547 return local.GetInt(settingName, global.GetInt(settingName, defaultValue));
548 }
549 else
550 {
551 return global.GetInt(settingName, defaultValue);
552 }
553 }
554
555 /// <summary>
556 /// Helper function for ParseConfig.
557 /// </summary>
558 /// <param name="settingName"></param>
559 /// <param name="defaultValue"></param>
560 /// <param name="global"></param>
561 /// <param name="local"></param>
562 /// <returns></returns>
563 private string ResolveString(string settingName, string defaultValue, IConfig global, IConfig local)
564 {
565 if (local != null)
566 {
567 return local.GetString(settingName, global.GetString(settingName, defaultValue));
568 }
569 else
570 {
571 return global.GetString(settingName, defaultValue);
572 }
573 }
574
575 /// <summary>
576 /// Called when any auto-backup timer expires. This starts the code path for actually performing a backup.
577 /// </summary>
578 /// <param name="sender"></param>
579 /// <param name="e"></param>
580 private void HandleElapsed(object sender, ElapsedEventArgs e)
581 {
582 // TODO: heuristic thresholds are per-region, so we should probably run heuristics once per region
583 // XXX: Running heuristics once per region could add undue performance penalty for something that's supposed to
584 // check whether the region is too busy! Especially on sims with LOTS of regions.
585 // Alternative: make heuristics thresholds global to the module rather than per-region. Less flexible,
586 // but would allow us to be semantically correct while being easier on perf.
587 // Alternative 2: Run heuristics once per unique set of heuristics threshold parameters! Ay yi yi...
588 // Alternative 3: Don't support per-region heuristics at all; just accept them as a global only parameter.
589 // Since this is pretty experimental, I haven't decided which alternative makes the most sense.
590 if (this.m_closed)
591 {
592 return;
593 }
594 bool heuristicsRun = false;
595 bool heuristicsPassed = false;
596 if (!this.m_timerMap.ContainsKey((Timer) sender))
597 {
598 m_log.Debug("Code-up error: timerMap doesn't contain timer " + sender);
599 }
600
601 List<IScene> tmap = this.m_timerMap[(Timer) sender];
602 if (tmap != null && tmap.Count > 0)
603 {
604 foreach (IScene scene in tmap)
605 {
606 AutoBackupModuleState state = this.m_states[scene];
607 bool heuristics = state.BusyCheck;
608
609 // Fast path: heuristics are on; already ran em; and sim is fine; OR, no heuristics for the region.
610 if ((heuristics && heuristicsRun && heuristicsPassed) || !heuristics)
611 {
612 this.DoRegionBackup(scene);
613 // Heuristics are on; ran but we're too busy -- keep going. Maybe another region will have heuristics off!
614 }
615 else if (heuristicsRun)
616 {
617 m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " +
618 scene.RegionInfo.RegionName + " right now.");
619 continue;
620 // Logical Deduction: heuristics are on but haven't been run
621 }
622 else
623 {
624 heuristicsPassed = this.RunHeuristics(scene);
625 heuristicsRun = true;
626 if (!heuristicsPassed)
627 {
628 m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " +
629 scene.RegionInfo.RegionName + " right now.");
630 continue;
631 }
632 this.DoRegionBackup(scene);
633 }
634 }
635 }
636 }
637
638 /// <summary>
639 /// Save an OAR, register for the callback for when it's done, then call the AutoBackupScript (if applicable).
640 /// </summary>
641 /// <param name="scene"></param>
642 private void DoRegionBackup(IScene scene)
643 {
644 if (scene.RegionStatus != RegionStatus.Up)
645 {
646 // We won't backup a region that isn't operating normally.
647 m_log.Warn("[AUTO BACKUP]: Not backing up region " + scene.RegionInfo.RegionName +
648 " because its status is " + scene.RegionStatus);
649 return;
650 }
651
652 AutoBackupModuleState state = this.m_states[scene];
653 IRegionArchiverModule iram = scene.RequestModuleInterface<IRegionArchiverModule>();
654 string savePath = BuildOarPath(scene.RegionInfo.RegionName,
655 state.BackupDir,
656 state.NamingType);
657 if (savePath == null)
658 {
659 m_log.Warn("[AUTO BACKUP]: savePath is null in HandleElapsed");
660 return;
661 }
662 Guid guid = Guid.NewGuid();
663 m_pendingSaves.Add(guid, scene);
664 state.LiveRequests.Add(guid, savePath);
665 ((Scene) scene).EventManager.OnOarFileSaved += new EventManager.OarFileSaved(EventManager_OnOarFileSaved);
666 iram.ArchiveRegion(savePath, guid, null);
667 }
668
669 /// <summary>
670 /// Called by the Event Manager when the OnOarFileSaved event is fired.
671 /// </summary>
672 /// <param name="guid"></param>
673 /// <param name="message"></param>
674 void EventManager_OnOarFileSaved(Guid guid, string message)
675 {
676 // Ignore if the OAR save is being done by some other part of the system
677 if (m_pendingSaves.ContainsKey(guid))
678 {
679 AutoBackupModuleState abms = m_states[(m_pendingSaves[guid])];
680 ExecuteScript(abms.Script, abms.LiveRequests[guid]);
681 m_pendingSaves.Remove(guid);
682 abms.LiveRequests.Remove(guid);
683 }
684 }
685
686 /// <summary>This format may turn out to be too unwieldy to keep...
687 /// Besides, that's what ctimes are for. But then how do I name each file uniquely without using a GUID?
688 /// Sequential numbers, right? We support those, too!</summary>
689 private static string GetTimeString()
690 {
691 StringWriter sw = new StringWriter();
692 sw.Write("_");
693 DateTime now = DateTime.Now;
694 sw.Write(now.Year);
695 sw.Write("y_");
696 sw.Write(now.Month);
697 sw.Write("M_");
698 sw.Write(now.Day);
699 sw.Write("d_");
700 sw.Write(now.Hour);
701 sw.Write("h_");
702 sw.Write(now.Minute);
703 sw.Write("m_");
704 sw.Write(now.Second);
705 sw.Write("s");
706 sw.Flush();
707 string output = sw.ToString();
708 sw.Close();
709 return output;
710 }
711
712 /// <summary>Return value of true ==> not too busy; false ==> too busy to backup an OAR right now, or error.</summary>
713 private bool RunHeuristics(IScene region)
714 {
715 try
716 {
717 return this.RunTimeDilationHeuristic(region) && this.RunAgentLimitHeuristic(region);
718 }
719 catch (Exception e)
720 {
721 m_log.Warn("[AUTO BACKUP]: Exception in RunHeuristics", e);
722 return false;
723 }
724 }
725
726 /// <summary>
727 /// If the time dilation right at this instant is less than the threshold specified in AutoBackupDilationThreshold (default 0.5),
728 /// then we return false and trip the busy heuristic's "too busy" path (i.e. don't save an OAR).
729 /// AutoBackupDilationThreshold is a _LOWER BOUND_. Lower Time Dilation is bad, so if you go lower than our threshold, it's "too busy".
730 /// </summary>
731 /// <param name="region"></param>
732 /// <returns>Returns true if we're not too busy; false means we've got worse time dilation than the threshold.</returns>
733 private bool RunTimeDilationHeuristic(IScene region)
734 {
735 string regionName = region.RegionInfo.RegionName;
736 return region.TimeDilation >=
737 this.m_configSource.Configs["AutoBackupModule"].GetFloat(
738 regionName + ".AutoBackupDilationThreshold", 0.5f);
739 }
740
741 /// <summary>
742 /// If the root agent count right at this instant is less than the threshold specified in AutoBackupAgentThreshold (default 10),
743 /// then we return false and trip the busy heuristic's "too busy" path (i.e., don't save an OAR).
744 /// AutoBackupAgentThreshold is an _UPPER BOUND_. Higher Agent Count is bad, so if you go higher than our threshold, it's "too busy".
745 /// </summary>
746 /// <param name="region"></param>
747 /// <returns>Returns true if we're not too busy; false means we've got more agents on the sim than the threshold.</returns>
748 private bool RunAgentLimitHeuristic(IScene region)
749 {
750 string regionName = region.RegionInfo.RegionName;
751 try
752 {
753 Scene scene = (Scene) region;
754 // TODO: Why isn't GetRootAgentCount() a method in the IScene interface? Seems generally useful...
755 return scene.GetRootAgentCount() <=
756 this.m_configSource.Configs["AutoBackupModule"].GetInt(
757 regionName + ".AutoBackupAgentThreshold", 10);
758 }
759 catch (InvalidCastException ice)
760 {
761 m_log.Debug(
762 "[AUTO BACKUP]: I NEED MAINTENANCE: IScene is not a Scene; can't get root agent count!",
763 ice);
764 return true;
765 // Non-obstructionist safest answer...
766 }
767 }
768
769 /// <summary>
770 /// Run the script or executable specified by the "AutoBackupScript" config setting.
771 /// Of course this is a security risk if you let anyone modify OpenSim.ini and they want to run some nasty bash script.
772 /// But there are plenty of other nasty things that can be done with an untrusted OpenSim.ini, such as running high threat level scripting functions.
773 /// </summary>
774 /// <param name="scriptName"></param>
775 /// <param name="savePath"></param>
776 private static void ExecuteScript(string scriptName, string savePath)
777 {
778 // Do nothing if there's no script.
779 if (scriptName == null || scriptName.Length <= 0)
780 {
781 return;
782 }
783
784 try
785 {
786 FileInfo fi = new FileInfo(scriptName);
787 if (fi.Exists)
788 {
789 ProcessStartInfo psi = new ProcessStartInfo(scriptName);
790 psi.Arguments = savePath;
791 psi.CreateNoWindow = true;
792 Process proc = Process.Start(psi);
793 proc.ErrorDataReceived += HandleProcErrorDataReceived;
794 }
795 }
796 catch (Exception e)
797 {
798 m_log.Warn(
799 "Exception encountered when trying to run script for oar backup " + savePath, e);
800 }
801 }
802
803 /// <summary>
804 /// Called if a running script process writes to stderr.
805 /// </summary>
806 /// <param name="sender"></param>
807 /// <param name="e"></param>
808 private static void HandleProcErrorDataReceived(object sender, DataReceivedEventArgs e)
809 {
810 m_log.Warn("ExecuteScript hook " + ((Process) sender).ProcessName +
811 " is yacking on stderr: " + e.Data);
812 }
813
814 /// <summary>
815 /// Quickly stop all timers from firing.
816 /// </summary>
817 private void StopAllTimers()
818 {
819 foreach (Timer t in this.m_timerMap.Keys)
820 {
821 t.Close();
822 }
823 this.m_closed = true;
824 }
825
826 /// <summary>
827 /// Determine the next unique filename by number, for "Sequential" AutoBackupNamingType.
828 /// </summary>
829 /// <param name="dirName"></param>
830 /// <param name="regionName"></param>
831 /// <returns></returns>
832 private static string GetNextFile(string dirName, string regionName)
833 {
834 FileInfo uniqueFile = null;
835 long biggestExistingFile = GetNextOarFileNumber(dirName, regionName);
836 biggestExistingFile++;
837 // We don't want to overwrite the biggest existing file; we want to write to the NEXT biggest.
838 uniqueFile =
839 new FileInfo(dirName + Path.DirectorySeparatorChar + regionName + "_" +
840 biggestExistingFile + ".oar");
841 return uniqueFile.FullName;
842 }
843
844 /// <summary>
845 /// Top-level method for creating an absolute path to an OAR backup file based on what naming scheme the user wants.
846 /// </summary>
847 /// <param name="regionName">Name of the region to save.</param>
848 /// <param name="baseDir">Absolute or relative path to the directory where the file should reside.</param>
849 /// <param name="naming">The naming scheme for the file name.</param>
850 /// <returns></returns>
851 private static string BuildOarPath(string regionName, string baseDir, NamingType naming)
852 {
853 FileInfo path = null;
854 switch (naming)
855 {
856 case NamingType.Overwrite:
857 path = new FileInfo(baseDir + Path.DirectorySeparatorChar + regionName + ".oar");
858 return path.FullName;
859 case NamingType.Time:
860 path =
861 new FileInfo(baseDir + Path.DirectorySeparatorChar + regionName +
862 GetTimeString() + ".oar");
863 return path.FullName;
864 case NamingType.Sequential:
865 // All codepaths in GetNextFile should return a file name ending in .oar
866 path = new FileInfo(GetNextFile(baseDir, regionName));
867 return path.FullName;
868 default:
869 m_log.Warn("VERY BAD: Unhandled case element " + naming);
870 break;
871 }
872
873 return null;
874 }
875
876 /// <summary>
877 /// Helper function for Sequential file naming type (see BuildOarPath and GetNextFile).
878 /// </summary>
879 /// <param name="dirName"></param>
880 /// <param name="regionName"></param>
881 /// <returns></returns>
882 private static long GetNextOarFileNumber(string dirName, string regionName)
883 {
884 long retval = 1;
885
886 DirectoryInfo di = new DirectoryInfo(dirName);
887 FileInfo[] fi = di.GetFiles(regionName, SearchOption.TopDirectoryOnly);
888 Array.Sort(fi, (f1, f2) => StringComparer.CurrentCultureIgnoreCase.Compare(f1.Name, f2.Name));
889
890 if (fi.LongLength > 0)
891 {
892 long subtract = 1L;
893 bool worked = false;
894 Regex reg = new Regex(regionName + "_([0-9])+" + ".oar");
895
896 while (!worked && subtract <= fi.LongLength)
897 {
898 // Pick the file with the last natural ordering
899 string biggestFileName = fi[fi.LongLength - subtract].Name;
900 MatchCollection matches = reg.Matches(biggestFileName);
901 long l = 1;
902 if (matches.Count > 0 && matches[0].Groups.Count > 0)
903 {
904 try
905 {
906 long.TryParse(matches[0].Groups[1].Value, out l);
907 retval = l;
908 worked = true;
909 }
910 catch (FormatException fe)
911 {
912 m_log.Warn(
913 "[AUTO BACKUP]: Error: Can't parse long value from file name to determine next OAR backup file number!",
914 fe);
915 subtract++;
916 }
917 }
918 else
919 {
920 subtract++;
921 }
922 }
923 }
924 return retval;
925 }
926 }
927}
928
929
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
new file mode 100644
index 0000000..2db718c
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
@@ -0,0 +1,126 @@
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
28using System;
29using System.Collections.Generic;
30
31
32namespace OpenSim.Region.OptionalModules.World.AutoBackup
33{
34 /// <summary>AutoBackupModuleState: Auto-Backup state for one region (scene).
35 /// If you use this class in any way outside of AutoBackupModule, you should treat the class as opaque.
36 /// Since it is not part of the framework, you really should not rely upon it outside of the AutoBackupModule implementation.
37 /// </summary>
38 ///
39 public class AutoBackupModuleState
40 {
41 private Dictionary<Guid, string> m_liveRequests = null;
42
43 public AutoBackupModuleState()
44 {
45 this.Enabled = false;
46 this.BackupDir = ".";
47 this.BusyCheck = true;
48 this.Timer = null;
49 this.NamingType = NamingType.Time;
50 this.Script = null;
51 }
52
53 public Dictionary<Guid, string> LiveRequests
54 {
55 get {
56 return this.m_liveRequests ??
57 (this.m_liveRequests = new Dictionary<Guid, string>(1));
58 }
59 }
60
61 public bool Enabled
62 {
63 get;
64 set;
65 }
66
67 public System.Timers.Timer Timer
68 {
69 get;
70 set;
71 }
72
73 public double IntervalMinutes
74 {
75 get
76 {
77 if (this.Timer == null)
78 {
79 return -1.0;
80 }
81 else
82 {
83 return this.Timer.Interval / 60000.0;
84 }
85 }
86 }
87
88 public bool BusyCheck
89 {
90 get;
91 set;
92 }
93
94 public string Script
95 {
96 get;
97 set;
98 }
99
100 public string BackupDir
101 {
102 get;
103 set;
104 }
105
106 public NamingType NamingType
107 {
108 get;
109 set;
110 }
111
112 public new string ToString()
113 {
114 string retval = "";
115
116 retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n";
117 retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n";
118 retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n";
119 retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n";
120 retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n";
121 retval += "[AUTO BACKUP]: Script: " + Script + "\n";
122 return retval;
123 }
124 }
125}
126
diff --git a/OpenSim/Server/Base/HttpServerBase.cs b/OpenSim/Server/Base/HttpServerBase.cs
index 9e4593e..bb5ce96 100644
--- a/OpenSim/Server/Base/HttpServerBase.cs
+++ b/OpenSim/Server/Base/HttpServerBase.cs
@@ -97,16 +97,76 @@ namespace OpenSim.Server.Base
97 97
98 if (port == 0) 98 if (port == 0)
99 { 99 {
100 System.Console.WriteLine("Port number not specified or 0, server can't start"); 100
101 Thread.CurrentThread.Abort(); 101 Thread.CurrentThread.Abort();
102 } 102 }
103 //
104 bool ssl_main = networkConfig.GetBoolean("https_main",false);
105 bool ssl_listener = networkConfig.GetBoolean("https_listener",false);
103 106
104 m_consolePort = (uint)networkConfig.GetInt("ConsolePort", 0); 107 m_consolePort = (uint)networkConfig.GetInt("ConsolePort", 0);
105 m_Port = port; 108 m_Port = port;
109 //
110 // This is where to make the servers:
111 //
112 //
113 // Make the base server according to the port, etc.
114 // ADD: Possibility to make main server ssl
115 // Then, check for https settings and ADD a server to
116 // m_Servers
117 //
118 if ( !ssl_main )
119 {
120 m_HttpServer = new BaseHttpServer(port);
106 121
107 m_HttpServer = new BaseHttpServer(port); 122 }
123 else
124 {
125 string cert_path = networkConfig.GetString("cert_path",String.Empty);
126 if ( cert_path == String.Empty )
127 {
128 System.Console.WriteLine("Path to X509 certificate is missing, server can't start.");
129 Thread.CurrentThread.Abort();
130 }
131 string cert_pass = networkConfig.GetString("cert_pass",String.Empty);
132 if ( cert_pass == String.Empty )
133 {
134 System.Console.WriteLine("Password for X509 certificate is missing, server can't start.");
135 Thread.CurrentThread.Abort();
136 }
137 m_HttpServer = new BaseHttpServer(port, ssl_main, cert_path, cert_pass);
138 }
108 139
109 MainServer.Instance = m_HttpServer; 140 MainServer.Instance = m_HttpServer;
141
142 // If https_listener = true, then add an ssl listener on the https_port...
143 if ( ssl_listener == true ) {
144
145 uint https_port = (uint)networkConfig.GetInt("https_port", 0);
146
147 string cert_path = networkConfig.GetString("cert_path",String.Empty);
148 if ( cert_path == String.Empty )
149 {
150 System.Console.WriteLine("Path to X509 certificate is missing, server can't start.");
151 Thread.CurrentThread.Abort();
152 }
153 string cert_pass = networkConfig.GetString("cert_pass",String.Empty);
154 if ( cert_pass == String.Empty )
155 {
156 System.Console.WriteLine("Password for X509 certificate is missing, server can't start.");
157 Thread.CurrentThread.Abort();
158 }
159 // Add our https_server
160 BaseHttpServer server = null;
161 server = new BaseHttpServer(https_port, ssl_listener, cert_path, cert_pass);
162 if (server != null)
163 {
164 m_Log.InfoFormat("[SERVER]: Starting HTTPS server on port {0}", https_port);
165 m_Servers.Add(https_port,server);
166 }
167 else
168 System.Console.WriteLine(String.Format("Failed to start HTTPS server on port {0}",https_port));
169 }
110 } 170 }
111 171
112 protected override void Initialise() 172 protected override void Initialise()
@@ -114,6 +174,19 @@ namespace OpenSim.Server.Base
114 m_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", m_HttpServer.Port); 174 m_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", m_HttpServer.Port);
115 m_HttpServer.Start(); 175 m_HttpServer.Start();
116 176
177 if (m_Servers.Count > 0)
178 {
179 foreach (BaseHttpServer s in m_Servers.Values)
180 {
181 if (!s.UseSSL)
182 m_Log.InfoFormat("[SERVER]: Starting HTTP server on port {0}", s.Port);
183 else
184 m_Log.InfoFormat("[SERVER]: Starting HTTPS server on port {0}", s.Port);
185
186 s.Start();
187 }
188 }
189
117 if (MainConsole.Instance is RemoteConsole) 190 if (MainConsole.Instance is RemoteConsole)
118 { 191 {
119 if (m_consolePort == 0) 192 if (m_consolePort == 0)
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index e1f90b6..851b7b4 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -26,6 +26,8 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
30using System.IO;
29using System.Reflection; 31using System.Reflection;
30using Nini.Config; 32using Nini.Config;
31using log4net; 33using log4net;
@@ -60,6 +62,13 @@ namespace OpenSim.Services.AssetService
60 "delete asset", 62 "delete asset",
61 "delete asset <ID>", 63 "delete asset <ID>",
62 "Delete asset from database", HandleDeleteAsset); 64 "Delete asset from database", HandleDeleteAsset);
65
66 MainConsole.Instance.Commands.AddCommand("kfs", false,
67 "dump asset",
68 "dump asset <ID>",
69 "Dump asset to a file",
70 "The filename is the same as the ID given.",
71 HandleDumpAsset);
63 72
64 if (m_AssetLoader != null) 73 if (m_AssetLoader != null)
65 { 74 {
@@ -189,6 +198,43 @@ namespace OpenSim.Services.AssetService
189 198
190 return false; 199 return false;
191 } 200 }
201
202 void HandleDumpAsset(string module, string[] args)
203 {
204 if (args.Length < 3)
205 {
206 MainConsole.Instance.Output("Usage is dump asset <ID>");
207 return;
208 }
209
210 string rawAssetId = args[2];
211 UUID assetId;
212
213 if (!UUID.TryParse(rawAssetId, out assetId))
214 {
215 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
216 return;
217 }
218
219 AssetBase asset = m_Database.GetAsset(assetId);
220 if (asset == null)
221 {
222 MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
223 return;
224 }
225
226 string fileName = rawAssetId;
227
228 using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
229 {
230 using (BinaryWriter bw = new BinaryWriter(fs))
231 {
232 bw.Write(asset.Data);
233 }
234 }
235
236 MainConsole.Instance.OutputFormat("Asset dumped to file {0}", fileName);
237 }
192 238
193 void HandleShowDigest(string module, string[] args) 239 void HandleShowDigest(string module, string[] args)
194 { 240 {
@@ -208,11 +254,11 @@ namespace OpenSim.Services.AssetService
208 254
209 int i; 255 int i;
210 256
211 MainConsole.Instance.Output(String.Format("Name: {0}", asset.Name)); 257 MainConsole.Instance.OutputFormat("Name: {0}", asset.Name);
212 MainConsole.Instance.Output(String.Format("Description: {0}", asset.Description)); 258 MainConsole.Instance.OutputFormat("Description: {0}", asset.Description);
213 MainConsole.Instance.Output(String.Format("Type: {0}", asset.Type)); 259 MainConsole.Instance.OutputFormat("Type: {0} (type number = {1})", (AssetType)asset.Type, asset.Type);
214 MainConsole.Instance.Output(String.Format("Content-type: {0}", asset.Metadata.ContentType)); 260 MainConsole.Instance.OutputFormat("Content-type: {0}", asset.Metadata.ContentType);
215 MainConsole.Instance.Output(String.Format("Flags: {0}", asset.Metadata.Flags.ToString())); 261 MainConsole.Instance.OutputFormat("Flags: {0}", asset.Metadata.Flags);
216 262
217 for (i = 0 ; i < 5 ; i++) 263 for (i = 0 ; i < 5 ; i++)
218 { 264 {