aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.RegionServer/world
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim.RegionServer/world')
-rw-r--r--OpenSim.RegionServer/world/Primitive.cs103
-rw-r--r--OpenSim.RegionServer/world/World.cs122
2 files changed, 193 insertions, 32 deletions
diff --git a/OpenSim.RegionServer/world/Primitive.cs b/OpenSim.RegionServer/world/Primitive.cs
index 2f97053..2c55004 100644
--- a/OpenSim.RegionServer/world/Primitive.cs
+++ b/OpenSim.RegionServer/world/Primitive.cs
@@ -27,6 +27,7 @@ namespace OpenSim.world
27 private Dictionary<uint, SimClient> m_clientThreads; 27 private Dictionary<uint, SimClient> m_clientThreads;
28 private ulong m_regionHandle; 28 private ulong m_regionHandle;
29 private World m_world; 29 private World m_world;
30 private const uint FULL_MASK_PERMISSIONS = 2147483647;
30 31
31 public bool PhysicsEnabled 32 public bool PhysicsEnabled
32 { 33 {
@@ -94,6 +95,40 @@ namespace OpenSim.world
94 return mesh; 95 return mesh;
95 } 96 }
96 97
98 public byte[] GetByteArray()
99 {
100 return this.primData.ToBytes();
101 }
102
103 public void GetProperites(SimClient client)
104 {
105 ObjectPropertiesPacket proper = new ObjectPropertiesPacket();
106 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1];
107 proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock();
108 proper.ObjectData[0].ItemID = LLUUID.Zero; // this.uuid;
109 proper.ObjectData[0].CreationDate = (ulong) this.primData.CreationDate;
110 proper.ObjectData[0].CreatorID = this.primData.OwnerID;
111 proper.ObjectData[0].FolderID = LLUUID.Zero;
112 proper.ObjectData[0].FromTaskID = LLUUID.Zero;
113 proper.ObjectData[0].GroupID = LLUUID.Zero;
114 proper.ObjectData[0].InventorySerial = 0;
115 proper.ObjectData[0].LastOwnerID = LLUUID.Zero;
116 proper.ObjectData[0].ObjectID = this.uuid;
117 proper.ObjectData[0].OwnerID = primData.OwnerID;
118 proper.ObjectData[0].TouchName = new byte[0];
119 proper.ObjectData[0].TextureID = new byte[0];
120 proper.ObjectData[0].SitName = new byte[0];
121 proper.ObjectData[0].Name = new byte[0];
122 proper.ObjectData[0].Description = new byte[0];
123 proper.ObjectData[0].OwnerMask = this.primData.OwnerMask;
124 proper.ObjectData[0].NextOwnerMask = this.primData.NextOwnerMask;
125 proper.ObjectData[0].GroupMask = this.primData.GroupMask;
126 proper.ObjectData[0].EveryoneMask = this.primData.EveryoneMask;
127 proper.ObjectData[0].BaseMask = this.primData.BaseMask;
128
129 client.OutPacket(proper);
130 }
131
97 public void UpdatePosition(LLVector3 pos) 132 public void UpdatePosition(LLVector3 pos)
98 { 133 {
99 this.position = pos; 134 this.position = pos;
@@ -125,9 +160,45 @@ namespace OpenSim.world
125 } 160 }
126 if (this.newPrimFlag) 161 if (this.newPrimFlag)
127 { 162 {
163 /* ObjectOwnerPacket objown = new ObjectOwnerPacket();
164 objown.HeaderData.GroupID = LLUUID.Zero;
165 objown.HeaderData.Override = false;
166 objown.HeaderData.OwnerID = LLUUID.Zero;
167 objown.ObjectData = new ObjectOwnerPacket.ObjectDataBlock[1];
168 objown.ObjectData[0] = new ObjectOwnerPacket.ObjectDataBlock();
169 objown.ObjectData[0].ObjectLocalID = this.localid;
170 ObjectGroupPacket objgroup = new ObjectGroupPacket();
171 objgroup.ObjectData = new ObjectGroupPacket.ObjectDataBlock[1];
172 objgroup.ObjectData[0] = new ObjectGroupPacket.ObjectDataBlock();
173 objgroup.ObjectData[0].ObjectLocalID = this.localid;
174 ObjectPermissionsPacket objper = new ObjectPermissionsPacket();
175 objper.HeaderData.Override = false;
176 objper.ObjectData = new ObjectPermissionsPacket.ObjectDataBlock[3];
177 for (int i = 0; i < 3; i++)
178 {
179 objper.ObjectData[i] = new ObjectPermissionsPacket.ObjectDataBlock();
180 objper.ObjectData[i].ObjectLocalID = this.localid;
181 objper.ObjectData[i].Set = 1;
182 objper.ObjectData[i].Field = 0;
183 }
184 objper.ObjectData[0].Mask = 8192;
185 objper.ObjectData[1].Mask = 16384;
186 objper.ObjectData[2].Mask = 32768;*/
187
128 foreach (SimClient client in m_clientThreads.Values) 188 foreach (SimClient client in m_clientThreads.Values)
129 { 189 {
130 client.OutPacket(OurPacket); 190 client.OutPacket(OurPacket);
191 /* objown.AgentData.AgentID = client.AgentID;
192 objown.AgentData.SessionID = client.SessionID;
193 objown.HeaderData.OwnerID = client.AgentID;
194 client.OutPacket(objown);
195 objgroup.AgentData.AgentID = client.AgentID;
196 objgroup.AgentData.GroupID = LLUUID.Zero;
197 objgroup.AgentData.SessionID = client.SessionID;
198 client.OutPacket(objgroup);
199 objper.AgentData.AgentID = client.AgentID;
200 objper.AgentData.SessionID = client.SessionID;
201 client.OutPacket(objper);*/
131 } 202 }
132 this.newPrimFlag = false; 203 this.newPrimFlag = false;
133 } 204 }
@@ -286,18 +357,18 @@ namespace OpenSim.world
286 { 357 {
287 ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); 358 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
288 objupdate.RegionData.RegionHandle = m_regionHandle; 359 objupdate.RegionData.RegionHandle = m_regionHandle;
289 objupdate.RegionData.TimeDilation = 64096; 360 objupdate.RegionData.TimeDilation = 64096;
290 361
291 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; 362 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
292 PrimData PData = new PrimData(); 363 PrimData PData = new PrimData();
293 this.primData = PData; 364 this.primData = PData;
365 this.primData.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
366
294 objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock(); 367 objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
295 objupdate.ObjectData[0].PSBlock = new byte[0]; 368 objupdate.ObjectData[0].PSBlock = new byte[0];
296 objupdate.ObjectData[0].ExtraParams = new byte[1]; 369 objupdate.ObjectData[0].ExtraParams = new byte[1];
297 objupdate.ObjectData[0].MediaURL = new byte[0]; 370 objupdate.ObjectData[0].MediaURL = new byte[0];
298 objupdate.ObjectData[0].NameValue = new byte[2]; 371 objupdate.ObjectData[0].NameValue = new byte[0];
299 objupdate.ObjectData[0].NameValue[0] = (byte)'t';
300 objupdate.ObjectData[0].NameValue[1] = (byte)'o';
301 objupdate.ObjectData[0].Text = new byte[0]; 372 objupdate.ObjectData[0].Text = new byte[0];
302 objupdate.ObjectData[0].TextColor = new byte[4]; 373 objupdate.ObjectData[0].TextColor = new byte[4];
303 objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0); 374 objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
@@ -307,7 +378,7 @@ namespace OpenSim.world
307 objupdate.ObjectData[0].TextureAnim = new byte[0]; 378 objupdate.ObjectData[0].TextureAnim = new byte[0];
308 objupdate.ObjectData[0].Sound = LLUUID.Zero; 379 objupdate.ObjectData[0].Sound = LLUUID.Zero;
309 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); 380 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
310 objupdate.ObjectData[0].TextureEntry = ntex.ToBytes(); 381 this.primData.Texture = objupdate.ObjectData[0].TextureEntry = ntex.ToBytes();
311 objupdate.ObjectData[0].State = 0; 382 objupdate.ObjectData[0].State = 0;
312 objupdate.ObjectData[0].Data = new byte[0]; 383 objupdate.ObjectData[0].Data = new byte[0];
313 PData.OwnerID = objupdate.ObjectData[0].OwnerID = agentID; 384 PData.OwnerID = objupdate.ObjectData[0].OwnerID = agentID;
@@ -326,14 +397,12 @@ namespace OpenSim.world
326 PData.ProfileCurve = objupdate.ObjectData[0].ProfileCurve = addPacket.ObjectData.ProfileCurve; 397 PData.ProfileCurve = objupdate.ObjectData[0].ProfileCurve = addPacket.ObjectData.ProfileCurve;
327 PData.ParentID = objupdate.ObjectData[0].ParentID = 0; 398 PData.ParentID = objupdate.ObjectData[0].ParentID = 0;
328 PData.ProfileHollow = objupdate.ObjectData[0].ProfileHollow = addPacket.ObjectData.ProfileHollow; 399 PData.ProfileHollow = objupdate.ObjectData[0].ProfileHollow = addPacket.ObjectData.ProfileHollow;
329
330 PData.PathRadiusOffset = objupdate.ObjectData[0].PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset; 400 PData.PathRadiusOffset = objupdate.ObjectData[0].PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
331 PData.PathRevolutions = objupdate.ObjectData[0].PathRevolutions = addPacket.ObjectData.PathRevolutions; 401 PData.PathRevolutions = objupdate.ObjectData[0].PathRevolutions = addPacket.ObjectData.PathRevolutions;
332 PData.PathTaperX = objupdate.ObjectData[0].PathTaperX = addPacket.ObjectData.PathTaperX; 402 PData.PathTaperX = objupdate.ObjectData[0].PathTaperX = addPacket.ObjectData.PathTaperX;
333 PData.PathTaperY = objupdate.ObjectData[0].PathTaperY = addPacket.ObjectData.PathTaperY; 403 PData.PathTaperY = objupdate.ObjectData[0].PathTaperY = addPacket.ObjectData.PathTaperY;
334 PData.PathTwist = objupdate.ObjectData[0].PathTwist = addPacket.ObjectData.PathTwist; 404 PData.PathTwist = objupdate.ObjectData[0].PathTwist = addPacket.ObjectData.PathTwist;
335 PData.PathTwistBegin = objupdate.ObjectData[0].PathTwistBegin = addPacket.ObjectData.PathTwistBegin; 405 PData.PathTwistBegin = objupdate.ObjectData[0].PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
336
337 objupdate.ObjectData[0].ID = (uint)(localID); 406 objupdate.ObjectData[0].ID = (uint)(localID);
338 objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efef" + (localID - 702000).ToString("00000")); 407 objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efef" + (localID - 702000).ToString("00000"));
339 objupdate.ObjectData[0].ObjectData = new byte[60]; 408 objupdate.ObjectData[0].ObjectData = new byte[60];
@@ -343,16 +412,20 @@ namespace OpenSim.world
343 //update position 412 //update position
344 byte[] pb = pos1.GetBytes(); 413 byte[] pb = pos1.GetBytes();
345 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length); 414 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length);
346
347 this.newPrimFlag = true; 415 this.newPrimFlag = true;
348 this.uuid = objupdate.ObjectData[0].FullID; 416 this.primData.FullID = this.uuid = objupdate.ObjectData[0].FullID;
349 this.localid = objupdate.ObjectData[0].ID; 417 this.localid = objupdate.ObjectData[0].ID;
350 this.position = pos1; 418 this.primData.Position = this.position = pos1;
351 this.OurPacket = objupdate; 419 this.OurPacket = objupdate;
352 } 420 }
353 421
354 public void CreateFromStorage(PrimData store) 422 public void CreateFromStorage(PrimData store)
355 { 423 {
424 this.CreateFromStorage(store, store.Position, store.LocalID, false);
425 }
426
427 public void CreateFromStorage(PrimData store, LLVector3 posi, uint localID, bool newprim)
428 {
356 //need to clean this up as it shares a lot of code with CreateFromPacket() 429 //need to clean this up as it shares a lot of code with CreateFromPacket()
357 ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); 430 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
358 objupdate.RegionData.RegionHandle = m_regionHandle; 431 objupdate.RegionData.RegionHandle = m_regionHandle;
@@ -410,13 +483,13 @@ namespace OpenSim.world
410 objupdate.ObjectData[0].PathTwist = this.primData.PathTwist; 483 objupdate.ObjectData[0].PathTwist = this.primData.PathTwist;
411 objupdate.ObjectData[0].PathTwistBegin = this.primData.PathTwistBegin; 484 objupdate.ObjectData[0].PathTwistBegin = this.primData.PathTwistBegin;
412 485
413 objupdate.ObjectData[0].ID = (uint)store.LocalID; 486 objupdate.ObjectData[0].ID = localID; // (uint)store.LocalID;
414 objupdate.ObjectData[0].FullID = store.FullID; 487 objupdate.ObjectData[0].FullID = store.FullID;
415 488
416 objupdate.ObjectData[0].ObjectData = new byte[60]; 489 objupdate.ObjectData[0].ObjectData = new byte[60];
417 objupdate.ObjectData[0].ObjectData[46] = 128; 490 objupdate.ObjectData[0].ObjectData[46] = 128;
418 objupdate.ObjectData[0].ObjectData[47] = 63; 491 objupdate.ObjectData[0].ObjectData[47] = 63;
419 LLVector3 pos1 = store.Position; 492 LLVector3 pos1 = posi; // store.Position;
420 //update position 493 //update position
421 byte[] pb = pos1.GetBytes(); 494 byte[] pb = pos1.GetBytes();
422 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length); 495 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length);
@@ -425,8 +498,12 @@ namespace OpenSim.world
425 this.localid = objupdate.ObjectData[0].ID; 498 this.localid = objupdate.ObjectData[0].ID;
426 this.position = pos1; 499 this.position = pos1;
427 this.OurPacket = objupdate; 500 this.OurPacket = objupdate;
428 501 if (newprim)
502 {
503 this.newPrimFlag = true;
504 }
429 } 505 }
506
430 public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedBlock() 507 public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedBlock()
431 { 508 {
432 uint ID = this.localid; 509 uint ID = this.localid;
diff --git a/OpenSim.RegionServer/world/World.cs b/OpenSim.RegionServer/world/World.cs
index 446d37c..82e8b8d 100644
--- a/OpenSim.RegionServer/world/World.cs
+++ b/OpenSim.RegionServer/world/World.cs
@@ -9,6 +9,8 @@ using OpenSim.Physics.Manager;
9using OpenSim.Framework.Interfaces; 9using OpenSim.Framework.Interfaces;
10using OpenSim.Framework.Assets; 10using OpenSim.Framework.Assets;
11using OpenSim.Framework.Terrain; 11using OpenSim.Framework.Terrain;
12using OpenSim.Framework.Inventory;
13using OpenSim.Assets;
12 14
13namespace OpenSim.world 15namespace OpenSim.world
14{ 16{
@@ -30,6 +32,8 @@ namespace OpenSim.world
30 private ulong m_regionHandle; 32 private ulong m_regionHandle;
31 private string m_regionName; 33 private string m_regionName;
32 private SimConfig m_cfg; 34 private SimConfig m_cfg;
35 private InventoryCache _inventoryCache;
36 private AssetCache _assetCache;
33 37
34 public World(Dictionary<uint, SimClient> clientThreads, ulong regionHandle, string regionName, SimConfig cfg) 38 public World(Dictionary<uint, SimClient> clientThreads, ulong regionHandle, string regionName, SimConfig cfg)
35 { 39 {
@@ -50,6 +54,21 @@ namespace OpenSim.world
50 Avatar.LoadAnims(); 54 Avatar.LoadAnims();
51 } 55 }
52 56
57 public InventoryCache InventoryCache
58 {
59 set
60 {
61 this._inventoryCache = value;
62 }
63 }
64
65 public AssetCache AssetCache
66 {
67 set
68 {
69 this._assetCache = value;
70 }
71 }
53 public PhysicsScene PhysScene 72 public PhysicsScene PhysScene
54 { 73 {
55 set 74 set
@@ -291,44 +310,109 @@ namespace OpenSim.world
291 310
292 public void DeRezObject(DeRezObjectPacket DeRezPacket, SimClient AgentClient) 311 public void DeRezObject(DeRezObjectPacket DeRezPacket, SimClient AgentClient)
293 { 312 {
313 // Console.WriteLine(DeRezPacket);
294 //Needs to delete object from physics at a later date 314 //Needs to delete object from physics at a later date
315 if (DeRezPacket.AgentBlock.DestinationID == LLUUID.Zero)
316 {
317 libsecondlife.LLUUID[] DeRezEnts;
318 DeRezEnts = new libsecondlife.LLUUID[DeRezPacket.ObjectData.Length];
319 int i = 0;
320 foreach (DeRezObjectPacket.ObjectDataBlock Data in DeRezPacket.ObjectData)
321 {
295 322
296 libsecondlife.LLUUID[] DeRezEnts; 323 //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LocalID:" + Data.ObjectLocalID.ToString());
297 DeRezEnts = new libsecondlife.LLUUID[DeRezPacket.ObjectData.Length]; 324 foreach (Entity ent in this.Entities.Values)
298 int i = 0; 325 {
299 foreach (DeRezObjectPacket.ObjectDataBlock Data in DeRezPacket.ObjectData) 326 if (ent.localid == Data.ObjectLocalID)
327 {
328 DeRezEnts[i++] = ent.uuid;
329 this.localStorage.RemovePrim(ent.uuid);
330 KillObjectPacket kill = new KillObjectPacket();
331 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
332 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
333 kill.ObjectData[0].ID = ent.localid;
334 foreach (SimClient client in m_clientThreads.Values)
335 {
336 client.OutPacket(kill);
337 }
338 //Uncommenting this means an old UUID will be re-used, thus crashing the asset server
339 //Uncomment when prim/object UUIDs are random or such
340 //2007-03-22 - Randomskk
341 //this._primCount--;
342 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Deleted UUID " + ent.uuid);
343 }
344 }
345 }
346 foreach (libsecondlife.LLUUID uuid in DeRezEnts)
347 {
348 lock (Entities)
349 {
350 Entities.Remove(uuid);
351 }
352 }
353 }
354 else
300 { 355 {
301 //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LocalID:" + Data.ObjectLocalID.ToString()); 356 foreach (DeRezObjectPacket.ObjectDataBlock Data in DeRezPacket.ObjectData)
302 foreach (Entity ent in this.Entities.Values)
303 { 357 {
304 if (ent.localid == Data.ObjectLocalID) 358 Entity selectedEnt = null;
359 //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LocalID:" + Data.ObjectLocalID.ToString());
360 foreach (Entity ent in this.Entities.Values)
361 {
362 if (ent.localid == Data.ObjectLocalID)
363 {
364 AssetBase primAsset = new AssetBase();
365 primAsset.FullID = LLUUID.Random();//DeRezPacket.AgentBlock.TransactionID.Combine(LLUUID.Zero); //should be combining with securesessionid
366 primAsset.InvType = 6;
367 primAsset.Type = 6;
368 primAsset.Name = "Prim";
369 primAsset.Description = "";
370 primAsset.Data = ((Primitive)ent).GetByteArray();
371 this._assetCache.AddAsset(primAsset);
372 this._inventoryCache.AddNewInventoryItem(AgentClient, DeRezPacket.AgentBlock.DestinationID, primAsset);
373 selectedEnt = ent;
374 break;
375 }
376 }
377 if (selectedEnt != null)
305 { 378 {
306 DeRezEnts[i++] = ent.uuid; 379 this.localStorage.RemovePrim(selectedEnt.uuid);
307 this.localStorage.RemovePrim(ent.uuid);
308 KillObjectPacket kill = new KillObjectPacket(); 380 KillObjectPacket kill = new KillObjectPacket();
309 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 381 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
310 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 382 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
311 kill.ObjectData[0].ID = ent.localid; 383 kill.ObjectData[0].ID = selectedEnt.localid;
312 foreach (SimClient client in m_clientThreads.Values) 384 foreach (SimClient client in m_clientThreads.Values)
313 { 385 {
314 client.OutPacket(kill); 386 client.OutPacket(kill);
315 } 387 }
316 //Uncommenting this means an old UUID will be re-used, thus crashing the asset server 388 lock (Entities)
317 //Uncomment when prim/object UUIDs are random or such 389 {
318 //2007-03-22 - Randomskk 390 Entities.Remove(selectedEnt.uuid);
319 //this._primCount--; 391 }
320 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Deleted UUID " + ent.uuid);
321 } 392 }
322 } 393 }
323 } 394 }
324 foreach (libsecondlife.LLUUID uuid in DeRezEnts) 395 }
396
397 public void RezObject(SimClient remoteClient, RezObjectPacket packet)
398 {
399 AgentInventory inven =this._inventoryCache.GetAgentsInventory(remoteClient.AgentID);
400 if(inven != null)
325 { 401 {
326 lock (Entities) 402 if (inven.InventoryItems.ContainsKey(packet.InventoryData.ItemID))
327 { 403 {
328 Entities.Remove(uuid); 404 AssetBase asset = this._assetCache.GetAsset(inven.InventoryItems[packet.InventoryData.ItemID].AssetID);
405 if (asset != null)
406 {
407 PrimData primd = new PrimData(asset.Data);
408 Primitive nPrim = new Primitive(m_clientThreads, m_regionHandle, this);
409 nPrim.CreateFromStorage(primd, packet.RezData.RayEnd, this._primCount, true);
410 this.Entities.Add(nPrim.uuid, nPrim);
411 this._primCount++;
412 this._inventoryCache.DeleteInventoryItem(remoteClient, packet.InventoryData.ItemID);
413 }
329 } 414 }
330 } 415 }
331
332 } 416 }
333 417
334 public bool Backup() 418 public bool Backup()