From f60bc970eb925cd245cc77b1ae700b28d4589163 Mon Sep 17 00:00:00 2001 From: MW Date: Thu, 8 Mar 2007 13:21:24 +0000 Subject: Another attemp to fix the Session Logout bug World map data is now saved in database and recovered on startup. Primitives are now backed up to a local database and reloaded on startup. --- src/world/Entity.cs | 5 +++ src/world/Primitive.cs | 110 ++++++++++++++++++++++++++++++++++------------ src/world/World.cs | 115 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 184 insertions(+), 46 deletions(-) (limited to 'src/world') diff --git a/src/world/Entity.cs b/src/world/Entity.cs index 147478b..ee4b2e4 100644 --- a/src/world/Entity.cs +++ b/src/world/Entity.cs @@ -58,5 +58,10 @@ namespace OpenSim.world return mesh; } + + public virtual void BackUp() + { + + } } } diff --git a/src/world/Primitive.cs b/src/world/Primitive.cs index 1fb7142..6029f76 100644 --- a/src/world/Primitive.cs +++ b/src/world/Primitive.cs @@ -4,6 +4,7 @@ using System.Text; using OpenSim.types; using libsecondlife; using libsecondlife.Packets; +using GridInterfaces; namespace OpenSim.world { @@ -15,7 +16,7 @@ namespace OpenSim.world protected bool newPrimFlag; protected bool updateFlag; protected ObjectUpdatePacket OurPacket; - + public bool UpdateFlag { get @@ -69,6 +70,14 @@ namespace OpenSim.world } this.updateFlag = false; } + + } + + public void UpdateClient(OpenSimClient RemoteClient) + { + byte[] pb = this.position.GetBytes(); + Array.Copy(pb, 0, OurPacket.ObjectData[0].ObjectData, 0, pb.Length); + RemoteClient.OutPacket(OurPacket); } public void CreateFromPacket( ObjectAddPacket addPacket, LLUUID agentID, uint localID) @@ -118,8 +127,7 @@ namespace OpenSim.world //finish off copying rest of shape data objupdate.ObjectData[0].ID = (uint)(localID); - objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efefda" + (localID- 702000).ToString("000")); - + objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efef" + (localID- 702000).ToString("00000")); objupdate.ObjectData[0].ObjectData = new byte[60]; objupdate.ObjectData[0].ObjectData[46] = 128; objupdate.ObjectData[0].ObjectData[47] = 63; @@ -135,6 +143,67 @@ namespace OpenSim.world this.OurPacket = objupdate; } + public void CreateFromStorage(PrimStorage store) + { + //need to clean this up as it shares a lot of code with CreateFromPacket() + ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); + objupdate.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle; + objupdate.RegionData.TimeDilation = 64096; + objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; + + this.primData = store.Data; + objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock(); + objupdate.ObjectData[0].PSBlock = new byte[0]; + objupdate.ObjectData[0].ExtraParams = new byte[1]; + objupdate.ObjectData[0].MediaURL = new byte[0]; + objupdate.ObjectData[0].NameValue = new byte[0]; + objupdate.ObjectData[0].PSBlock = new byte[0]; + objupdate.ObjectData[0].Text = new byte[0]; + objupdate.ObjectData[0].TextColor = new byte[4]; + objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0,0,0); + objupdate.ObjectData[0].JointPivot = new LLVector3(0,0,0); + objupdate.ObjectData[0].Material = 3; + objupdate.ObjectData[0].UpdateFlags=32+65536+131072+256+4+8+2048+524288+268435456; + objupdate.ObjectData[0].TextureAnim = new byte[0]; + objupdate.ObjectData[0].Sound = LLUUID.Zero; + LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); + objupdate.ObjectData[0].TextureEntry = ntex.ToBytes(); + objupdate.ObjectData[0].State = 0; + objupdate.ObjectData[0].Data = new byte[0]; + objupdate.ObjectData[0].OwnerID = this.primData.OwnerID; + objupdate.ObjectData[0].PCode = this.primData.PCode; + objupdate.ObjectData[0].PathBegin = this.primData.PathBegin; + objupdate.ObjectData[0].PathEnd = this.primData.PathEnd; + objupdate.ObjectData[0].PathScaleX = this.primData.PathScaleX; + objupdate.ObjectData[0].PathScaleY = this.primData.PathScaleY; + objupdate.ObjectData[0].PathShearX = this.primData.PathShearX; + objupdate.ObjectData[0].PathShearY = this.primData.PathShearY; + objupdate.ObjectData[0].PathSkew = this.primData.PathSkew; + objupdate.ObjectData[0].ProfileBegin = this.primData.ProfileBegin; + objupdate.ObjectData[0].ProfileEnd = this.primData.ProfileEnd; + objupdate.ObjectData[0].Scale = this.primData.Scale; + objupdate.ObjectData[0].PathCurve = this.primData.PathCurve; + objupdate.ObjectData[0].ProfileCurve = this.primData.ProfileCurve; + objupdate.ObjectData[0].ParentID = 0; + objupdate.ObjectData[0].ProfileHollow = this.primData.ProfileHollow; + //finish off copying rest of shape data + + objupdate.ObjectData[0].ID = (uint)store.LocalID; + objupdate.ObjectData[0].FullID = store.FullID; + + objupdate.ObjectData[0].ObjectData = new byte[60]; + objupdate.ObjectData[0].ObjectData[46] = 128; + objupdate.ObjectData[0].ObjectData[47] = 63; + LLVector3 pos1= store.Position; + //update position + byte[] pb = pos1.GetBytes(); + Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length); + + this.uuid = objupdate.ObjectData[0].FullID; + this.localid = objupdate.ObjectData[0].ID; + this.position = pos1; + this.OurPacket = objupdate; + } public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedBlock() { uint ID = this.localid; @@ -200,30 +269,17 @@ namespace OpenSim.world dat.Data=bytes; return dat; } + + public override void BackUp() + { + PrimStorage pStore = new PrimStorage(); + pStore.Data = this.primData; + pStore.FullID = this.uuid; + pStore.LocalID = this.localid; + pStore.Position = this.position; + pStore.Rotation = new LLQuaternion(this.rotation.x, this.rotation.y, this.rotation.z , this.rotation.w); + OpenSim_Main.local_world.localStorage.StorePrim(pStore); + } } - public class PrimData - { - public LLUUID OwnerID; - public byte PCode; - public byte PathBegin; - public byte PathEnd; - public byte PathScaleX; - public byte PathScaleY; - public byte PathShearX; - public byte PathShearY; - public sbyte PathSkew; - public byte ProfileBegin; - public byte ProfileEnd; - public LLVector3 Scale; - public byte PathCurve; - public byte ProfileCurve; - public uint ParentID=0; - public byte ProfileHollow; - - public PrimData() - { - - } - } } diff --git a/src/world/World.cs b/src/world/World.cs index f6f58c7..6be9dd2 100644 --- a/src/world/World.cs +++ b/src/world/World.cs @@ -3,12 +3,14 @@ using libsecondlife; using libsecondlife.Packets; using System.Collections.Generic; using System.Text; +using System.Reflection; using System.IO; using PhysicsSystem; +using GridInterfaces; namespace OpenSim.world { - public class World + public class World : ILocalStorageReceiver { public Dictionary Entities; public float[] LandMap; @@ -17,9 +19,10 @@ namespace OpenSim.world private PhysicsScene phyScene; private float timeStep= 0.1f; private libsecondlife.TerrainManager TerrainManager; - + public ILocalStorage localStorage; private Random Rand = new Random(); private uint _primCount = 702000; + private int storageCount; public World() { @@ -48,8 +51,7 @@ namespace OpenSim.world public void Update() { - - if(this.phyScene.IsThreaded) + if(this.phyScene.IsThreaded) { this.phyScene.GetResults(); @@ -66,24 +68,95 @@ namespace OpenSim.world { Entities[UUID].update(); } + + //backup world data + this.storageCount++; + if(storageCount> 1200) //set to how often you want to backup (currently set for about every 2 minutes) + { + this.Backup(); + storageCount =0; + } } + public bool LoadStorageDLL(string dllName) + { + Assembly pluginAssembly = Assembly.LoadFrom(dllName); + ILocalStorage store = null; + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("ILocalStorage", true); + + if (typeInterface != null) + { + ILocalStorage plug = (ILocalStorage)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + store = plug; + break; + } + + typeInterface = null; + } + } + } + pluginAssembly = null; + this.localStorage = store; + return(store == null); + } + + public void LoadPrimsFromStorage() + { + ServerConsole.MainConsole.Instance.WriteLine("World.cs: LoadPrimsFromStorage() - Loading primitives"); + this.localStorage.LoadPrimitives(this); + } + + public void PrimFromStorage(PrimStorage prim) + { + if(prim.LocalID >= this._primCount) + { + _primCount = prim.LocalID + 1; + } + ServerConsole.MainConsole.Instance.WriteLine("World.cs: PrimFromStorage() - Reloading prim (localId "+ prim.LocalID+ " ) from storage"); + Primitive nPrim = new Primitive(); + nPrim.CreateFromStorage(prim); + this.Entities.Add(nPrim.uuid, nPrim); + } + + public void Close() + { + this.localStorage.ShutDown(); + } + public void SendLayerData(OpenSimClient RemoteClient) { int[] patches = new int[4]; - for (int y = 0; y < 16; y++) - { - for (int x = 0; x < 16; x = x + 4) - { - patches[0] = x + 0 + y * 16; - patches[1] = x + 1 + y * 16; - patches[2] = x + 2 + y * 16; - patches[3] = x + 3 + y * 16; + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x = x + 4) + { + patches[0] = x + 0 + y * 16; + patches[1] = x + 1 + y * 16; + patches[2] = x + 2 + y * 16; + patches[3] = x + 3 + y * 16; - Packet layerpack = TerrainManager.CreateLandPacket(LandMap, patches); - RemoteClient.OutPacket(layerpack); - } - } + Packet layerpack = TerrainManager.CreateLandPacket(LandMap, patches); + RemoteClient.OutPacket(layerpack); + } + } + } + + public void GetInitialPrims(OpenSimClient RemoteClient) + { + foreach (libsecondlife.LLUUID UUID in Entities.Keys) + { + if(Entities[UUID].ToString()== "OpenSim.world.Primitive") + { + ((OpenSim.world.Primitive)Entities[UUID]).UpdateClient(RemoteClient); + } + } } public void AddViewerAgent(OpenSimClient AgentClient) { @@ -96,7 +169,7 @@ namespace OpenSim.world NewAvatar.PhysActor = this.phyScene.AddAvatar(new PhysicsVector(NewAvatar.position.X, NewAvatar.position.Y, NewAvatar.position.Z)); //this.Update(); // will work for now, but needs to be optimised so we don't update everything in the sim for each new user this.Entities.Add(AgentClient.AgentID, NewAvatar); - } + } public void AddNewPrim(ObjectAddPacket addPacket, OpenSimClient AgentClient) { @@ -109,8 +182,12 @@ namespace OpenSim.world public bool Backup() { /* TODO: Save the current world entities state. */ - - return false; + ServerConsole.MainConsole.Instance.WriteLine("World.cs: Backup() - Backing up Primitives"); + foreach (libsecondlife.LLUUID UUID in Entities.Keys) + { + Entities[UUID].BackUp(); + } + return true; } } -- cgit v1.1