mirror of
https://github.com/opensim/opensim.git
synced 2026-08-05 08:55:56 +08:00
Merge branch 'master' into careminster-presence-refactor
This commit is contained in:
@@ -37,6 +37,11 @@ namespace OpenSim.Data
|
||||
{
|
||||
public string UserID;
|
||||
public Dictionary<string, string> Data;
|
||||
|
||||
public GridUserData()
|
||||
{
|
||||
Data = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -44,7 +49,7 @@ namespace OpenSim.Data
|
||||
/// </summary>
|
||||
public interface IGridUserData
|
||||
{
|
||||
GridUserData GetGridUserData(string userID);
|
||||
bool StoreGridUserData(GridUserData data);
|
||||
GridUserData Get(string userID);
|
||||
bool Store(GridUserData data);
|
||||
}
|
||||
}
|
||||
@@ -50,10 +50,8 @@ namespace OpenSim.Data
|
||||
|
||||
PresenceData Get(UUID sessionID);
|
||||
void LogoutRegionAgents(UUID regionID);
|
||||
bool ReportAgent(UUID sessionID, UUID regionID, string position, string lookAt);
|
||||
bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt);
|
||||
bool ReportAgent(UUID sessionID, UUID regionID);
|
||||
PresenceData[] Get(string field, string data);
|
||||
void Prune(string userID);
|
||||
bool Delete(string field, string val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,11 @@ namespace OpenSim.Data.MSSQL
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public MSSQLGridUserData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "UserGrid")
|
||||
base(connectionString, realm, "GridUserStore")
|
||||
{
|
||||
}
|
||||
|
||||
public GridUserData GetGridUserData(string userID)
|
||||
public GridUserData Get(string userID)
|
||||
{
|
||||
GridUserData[] ret = Get("UserID", userID);
|
||||
|
||||
@@ -60,9 +60,5 @@ namespace OpenSim.Data.MSSQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public bool StoreGridUserData(GridUserData data)
|
||||
{
|
||||
return Store(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenSim.Data.MSSQL
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
cmd.CommandText = String.Format("UPDATE {0} SET Online='false' WHERE [RegionID]=@RegionID", m_Realm);
|
||||
cmd.CommandText = String.Format("DELETE FROM {0} WHERE [RegionID]=@RegionID", m_Realm);
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
|
||||
cmd.Connection = conn;
|
||||
@@ -76,8 +76,7 @@ namespace OpenSim.Data.MSSQL
|
||||
}
|
||||
}
|
||||
|
||||
public bool ReportAgent(UUID sessionID, UUID regionID, string position,
|
||||
string lookAt)
|
||||
public bool ReportAgent(UUID sessionID, UUID regionID)
|
||||
{
|
||||
PresenceData[] pd = Get("SessionID", sessionID.ToString());
|
||||
if (pd.Length == 0)
|
||||
@@ -88,16 +87,11 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
|
||||
cmd.CommandText = String.Format(@"UPDATE {0} SET
|
||||
[RegionID] = @RegionID,
|
||||
[Position] = @Position,
|
||||
[LookAt] = @LookAt,
|
||||
[Online] = 'true'
|
||||
[RegionID] = @RegionID
|
||||
WHERE [SessionID] = @SessionID", m_Realm);
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@SessionID", sessionID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@Position", position.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@LookAt", lookAt.ToString()));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() == 0)
|
||||
@@ -106,65 +100,5 @@ namespace OpenSim.Data.MSSQL
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
||||
{
|
||||
PresenceData[] pd = Get("UserID", userID);
|
||||
if (pd.Length == 0)
|
||||
return false;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
|
||||
cmd.CommandText = String.Format(@"UPDATE {0} SET
|
||||
[HomeRegionID] = @HomeRegionID,
|
||||
[HomePosition] = @HomePosition,
|
||||
[HomeLookAt] = @HomeLookAt
|
||||
WHERE [UserID] = @UserID", m_Realm);
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@UserID", userID));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@HomeRegionID", regionID.ToString()));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@HomePosition", position));
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@HomeLookAt", lookAt));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
if (cmd.ExecuteNonQuery() == 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Prune(string userID)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("SELECT * from {0} WHERE [UserID] = @UserID", m_Realm);
|
||||
|
||||
cmd.Parameters.Add(m_database.CreateParameter("@UserID", userID));
|
||||
cmd.Connection = conn;
|
||||
conn.Open();
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
List<UUID> deleteSessions = new List<UUID>();
|
||||
int online = 0;
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (bool.Parse(reader["Online"].ToString()))
|
||||
online++;
|
||||
else
|
||||
deleteSessions.Add(new UUID(reader["SessionID"].ToString()));
|
||||
}
|
||||
|
||||
if (online == 0 && deleteSessions.Count > 0)
|
||||
deleteSessions.RemoveAt(0);
|
||||
|
||||
foreach (UUID s in deleteSessions)
|
||||
Delete("SessionID", s.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public MySQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "UserGrid") {}
|
||||
public MySQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "GridUserStore") {}
|
||||
|
||||
public GridUserData GetGridUserData(string userID)
|
||||
public GridUserData Get(string userID)
|
||||
{
|
||||
GridUserData[] ret = Get("UserID", userID);
|
||||
|
||||
@@ -56,9 +56,6 @@ namespace OpenSim.Data.MySQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public bool StoreGridUserData(GridUserData data)
|
||||
{
|
||||
return Store(data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -65,15 +65,14 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
cmd.CommandText = String.Format("update {0} set Online='false' where `RegionID`=?RegionID", m_Realm);
|
||||
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
|
||||
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
|
||||
public bool ReportAgent(UUID sessionID, UUID regionID, string position,
|
||||
string lookAt)
|
||||
public bool ReportAgent(UUID sessionID, UUID regionID)
|
||||
{
|
||||
PresenceData[] pd = Get("SessionID", sessionID.ToString());
|
||||
if (pd.Length == 0)
|
||||
@@ -81,12 +80,10 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, Position=?Position, LookAt=?LookAt, Online='true' where `SessionID`=?SessionID", m_Realm);
|
||||
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID where `SessionID`=?SessionID", m_Realm);
|
||||
|
||||
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Position", position.ToString());
|
||||
cmd.Parameters.AddWithValue("?LookAt", lookAt.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) == 0)
|
||||
return false;
|
||||
@@ -94,62 +91,5 @@ namespace OpenSim.Data.MySQL
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
||||
{
|
||||
PresenceData[] pd = Get("UserID", userID);
|
||||
if (pd.Length == 0)
|
||||
return false;
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
cmd.CommandText = String.Format("update {0} set HomeRegionID=?HomeRegionID, HomePosition=?HomePosition, HomeLookAt=?HomeLookAt where UserID=?UserID", m_Realm);
|
||||
|
||||
cmd.Parameters.AddWithValue("?UserID", userID);
|
||||
cmd.Parameters.AddWithValue("?HomeRegionID", regionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?HomePosition", position);
|
||||
cmd.Parameters.AddWithValue("?HomeLookAt", lookAt);
|
||||
|
||||
if (ExecuteNonQuery(cmd) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Prune(string userID)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
cmd.CommandText = String.Format("select * from {0} where UserID=?UserID", m_Realm);
|
||||
|
||||
cmd.Parameters.AddWithValue("?UserID", userID);
|
||||
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
List<UUID> deleteSessions = new List<UUID>();
|
||||
int online = 0;
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (bool.Parse(reader["Online"].ToString()))
|
||||
online++;
|
||||
else
|
||||
deleteSessions.Add(new UUID(reader["SessionID"].ToString()));
|
||||
}
|
||||
|
||||
// Leave one session behind so that we can pick up details such as home location
|
||||
if (online == 0 && deleteSessions.Count > 0)
|
||||
deleteSessions.RemoveAt(0);
|
||||
|
||||
foreach (UUID s in deleteSessions)
|
||||
Delete("SessionID", s.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
OpenSim/Data/MySQL/Resources/001_GridUserStore.sql
Normal file
17
OpenSim/Data/MySQL/Resources/001_GridUserStore.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `GridUser` (
|
||||
`UserID` VARCHAR(255) NOT NULL,
|
||||
`HomeRegionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`HomePosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
`HomeLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
`LastRegionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`LastPosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
`LastLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
`Online` CHAR(5) NOT NULL DEFAULT 'false',
|
||||
`Login` CHAR(16) NOT NULL DEFAULT '0',
|
||||
`Logout` CHAR(16) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`UserID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
COMMIT;
|
||||
@@ -4,12 +4,10 @@ CREATE TABLE `Presence` (
|
||||
`UserID` VARCHAR(255) NOT NULL,
|
||||
`RegionID` CHAR(36) NOT NULL,
|
||||
`SessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`SecureSessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
`Online` CHAR(5) NOT NULL DEFAULT 'false',
|
||||
`Login` CHAR(16) NOT NULL DEFAULT '0',
|
||||
`Logout` CHAR(16) NOT NULL DEFAULT '0',
|
||||
`Position` CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
`LookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>'
|
||||
`SecureSessionID` CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE UNIQUE INDEX SessionID ON Presence(SessionID);
|
||||
CREATE INDEX UserID ON Presence(UserID);
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE Presence ADD COLUMN `HomeRegionID` CHAR(36) NOT NULL;
|
||||
ALTER TABLE Presence ADD COLUMN `HomePosition` CHAR(64) NOT NULL DEFAULT '<0,0,0>';
|
||||
ALTER TABLE Presence ADD COLUMN `HomeLookAt` CHAR(64) NOT NULL DEFAULT '<0,0,0>';
|
||||
|
||||
COMMIT;
|
||||
@@ -1,6 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE UNIQUE INDEX SessionID ON Presence(SessionID);
|
||||
CREATE INDEX UserID ON Presence(UserID);
|
||||
|
||||
COMMIT;
|
||||
@@ -96,45 +96,20 @@ namespace OpenSim.Data.Null
|
||||
m_presenceData.Remove(u);
|
||||
}
|
||||
|
||||
public bool ReportAgent(UUID sessionID, UUID regionID, string position, string lookAt)
|
||||
public bool ReportAgent(UUID sessionID, UUID regionID)
|
||||
{
|
||||
if (Instance != this)
|
||||
return Instance.ReportAgent(sessionID, regionID, position, lookAt);
|
||||
return Instance.ReportAgent(sessionID, regionID);
|
||||
|
||||
if (m_presenceData.ContainsKey(sessionID))
|
||||
{
|
||||
m_presenceData[sessionID].RegionID = regionID;
|
||||
m_presenceData[sessionID].Data["Position"] = position;
|
||||
m_presenceData[sessionID].Data["LookAt"] = lookAt;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
||||
{
|
||||
if (Instance != this)
|
||||
return Instance.SetHomeLocation(userID, regionID, position, lookAt);
|
||||
|
||||
bool foundone = false;
|
||||
foreach (PresenceData p in m_presenceData.Values)
|
||||
{
|
||||
if (p.UserID == userID)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[NULL PRESENCE DATA]: Setting home location {0} {1} {2} for {3}",
|
||||
// regionID, position, lookAt, p.UserID);
|
||||
|
||||
p.Data["HomeRegionID"] = regionID.ToString();
|
||||
p.Data["HomePosition"] = position.ToString();
|
||||
p.Data["HomeLookAt"] = lookAt.ToString();
|
||||
foundone = true;
|
||||
}
|
||||
}
|
||||
|
||||
return foundone;
|
||||
}
|
||||
|
||||
public PresenceData[] Get(string field, string data)
|
||||
{
|
||||
@@ -193,39 +168,6 @@ namespace OpenSim.Data.Null
|
||||
return presences.ToArray();
|
||||
}
|
||||
|
||||
public void Prune(string userID)
|
||||
{
|
||||
if (Instance != this)
|
||||
{
|
||||
Instance.Prune(userID);
|
||||
return;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[NULL PRESENCE DATA]: Prune called for {0}", userID);
|
||||
|
||||
List<UUID> deleteSessions = new List<UUID>();
|
||||
int online = 0;
|
||||
|
||||
foreach (KeyValuePair<UUID, PresenceData> kvp in m_presenceData)
|
||||
{
|
||||
// m_log.DebugFormat("Online: {0}", kvp.Value.Data["Online"]);
|
||||
|
||||
bool on = false;
|
||||
if (bool.TryParse(kvp.Value.Data["Online"], out on) && on)
|
||||
online++;
|
||||
else
|
||||
deleteSessions.Add(kvp.Key);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[NULL PRESENCE DATA]: online [{0}], deleteSession.Count [{1}]", online, deleteSessions.Count);
|
||||
|
||||
// Leave one session behind so that we can pick up details such as home location
|
||||
if (online == 0 && deleteSessions.Count > 0)
|
||||
deleteSessions.RemoveAt(0);
|
||||
|
||||
foreach (UUID s in deleteSessions)
|
||||
m_presenceData.Remove(s);
|
||||
}
|
||||
|
||||
public bool Delete(string field, string data)
|
||||
{
|
||||
|
||||
16
OpenSim/Data/SQLite/Resources/001_GridUserStore.sql
Normal file
16
OpenSim/Data/SQLite/Resources/001_GridUserStore.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
CREATE TABLE GridUser (
|
||||
UserID VARCHAR(255) primary key,
|
||||
HomeRegionID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
HomePosition CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
HomeLookAt CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
LastRegionID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
LastPosition CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
LastLookAt CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
Online CHAR(5) NOT NULL DEFAULT 'false',
|
||||
Login CHAR(16) NOT NULL DEFAULT '0',
|
||||
Logout CHAR(16) NOT NULL DEFAULT '0'
|
||||
) ;
|
||||
|
||||
COMMIT;
|
||||
61
OpenSim/Data/SQLite/SQLiteGridUserData.cs
Normal file
61
OpenSim/Data/SQLite/SQLiteGridUserData.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.Generic;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Data.SQLite
|
||||
{
|
||||
/// <summary>
|
||||
/// A SQL Interface for user grid data
|
||||
/// </summary>
|
||||
public class SQLiteGridUserData : SQLiteGenericTableHandler<GridUserData>, IGridUserData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public SQLiteGridUserData(string connectionString, string realm)
|
||||
: base(connectionString, realm, "GridUserStore") {}
|
||||
|
||||
public new GridUserData Get(string userID)
|
||||
{
|
||||
GridUserData[] ret = Get("UserID", userID);
|
||||
|
||||
if (ret.Length == 0)
|
||||
return null;
|
||||
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user