aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/MySQL/Resources/XMute.migrations16
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/XMuteModule.cs357
2 files changed, 373 insertions, 0 deletions
diff --git a/OpenSim/Data/MySQL/Resources/XMute.migrations b/OpenSim/Data/MySQL/Resources/XMute.migrations
new file mode 100644
index 0000000..4ac7f82
--- /dev/null
+++ b/OpenSim/Data/MySQL/Resources/XMute.migrations
@@ -0,0 +1,16 @@
1:VERSION 1
2
3BEGIN;
4
5CREATE TABLE `XMute` (
6 `AgentID` char(36) NOT NULL,
7 `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
8 `MuteName` varchar(64) NOT NULL DEFAULT '',
9 `MuteType` int(11) NOT NULL DEFAULT '1',
10 `MuteFlags` int(11) NOT NULL DEFAULT '0',
11 `Stamp` int(11) NOT NULL,
12 UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`),
13 KEY `AgentID` (`AgentID`)
14);
15
16COMMIT;
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/XMuteModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/XMuteModule.cs
new file mode 100644
index 0000000..fb5239f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/XMuteModule.cs
@@ -0,0 +1,357 @@
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 */
27using System;
28using System.Collections.Generic;
29using System.Reflection;
30using log4net;
31using Nini.Config;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Servers;
35using OpenSim.Framework.Client;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38using Mono.Addins;
39using OpenSim.Data;
40using OpenSim.Data.MySQL;
41using MySql.Data.MySqlClient;
42using System.Security.Cryptography;
43
44namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
45{
46 public class MuteData
47 {
48 public UUID AgentID;
49 public UUID MuteID;
50 public string MuteName;
51 public int MuteType;
52 public int MuteFlags;
53 public int Stamp;
54 }
55
56 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XMute")]
57 public class XMuteModule : ISharedRegionModule
58 {
59 private static readonly ILog m_log = LogManager.GetLogger(
60 MethodBase.GetCurrentMethod().DeclaringType);
61
62 protected bool m_Enabled = true;
63 protected List<Scene> m_SceneList = new List<Scene>();
64 protected MuteTableHandler m_MuteTable;
65 protected string m_DatabaseConnect;
66
67 public void Initialise(IConfigSource config)
68 {
69 IConfig cnf = config.Configs["Messaging"];
70 if (cnf == null)
71 {
72 m_Enabled = false;
73 return;
74 }
75
76 if (cnf.GetString("MuteListModule", "None") !=
77 "XMute")
78 {
79 m_Enabled = false;
80 return;
81 }
82
83 m_DatabaseConnect = cnf.GetString("MuteDatabaseConnect", String.Empty);
84 if (m_DatabaseConnect == String.Empty)
85 {
86 m_log.Debug("[XMute]: MuteDatabaseConnect missing or empty");
87 m_Enabled = false;
88 return;
89 }
90
91 m_MuteTable = new MuteTableHandler(
92 m_DatabaseConnect, "XMute", String.Empty);
93 }
94
95 public void AddRegion(Scene scene)
96 {
97 if (!m_Enabled)
98 return;
99
100 lock (m_SceneList)
101 {
102 m_SceneList.Add(scene);
103
104 scene.EventManager.OnNewClient += OnNewClient;
105 }
106 }
107
108 public void RegionLoaded(Scene scene)
109 {
110 }
111
112 public void RemoveRegion(Scene scene)
113 {
114 if (!m_Enabled)
115 return;
116
117 lock (m_SceneList)
118 {
119 m_SceneList.Remove(scene);
120 }
121 }
122
123 public void PostInitialise()
124 {
125 if (!m_Enabled)
126 return;
127
128 m_log.Debug("[XMute]: Mute list enabled");
129 }
130
131 public string Name
132 {
133 get { return "XMuteModule"; }
134 }
135
136 public Type ReplaceableInterface
137 {
138 get { return null; }
139 }
140
141 public void Close()
142 {
143 }
144
145 private void OnNewClient(IClientAPI client)
146 {
147 client.OnMuteListRequest += OnMuteListRequest;
148 client.OnUpdateMuteListEntry += OnUpdateMuteListEntry;
149 client.OnRemoveMuteListEntry += OnRemoveMuteListEntry;
150 }
151
152 private void OnMuteListRequest(IClientAPI client, uint crc)
153 {
154 string filename = "mutes"+client.AgentId.ToString();
155
156 IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
157 if (xfer != null)
158 {
159 MuteData[] data = m_MuteTable.Get("AgentID", client.AgentId.ToString());
160 if (data == null || data.Length == 0)
161 {
162 xfer.AddNewFile(filename, new Byte[0]);
163 }
164 else
165 {
166 List<string> mutes = new List<string>();
167
168 foreach (MuteData d in data)
169 mutes.Add(String.Format("{0} {1} {2}|{3}",
170 d.MuteType,
171 d.MuteID.ToString(),
172 d.MuteName,
173 d.MuteFlags));
174
175 Byte[] filedata = Util.UTF8.GetBytes(String.Join("\n",
176 mutes.ToArray()) + "\n");
177
178 uint dataCrc = Crc32.Compute(filedata);
179
180 if (dataCrc == crc)
181 {
182 client.SendUseCachedMuteList();
183 return;
184 }
185
186 xfer.AddNewFile(filename, filedata);
187 }
188
189 client.SendMuteListUpdate(filename);
190 }
191 }
192
193 private void OnUpdateMuteListEntry(IClientAPI client, UUID muteID, string muteName, int muteType, uint muteFlags)
194 {
195 MuteData mute = new MuteData();
196
197 mute.AgentID = client.AgentId;
198 mute.MuteID = muteID;
199 mute.MuteName = muteName;
200 mute.MuteType = muteType;
201 mute.MuteFlags = (int)muteFlags;
202 mute.Stamp = Util.UnixTimeSinceEpoch();
203
204 m_MuteTable.Store(mute);
205 }
206
207 private void OnRemoveMuteListEntry(IClientAPI client, UUID muteID, string muteName)
208 {
209 m_MuteTable.Delete(new string[] { "AgentID",
210 "MuteID",
211 "MuteName" },
212 new string[] { client.AgentId.ToString(),
213 muteID.ToString(),
214 muteName });
215 }
216 }
217
218 public class MuteTableHandler : MySQLGenericTableHandler<MuteData>
219 {
220 public MuteTableHandler(string conn, string realm, string m) : base(conn, realm, m)
221 {
222 }
223
224 public bool Delete(string[] fields, string[] val)
225 {
226 if (fields.Length != val.Length)
227 return false;
228
229 using (MySqlCommand cmd = new MySqlCommand())
230 {
231 string text = String.Format("delete from {0} where ", m_Realm);
232
233 List<string> terms = new List<string>();
234
235 for (int i = 0 ; i < fields.Length ; i++)
236 {
237 terms.Add(String.Format("{0} = ?{0}", fields[i]));
238 cmd.Parameters.AddWithValue("?" + fields[i], val[i]);
239 }
240
241 text += string.Join(" and ", terms.ToArray());
242
243 cmd.CommandText = text;
244
245 if (ExecuteNonQuery(cmd) > 0)
246 return true;
247 return false;
248 }
249 }
250 }
251
252 public class Crc32 : HashAlgorithm
253 {
254 public const UInt32 DefaultPolynomial = 0xedb88320;
255 public const UInt32 DefaultSeed = 0xffffffff;
256
257 private UInt32 hash;
258 private UInt32 seed;
259 private UInt32[] table;
260 private static UInt32[] defaultTable;
261
262 public Crc32()
263 {
264 table = InitializeTable(DefaultPolynomial);
265 seed = DefaultSeed;
266 Initialize();
267 }
268
269 public Crc32(UInt32 polynomial, UInt32 seed)
270 {
271 table = InitializeTable(polynomial);
272 this.seed = seed;
273 Initialize();
274 }
275
276 public override void Initialize()
277 {
278 hash = seed;
279 }
280
281 protected override void HashCore(byte[] buffer, int start, int length)
282 {
283 hash = CalculateHash(table, hash, buffer, start, length);
284 }
285
286 protected override byte[] HashFinal()
287 {
288 byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);
289 this.HashValue = hashBuffer;
290 return hashBuffer;
291 }
292
293 public override int HashSize
294 {
295 get { return 32; }
296 }
297
298 public static UInt32 Compute(byte[] buffer)
299 {
300 return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
301 }
302
303 public static UInt32 Compute(UInt32 seed, byte[] buffer)
304 {
305 return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
306 }
307
308 public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
309 {
310 return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
311 }
312
313 private static UInt32[] InitializeTable(UInt32 polynomial)
314 {
315 if (polynomial == DefaultPolynomial && defaultTable != null)
316 return defaultTable;
317
318 UInt32[] createTable = new UInt32[256];
319 for (int i = 0; i < 256; i++)
320 {
321 UInt32 entry = (UInt32)i;
322 for (int j = 0; j < 8; j++)
323 if ((entry & 1) == 1)
324 entry = (entry >> 1) ^ polynomial;
325 else
326 entry = entry >> 1;
327 createTable[i] = entry;
328 }
329
330 if (polynomial == DefaultPolynomial)
331 defaultTable = createTable;
332
333 return createTable;
334 }
335
336 private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
337 {
338 UInt32 crc = seed;
339 for (int i = start; i < size; i++)
340 unchecked
341 {
342 crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
343 }
344 return crc;
345 }
346
347 private byte[] UInt32ToBigEndianBytes(UInt32 x)
348 {
349 return new byte[] {
350 (byte)((x >> 24) & 0xff),
351 (byte)((x >> 16) & 0xff),
352 (byte)((x >> 8) & 0xff),
353 (byte)(x & 0xff) };
354 }
355 }
356}
357