Annotation of /trunk/ModularRex/RexNetwork/RexLogin/RexLoginModule.cs
Parent Directory
|
Revision Log
Revision 73 - (view) (download)
| 1 : | afrisby | 3 | using System; |
| 2 : | afrisby | 5 | using System.Collections; |
| 3 : | afrisby | 3 | using System.Collections.Generic; |
| 4 : | afrisby | 6 | using System.Reflection; |
| 5 : | using log4net; | ||
| 6 : | afrisby | 3 | using Nini.Config; |
| 7 : | afrisby | 6 | using Nwc.XmlRpc; |
| 8 : | using OpenMetaverse; | ||
| 9 : | using OpenSim.Framework; | ||
| 10 : | using OpenSim.Framework.Communications; | ||
| 11 : | mikkopa | 63 | using OpenSim.Region.Framework.Interfaces; |
| 12 : | using OpenSim.Region.Framework.Scenes; | ||
| 13 : | mikkopa | 73 | using OpenSim.Framework.Communications.Cache; |
| 14 : | afrisby | 3 | |
| 15 : | namespace ModularRex.RexNetwork.RexLogin | ||
| 16 : | { | ||
| 17 : | afrisby | 6 | public class RexLoginModule : IRegionModule |
| 18 : | afrisby | 3 | { |
| 19 : | afrisby | 6 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
| 20 : | afrisby | 3 | |
| 21 : | afrisby | 6 | private readonly List<Scene> m_scenes = new List<Scene>(); |
| 22 : | mikkopa | 39 | private readonly Dictionary<UUID, string> m_authUrl = new Dictionary<UUID, string>(); |
| 23 : | afrisby | 10 | |
| 24 : | mikkopa | 68 | private List<RexUDPServer> m_udpservers = new List<RexUDPServer>(); |
| 25 : | afrisby | 6 | private IConfigSource m_config; |
| 26 : | |||
| 27 : | private RegionInfo m_primaryRegionInfo; | ||
| 28 : | private uint m_rexPort = 7000; | ||
| 29 : | |||
| 30 : | mikkopa | 68 | private OpenSim.Framework.Servers.XmlRpcMethod default_login_to_simulator; |
| 31 : | |||
| 32 : | mikkopa | 73 | /// <summary> |
| 33 : | /// Used during login to send the skeleton of the OpenSim Library to the client. | ||
| 34 : | /// </summary> | ||
| 35 : | protected LibraryRootFolder m_libraryRootFolder; | ||
| 36 : | |||
| 37 : | mikkopa | 39 | public void Configure(IConfigSource config) |
| 38 : | { | ||
| 39 : | if (config.Configs.Contains("ModRex")) | ||
| 40 : | { | ||
| 41 : | m_rexPort = (uint) config.Configs["ModRex"].GetInt("FirstPort", (int) m_rexPort); | ||
| 42 : | } | ||
| 43 : | |||
| 44 : | } | ||
| 45 : | |||
| 46 : | afrisby | 3 | public void Initialise(Scene scene, IConfigSource source) |
| 47 : | { | ||
| 48 : | mikkopa | 68 | //if (m_udpserver == null) |
| 49 : | // m_udpserver = new RexUDPServer(); | ||
| 50 : | afrisby | 5 | |
| 51 : | afrisby | 6 | m_config = source; |
| 52 : | afrisby | 5 | |
| 53 : | afrisby | 6 | m_scenes.Add(scene); |
| 54 : | afrisby | 10 | |
| 55 : | scene.EventManager.OnClientConnect += EventManager_OnClientConnect; | ||
| 56 : | afrisby | 3 | } |
| 57 : | |||
| 58 : | afrisby | 10 | /// <summary> |
| 59 : | /// Used to transmit in the Account Name to the new RexClientView | ||
| 60 : | /// Would like to pipe it via the RexClientView constructor, | ||
| 61 : | /// but doing so would require a stactic dictionary of expected | ||
| 62 : | /// values. | ||
| 63 : | /// </summary> | ||
| 64 : | void EventManager_OnClientConnect(OpenSim.Framework.Client.IClientCore client) | ||
| 65 : | { | ||
| 66 : | RexClientView rex; | ||
| 67 : | if(client.TryGet(out rex)) | ||
| 68 : | { | ||
| 69 : | afrisby | 25 | rex.RexAccount = m_authUrl[rex.AgentId]; |
| 70 : | afrisby | 10 | } |
| 71 : | } | ||
| 72 : | afrisby | 6 | |
| 73 : | afrisby | 10 | |
| 74 : | afrisby | 6 | public void PostInitialise() |
| 75 : | afrisby | 5 | { |
| 76 : | mikkopa | 42 | if (m_config.Configs["realXtend"].GetBoolean("enabled", true)) |
| 77 : | { | ||
| 78 : | mikkopa | 73 | //Load OpenSim Library folder config |
| 79 : | string LibrariesXMLFile = m_config.Configs["StandAlone"].GetString("LibrariesXMLFile"); | ||
| 80 : | m_libraryRootFolder = new LibraryRootFolder(LibrariesXMLFile); | ||
| 81 : | afrisby | 5 | |
| 82 : | mikkopa | 42 | m_log.Info("[REX] Overloading Login_to_Simulator"); |
| 83 : | mikkopa | 68 | default_login_to_simulator = m_scenes[0].CommsManager.HttpServer.GetXmlRPCHandler("login_to_simulator"); |
| 84 : | mikkopa | 42 | m_scenes[0].CommsManager.HttpServer.AddXmlRPCHandler("login_to_simulator", XmlRpcLoginMethod); |
| 85 : | afrisby | 5 | |
| 86 : | mikkopa | 42 | m_primaryRegionInfo = m_scenes[0].RegionInfo; |
| 87 : | |||
| 88 : | m_log.Info("[REX] Initialising"); | ||
| 89 : | mikkopa | 68 | //m_udpserver.Initialise(m_primaryRegionInfo.InternalEndPoint.Address, ref m_rexPort, 0, false, m_config, m_scenes[0].AssetCache, |
| 90 : | // m_scenes[0].AuthenticateHandler); | ||
| 91 : | mikkopa | 42 | foreach (Scene scene in m_scenes) |
| 92 : | { | ||
| 93 : | mikkopa | 68 | RexUDPServer udpserver = new RexUDPServer(); |
| 94 : | m_log.Debug("[REX] RegionInfo: " + scene.RegionInfo.InternalEndPoint.Port); | ||
| 95 : | uint udp_port = Convert.ToUInt32(scene.RegionInfo.InternalEndPoint.Port - 2000); | ||
| 96 : | //uses 2000 smaller port num than spesified for LLClient in Regions/ xml-file | ||
| 97 : | udpserver.Initialise(scene.RegionInfo.InternalEndPoint.Address, ref udp_port, 0, false, m_config, | ||
| 98 : | mikkopa | 72 | scene.CommsManager.AssetCache, scene.AuthenticateHandler); |
| 99 : | mikkopa | 68 | udpserver.AddScene(scene); |
| 100 : | //m_udpserver.AddScene(scene); //this doesn't add scene to existing UDP server, but instead replaces the old one | ||
| 101 : | m_udpservers.Add(udpserver); | ||
| 102 : | udpserver.Start(); | ||
| 103 : | mikkopa | 42 | } |
| 104 : | mikkopa | 68 | //m_udpserver.Start(); |
| 105 : | mikkopa | 42 | } |
| 106 : | else | ||
| 107 : | afrisby | 6 | { |
| 108 : | mikkopa | 42 | m_log.Info("[REX] Not overloading Login_to_Simulator and not starting UDP server"); |
| 109 : | afrisby | 6 | } |
| 110 : | afrisby | 3 | } |
| 111 : | |||
| 112 : | public void Close() | ||
| 113 : | { | ||
| 114 : | |||
| 115 : | } | ||
| 116 : | |||
| 117 : | public string Name | ||
| 118 : | { | ||
| 119 : | get { return "RexLoginOverrider"; } | ||
| 120 : | } | ||
| 121 : | |||
| 122 : | public bool IsSharedModule | ||
| 123 : | { | ||
| 124 : | get { return true; } | ||
| 125 : | } | ||
| 126 : | afrisby | 6 | |
| 127 : | #region RexLoginHelper | ||
| 128 : | |||
| 129 : | public bool AuthenticateUser(string accountName, string sessionHash) | ||
| 130 : | { | ||
| 131 : | return true; | ||
| 132 : | } | ||
| 133 : | |||
| 134 : | mikkopa | 39 | private static LoginService.InventoryData GetInventorySkeleton(Scene any, UUID userID) |
| 135 : | { | ||
| 136 : | List<InventoryFolderBase> folders = any.CommsManager.InterServiceInventoryService.GetInventorySkeleton(userID); | ||
| 137 : | |||
| 138 : | // If we have user auth but no inventory folders for some reason, create a new set of folders. | ||
| 139 : | if (null == folders || 0 == folders.Count) | ||
| 140 : | { | ||
| 141 : | any.CommsManager.InterServiceInventoryService.CreateNewUserInventory(userID); | ||
| 142 : | folders = any.CommsManager.InterServiceInventoryService.GetInventorySkeleton(userID); | ||
| 143 : | } | ||
| 144 : | |||
| 145 : | UUID rootID = UUID.Zero; | ||
| 146 : | ArrayList AgentInventoryArray = new ArrayList(); | ||
| 147 : | foreach (InventoryFolderBase InvFolder in folders) | ||
| 148 : | { | ||
| 149 : | if (InvFolder.ParentID == UUID.Zero) | ||
| 150 : | { | ||
| 151 : | rootID = InvFolder.ID; | ||
| 152 : | } | ||
| 153 : | Hashtable TempHash = new Hashtable(); | ||
| 154 : | TempHash["name"] = InvFolder.Name; | ||
| 155 : | TempHash["parent_id"] = InvFolder.ParentID.ToString(); | ||
| 156 : | TempHash["version"] = (Int32)InvFolder.Version; | ||
| 157 : | TempHash["type_default"] = (Int32)InvFolder.Type; | ||
| 158 : | TempHash["folder_id"] = InvFolder.ID.ToString(); | ||
| 159 : | AgentInventoryArray.Add(TempHash); | ||
| 160 : | } | ||
| 161 : | |||
| 162 : | return new LoginService.InventoryData(AgentInventoryArray, rootID); | ||
| 163 : | } | ||
| 164 : | |||
| 165 : | private static ArrayList GetLibraryOwner() | ||
| 166 : | { | ||
| 167 : | //for now create random inventory library owner | ||
| 168 : | Hashtable TempHash = new Hashtable(); | ||
| 169 : | TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000"; | ||
| 170 : | ArrayList inventoryLibOwner = new ArrayList(); | ||
| 171 : | inventoryLibOwner.Add(TempHash); | ||
| 172 : | return inventoryLibOwner; | ||
| 173 : | } | ||
| 174 : | |||
| 175 : | // TEMP // TEMP // | ||
| 176 : | |||
| 177 : | public class RexAccountProperties | ||
| 178 : | { | ||
| 179 : | public string FirstName; | ||
| 180 : | public string LastName; | ||
| 181 : | public string AsAddress; | ||
| 182 : | public UUID uuid; | ||
| 183 : | public string Account; | ||
| 184 : | } | ||
| 185 : | |||
| 186 : | public RexAccountProperties GetRexProperties(string RexAccount, string RexAuthURL) | ||
| 187 : | { | ||
| 188 : | m_log.Info("[REXCLIENT] Resolving avatar..."); | ||
| 189 : | Hashtable ReqVals = new Hashtable(); | ||
| 190 : | ReqVals["avatar_account"] = RexAccount; | ||
| 191 : | ReqVals["AuthenticationAddress"] = RexAuthURL; | ||
| 192 : | |||
| 193 : | ArrayList SendParams = new ArrayList(); | ||
| 194 : | SendParams.Add(ReqVals); | ||
| 195 : | |||
| 196 : | XmlRpcRequest req = new XmlRpcRequest("get_user_by_account", SendParams); | ||
| 197 : | |||
| 198 : | m_log.Info("[REXCLIENT] Sending XMLRPC Request to http://" + RexAuthURL); | ||
| 199 : | |||
| 200 : | XmlRpcResponse authreply = req.Send("http://" + RexAuthURL, 9000); | ||
| 201 : | |||
| 202 : | //m_log.Info(authreply.ToString()); | ||
| 203 : | |||
| 204 : | string rexAsAddress = ((Hashtable) authreply.Value)["as_address"].ToString(); | ||
| 205 : | /* string rexSkypeURL = ((Hashtable)authreply.Value)["skype_url"].ToString(); */ | ||
| 206 : | UUID userID = new UUID(((Hashtable) authreply.Value)["uuid"].ToString()); | ||
| 207 : | |||
| 208 : | RexAccountProperties rtn = new RexAccountProperties(); | ||
| 209 : | |||
| 210 : | rtn.FirstName = ((Hashtable)authreply.Value)["firstname"].ToString(); | ||
| 211 : | rtn.LastName = ((Hashtable)authreply.Value)["lastname"].ToString(); | ||
| 212 : | rtn.AsAddress = ((Hashtable)authreply.Value)["as_address"].ToString(); | ||
| 213 : | rtn.uuid = userID; | ||
| 214 : | rtn.Account = RexAccount; | ||
| 215 : | |||
| 216 : | return rtn; | ||
| 217 : | } | ||
| 218 : | |||
| 219 : | // TEMP // TEMP // | ||
| 220 : | |||
| 221 : | afrisby | 6 | public virtual XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) |
| 222 : | { | ||
| 223 : | //CFK: CustomizeResponse contains sufficient strings to alleviate the need for this. | ||
| 224 : | //CKF: m_log.Info("[LOGIN]: Attempting login now..."); | ||
| 225 : | XmlRpcResponse response = new XmlRpcResponse(); | ||
| 226 : | Hashtable requestData = (Hashtable)request.Params[0]; | ||
| 227 : | |||
| 228 : | bool GoodXML = (requestData.Contains("account") && requestData.Contains("sessionhash")); | ||
| 229 : | bool GoodLogin; | ||
| 230 : | |||
| 231 : | string startLocationRequest = "last"; | ||
| 232 : | |||
| 233 : | LoginResponse logResponse = new LoginResponse(); | ||
| 234 : | |||
| 235 : | string account; | ||
| 236 : | string sessionHash; | ||
| 237 : | |||
| 238 : | if (GoodXML) | ||
| 239 : | { | ||
| 240 : | account = (string)requestData["account"]; | ||
| 241 : | sessionHash = (string)requestData["sessionhash"]; | ||
| 242 : | |||
| 243 : | m_log.InfoFormat( | ||
| 244 : | "[REX LOGIN BEGIN]: XMLRPC Received login request message from user '{0}' '{1}'", | ||
| 245 : | account, sessionHash); | ||
| 246 : | |||
| 247 : | string clientVersion = "Unknown"; | ||
| 248 : | |||
| 249 : | if (requestData.Contains("version")) | ||
| 250 : | { | ||
| 251 : | clientVersion = (string)requestData["version"]; | ||
| 252 : | } | ||
| 253 : | |||
| 254 : | if (requestData.Contains("start")) | ||
| 255 : | { | ||
| 256 : | startLocationRequest = (string)requestData["start"]; | ||
| 257 : | } | ||
| 258 : | |||
| 259 : | m_log.DebugFormat( | ||
| 260 : | "[REXLOGIN]: XMLRPC Client is {0}, start location is {1}", clientVersion, startLocationRequest); | ||
| 261 : | |||
| 262 : | GoodLogin = AuthenticateUser(account, sessionHash); | ||
| 263 : | } | ||
| 264 : | else | ||
| 265 : | { | ||
| 266 : | mikkopa | 68 | if (default_login_to_simulator != null) |
| 267 : | { | ||
| 268 : | m_log.Info( | ||
| 269 : | "[REXLOGIN END]: XMLRPC login_to_simulator login message did not contain all the required data. Trying default method."); | ||
| 270 : | return default_login_to_simulator(request); | ||
| 271 : | } | ||
| 272 : | else | ||
| 273 : | { | ||
| 274 : | m_log.Info( | ||
| 275 : | "[REXLOGIN END]: XMLRPC login_to_simulator login message did not contain all the required data."); | ||
| 276 : | return logResponse.CreateGridErrorResponse(); | ||
| 277 : | } | ||
| 278 : | afrisby | 6 | } |
| 279 : | |||
| 280 : | if (!GoodLogin) | ||
| 281 : | { | ||
| 282 : | m_log.InfoFormat("[LOGIN END]: XMLRPC User {0} ({1}) failed authentication", account, sessionHash); | ||
| 283 : | |||
| 284 : | return logResponse.CreateLoginFailedResponse(); | ||
| 285 : | } | ||
| 286 : | try | ||
| 287 : | { | ||
| 288 : | mikkopa | 39 | string actName = account.Split('@')[0]; |
| 289 : | string actSrv = account.Split('@')[1]; | ||
| 290 : | afrisby | 6 | |
| 291 : | mikkopa | 39 | RexAccountProperties rap = GetRexProperties(actName, actSrv); |
| 292 : | afrisby | 6 | |
| 293 : | mikkopa | 39 | UUID agentID = rap.uuid; |
| 294 : | afrisby | 6 | |
| 295 : | afrisby | 10 | // Used to transmit the login URL to the |
| 296 : | // RexAvatar class when it connects. | ||
| 297 : | m_authUrl[agentID] = account; | ||
| 298 : | |||
| 299 : | afrisby | 6 | logResponse.CircuitCode = Util.RandomClass.Next(); |
| 300 : | |||
| 301 : | mikkopa | 39 | logResponse.Lastname = "<" + account + ">"; |
| 302 : | logResponse.Firstname = rap.FirstName + " " + rap.LastName; | ||
| 303 : | afrisby | 6 | |
| 304 : | mikkopa | 39 | logResponse.AgentID = agentID; |
| 305 : | afrisby | 6 | |
| 306 : | mikkopa | 39 | // NOT SECURE |
| 307 : | afrisby | 6 | logResponse.SessionID = GetSessionID(account); |
| 308 : | logResponse.SecureSessionID = GetSecureID(account); | ||
| 309 : | mikkopa | 39 | |
| 310 : | afrisby | 6 | logResponse.Message = "Welcome to ModularRex"; |
| 311 : | |||
| 312 : | logResponse.SimAddress = m_primaryRegionInfo.ExternalEndPoint.Address.ToString(); | ||
| 313 : | logResponse.SimPort = m_rexPort; | ||
| 314 : | logResponse.RegionX = m_primaryRegionInfo.RegionLocX; | ||
| 315 : | logResponse.RegionY = m_primaryRegionInfo.RegionLocY; | ||
| 316 : | |||
| 317 : | |||
| 318 : | logResponse.StartLocation = startLocationRequest; | ||
| 319 : | |||
| 320 : | mikkopa | 39 | string capsPath = OpenSim.Framework.Communications.Capabilities.CapsUtil.GetRandomCapsObjectPath(); |
| 321 : | //string seedcap = "http://" + m_scenes[0].RegionInfo.ExternalEndPoint.Address + ":" + | ||
| 322 : | // "9000" + "/CAPS/" + capsPath + "0000/"; | ||
| 323 : | string seedcap = capsPath;// + "0000/"; | ||
| 324 : | afrisby | 6 | |
| 325 : | logResponse.SeedCapability = seedcap; | ||
| 326 : | |||
| 327 : | mikkopa | 39 | m_scenes[0].CommsManager.UserAdminService.AddUser(logResponse.Firstname, logResponse.Lastname, "", |
| 328 : | account, 1000, 1000, agentID); | ||
| 329 : | m_scenes[0].CommsManager.InterServiceInventoryService.CreateNewUserInventory(agentID); | ||
| 330 : | |||
| 331 : | LoginService.InventoryData inventData = GetInventorySkeleton(m_scenes[0], agentID); | ||
| 332 : | |||
| 333 : | ArrayList AgentInventoryArray = inventData.InventoryArray; | ||
| 334 : | |||
| 335 : | Hashtable InventoryRootHash = new Hashtable(); | ||
| 336 : | InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString(); | ||
| 337 : | ArrayList InventoryRoot = new ArrayList(); | ||
| 338 : | InventoryRoot.Add(InventoryRootHash); | ||
| 339 : | //userProfile.RootInventoryFolderID = inventData.RootFolderID; | ||
| 340 : | |||
| 341 : | // Inventory Library Section | ||
| 342 : | Hashtable InventoryLibRootHash = new Hashtable(); | ||
| 343 : | InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; | ||
| 344 : | ArrayList InventoryLibRoot = new ArrayList(); | ||
| 345 : | InventoryLibRoot.Add(InventoryLibRootHash); | ||
| 346 : | |||
| 347 : | logResponse.InventoryLibRoot = InventoryLibRoot; | ||
| 348 : | logResponse.InventoryLibraryOwner = GetLibraryOwner(); | ||
| 349 : | logResponse.InventoryRoot = InventoryRoot; | ||
| 350 : | logResponse.InventorySkeleton = AgentInventoryArray; | ||
| 351 : | mikkopa | 73 | logResponse.InventoryLibrary = GetInventoryLibrary(); |
| 352 : | mikkopa | 39 | |
| 353 : | afrisby | 6 | foreach (Scene scene in m_scenes) |
| 354 : | { | ||
| 355 : | AgentCircuitData acd = new AgentCircuitData(); | ||
| 356 : | |||
| 357 : | acd.AgentID = agentID; | ||
| 358 : | acd.BaseFolder = UUID.Zero; | ||
| 359 : | acd.CapsPath = seedcap; | ||
| 360 : | |||
| 361 : | // Will login to the first region | ||
| 362 : | acd.child = scene == m_scenes[0]; | ||
| 363 : | |||
| 364 : | acd.circuitcode = (uint)logResponse.CircuitCode; | ||
| 365 : | acd.firstname = logResponse.Firstname; | ||
| 366 : | acd.InventoryFolder = UUID.Zero; | ||
| 367 : | acd.lastname = logResponse.Lastname; | ||
| 368 : | acd.SecureSessionID = logResponse.SecureSessionID; | ||
| 369 : | acd.SessionID = logResponse.SessionID; | ||
| 370 : | acd.startpos = new Vector3(128, 128, 128); | ||
| 371 : | |||
| 372 : | scene.NewUserConnection(acd); | ||
| 373 : | } | ||
| 374 : | |||
| 375 : | |||
| 376 : | |||
| 377 : | XmlRpcResponse rep = logResponse.ToXmlRpcResponse(); | ||
| 378 : | |||
| 379 : | Hashtable val = (Hashtable) rep.Value; | ||
| 380 : | val["rex"] = "running rex mode"; | ||
| 381 : | |||
| 382 : | mikkopa | 34 | //m_log.Debug(rep.ToString()); |
| 383 : | afrisby | 6 | |
| 384 : | return rep; | ||
| 385 : | } | ||
| 386 : | catch (Exception e) | ||
| 387 : | { | ||
| 388 : | m_log.Info("[REXLOGIN END]: XMLRPC Login failed, " + e); | ||
| 389 : | } | ||
| 390 : | |||
| 391 : | m_log.Info("[REXLOGIN END]: XMLRPC Login failed. Sending back blank XMLRPC response"); | ||
| 392 : | return response; | ||
| 393 : | } | ||
| 394 : | |||
| 395 : | private static UUID GetAgentID(string account) | ||
| 396 : | { | ||
| 397 : | UUID agentID = new UUID(Util.Md5Hash(account)); | ||
| 398 : | return agentID; | ||
| 399 : | } | ||
| 400 : | |||
| 401 : | private static UUID GetSessionID(string account) | ||
| 402 : | { | ||
| 403 : | UUID agentID = new UUID(Util.Md5Hash(account + "session")); | ||
| 404 : | return agentID; | ||
| 405 : | } | ||
| 406 : | |||
| 407 : | /// <summary> | ||
| 408 : | /// Not really secure. | ||
| 409 : | /// </summary> | ||
| 410 : | private static UUID GetSecureID(string account) | ||
| 411 : | { | ||
| 412 : | UUID agentID = new UUID(Util.Md5Hash(account + "secure")); | ||
| 413 : | return agentID; | ||
| 414 : | } | ||
| 415 : | |||
| 416 : | mikkopa | 73 | /// <summary> |
| 417 : | /// Converts the inventory library skeleton into the form required by the rpc request. | ||
| 418 : | /// </summary> | ||
| 419 : | /// <returns></returns> | ||
| 420 : | protected virtual ArrayList GetInventoryLibrary() | ||
| 421 : | { | ||
| 422 : | Dictionary<UUID, InventoryFolderImpl> rootFolders | ||
| 423 : | = m_libraryRootFolder.RequestSelfAndDescendentFolders(); | ||
| 424 : | ArrayList folderHashes = new ArrayList(); | ||
| 425 : | |||
| 426 : | foreach (InventoryFolderBase folder in rootFolders.Values) | ||
| 427 : | { | ||
| 428 : | Hashtable TempHash = new Hashtable(); | ||
| 429 : | TempHash["name"] = folder.Name; | ||
| 430 : | TempHash["parent_id"] = folder.ParentID.ToString(); | ||
| 431 : | TempHash["version"] = (Int32)folder.Version; | ||
| 432 : | TempHash["type_default"] = (Int32)folder.Type; | ||
| 433 : | TempHash["folder_id"] = folder.ID.ToString(); | ||
| 434 : | folderHashes.Add(TempHash); | ||
| 435 : | } | ||
| 436 : | |||
| 437 : | return folderHashes; | ||
| 438 : | } | ||
| 439 : | |||
| 440 : | afrisby | 6 | #endregion |
| 441 : | |||
| 442 : | afrisby | 3 | } |
| 443 : | afrisby | 6 | } |
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

