aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/MySQL/MySQLEstateData.cs
diff options
context:
space:
mode:
authorMelanie Thielker2008-07-18 02:40:47 +0000
committerMelanie Thielker2008-07-18 02:40:47 +0000
commit263633e274082135b21b8183b92280b768d18883 (patch)
treef6104eef3633a8b454a4e8ac09d15182970c6bae /OpenSim/Data/MySQL/MySQLEstateData.cs
parentadded region port number to output of "show regions" command (diff)
downloadopensim-SC-263633e274082135b21b8183b92280b768d18883.zip
opensim-SC-263633e274082135b21b8183b92280b768d18883.tar.gz
opensim-SC-263633e274082135b21b8183b92280b768d18883.tar.bz2
opensim-SC-263633e274082135b21b8183b92280b768d18883.tar.xz
Patch #9151
Makes the estate dialog fully functional. Implements all client facing functionality. Moves estate data from estate_settings.xml, which is used to provide defaults, to the region data store. Creates one estate for each region, and places the region in it. Converts all region bans to estate bans.
Diffstat (limited to 'OpenSim/Data/MySQL/MySQLEstateData.cs')
-rw-r--r--OpenSim/Data/MySQL/MySQLEstateData.cs386
1 files changed, 386 insertions, 0 deletions
diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs
new file mode 100644
index 0000000..eeff31b
--- /dev/null
+++ b/OpenSim/Data/MySQL/MySQLEstateData.cs
@@ -0,0 +1,386 @@
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 OpenSim 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.Data;
31using System.IO;
32using System.Reflection;
33using System.Threading;
34using libsecondlife;
35using log4net;
36using MySql.Data.MySqlClient;
37using OpenSim.Framework;
38using OpenSim.Region.Environment.Interfaces;
39using OpenSim.Region.Environment.Scenes;
40
41namespace OpenSim.Data.MySQL
42{
43 public class MySQLEstateStore : IEstateDataStore
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 private const string m_waitTimeoutSelect = "select @@wait_timeout";
49
50 private MySqlConnection m_connection;
51 private string m_connectionString;
52 private long m_waitTimeout;
53 private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
54 private long m_lastConnectionUse;
55
56 private FieldInfo[] m_Fields;
57 private Dictionary<string, FieldInfo> m_FieldMap =
58 new Dictionary<string, FieldInfo>();
59
60 public void Initialise(string connectionString)
61 {
62 m_connectionString = connectionString;
63
64 m_log.Info("[ESTATE DB]: MySql - connecting: "+m_connectionString);
65
66 m_connection = new MySqlConnection(m_connectionString);
67 m_connection.Open();
68
69 GetWaitTimeout();
70
71 Assembly assem = GetType().Assembly;
72 Migration m = new Migration(m_connection, assem, "EstateStore");
73 m.Update();
74
75 Type t = typeof(EstateSettings);
76 m_Fields = t.GetFields(BindingFlags.NonPublic |
77 BindingFlags.Instance |
78 BindingFlags.DeclaredOnly);
79
80 foreach (FieldInfo f in m_Fields)
81 if(f.Name.Substring(0, 2) == "m_")
82 m_FieldMap[f.Name.Substring(2)] = f;
83 }
84
85 private string[] FieldList
86 {
87 get { return new List<string>(m_FieldMap.Keys).ToArray(); }
88 }
89
90 protected void GetWaitTimeout()
91 {
92 MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect,
93 m_connection);
94
95 using (MySqlDataReader dbReader =
96 cmd.ExecuteReader(CommandBehavior.SingleRow))
97 {
98 if (dbReader.Read())
99 {
100 m_waitTimeout
101 = Convert.ToInt32(dbReader["@@wait_timeout"]) *
102 TimeSpan.TicksPerSecond + m_waitTimeoutLeeway;
103 }
104
105 dbReader.Close();
106 cmd.Dispose();
107 }
108
109 m_lastConnectionUse = System.DateTime.Now.Ticks;
110
111 m_log.DebugFormat(
112 "[REGION DB]: Connection wait timeout {0} seconds",
113 m_waitTimeout / TimeSpan.TicksPerSecond);
114 }
115
116 protected void CheckConnection()
117 {
118 long timeNow = System.DateTime.Now.Ticks;
119 if (timeNow - m_lastConnectionUse > m_waitTimeout ||
120 m_connection.State != ConnectionState.Open)
121 {
122 m_log.DebugFormat("[REGION DB]: Database connection has gone away - reconnecting");
123
124 lock (m_connection)
125 {
126 m_connection.Close();
127 m_connection = new MySqlConnection(m_connectionString);
128 m_connection.Open();
129 }
130 }
131
132 m_lastConnectionUse = timeNow;
133 }
134
135 public EstateSettings LoadEstateSettings(LLUUID regionID)
136 {
137 EstateSettings es = new EstateSettings();
138
139 string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = ?RegionID";
140
141 CheckConnection();
142
143 MySqlCommand cmd = m_connection.CreateCommand();
144
145 cmd.CommandText = sql;
146 cmd.Parameters.Add("?RegionID", regionID.ToString());
147
148 IDataReader r = cmd.ExecuteReader();
149
150 if(r.Read())
151 {
152 foreach (string name in FieldList)
153 {
154 if(m_FieldMap[name].GetValue(es) is bool)
155 {
156 int v = Convert.ToInt32(r[name]);
157 if(v != 0)
158 m_FieldMap[name].SetValue(es, true);
159 else
160 m_FieldMap[name].SetValue(es, false);
161 }
162 else
163 {
164 m_FieldMap[name].SetValue(es, r[name]);
165 }
166 }
167 r.Close();
168 }
169 else
170 {
171 // Migration case
172 //
173 r.Close();
174
175 List<string> names = new List<string>(FieldList);
176
177 names.Remove("EstateID");
178
179 sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( ?"+String.Join(", ?", names.ToArray())+")";
180
181 cmd.CommandText = sql;
182 cmd.Parameters.Clear();
183
184 foreach (string name in FieldList)
185 {
186 if(m_FieldMap[name].GetValue(es) is bool)
187 {
188 if((bool)m_FieldMap[name].GetValue(es))
189 cmd.Parameters.Add("?"+name, "1");
190 else
191 cmd.Parameters.Add("?"+name, "0");
192 }
193 else
194 {
195 cmd.Parameters.Add("?"+name, m_FieldMap[name].GetValue(es).ToString());
196 }
197 }
198
199 cmd.ExecuteNonQuery();
200
201 cmd.CommandText = "select LAST_INSERT_ID() as id";
202 cmd.Parameters.Clear();
203
204 r = cmd.ExecuteReader();
205
206 r.Read();
207
208 es.EstateID = Convert.ToUInt32(r["id"]);
209
210 r.Close();
211
212 cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)";
213 cmd.Parameters.Add("?RegionID", regionID.ToString());
214 cmd.Parameters.Add("?EstateID", es.EstateID.ToString());
215
216 // This will throw on dupe key
217 try
218 {
219 cmd.ExecuteNonQuery();
220 }
221 catch (Exception)
222 {
223 }
224
225 // Munge and transfer the ban list
226 //
227 cmd.Parameters.Clear();
228 cmd.CommandText = "insert into estateban select "+es.EstateID.ToString()+", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = ?UUID";
229 cmd.Parameters.Add("?UUID", regionID.ToString());
230
231 try
232 {
233 cmd.ExecuteNonQuery();
234 }
235 catch (Exception)
236 {
237 }
238 }
239
240 LoadBanList(es);
241
242 es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
243 es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
244 es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
245 return es;
246 }
247
248 public void StoreEstateSettings(EstateSettings es)
249 {
250 string sql = "replace into estate_settings ("+String.Join(",", FieldList)+") values ( ?"+String.Join(", ?", FieldList)+")";
251
252 CheckConnection();
253
254 MySqlCommand cmd = m_connection.CreateCommand();
255
256 cmd.CommandText = sql;
257
258 foreach (string name in FieldList)
259 {
260 if(m_FieldMap[name].GetValue(es) is bool)
261 {
262 if((bool)m_FieldMap[name].GetValue(es))
263 cmd.Parameters.Add("?"+name, "1");
264 else
265 cmd.Parameters.Add("?"+name, "0");
266 }
267 else
268 {
269 cmd.Parameters.Add("?"+name, m_FieldMap[name].GetValue(es).ToString());
270 }
271 }
272
273 cmd.ExecuteNonQuery();
274
275 SaveBanList(es);
276 SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
277 SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
278 SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
279 }
280
281 private void LoadBanList(EstateSettings es)
282 {
283 es.ClearBans();
284
285 CheckConnection();
286
287 MySqlCommand cmd = m_connection.CreateCommand();
288
289 cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID";
290 cmd.Parameters.Add("?EstateID", es.EstateID);
291
292 IDataReader r = cmd.ExecuteReader();
293
294 while(r.Read())
295 {
296 EstateBan eb = new EstateBan();
297
298 LLUUID uuid = new LLUUID();
299 LLUUID.TryParse(r["bannedUUID"].ToString(), out uuid);
300
301 eb.bannedUUID = uuid;
302 eb.bannedIP = "0.0.0.0";
303 eb.bannedIPHostMask = "0.0.0.0";
304 es.AddBan(eb);
305 }
306 r.Close();
307 }
308
309 private void SaveBanList(EstateSettings es)
310 {
311 CheckConnection();
312
313 MySqlCommand cmd = m_connection.CreateCommand();
314
315 cmd.CommandText = "delete from estateban where EstateID = ?EstateID";
316 cmd.Parameters.Add("?EstateID", es.EstateID.ToString());
317
318 cmd.ExecuteNonQuery();
319
320 cmd.Parameters.Clear();
321
322 cmd.CommandText = "insert into estateban (EstateID, bannedUUID) values ( ?EstateID, ?bannedUUID )";
323
324 foreach(EstateBan b in es.EstateBans)
325 {
326 cmd.Parameters.Add("?EstateID", es.EstateID.ToString());
327 cmd.Parameters.Add("?bannedUUID", b.bannedUUID.ToString());
328
329 cmd.ExecuteNonQuery();
330 cmd.Parameters.Clear();
331 }
332 }
333
334 void SaveUUIDList(uint EstateID, string table, LLUUID[] data)
335 {
336 CheckConnection();
337
338 MySqlCommand cmd = m_connection.CreateCommand();
339
340 cmd.CommandText = "delete from "+table+" where EstateID = ?EstateID";
341 cmd.Parameters.Add("?EstateID", EstateID.ToString());
342
343 cmd.ExecuteNonQuery();
344
345 cmd.Parameters.Clear();
346
347 cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( ?EstateID, ?uuid )";
348
349 foreach(LLUUID uuid in data)
350 {
351 cmd.Parameters.Add("?EstateID", EstateID.ToString());
352 cmd.Parameters.Add("?uuid", uuid.ToString());
353
354 cmd.ExecuteNonQuery();
355 cmd.Parameters.Clear();
356 }
357 }
358
359 LLUUID[] LoadUUIDList(uint EstateID, string table)
360 {
361 List<LLUUID> uuids = new List<LLUUID>();
362
363 CheckConnection();
364
365 MySqlCommand cmd = m_connection.CreateCommand();
366
367 cmd.CommandText = "select uuid from "+table+" where EstateID = ?EstateID";
368 cmd.Parameters.Add("?EstateID", EstateID);
369
370 IDataReader r = cmd.ExecuteReader();
371
372 while(r.Read())
373 {
374 EstateBan eb = new EstateBan();
375
376 LLUUID uuid = new LLUUID();
377 LLUUID.TryParse(r["uuid"].ToString(), out uuid);
378
379 uuids.Add(uuid);
380 }
381 r.Close();
382
383 return uuids.ToArray();
384 }
385 }
386}