diff --git a/OpenGridServices.sln b/OpenGridServices.sln index 2343bc085d..5f47b6b81e 100644 --- a/OpenGridServices.sln +++ b/OpenGridServices.sln @@ -1,5 +1,5 @@ Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 +# Visual C# Express 2005 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSim.Framework.Data", "OpenSim\Framework\Data\OpenSim.Framework.Data.csproj", "{36B72A9B-0000-0000-0000-000000000000}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSim.Framework.Data.DB4o", "OpenSim\Framework\Data.DB4o\OpenSim.Framework.Data.DB4o.csproj", "{FD2D303D-0000-0000-0000-000000000000}" @@ -25,72 +25,61 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSim.Grid.UserServer.Config", "OpenSim\Grid\UserServer.Config\OpenSim.Grid.UserServer.Config.csproj", "{08F87229-0000-0000-0000-000000000000}" EndProject Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectDependencies) = postSolution - ({FD2D303D-0000-0000-0000-000000000000}).2 = ({36B72A9B-0000-0000-0000-000000000000}) - ({17F7F694-0000-0000-0000-000000000000}).1 = ({36B72A9B-0000-0000-0000-000000000000}) - ({17F7F6BE-0000-0000-0000-000000000000}).2 = ({36B72A9B-0000-0000-0000-000000000000}) - ({6ECC56A9-0000-0000-0000-000000000000}).1 = ({36B72A9B-0000-0000-0000-000000000000}) - ({586E2916-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000}) - ({60FCC3A6-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000}) - ({60FCC3A6-0000-0000-0000-000000000000}).7 = ({4B7BFD1C-0000-0000-0000-000000000000}) - ({2FC96F92-0000-0000-0000-000000000000}).4 = ({36B72A9B-0000-0000-0000-000000000000}) - ({2FC96F92-0000-0000-0000-000000000000}).7 = ({586E2916-0000-0000-0000-000000000000}) - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {36B72A9B-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {36B72A9B-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {FD2D303D-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FD2D303D-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FD2D303D-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FD2D303D-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {17F7F694-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17F7F694-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17F7F694-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17F7F694-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {17F7F6BE-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17F7F6BE-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17F7F6BE-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17F7F6BE-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {6ECC56A9-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6ECC56A9-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6ECC56A9-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6ECC56A9-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {586E2916-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {586E2916-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {586E2916-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {586E2916-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {E5F1A03B-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E5F1A03B-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E5F1A03B-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E5F1A03B-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {4B7BFD1C-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4B7BFD1C-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4B7BFD1C-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4B7BFD1C-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {60FCC3A6-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60FCC3A6-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60FCC3A6-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60FCC3A6-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {1442B635-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1442B635-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1442B635-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1442B635-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {2FC96F92-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2FC96F92-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2FC96F92-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2FC96F92-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - {08F87229-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {08F87229-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {08F87229-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU - {08F87229-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36B72A9B-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36B72A9B-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36B72A9B-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {FD2D303D-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD2D303D-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD2D303D-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD2D303D-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {17F7F694-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17F7F694-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17F7F694-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17F7F694-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {17F7F6BE-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17F7F6BE-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17F7F6BE-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17F7F6BE-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {6ECC56A9-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6ECC56A9-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6ECC56A9-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6ECC56A9-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {586E2916-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {586E2916-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {586E2916-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {586E2916-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {E5F1A03B-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5F1A03B-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5F1A03B-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5F1A03B-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {4B7BFD1C-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4B7BFD1C-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4B7BFD1C-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4B7BFD1C-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {60FCC3A6-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {60FCC3A6-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {60FCC3A6-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {60FCC3A6-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {1442B635-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1442B635-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1442B635-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1442B635-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {2FC96F92-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2FC96F92-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2FC96F92-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2FC96F92-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {08F87229-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08F87229-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08F87229-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08F87229-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal diff --git a/OpenSim/Framework/Communications/IUserServices.cs b/OpenSim/Framework/Communications/IUserServices.cs index 679065122d..37f4942fa3 100644 --- a/OpenSim/Framework/Communications/IUserServices.cs +++ b/OpenSim/Framework/Communications/IUserServices.cs @@ -39,6 +39,9 @@ namespace OpenSim.Framework.Communications UserProfileData GetUserProfile(string firstName, string lastName); UserProfileData GetUserProfile(string name); UserProfileData GetUserProfile(LLUUID avatarID); - + + UserProfileData SetupMasterUser(string firstName, string lastName); + UserProfileData SetupMasterUser(string firstName, string lastName, string password); + } } diff --git a/OpenSim/Framework/UserManager/UserManagerBase.cs b/OpenSim/Framework/UserManager/UserManagerBase.cs index eb46c14d17..bc35164d9c 100644 --- a/OpenSim/Framework/UserManager/UserManagerBase.cs +++ b/OpenSim/Framework/UserManager/UserManagerBase.cs @@ -537,27 +537,15 @@ namespace OpenSim.Framework.UserManagement /// Returns an error message that the user could not be found in the database /// /// XML string consisting of a error element containing individual error(s) - public string CreateUnknownUserErrorResponse() + public XmlRpcResponse CreateUnknownUserErrorResponse() { - System.IO.StringWriter sw = new System.IO.StringWriter(); - XmlTextWriter xw = new XmlTextWriter(sw); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + responseData["error_type"] = "unknown_user"; + responseData["error_desc"] = "The user requested is not in the database"; - // Header - xw.Formatting = Formatting.Indented; - xw.WriteStartDocument(); - xw.WriteDocType("error", null, null, null); - xw.WriteComment("An error occured"); - xw.WriteStartElement("error"); - - // User - xw.WriteElementString("unknownuser", "Unable to find a user with that name"); - - // Footer - xw.WriteEndElement(); - xw.Flush(); - xw.Close(); - - return sw.ToString(); + response.Value = responseData; + return response; } /// @@ -565,75 +553,81 @@ namespace OpenSim.Framework.UserManagement /// /// The user profile /// A string containing an XML Document of the user profile - public string ProfileToXml(UserProfileData profile) + public XmlRpcResponse ProfileToXmlRPCResponse(UserProfileData profile) { - System.IO.StringWriter sw = new System.IO.StringWriter(); - XmlTextWriter xw = new XmlTextWriter(sw); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); - // Header - xw.Formatting = Formatting.Indented; - xw.WriteStartDocument(); - xw.WriteDocType("userprofile", null, null, null); - xw.WriteComment("Found user profiles matching the request"); - xw.WriteStartElement("users"); - - // User - xw.WriteStartElement("user"); // Account information - xw.WriteAttributeString("firstname", profile.username); - xw.WriteAttributeString("lastname", profile.surname); - xw.WriteAttributeString("uuid", profile.UUID.ToStringHyphenated()); + responseData["firstname"] = profile.username; + responseData["lastname"] = profile.surname; + responseData["uuid"] = profile.UUID.ToStringHyphenated(); // Server Information - xw.WriteAttributeString("server_inventory", profile.userInventoryURI); - xw.WriteAttributeString("server_asset", profile.userAssetURI); + responseData["server_inventory"] = profile.userInventoryURI; + responseData["server_asset"] = profile.userAssetURI; // Profile Information - xw.WriteAttributeString("profile_about", profile.profileAboutText); - xw.WriteAttributeString("profile_firstlife_about", profile.profileFirstText); - xw.WriteAttributeString("profile_firstlife_image", profile.profileFirstImage.ToStringHyphenated()); - xw.WriteAttributeString("profile_can_do", profile.profileCanDoMask.ToString()); - xw.WriteAttributeString("profile_want_do", profile.profileWantDoMask.ToString()); - xw.WriteAttributeString("profile_image", profile.profileImage.ToStringHyphenated()); - xw.WriteAttributeString("profile_created",profile.created.ToString()); - xw.WriteAttributeString("profile_lastlogin",profile.lastLogin.ToString()); + responseData["profile_about"] = profile.profileAboutText; + responseData["profile_firstlife_about"] = profile.profileFirstText; + responseData["profile_firstlife_image"] = profile.profileFirstImage.ToStringHyphenated(); + responseData["profile_can_do"] = profile.profileCanDoMask.ToString(); + responseData["profile_want_do"] = profile.profileWantDoMask.ToString(); + responseData["profile_image"] = profile.profileImage.ToStringHyphenated(); + responseData["profile_created"] = profile.created.ToString(); + responseData["profile_lastlogin"] = profile.lastLogin.ToString(); // Home region information - xw.WriteAttributeString("home_coordinates", profile.homeLocation.ToString()); - xw.WriteAttributeString("home_region", profile.homeRegion.ToString()); - xw.WriteAttributeString("home_look", profile.homeLookAt.ToString()); + responseData["home_coordinates"] = profile.homeLocation.ToString(); + responseData["home_region"] = profile.homeRegion.ToString(); + responseData["home_look"] = profile.homeLookAt.ToString(); - xw.WriteEndElement(); - - // Footer - xw.WriteEndElement(); - xw.Flush(); - xw.Close(); - - return sw.ToString(); + response.Value = responseData; + return response; } - #region REST Methods + #region XMLRPC User Methods //should most likely move out of here and into the grid's userserver sub class - public string RestGetUserMethodName(string request, string path, string param) + public XmlRpcResponse XmlRPCGetUserMethodName(XmlRpcRequest request) { - UserProfileData userProfile = getUserProfile(param.Trim()); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + UserProfileData userProfile; - if (userProfile == null) + if (requestData.Contains("avatar_name")) + { + userProfile = getUserProfile((string)requestData["avatar_name"]); + if (userProfile == null) + { + return CreateUnknownUserErrorResponse(); + } + } + else { return CreateUnknownUserErrorResponse(); } + - return ProfileToXml(userProfile); + return ProfileToXmlRPCResponse(userProfile); } - public string RestGetUserMethodUUID(string request, string path, string param) + public XmlRpcResponse XmlRPCGetUserMethodUUID(XmlRpcRequest request) { - UserProfileData userProfile = getUserProfile(new LLUUID(param)); - - if (userProfile == null) + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + UserProfileData userProfile; + if (requestData.Contains("avatar_uuid")) + { + userProfile = getUserProfile((LLUUID)requestData["avatar_uuid"]); + if (userProfile == null) + { + return CreateUnknownUserErrorResponse(); + } + } + else { return CreateUnknownUserErrorResponse(); } - return ProfileToXml(userProfile); + + return ProfileToXmlRPCResponse(userProfile); } #endregion diff --git a/OpenSim/Grid/UserServer/Main.cs b/OpenSim/Grid/UserServer/Main.cs index 8ae4dbf32f..640f91a57a 100644 --- a/OpenSim/Grid/UserServer/Main.cs +++ b/OpenSim/Grid/UserServer/Main.cs @@ -107,8 +107,8 @@ namespace OpenSim.Grid.UserServer httpServer.AddXmlRPCHandler("login_to_simulator", m_userManager.XmlRpcLoginMethod); - httpServer.AddRestHandler("GET", "/user/name/", m_userManager.RestGetUserMethodName); - httpServer.AddRestHandler("GET", "/user/uuid/", m_userManager.RestGetUserMethodUUID); + httpServer.AddXmlRPCHandler("get_user_by_name", m_userManager.XmlRPCGetUserMethodName); + httpServer.AddXmlRPCHandler("get_user_by_uuid", m_userManager.XmlRPCGetUserMethodUUID); httpServer.AddRestHandler("DELETE", "/usersessions/", m_userManager.RestDeleteUserSessionMethod); diff --git a/OpenSim/Region/Communications/Local/LocalUserServices.cs b/OpenSim/Region/Communications/Local/LocalUserServices.cs index 1eb574c053..2097870ec4 100644 --- a/OpenSim/Region/Communications/Local/LocalUserServices.cs +++ b/OpenSim/Region/Communications/Local/LocalUserServices.cs @@ -114,5 +114,30 @@ namespace OpenSim.Region.Communications.Local } + public UserProfileData SetupMasterUser(string firstName, string lastName) + { + return SetupMasterUser(firstName, lastName, ""); + } + public UserProfileData SetupMasterUser(string firstName, string lastName, string password) + { + UserProfileData profile = getUserProfile(firstName, lastName); + if (profile != null) + { + + return profile; + } + + Console.WriteLine("Unknown Master User. Sandbox Mode: Creating Account"); + this.AddUserProfile(firstName, lastName, password, defaultHomeX, defaultHomeY); + + profile = getUserProfile(firstName, lastName); + + if (profile == null) + { + Console.WriteLine("Unknown Master User after creation attempt. No clue what to do here."); + } + + return profile; + } } } diff --git a/OpenSim/Region/Communications/OGS1/OGSUserServices.cs b/OpenSim/Region/Communications/OGS1/OGSUserServices.cs index 012774d240..48d3018e54 100644 --- a/OpenSim/Region/Communications/OGS1/OGSUserServices.cs +++ b/OpenSim/Region/Communications/OGS1/OGSUserServices.cs @@ -11,7 +11,7 @@ namespace OpenSim.Region.Communications.OGS1 { public UserProfileData GetUserProfile(string firstName, string lastName) { - return null; + return GetUserProfile(firstName + " " + lastName); } public UserProfileData GetUserProfile(string name) { @@ -21,5 +21,20 @@ namespace OpenSim.Region.Communications.OGS1 { return null; } + + public UserProfileData SetupMasterUser(string firstName, string lastName) + { + return SetupMasterUser(firstName, lastName, ""); + } + + public UserProfileData SetupMasterUser(string firstName, string lastName, string password) + { + UserProfileData profile = GetUserProfile(firstName, lastName); + if (profile == null) + { + Console.WriteLine("Unknown Master User. Grid Mode: No clue what I should do. Probably would choose the grid owner UUID when that is implemented"); + } + return null; + } } }