mirror of
https://github.com/opensim/opensim.git
synced 2026-05-16 03:36:04 +08:00
This resolves the problem where eyes and hair would turn white on standalone configurations When a client receives body part information, for some insane reason or other it always ends up uploading this back to the server and then immediately re-requesting it. This should have been okay since we stored that asset in cache. However, the standalone asset service connector was not checking this cache properly, so every time the client made the request for the asset it has just loaded it would get a big fat null back in the face, causing it to make clothes and hair white. This bug did not affect grids since they use a different service connector.
767 lines
29 KiB
C#
767 lines
29 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/
|
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the OpenSimulator Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using log4net;
|
|
using MySql.Data.MySqlClient;
|
|
using OpenMetaverse;
|
|
using OpenSim.Framework;
|
|
|
|
namespace OpenSim.Data.MySQL
|
|
{
|
|
/// <summary>
|
|
/// A database interface class to a user profile storage system
|
|
/// </summary>
|
|
public class MySQLUserData : UserDataBase
|
|
{
|
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
private MySQLManager m_database;
|
|
private string m_connectionString;
|
|
private object m_dbLock = new object();
|
|
|
|
public int m_maxConnections = 10;
|
|
public int m_lastConnect;
|
|
|
|
private string m_agentsTableName = "agents";
|
|
private string m_usersTableName = "users";
|
|
private string m_userFriendsTableName = "userfriends";
|
|
private string m_appearanceTableName = "avatarappearance";
|
|
private string m_attachmentsTableName = "avatarattachments";
|
|
|
|
public override void Initialise()
|
|
{
|
|
m_log.Info("[MySQLUserData]: " + Name + " cannot be default-initialized!");
|
|
throw new PluginNotInitialisedException(Name);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialise User Interface
|
|
/// Loads and initialises the MySQL storage plugin
|
|
/// Warns and uses the obsolete mysql_connection.ini if connect string is empty.
|
|
/// Checks for migration
|
|
/// </summary>
|
|
/// <param name="connect">connect string.</param>
|
|
public override void Initialise(string connect)
|
|
{
|
|
m_connectionString = connect;
|
|
m_database = new MySQLManager(connect);
|
|
|
|
// This actually does the roll forward assembly stuff
|
|
Assembly assem = GetType().Assembly;
|
|
|
|
using (MySql.Data.MySqlClient.MySqlConnection dbcon = new MySql.Data.MySqlClient.MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
Migration m = new Migration(dbcon, assem, "UserStore");
|
|
m.Update();
|
|
}
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
}
|
|
|
|
// see IUserDataPlugin
|
|
public override UserProfileData GetUserByName(string user, string last)
|
|
{
|
|
try
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?first"] = user;
|
|
param["?second"] = last;
|
|
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon,
|
|
"SELECT * FROM " + m_usersTableName + " WHERE username = ?first AND lastname = ?second", param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
UserProfileData row = m_database.readUserRow(reader);
|
|
return row;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#region User Friends List Data
|
|
|
|
public override void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms)
|
|
{
|
|
int dtvalue = Util.UnixTimeSinceEpoch();
|
|
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?ownerID"] = friendlistowner.ToString();
|
|
param["?friendID"] = friend.ToString();
|
|
param["?friendPerms"] = perms.ToString();
|
|
param["?datetimestamp"] = dtvalue.ToString();
|
|
|
|
try
|
|
{
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand adder = m_database.Query(dbcon,
|
|
"INSERT INTO `" + m_userFriendsTableName + "` " +
|
|
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
|
|
"VALUES " +
|
|
"(?ownerID,?friendID,?friendPerms,?datetimestamp)",
|
|
param))
|
|
{
|
|
adder.ExecuteNonQuery();
|
|
}
|
|
|
|
using (IDbCommand adder = m_database.Query(dbcon,
|
|
"INSERT INTO `" + m_userFriendsTableName + "` " +
|
|
"(`ownerID`,`friendID`,`friendPerms`,`datetimestamp`) " +
|
|
"VALUES " +
|
|
"(?friendID,?ownerID,?friendPerms,?datetimestamp)",
|
|
param))
|
|
{
|
|
adder.ExecuteNonQuery();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return;
|
|
}
|
|
}
|
|
|
|
public override void RemoveUserFriend(UUID friendlistowner, UUID friend)
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?ownerID"] = friendlistowner.ToString();
|
|
param["?friendID"] = friend.ToString();
|
|
|
|
try
|
|
{
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand updater = m_database.Query(dbcon,
|
|
"delete from " + m_userFriendsTableName + " where ownerID = ?ownerID and friendID = ?friendID",
|
|
param))
|
|
{
|
|
updater.ExecuteNonQuery();
|
|
}
|
|
|
|
using (IDbCommand updater = m_database.Query(dbcon,
|
|
"delete from " + m_userFriendsTableName + " where ownerID = ?friendID and friendID = ?ownerID",
|
|
param))
|
|
{
|
|
updater.ExecuteNonQuery();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return;
|
|
}
|
|
}
|
|
|
|
public override void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms)
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?ownerID"] = friendlistowner.ToString();
|
|
param["?friendID"] = friend.ToString();
|
|
param["?friendPerms"] = perms.ToString();
|
|
|
|
try
|
|
{
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand updater = m_database.Query(dbcon,
|
|
"update " + m_userFriendsTableName +
|
|
" SET friendPerms = ?friendPerms " +
|
|
"where ownerID = ?ownerID and friendID = ?friendID",
|
|
param))
|
|
{
|
|
updater.ExecuteNonQuery();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return;
|
|
}
|
|
}
|
|
|
|
public override List<FriendListItem> GetUserFriendList(UUID friendlistowner)
|
|
{
|
|
List<FriendListItem> Lfli = new List<FriendListItem>();
|
|
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?ownerID"] = friendlistowner.ToString();
|
|
|
|
try
|
|
{
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
//Left Join userfriends to itself
|
|
using (IDbCommand result = m_database.Query(dbcon,
|
|
"select a.ownerID,a.friendID,a.friendPerms,b.friendPerms as ownerperms from " +
|
|
m_userFriendsTableName + " as a, " + m_userFriendsTableName + " as b" +
|
|
" where a.ownerID = ?ownerID and b.ownerID = a.friendID and b.friendID = a.ownerID",
|
|
param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
FriendListItem fli = new FriendListItem();
|
|
fli.FriendListOwner = new UUID((string)reader["ownerID"]);
|
|
fli.Friend = new UUID((string)reader["friendID"]);
|
|
fli.FriendPerms = (uint)Convert.ToInt32(reader["friendPerms"]);
|
|
|
|
// This is not a real column in the database table, it's a joined column from the opposite record
|
|
fli.FriendListOwnerPerms = (uint)Convert.ToInt32(reader["ownerperms"]);
|
|
|
|
Lfli.Add(fli);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return Lfli;
|
|
}
|
|
|
|
return Lfli;
|
|
}
|
|
|
|
override public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos (List<UUID> uuids)
|
|
{
|
|
Dictionary<UUID, FriendRegionInfo> infos = new Dictionary<UUID,FriendRegionInfo>();
|
|
|
|
try
|
|
{
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
foreach (UUID uuid in uuids)
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?uuid"] = uuid.ToString();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon, "select agentOnline,currentHandle from " + m_agentsTableName +
|
|
" where UUID = ?uuid", param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
FriendRegionInfo fri = new FriendRegionInfo();
|
|
fri.isOnline = (sbyte)reader["agentOnline"] != 0;
|
|
fri.regionHandle = (ulong)reader["currentHandle"];
|
|
|
|
infos[uuid] = fri;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Warn("[MYSQL]: Got exception on trying to find friends regions:", e);
|
|
m_log.Error(e.Message, e);
|
|
}
|
|
|
|
return infos;
|
|
}
|
|
|
|
#endregion
|
|
|
|
public override List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query)
|
|
{
|
|
List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>();
|
|
|
|
Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
|
|
|
|
string[] querysplit;
|
|
querysplit = query.Split(' ');
|
|
if (querysplit.Length > 1 && querysplit[1].Trim() != String.Empty)
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
|
|
param["?second"] = objAlphaNumericPattern.Replace(querysplit[1], String.Empty) + "%";
|
|
|
|
try
|
|
{
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon,
|
|
"SELECT UUID,username,lastname FROM " + m_usersTableName +
|
|
" WHERE username like ?first AND lastname like ?second LIMIT 100",
|
|
param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
AvatarPickerAvatar user = new AvatarPickerAvatar();
|
|
user.AvatarID = new UUID((string)reader["UUID"]);
|
|
user.firstName = (string)reader["username"];
|
|
user.lastName = (string)reader["lastname"];
|
|
returnlist.Add(user);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return returnlist;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?first"] = objAlphaNumericPattern.Replace(querysplit[0], String.Empty) + "%";
|
|
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon,
|
|
"SELECT UUID,username,lastname FROM " + m_usersTableName +
|
|
" WHERE username like ?first OR lastname like ?first LIMIT 100",
|
|
param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
AvatarPickerAvatar user = new AvatarPickerAvatar();
|
|
user.AvatarID = new UUID((string)reader["UUID"]);
|
|
user.firstName = (string)reader["username"];
|
|
user.lastName = (string)reader["lastname"];
|
|
returnlist.Add(user);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return returnlist;
|
|
}
|
|
}
|
|
return returnlist;
|
|
}
|
|
|
|
/// <summary>
|
|
/// See IUserDataPlugin
|
|
/// </summary>
|
|
/// <param name="uuid">User UUID</param>
|
|
/// <returns>User profile data</returns>
|
|
public override UserProfileData GetUserByUUID(UUID uuid)
|
|
{
|
|
try
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?uuid"] = uuid.ToString();
|
|
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_usersTableName + " WHERE UUID = ?uuid", param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
UserProfileData row = m_database.readUserRow(reader);
|
|
return row;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a user session searching by name
|
|
/// </summary>
|
|
/// <param name="name">The account name : "Username Lastname"</param>
|
|
/// <returns>The users session</returns>
|
|
public override UserAgentData GetAgentByName(string name)
|
|
{
|
|
return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a user session by account name
|
|
/// </summary>
|
|
/// <param name="user">First part of the users account name</param>
|
|
/// <param name="last">Second part of the users account name</param>
|
|
/// <returns>The users session</returns>
|
|
public override UserAgentData GetAgentByName(string user, string last)
|
|
{
|
|
UserProfileData profile = GetUserByName(user, last);
|
|
return GetAgentByUUID(profile.ID);
|
|
}
|
|
|
|
/// <summary>
|
|
/// </summary>
|
|
/// <param name="AgentID"></param>
|
|
/// <param name="WebLoginKey"></param>
|
|
/// <remarks>is it still used ?</remarks>
|
|
public override void StoreWebLoginKey(UUID AgentID, UUID WebLoginKey)
|
|
{
|
|
Dictionary<string, string> param = new Dictionary<string, string>();
|
|
param["?UUID"] = AgentID.ToString();
|
|
param["?webLoginKey"] = WebLoginKey.ToString();
|
|
|
|
try
|
|
{
|
|
m_database.ExecuteParameterizedSql(
|
|
"update " + m_usersTableName + " SET webLoginKey = ?webLoginKey " +
|
|
"where UUID = ?UUID",
|
|
param);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an agent session by account UUID
|
|
/// </summary>
|
|
/// <param name="uuid">The accounts UUID</param>
|
|
/// <returns>The users session</returns>
|
|
public override UserAgentData GetAgentByUUID(UUID uuid)
|
|
{
|
|
try
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?uuid"] = uuid.ToString();
|
|
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_agentsTableName + " WHERE UUID = ?uuid", param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
UserAgentData row = m_database.readAgentRow(reader);
|
|
return row;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new users profile
|
|
/// </summary>
|
|
/// <param name="user">The user profile to create</param>
|
|
public override void AddNewUserProfile(UserProfileData user)
|
|
{
|
|
UUID zero = UUID.Zero;
|
|
if (user.ID == zero)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
m_database.insertUserRow(
|
|
user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
|
|
user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y,
|
|
user.HomeLocation.Z,
|
|
user.HomeLookAt.X, user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created,
|
|
user.LastLogin, user.UserInventoryURI, user.UserAssetURI,
|
|
user.CanDoMask, user.WantDoMask,
|
|
user.AboutText, user.FirstLifeAboutText, user.Image,
|
|
user.FirstLifeImage, user.WebLoginKey, user.UserFlags, user.GodLevel, user.CustomType, user.Partner);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new agent
|
|
/// </summary>
|
|
/// <param name="agent">The agent to create</param>
|
|
public override void AddNewUserAgent(UserAgentData agent)
|
|
{
|
|
UUID zero = UUID.Zero;
|
|
if (agent.ProfileID == zero || agent.SessionID == zero)
|
|
return;
|
|
|
|
try
|
|
{
|
|
m_database.insertAgentRow(agent);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates a user profile stored in the DB
|
|
/// </summary>
|
|
/// <param name="user">The profile data to use to update the DB</param>
|
|
public override bool UpdateUserProfile(UserProfileData user)
|
|
{
|
|
try
|
|
{
|
|
m_database.updateUserRow(
|
|
user.ID, user.FirstName, user.SurName, user.Email, user.PasswordHash, user.PasswordSalt,
|
|
user.HomeRegion, user.HomeRegionID, user.HomeLocation.X, user.HomeLocation.Y,
|
|
user.HomeLocation.Z, user.HomeLookAt.X,
|
|
user.HomeLookAt.Y, user.HomeLookAt.Z, user.Created, user.LastLogin,
|
|
user.UserInventoryURI,
|
|
user.UserAssetURI, user.CanDoMask, user.WantDoMask, user.AboutText,
|
|
user.FirstLifeAboutText, user.Image, user.FirstLifeImage, user.WebLoginKey,
|
|
user.UserFlags, user.GodLevel, user.CustomType, user.Partner);
|
|
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs a money transfer request between two accounts
|
|
/// </summary>
|
|
/// <param name="from">The senders account ID</param>
|
|
/// <param name="to">The receivers account ID</param>
|
|
/// <param name="amount">The amount to transfer</param>
|
|
/// <returns>Success?</returns>
|
|
public override bool MoneyTransferRequest(UUID from, UUID to, uint amount)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs an inventory transfer request between two accounts
|
|
/// </summary>
|
|
/// <remarks>TODO: Move to inventory server</remarks>
|
|
/// <param name="from">The senders account ID</param>
|
|
/// <param name="to">The receivers account ID</param>
|
|
/// <param name="item">The item to transfer</param>
|
|
/// <returns>Success?</returns>
|
|
public override bool InventoryTransferRequest(UUID from, UUID to, UUID item)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public override AvatarAppearance GetUserAppearance(UUID user)
|
|
{
|
|
try
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?owner"] = user.ToString();
|
|
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon, "SELECT * FROM " + m_appearanceTableName + " WHERE owner = ?owner", param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
AvatarAppearance appearance = m_database.readAppearanceRow(reader);
|
|
|
|
if (appearance == null)
|
|
{
|
|
m_log.WarnFormat("[USER DB] No appearance found for user {0}", user.ToString());
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
appearance.SetAttachments(GetUserAttachments(user));
|
|
return appearance;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates an avatar appearence
|
|
/// </summary>
|
|
/// <param name="user">The user UUID</param>
|
|
/// <param name="appearance">The avatar appearance</param>
|
|
// override
|
|
public override void UpdateUserAppearance(UUID user, AvatarAppearance appearance)
|
|
{
|
|
try
|
|
{
|
|
appearance.Owner = user;
|
|
m_database.insertAppearanceRow(appearance);
|
|
|
|
UpdateUserAttachments(user, appearance.GetAttachments());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Database provider name
|
|
/// </summary>
|
|
/// <returns>Provider name</returns>
|
|
public override string Name
|
|
{
|
|
get { return "MySQL Userdata Interface"; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Database provider version
|
|
/// </summary>
|
|
/// <returns>provider version</returns>
|
|
public override string Version
|
|
{
|
|
get { return "0.1"; }
|
|
}
|
|
|
|
public Hashtable GetUserAttachments(UUID agentID)
|
|
{
|
|
Dictionary<string, object> param = new Dictionary<string, object>();
|
|
param["?uuid"] = agentID.ToString();
|
|
|
|
try
|
|
{
|
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
{
|
|
dbcon.Open();
|
|
|
|
using (IDbCommand result = m_database.Query(dbcon,
|
|
"SELECT attachpoint, item, asset from " + m_attachmentsTableName + " WHERE UUID = ?uuid", param))
|
|
{
|
|
using (IDataReader reader = result.ExecuteReader())
|
|
{
|
|
Hashtable ret = m_database.readAttachments(reader);
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void UpdateUserAttachments(UUID agentID, Hashtable data)
|
|
{
|
|
m_database.writeAttachments(agentID, data);
|
|
}
|
|
|
|
public override void ResetAttachments(UUID userID)
|
|
{
|
|
Dictionary<string, string> param = new Dictionary<string, string>();
|
|
param["?uuid"] = userID.ToString();
|
|
|
|
m_database.ExecuteParameterizedSql(
|
|
"UPDATE " + m_attachmentsTableName +
|
|
" SET asset = '00000000-0000-0000-0000-000000000000' WHERE UUID = ?uuid",
|
|
param);
|
|
}
|
|
|
|
public override void LogoutUsers(UUID regionID)
|
|
{
|
|
Dictionary<string, string> param = new Dictionary<string, string>();
|
|
param["?regionID"] = regionID.ToString();
|
|
|
|
try
|
|
{
|
|
m_database.ExecuteParameterizedSql(
|
|
"update " + m_agentsTableName + " SET agentOnline = 0 " +
|
|
"where currentRegion = ?regionID",
|
|
param);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error(e.Message, e);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|