MSSQLUserData.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  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. */
  28. using System;
  29. using System.Collections.Generic;
  30. using System.Data;
  31. using System.Data.SqlClient;
  32. using libsecondlife;
  33. using OpenSim.Framework.Console;
  34. namespace OpenSim.Framework.Data.MSSQL
  35. {
  36. /// <summary>
  37. /// A database interface class to a user profile storage system
  38. /// </summary>
  39. internal class MSSQLUserData : IUserData
  40. {
  41. /// <summary>
  42. /// Database manager for MySQL
  43. /// </summary>
  44. public MSSQLManager database;
  45. /// <summary>
  46. /// Loads and initialises the MySQL storage plugin
  47. /// </summary>
  48. public void Initialise()
  49. {
  50. // Load from an INI file connection details
  51. // TODO: move this to XML?
  52. IniFile GridDataMySqlFile = new IniFile("mssql_connection.ini");
  53. string settingDataSource = GridDataMySqlFile.ParseFileReadValue("data_source");
  54. string settingInitialCatalog = GridDataMySqlFile.ParseFileReadValue("initial_catalog");
  55. string settingPersistSecurityInfo = GridDataMySqlFile.ParseFileReadValue("persist_security_info");
  56. string settingUserId = GridDataMySqlFile.ParseFileReadValue("user_id");
  57. string settingPassword = GridDataMySqlFile.ParseFileReadValue("password");
  58. database =
  59. new MSSQLManager(settingDataSource, settingInitialCatalog, settingPersistSecurityInfo, settingUserId,
  60. settingPassword);
  61. }
  62. /// <summary>
  63. /// Searches the database for a specified user profile by name components
  64. /// </summary>
  65. /// <param name="user">The first part of the account name</param>
  66. /// <param name="last">The second part of the account name</param>
  67. /// <returns>A user profile</returns>
  68. public UserProfileData GetUserByName(string user, string last)
  69. {
  70. try
  71. {
  72. lock (database)
  73. {
  74. Dictionary<string, string> param = new Dictionary<string, string>();
  75. param["first"] = user;
  76. param["second"] = last;
  77. IDbCommand result =
  78. database.Query("SELECT * FROM users WHERE username = @first AND lastname = @second", param);
  79. IDataReader reader = result.ExecuteReader();
  80. UserProfileData row = database.readUserRow(reader);
  81. reader.Close();
  82. result.Dispose();
  83. return row;
  84. }
  85. }
  86. catch (Exception e)
  87. {
  88. database.Reconnect();
  89. MainLog.Instance.Error(e.ToString());
  90. return null;
  91. }
  92. }
  93. #region User Friends List Data
  94. public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
  95. {
  96. MainLog.Instance.Verbose("FRIEND", "Stub AddNewUserFriend called");
  97. }
  98. public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
  99. {
  100. MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called");
  101. }
  102. public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
  103. {
  104. MainLog.Instance.Verbose("FRIEND", "Stub UpdateUserFriendPerms called");
  105. }
  106. public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
  107. {
  108. MainLog.Instance.Verbose("FRIEND", "Stub GetUserFriendList called");
  109. return new List<FriendListItem>();
  110. }
  111. #endregion
  112. public void UpdateUserCurrentRegion(LLUUID avatarid, LLUUID regionuuid)
  113. {
  114. MainLog.Instance.Verbose("USER", "Stub UpdateUserCUrrentRegion called");
  115. }
  116. public void LogOffUser(LLUUID avatarid)
  117. {
  118. MainLog.Instance.Verbose("USER", "Stub LogOffUser called");
  119. }
  120. public List<Framework.AvatarPickerAvatar> GeneratePickerResults(LLUUID queryID, string query)
  121. {
  122. List<Framework.AvatarPickerAvatar> returnlist = new List<Framework.AvatarPickerAvatar>();
  123. string[] querysplit;
  124. querysplit = query.Split(' ');
  125. if (querysplit.Length == 2)
  126. {
  127. try
  128. {
  129. lock (database)
  130. {
  131. Dictionary<string, string> param = new Dictionary<string, string>();
  132. param["first"] = querysplit[0];
  133. param["second"] = querysplit[1];
  134. IDbCommand result =
  135. database.Query(
  136. "SELECT UUID,username,surname FROM users WHERE username = @first AND lastname = @second",
  137. param);
  138. IDataReader reader = result.ExecuteReader();
  139. while (reader.Read())
  140. {
  141. Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
  142. user.AvatarID = new LLUUID((string) reader["UUID"]);
  143. user.firstName = (string) reader["username"];
  144. user.lastName = (string) reader["surname"];
  145. returnlist.Add(user);
  146. }
  147. reader.Close();
  148. result.Dispose();
  149. }
  150. }
  151. catch (Exception e)
  152. {
  153. database.Reconnect();
  154. MainLog.Instance.Error(e.ToString());
  155. return returnlist;
  156. }
  157. }
  158. else if (querysplit.Length == 1)
  159. {
  160. try
  161. {
  162. lock (database)
  163. {
  164. Dictionary<string, string> param = new Dictionary<string, string>();
  165. param["first"] = querysplit[0];
  166. param["second"] = querysplit[1];
  167. IDbCommand result =
  168. database.Query(
  169. "SELECT UUID,username,surname FROM users WHERE username = @first OR lastname = @second",
  170. param);
  171. IDataReader reader = result.ExecuteReader();
  172. while (reader.Read())
  173. {
  174. Framework.AvatarPickerAvatar user = new Framework.AvatarPickerAvatar();
  175. user.AvatarID = new LLUUID((string) reader["UUID"]);
  176. user.firstName = (string) reader["username"];
  177. user.lastName = (string) reader["surname"];
  178. returnlist.Add(user);
  179. }
  180. reader.Close();
  181. result.Dispose();
  182. }
  183. }
  184. catch (Exception e)
  185. {
  186. database.Reconnect();
  187. MainLog.Instance.Error(e.ToString());
  188. return returnlist;
  189. }
  190. }
  191. return returnlist;
  192. }
  193. // See IUserData
  194. public UserProfileData GetUserByUUID(LLUUID uuid)
  195. {
  196. try
  197. {
  198. lock (database)
  199. {
  200. Dictionary<string, string> param = new Dictionary<string, string>();
  201. param["uuid"] = uuid.ToString();
  202. IDbCommand result = database.Query("SELECT * FROM users WHERE UUID = @uuid", param);
  203. IDataReader reader = result.ExecuteReader();
  204. UserProfileData row = database.readUserRow(reader);
  205. reader.Close();
  206. result.Dispose();
  207. return row;
  208. }
  209. }
  210. catch (Exception e)
  211. {
  212. database.Reconnect();
  213. MainLog.Instance.Error(e.ToString());
  214. return null;
  215. }
  216. }
  217. /// <summary>
  218. /// Searches the database for a specified user profile by account
  219. /// </summary>
  220. /// <param name="uuid">The account</param>
  221. /// <returns>The users profile</returns>
  222. public UserProfileData GetUserByAccount(string account)
  223. {
  224. try
  225. {
  226. lock (database)
  227. {
  228. Dictionary<string, string> param = new Dictionary<string, string>();
  229. param["account"] = account;
  230. IDbCommand result = database.Query("SELECT * FROM users WHERE account = @account", param);
  231. IDataReader reader = result.ExecuteReader();
  232. UserProfileData row = database.readUserRow(reader);
  233. reader.Close();
  234. result.Dispose();
  235. if (row != null)
  236. {
  237. UserAgentData agentData = GetAgentByUUID(row.UUID);
  238. if (agentData != null)
  239. {
  240. row.currentAgent = agentData;
  241. }
  242. }
  243. return row;
  244. }
  245. }
  246. catch (Exception e)
  247. {
  248. database.Reconnect();
  249. MainLog.Instance.Error(e.ToString());
  250. return null;
  251. }
  252. }
  253. /// <summary>
  254. /// Returns a user session searching by name
  255. /// </summary>
  256. /// <param name="name">The account name</param>
  257. /// <returns>The users session</returns>
  258. public UserAgentData GetAgentByName(string name)
  259. {
  260. return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
  261. }
  262. /// <summary>
  263. /// Returns a user session by account name
  264. /// </summary>
  265. /// <param name="user">First part of the users account name</param>
  266. /// <param name="last">Second part of the users account name</param>
  267. /// <returns>The users session</returns>
  268. public UserAgentData GetAgentByName(string user, string last)
  269. {
  270. UserProfileData profile = GetUserByName(user, last);
  271. return GetAgentByUUID(profile.UUID);
  272. }
  273. /// <summary>
  274. /// Returns an agent session by account UUID
  275. /// </summary>
  276. /// <param name="uuid">The accounts UUID</param>
  277. /// <returns>The users session</returns>
  278. public UserAgentData GetAgentByUUID(LLUUID uuid)
  279. {
  280. try
  281. {
  282. lock (database)
  283. {
  284. Dictionary<string, string> param = new Dictionary<string, string>();
  285. param["uuid"] = uuid.ToString();
  286. IDbCommand result = database.Query("SELECT * FROM agents WHERE UUID = @uuid", param);
  287. IDataReader reader = result.ExecuteReader();
  288. UserAgentData row = database.readAgentRow(reader);
  289. reader.Close();
  290. result.Dispose();
  291. return row;
  292. }
  293. }
  294. catch (Exception e)
  295. {
  296. database.Reconnect();
  297. MainLog.Instance.Error(e.ToString());
  298. return null;
  299. }
  300. }
  301. /// <summary>
  302. /// Creates a new users profile
  303. /// </summary>
  304. /// <param name="user">The user profile to create</param>
  305. public void AddNewUserProfile(UserProfileData user)
  306. {
  307. try
  308. {
  309. lock (database)
  310. {
  311. database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt,
  312. user.homeRegion, user.homeLocation.X, user.homeLocation.Y,
  313. user.homeLocation.Z,
  314. user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created,
  315. user.lastLogin, user.userInventoryURI, user.userAssetURI,
  316. user.profileCanDoMask, user.profileWantDoMask,
  317. user.profileAboutText, user.profileFirstText, user.profileImage,
  318. user.profileFirstImage,user.webLoginKey);
  319. }
  320. }
  321. catch (Exception e)
  322. {
  323. database.Reconnect();
  324. MainLog.Instance.Error(e.ToString());
  325. }
  326. }
  327. /// <summary>
  328. /// Creates a new agent
  329. /// </summary>
  330. /// <param name="agent">The agent to create</param>
  331. public void AddNewUserAgent(UserAgentData agent)
  332. {
  333. // Do nothing.
  334. }
  335. public bool UpdateUserProfile(UserProfileData user)
  336. {
  337. SqlCommand command = new SqlCommand("UPDATE users set UUID = @uuid, " +
  338. "username = @username, " +
  339. "lastname = @lastname," +
  340. "passwordHash = @passwordHash," +
  341. "passwordSalt = @passwordSalt," +
  342. "homeRegion = @homeRegion," +
  343. "homeLocationX = @homeLocationX," +
  344. "homeLocationY = @homeLocationY," +
  345. "homeLocationZ = @homeLocationZ," +
  346. "homeLookAtX = @homeLookAtX," +
  347. "homeLookAtY = @homeLookAtY," +
  348. "homeLookAtZ = @homeLookAtZ," +
  349. "created = @created," +
  350. "lastLogin = @lastLogin," +
  351. "userInventoryURI = @userInventoryURI," +
  352. "userAssetURI = @userAssetURI," +
  353. "profileCanDoMask = @profileCanDoMask," +
  354. "profileWantDoMask = @profileWantDoMask," +
  355. "profileAboutText = @profileAboutText," +
  356. "profileFirstText = @profileFirstText," +
  357. "profileImage = @profileImage," +
  358. "profileFirstImage = @profileFirstImage where " +
  359. "UUID = @keyUUUID;", database.getConnection());
  360. SqlParameter param1 = new SqlParameter("@uuid", user.UUID.ToString());
  361. SqlParameter param2 = new SqlParameter("@username", user.username);
  362. SqlParameter param3 = new SqlParameter("@lastname", user.surname);
  363. SqlParameter param4 = new SqlParameter("@passwordHash", user.passwordHash);
  364. SqlParameter param5 = new SqlParameter("@passwordSalt", user.passwordSalt);
  365. SqlParameter param6 = new SqlParameter("@homeRegion", Convert.ToInt64(user.homeRegion));
  366. SqlParameter param7 = new SqlParameter("@homeLocationX", user.homeLocation.X);
  367. SqlParameter param8 = new SqlParameter("@homeLocationY", user.homeLocation.Y);
  368. SqlParameter param9 = new SqlParameter("@homeLocationZ", user.homeLocation.Y);
  369. SqlParameter param10 = new SqlParameter("@homeLookAtX", user.homeLookAt.X);
  370. SqlParameter param11 = new SqlParameter("@homeLookAtY", user.homeLookAt.Y);
  371. SqlParameter param12 = new SqlParameter("@homeLookAtZ", user.homeLookAt.Z);
  372. SqlParameter param13 = new SqlParameter("@created", Convert.ToInt32(user.created));
  373. SqlParameter param14 = new SqlParameter("@lastLogin", Convert.ToInt32(user.lastLogin));
  374. SqlParameter param15 = new SqlParameter("@userInventoryURI", user.userInventoryURI);
  375. SqlParameter param16 = new SqlParameter("@userAssetURI", user.userAssetURI);
  376. SqlParameter param17 = new SqlParameter("@profileCanDoMask", Convert.ToInt32(user.profileCanDoMask));
  377. SqlParameter param18 = new SqlParameter("@profileWantDoMask", Convert.ToInt32(user.profileWantDoMask));
  378. SqlParameter param19 = new SqlParameter("@profileAboutText", user.profileAboutText);
  379. SqlParameter param20 = new SqlParameter("@profileFirstText", user.profileFirstText);
  380. SqlParameter param21 = new SqlParameter("@profileImage", LLUUID.Zero.ToString());
  381. SqlParameter param22 = new SqlParameter("@profileFirstImage", LLUUID.Zero.ToString());
  382. SqlParameter param23 = new SqlParameter("@keyUUUID", user.UUID.ToString());
  383. command.Parameters.Add(param1);
  384. command.Parameters.Add(param2);
  385. command.Parameters.Add(param3);
  386. command.Parameters.Add(param4);
  387. command.Parameters.Add(param5);
  388. command.Parameters.Add(param6);
  389. command.Parameters.Add(param7);
  390. command.Parameters.Add(param8);
  391. command.Parameters.Add(param9);
  392. command.Parameters.Add(param10);
  393. command.Parameters.Add(param11);
  394. command.Parameters.Add(param12);
  395. command.Parameters.Add(param13);
  396. command.Parameters.Add(param14);
  397. command.Parameters.Add(param15);
  398. command.Parameters.Add(param16);
  399. command.Parameters.Add(param17);
  400. command.Parameters.Add(param18);
  401. command.Parameters.Add(param19);
  402. command.Parameters.Add(param20);
  403. command.Parameters.Add(param21);
  404. command.Parameters.Add(param22);
  405. command.Parameters.Add(param23);
  406. try
  407. {
  408. int affected = command.ExecuteNonQuery();
  409. if (affected != 0)
  410. {
  411. return true;
  412. }
  413. else
  414. {
  415. return false;
  416. }
  417. }
  418. catch (Exception e)
  419. {
  420. MainLog.Instance.Error(e.ToString());
  421. }
  422. return false;
  423. }
  424. /// <summary>
  425. /// Performs a money transfer request between two accounts
  426. /// </summary>
  427. /// <param name="from">The senders account ID</param>
  428. /// <param name="to">The receivers account ID</param>
  429. /// <param name="amount">The amount to transfer</param>
  430. /// <returns>Success?</returns>
  431. public bool MoneyTransferRequest(LLUUID from, LLUUID to, uint amount)
  432. {
  433. return false;
  434. }
  435. /// <summary>
  436. /// Performs an inventory transfer request between two accounts
  437. /// </summary>
  438. /// <remarks>TODO: Move to inventory server</remarks>
  439. /// <param name="from">The senders account ID</param>
  440. /// <param name="to">The receivers account ID</param>
  441. /// <param name="item">The item to transfer</param>
  442. /// <returns>Success?</returns>
  443. public bool InventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item)
  444. {
  445. return false;
  446. }
  447. /// <summary>
  448. /// Database provider name
  449. /// </summary>
  450. /// <returns>Provider name</returns>
  451. public string getName()
  452. {
  453. return "MSSQL Userdata Interface";
  454. }
  455. /// <summary>
  456. /// Database provider version
  457. /// </summary>
  458. /// <returns>provider version</returns>
  459. public string GetVersion()
  460. {
  461. return database.getVersion();
  462. }
  463. /// <summary>
  464. /// Not implemented
  465. /// </summary>
  466. /// <param name="query"></param>
  467. public void runQuery(string query)
  468. {
  469. }
  470. }
  471. }